#include <bits/stdc++.h>
using namespace std;
const int T = 200005;
vector<pair<int, int> > g[T];
long long ans;
int son, sul, minn, center, i, j, N, l, L, W, a, w;
vector<pair<int, int> > child[T];
pair<int, int> V[T];
int node[T], size[T], block[T], s[T];
int prev(int x) { return x & (x - 1); }
int next(int x) { return (2 * x) - prev(x); }
int getsum(int l) {
  l += 3;
  int h = 0;
  while (l) {
    h += s[l];
    l = prev(l);
  }
  return h;
}
void update(int pos, int delta) {
  pos += 3;
  while (pos <= 100305) {
    s[pos] += delta;
    pos = next(pos);
  }
}
void recount(int v, int p, int len, int ww) {
  if (len > L || ww > W) return;
  ans += 2;
  for (int i = 0; i < g[v].size(); i++) {
    int to = g[v][i].first;
    if (p == to || block[to]) continue;
    recount(to, v, len + 1, ww + g[v][i].second);
  }
}
void dfs(int v, int p, int len, int ww) {
  if (len > L || ww > W) return;
  child[son].push_back(make_pair(ww, len));
  V[sul++] = make_pair(ww, len);
  for (int i = 0; i < g[v].size(); i++) {
    int to = g[v][i].first;
    if (to == p || block[to]) continue;
    dfs(to, v, len + 1, ww + g[v][i].second);
  }
}
void solve(int v) {
  son = 0;
  sul = 0;
  for (int i = 0; i < g[v].size(); i++)
    if (!block[g[v][i].first]) {
      child[son].clear();
      recount(g[v][i].first, v, 1, g[v][i].second);
      dfs(g[v][i].first, v, 1, g[v][i].second);
      son++;
    }
  sort(V, V + sul);
  for (int i = 0; i < son; i++) sort(child[i].begin(), child[i].end());
  for (int i = 0; i < sul; i++) update(V[i].second, 1);
  a = sul - 1;
  for (int i = 0; i < sul; i++) {
    while (a >= 0 && V[i].first + V[a].first > W) update(V[a].second, -1), a--;
    if (L > V[i].second) ans += getsum(L - V[i].second);
  }
  for (int i = 0; i <= a; i++) update(V[i].second, -1);
  if (getsum(100005)) exit(0);
  for (int i = 0; i < son; i++) {
    for (j = 0; j < child[i].size(); j++) update(child[i][j].second, 1);
    a = child[i].size() - 1;
    for (int j = 0; j < child[i].size(); j++) {
      while (a >= 0 && child[i][j].first + child[i][a].first > W)
        update(child[i][a].second, -1), a--;
      if (L > child[i][j].second) ans -= getsum(L - child[i][j].second);
    }
    for (int j = 0; j <= a; j++) update(child[i][j].second, -1);
    if (getsum(100005)) exit(0);
  }
}
void countsize(int v, int p) {
  node[l++] = v;
  size[v] = 1;
  for (int i = 0; i < g[v].size(); i++) {
    int to = g[v][i].first;
    if (block[to]) continue;
    if (to == p) continue;
    countsize(to, v);
    size[v] += size[to];
  }
}
void go(int v, int p) {
  center = v;
  l = 0;
  countsize(v, p);
  minn = 1000000500;
  for (int i = 0; i < l; i++)
    if (abs(size[node[i]] - size[v] / 2) < minn)
      minn = abs(size[node[i]] - size[v] / 2), center = node[i];
  block[center] = 1;
  solve(center);
  v = center;
  for (int i = 0; i < g[v].size(); i++) {
    int to = g[v][i].first;
    if (block[to] || to == p) continue;
    go(to, v);
  }
}
int main() {
  scanf("%d %d %d", &N, &L, &W);
  for (i = 1; i < N; i++) {
    scanf("%d %d", &a, &w);
    g[a].push_back(make_pair(i + 1, w));
    g[i + 1].push_back(make_pair(a, w));
  }
  go(1, -1);
  cout << ans / 2ll << endl;
}
