#include <bits/stdc++.h>
#pragma comment(linker, "/STACK:102400000,102400000")
using namespace std;
struct Edge {
  int to, len, next;
} e[1000050];
int now, n, l, w, first[100050], size[100050], q[100050], fat[100050],
    f[100050], g[100050], tree[100050];
pair<int, int> doing[100050];
long long ans;
bool vis[100050];
void Add(int x, int y, int z) {
  e[++now].to = y;
  e[now].len = z;
  e[now].next = first[x];
  first[x] = now;
}
void Size(int x, int fa) {
  int pt, next;
  size[x] = 1;
  for (pt = first[x]; pt; pt = e[pt].next) {
    next = e[pt].to;
    if (next == fa || vis[next]) continue;
    Size(next, x);
    size[x] += size[next];
  }
}
int Center(int x, int fa, int ori) {
  int pt, next;
  for (pt = first[x]; pt; pt = e[pt].next) {
    next = e[pt].to;
    if (next == fa || vis[next] || 2 * size[next] <= size[ori]) continue;
    return Center(next, x, ori);
  }
  return x;
}
void Solve(int x, int fa, int cnt, int len, int &high) {
  int pt, next, head, tail, i;
  q[head = tail = 0] = x;
  f[x] = cnt;
  g[x] = len;
  fat[x] = fa;
  for (; head <= tail; head++)
    for (pt = first[q[head]]; pt; pt = e[pt].next) {
      next = e[pt].to;
      if (next == fat[q[head]] || vis[next]) continue;
      q[++tail] = next;
      fat[next] = q[head];
      f[next] = f[q[head]] + 1;
      g[next] = g[q[head]] + e[pt].len;
    }
  for (i = 0; i <= tail; i++) doing[++high] = make_pair(g[q[i]], f[q[i]]);
}
void Update(int x, int add) {
  for (; x <= n; x += x & -x) tree[x] += add;
}
int Ask(int x) {
  int ans = 0;
  for (; x; x -= x & -x) ans += tree[x];
  return ans;
}
void Calc(int from, int to, int flag) {
  int i, j;
  long long add = 0;
  sort(doing + from, doing + to + 1);
  for (i = from; i <= to; i++) Update(doing[i].second, 1);
  j = to;
  for (i = from; i <= to; i++) {
    for (; j >= from && doing[i].first + doing[j].first > w; j--)
      Update(doing[j].second, -1);
    if (doing[i].second < l) add += Ask(l - doing[i].second);
    if (doing[i].first * 2 <= w && doing[i].second * 2 <= l) add--;
  }
  for (; j >= from; j--) Update(doing[j].second, -1);
  ans += flag * (add / 2);
}
void DFS(int x) {
  int pt, next, i, j, low, high;
  Size(x, x);
  x = Center(x, x, x);
  vis[x] = true;
  for (pt = first[x]; pt; pt = e[pt].next) {
    next = e[pt].to;
    if (vis[next]) continue;
    DFS(next);
  }
  high = 0;
  for (pt = first[x]; pt; pt = e[pt].next) {
    next = e[pt].to;
    if (vis[next]) continue;
    low = high + 1;
    Solve(next, x, 1, e[pt].len, high);
    Calc(low, high, -1);
  }
  Calc(1, high, 1);
  for (i = 1; i <= high; i++)
    if (doing[i].first <= w && doing[i].second <= l) ans++;
  vis[x] = false;
}
int main() {
  int i, x, y;
  while (scanf("%d%d%d", &n, &l, &w) != EOF) {
    memset(first, 0, sizeof(first));
    now = 0;
    for (i = 2; i <= n; i++) {
      scanf("%d%d", &x, &y);
      Add(i, x, y);
      Add(x, i, y);
    }
    ans = 0;
    DFS(1);
    printf("%I64d\n", ans);
  }
}
