#include <bits/stdc++.h>
using namespace std;
template <class T>
T sqr(T x) {
  return x * x;
}
const int maxn = 1e6;
vector<pair<int, int> > g[maxn];
int x, y, z;
long long tree[maxn];
vector<pair<int, int> > path;
vector<int> modify;
int root, l, w, n, sum;
long long ans;
int sz[maxn], f[maxn], visit[maxn], depth[maxn], dis[maxn];
void findroot(int k, int last) {
  sz[k] = 1;
  f[k] = 0;
  for (int i = 0; i < g[k].size(); i++)
    if (g[k][i].first != last && !visit[g[k][i].first]) {
      findroot(g[k][i].first, k);
      sz[k] += sz[g[k][i].first];
      f[k] = max(f[k], sz[g[k][i].first]);
    }
  f[k] = max(f[k], sum - sz[k]);
  if (f[root] > f[k]) root = k;
}
void dfs_dis(int k, int last) {
  if (k != root) path.push_back(pair<int, int>(dis[k], depth[k]));
  for (int i = 0; i < g[k].size(); i++)
    if (g[k][i].first != last && !visit[g[k][i].first]) {
      depth[g[k][i].first] = depth[k] + 1;
      dis[g[k][i].first] = dis[k] + g[k][i].second;
      dfs_dis(g[k][i].first, k);
    }
}
inline void insert(int k, int s) {
  while (k <= n) {
    tree[k] += s;
    k += k & -k;
  }
}
inline long long query(int k) {
  long long ret = 0;
  while (k > 0) {
    ret += tree[k];
    k -= k & -k;
  }
  return ret;
}
inline long long calc() {
  if (path.empty()) return 0;
  long long ans = 0;
  sort(path.begin(), path.end());
  int tem = 0;
  int psz = path.size();
  for (int i = path.size() - 1; i >= 0; i--) {
    while (tem < psz && path[tem].first + path[i].first <= w) {
      insert(path[tem].second, 1);
      modify.push_back(path[tem++].second);
    }
    if (path[i].first * 2 <= w && path[i].second * 2 <= l) ans--;
    ans += query(l - path[i].second);
  }
  return ans / 2;
}
inline void releases() {
  for (int i = 0; i < modify.size(); i++) insert(modify[i], -1);
  modify.clear();
  path.clear();
}
void divide(int k) {
  visit[k] = 1;
  depth[k] = dis[k] = 0;
  dfs_dis(k, -1);
  for (int i = 0; i < path.size(); i++)
    if (path[i].first <= w && path[i].second <= l) ans++;
  ans += calc();
  releases();
  for (int i = 0; i < g[k].size(); i++)
    if (!visit[g[k][i].first]) {
      dfs_dis(g[k][i].first, k);
      ans -= calc();
      releases();
    }
  for (int i = 0; i < g[k].size(); i++)
    if (!visit[g[k][i].first]) {
      root = 0;
      sum = sz[g[k][i].first];
      findroot(g[k][i].first, -1);
      divide(root);
    }
}
int main() {
  scanf("%d%d%d", &n, &l, &w);
  for (int i = 1; i <= n - 1; i++) {
    scanf("%d%d", &x, &y);
    g[x].push_back(pair<int, int>(i + 1, y));
    g[i + 1].push_back(pair<int, int>(x, y));
  }
  sum = n;
  f[0] = 10 * n + 1;
  root = 0;
  findroot(1, -1);
  divide(root);
  cout << ans << endl;
}
