#include <bits/stdc++.h>
using namespace std;
struct edge {
  int nxt, t, s;
} e[100010 << 1];
int head[100010], edge_cnt;
inline void add_edge(int x, int y, int z) {
  e[edge_cnt] = (edge){head[x], y, z};
  head[x] = edge_cnt++;
}
int Siz[100010], Mx[100010], All, Mn, rt;
bool vis[100010];
void dfs_rt(int x, int f) {
  Siz[x] = 1;
  Mx[x] = 0;
  int i;
  for (i = head[x]; ~i; i = e[i].nxt) {
    int to = e[i].t;
    if (vis[to] || to == f) {
      continue;
    }
    dfs_rt(to, x);
    Siz[x] += Siz[to];
    Mx[x] = max(Mx[x], Siz[to]);
  }
  Mx[x] = max(Mx[x], All - Siz[x]);
  if (Mx[x] < Mn) {
    Mn = Mx[x];
    rt = x;
  }
}
struct Binary_Indexed_Tree {
  int bit[100010], n;
  void Add(int i, int x) {
    while (i <= n) {
      bit[i] += x;
      i += i & -i;
    }
  }
  int Query(int i) {
    int res = 0;
    while (i > 0) {
      res += bit[i];
      i -= i & -i;
    }
    return res;
  }
} BIT;
struct node {
  int l, w;
  bool operator<(const node &_) const { return l < _.l; }
} A[100010];
int L, W, B[100010], tot, pos[100010];
long long Ans;
void dfs_dis(int x, int f, int dep, int sum) {
  A[++tot] = (node){dep, sum};
  int i;
  for (i = head[x]; ~i; i = e[i].nxt) {
    int to = e[i].t, val = e[i].s;
    if (vis[to] || to == f) {
      continue;
    }
    dfs_dis(to, x, dep + 1, sum + val);
  }
}
long long Calc(int x, int t, int s) {
  tot = 0;
  dfs_dis(x, x, t, s);
  sort(A + 1, A + 1 + tot);
  int i, j = tot;
  long long res = 0;
  for (i = 1; i <= tot; i++) {
    B[i] = A[i].w;
  }
  sort(B + 1, B + 1 + tot);
  int h = unique(B + 1, B + 1 + tot) - B - 1;
  BIT.n = h;
  for (i = 1; i <= tot; i++) {
    pos[i] = lower_bound(B + 1, B + 1 + h, A[i].w) - B;
    BIT.Add(pos[i], 1);
  }
  for (i = 1; i <= j; i++) {
    BIT.Add(pos[i], -1);
    if (i == j) {
      break;
    }
    while (i < j && A[i].l + A[j].l > L) {
      BIT.Add(pos[j--], -1);
    }
    int p = upper_bound(B + 1, B + 1 + h, W - A[i].w) - B - 1;
    res += BIT.Query(p);
  }
  return res;
}
void Solve(int x, int all) {
  if (all == 1) {
    return;
  }
  All = Mn = all;
  dfs_rt(x, x);
  Ans += Calc(rt, 0, 0);
  vis[rt] = 1;
  int i, Rt = rt;
  for (i = head[Rt]; ~i; i = e[i].nxt) {
    int to = e[i].t, val = e[i].s;
    if (vis[to]) {
      continue;
    }
    Ans -= Calc(to, 1, val);
    Solve(to, Siz[to] < Siz[Rt] ? Siz[to] : all - Siz[Rt]);
  }
}
int main() {
  memset(head, -1, sizeof(head));
  int n, i;
  scanf("%d%d%d", &n, &L, &W);
  for (i = 2; i <= n; i++) {
    int x, y;
    scanf("%d%d", &x, &y);
    add_edge(i, x, y);
    add_edge(x, i, y);
  }
  Solve(1, n);
  cout << Ans << " \n";
  return 0;
}
