#include <bits/stdc++.h>
using namespace std;
static const int Maxn = 100005;
static const int inf = 0x3f3f3f3f;
int n, L, W;
long long ans;
struct Edge {
  int to;
  int w;
  Edge *nxt;
};
struct Graph {
  static const int Maxn = ::Maxn;
  Edge e[Maxn << 1];
  Edge *head[Maxn], *cur_edge;
  inline void clear(int n = Maxn - 1) {
    __builtin_memset(head, 0, sizeof(*head) * (n + 1));
    cur_edge = e;
  }
  Graph() { clear(); }
  inline void add_edge(int u, int v, int w) {
    *cur_edge = (Edge){v, w, head[u]};
    head[u] = cur_edge++;
  }
} G;
bool vis[Maxn];
int sz[Maxn], mxson[Maxn];
int root, total, mnson;
void get_root(int u, int fa) {
  sz[u] = 1, mxson[u] = 0;
  for (Edge *i = G.head[u]; i; i = i->nxt) {
    int v = i->to;
    int w = i->w;
    if (v == fa || vis[v]) {
      continue;
    }
    get_root(v, u);
    sz[u] += sz[v];
    mxson[u] = max(mxson[u], sz[v]);
  }
  mxson[u] = max(mxson[u], total - sz[u]);
  if (mnson > mxson[u]) {
    root = u;
    mnson = mxson[u];
  }
}
int qsz;
pair<int, int> q[Maxn];
void get_dist(int u, int fa, int dist, int dep) {
  q[++qsz] = make_pair(dist, dep);
  for (Edge *i = G.head[u]; i; i = i->nxt) {
    int v = i->to;
    int w = i->w;
    if (v == fa || vis[v]) continue;
    get_dist(v, u, dist + w, dep + 1);
  }
}
int bit[Maxn];
inline void add(int x, int v) {
  ++x;
  if (x <= 0) {
    return;
  }
  while (x < Maxn) {
    bit[x] += v;
    x += x & -x;
  }
}
inline int ask(int x) {
  ++x;
  if (x <= 0) {
    return 0;
  }
  int res = 0;
  while (x) {
    res += bit[x];
    x -= x & -x;
  }
  return res;
}
inline long long solve(int u, int dist, int len) {
  qsz = 0;
  get_dist(u, 0, dist, len);
  sort(q + 1, q + qsz + 1);
  int l = 1, r = qsz;
  for (int i = 1; i <= qsz; ++i) {
    add(q[i].second, 1);
  }
  long long res = 0;
  while (l < r) {
    if (q[l].first + q[r].first <= W) {
      add(q[l].second, -1);
      res += ask(L - q[l].second);
      ++l;
    } else {
      add(q[r].second, -1);
      --r;
    }
  }
  add(q[l].second, -1);
  return res;
}
void divide_root(int u) {
  vis[u] = true;
  ans += solve(u, 0, 0);
  for (Edge *i = G.head[u]; i; i = i->nxt) {
    int v = i->to;
    int w = i->w;
    if (vis[v]) continue;
    ans -= solve(v, w, 1);
    total = sz[v];
    mnson = inf;
    root = 0;
    get_root(v, 0);
    divide_root(root);
  }
}
int main() {
  scanf("%d%d%d", &n, &L, &W);
  for (int i = 2; i <= n; ++i) {
    int fa, w;
    scanf("%d%d", &fa, &w);
    G.add_edge(fa, i, w);
    G.add_edge(i, fa, w);
  }
  mnson = inf;
  total = n;
  root = 0;
  memset(vis, false, sizeof(vis));
  get_root(1, 0);
  fprintf(stderr, "root = %d\n", root);
  divide_root(root);
  printf("%lld\n", ans);
  return 0;
}
