#include <bits/stdc++.h>
using namespace std;
const int MAXN = 1e5 + 10;
const int MAXM = 1e5 + 10;
const int INF = 1e9;
struct edge {
  int u, v;
  long long w;
  int next;
} e[MAXM * 2];
int first[MAXN];
int idx;
int n;
long long len, wei;
struct node {
  long long weight, dist;
  int id;
} p[MAXN];
bool cmp(node x, node y) {
  if (x.weight == y.weight) return x.dist < y.dist;
  return x.weight < y.weight;
}
void add(int a, int b, long long c) {
  e[idx].u = a;
  e[idx].v = b;
  e[idx].w = c;
  e[idx].next = first[a];
  first[a] = idx++;
}
void init() {
  fill(first, first + n + 1, -1);
  idx = 0;
}
namespace BIT {
long long c[MAXN];
int n;
int lowbit(int x) { return x & (-x); }
void updata(int i, int k) {
  while (i <= n) {
    c[i] += k;
    i += lowbit(i);
  }
}
long long getsum(int i) {
  long long res = 0;
  while (i > 0) {
    res += c[i];
    i -= lowbit(i);
  }
  return res;
}
void change(int x, int k) { updata(x, k); }
long long query(int l, int r) {
  if (l <= 0 || r <= 0) return 0;
  return getsum(r) - getsum(l - 1);
}
void init(int _n) {
  n = _n;
  fill(c, c + n + 1, 0);
}
};  // namespace BIT
int sz[MAXN], mson[MAXN], vis[MAXN];
int tolsize, root, tol;
long long res;
void get_root(int x, int fa) {
  sz[x] = 1;
  mson[x] = 0;
  for (int i = first[x]; i != -1; i = e[i].next) {
    int v = e[i].v;
    if (vis[v] || v == fa) continue;
    get_root(v, x);
    sz[x] += sz[v];
    if (sz[v] > mson[x]) mson[x] = sz[v];
  }
  if (tolsize - sz[x] > mson[x]) mson[x] = tolsize - sz[x];
  if (mson[x] < mson[root]) root = x;
}
void get_dis(int x, int fa, long long w, long long l) {
  p[++tol].weight = w;
  p[tol].dist = l;
  for (int i = first[x]; i != -1; i = e[i].next) {
    int v = e[i].v;
    if (v == fa || vis[v]) continue;
    get_dis(v, x, w + e[i].w, l + 1);
  }
}
int right_bound(int l, long long x) {
  int ans = 0, r = tol;
  while (l <= r) {
    int mid = (l + r) >> 1;
    if (p[mid].weight <= x)
      ans = mid, l = mid + 1;
    else
      r = mid - 1;
  }
  return ans;
}
long long cal(int x, long long w, long long le) {
  long long ans = 0;
  tol = 0;
  get_dis(x, 0, w, le);
  sort(p + 1, p + tol + 1, cmp);
  int l = 1;
  BIT::init(tol + 1);
  long long maxdist = 0;
  for (int i = 1; i <= tol; i++) {
    maxdist = max(maxdist, p[i].dist);
    BIT::change(p[i].dist + 1, 1);
  }
  int last = tol;
  while (l < tol && p[l].weight * 2 <= wei) {
    BIT::change(p[l].dist + 1, -1);
    while (p[l].weight + p[last].weight > wei && last > l) {
      BIT::change(p[last].dist + 1, -1);
      last--;
    }
    long long tmp = BIT::query(1, min(maxdist + 1, len - p[l].dist + 1));
    ans += tmp;
    l++;
  }
  return ans;
}
void solve(int x) {
  vis[x] = 1;
  res += cal(x, 0, 0);
  for (int i = first[x]; i != -1; i = e[i].next) {
    int v = e[i].v;
    if (vis[v]) continue;
    res -= cal(v, e[i].w, 1);
    tolsize = sz[v];
    root = 0;
    get_root(v, x);
    solve(root);
  }
}
int main() {
  scanf("%d%lld%lld", &n, &len, &wei);
  init();
  for (int i = 2; i <= n; i++) {
    int v;
    long long w;
    scanf("%d%lld", &v, &w);
    add(i, v, w);
    add(v, i, w);
  }
  tolsize = n;
  root = 0;
  mson[0] = INF;
  get_root(1, 0);
  solve(root);
  printf("%lld\n", res);
  return 0;
}
