#include <bits/stdc++.h>
using namespace std;
char buffer[20 << 20], *S = buffer;
inline int Getint() {
  int x = 0, f = 1;
  while (*S < '0' || *S > '9')
    if (*S++ == '-') f = -1;
  while (*S >= '0' && *S <= '9') x = x * 10 + *S++ - '0';
  return x * f;
}
const int Maxn = 100005;
int n, L, W, h[Maxn];
int totsize, root, tot, size[Maxn], mx[Maxn];
long long ans = 0;
bool vis[Maxn];
struct edge {
  int to, next, w;
} e[Maxn * 2];
struct node {
  int w, l;
} path[Maxn];
int tr[Maxn * 2];
void add(int x, int val) {
  x++;
  for (int i = x; i <= 2 * n; i += i & -i) tr[i] += val;
}
int ask(int x) {
  int ans = 0;
  x++;
  if (x <= 0) return 0;
  for (int i = x; i; i -= i & -i) ans += tr[i];
  return ans;
}
void addedge(int x, int y, int z) {
  static int cnt;
  e[++cnt] = (edge){y, h[x], z};
  h[x] = cnt;
}
void getroot(int x, int fa) {
  size[x] = 1;
  mx[x] = 0;
  for (int i = h[x]; i; i = e[i].next) {
    int y = e[i].to;
    if (y == fa || vis[y]) continue;
    getroot(y, x);
    size[x] += size[y];
    mx[x] = max(mx[x], size[y]);
  }
  mx[x] = max(mx[x], totsize - size[x]);
  if (mx[x] < mx[root]) root = x;
}
void getsize(int x, int fa) {
  totsize++;
  for (int i = h[x]; i; i = e[i].next) {
    int y = e[i].to;
    if (y == fa || vis[y]) continue;
    getsize(y, x);
  }
}
void dfs(int x, int fa, int dep, int sum) {
  if (sum > W || dep > L) return;
  path[++tot] = (node){sum, dep};
  for (int i = h[x]; i; i = e[i].next) {
    int y = e[i].to;
    if (y == fa || vis[y]) continue;
    dfs(y, x, dep + 1, sum + e[i].w);
  }
}
bool cmp(const node &a, const node &b) { return a.w < b.w; }
long long calc(int x, int dep, int sum) {
  long long ret = 0;
  path[tot = 1] = (node){sum, dep};
  for (int i = h[x]; i; i = e[i].next) {
    int y = e[i].to;
    if (vis[y]) continue;
    dfs(y, x, dep + 1, sum + e[i].w);
  }
  sort(path + 1, path + tot + 1, cmp);
  int now = 1;
  for (int i = tot; i >= 1; i--) {
    while (now <= tot && path[now].w + path[i].w <= W)
      add(path[now].l, 1), now++;
    ret += ask(L - path[i].l);
  }
  for (int i = 1; i < now; i++) add(path[i].l, -1);
  for (int i = 1; i <= tot; i++)
    if (path[i].l * 2 <= L && path[i].w * 2 <= W) ret--;
  return ret;
}
void solve(int x) {
  vis[x] = 1;
  ans += calc(x, 0, 0);
  for (int i = h[x]; i; i = e[i].next) {
    int y = e[i].to;
    if (vis[y]) continue;
    ans -= calc(y, 1, e[i].w);
    root = 0;
    totsize = 0;
    getsize(y, x);
    getroot(y, x);
    solve(root);
  }
}
int main() {
  fread(buffer, 1, 20 << 20, stdin);
  n = Getint();
  L = Getint();
  W = Getint();
  for (int i = 2; i <= n; i++) {
    int fa = Getint(), v = Getint();
    addedge(fa, i, v);
    addedge(i, fa, v);
  }
  mx[0] = n + 1;
  root = 0;
  totsize = n;
  getroot(1, 0);
  solve(root);
  cout << ans / 2 << "\n";
}
