#include <bits/stdc++.h>
using namespace std;
const int INF = 0x3f3f3f3f;
const int N = 100005;
struct edge {
  int v, next, w;
} e[N << 1];
int head[N], ecnt;
void add_edge(int a, int b, int c) {
  e[ecnt].v = a;
  e[ecnt].w = c;
  e[ecnt].next = head[b];
  head[b] = ecnt++;
  e[ecnt].v = b;
  e[ecnt].w = c;
  e[ecnt].next = head[a];
  head[a] = ecnt++;
}
pair<int, int> tds[N], ds[N];
bool centroid[N];
int subtree_size[N];
int l, tot, tot2;
long long ans;
int bit[N], n, K;
inline int lowbit(int x) { return x & -x; }
void add(int x, int val) {
  ++x;
  if (x <= 0) return;
  for (int i = x; i <= n + 1; i += lowbit(i)) bit[i] += val;
}
int sum(int x) {
  ++x;
  if (x <= 0) return 0;
  if (x > n + 1) x = n + 1;
  int ret = 0;
  for (int i = x; i > 0; i -= lowbit(i)) ret += bit[i];
  return ret;
}
bool cmp(const pair<int, int> &x, const pair<int, int> &y) {
  return x.second == y.second ? x.first < y.first : x.second < y.second;
}
long long calc(pair<int, int> data[], int len) {
  sort(data, data + len, cmp);
  long long ret = 0;
  memset(bit, 0, (n + 2) * sizeof(int));
  int j = len;
  for (int i = 0; i < len; ++i) add(data[i].first, 1);
  for (int i = 0; i < len; ++i) {
    while (j > i && data[i].second + data[j - 1].second > K) {
      add(data[j - 1].first, -1);
      --j;
    }
    if (j <= i) break;
    ret += sum(l - data[i].first);
    add(data[i].first, -1);
    if (data[i].first * 2 <= l) --ret;
  }
  return ret;
}
pair<int, int> search_centroid(int s, int p, int t) {
  pair<int, int> res = make_pair(INF, -1);
  int m = 0;
  subtree_size[s] = 1;
  for (int i = head[s]; ~i; i = e[i].next) {
    int v = e[i].v;
    if (v == p || centroid[v]) continue;
    res = min(res, search_centroid(v, s, t));
    m = max(m, subtree_size[v]);
    subtree_size[s] += subtree_size[v];
  }
  m = max(m, t - subtree_size[s]);
  res = min(res, make_pair(m, s));
  return res;
}
void enumerate_paths(int s, int p, int l, long long d) {
  ds[tot2++] = tds[tot++] = make_pair(l, d);
  for (int i = head[s]; ~i; i = e[i].next) {
    int v = e[i].v, w = e[i].w;
    if (v == p || centroid[v]) continue;
    enumerate_paths(v, s, l + 1, d + w);
  }
}
void solve_subproblem(int v) {
  pair<int, int> ret = search_centroid(v, -1, subtree_size[v]);
  int s = ret.second;
  n = ret.first;
  centroid[s] = true;
  tot2 = 0;
  ds[tot2++] = make_pair(0, 0);
  for (int i = head[s]; ~i; i = e[i].next) {
    int v = e[i].v, w = e[i].w;
    if (centroid[v]) continue;
    tot = 0;
    enumerate_paths(v, s, 1, w);
    subtree_size[v] = tot;
    ans -= calc(tds, tot);
  }
  ans += calc(ds, tot2);
  for (int i = head[s]; ~i; i = e[i].next) {
    if (centroid[e[i].v]) continue;
    solve_subproblem(e[i].v);
  }
  centroid[s] = false;
}
int main() {
  scanf("%d%d%d", &n, &l, &K);
  memset(centroid, false, sizeof(centroid));
  memset(head, 0xff, sizeof(head));
  ecnt = 0;
  int a, b, c;
  for (int i = 1; i < n; ++i) {
    a = i + 1;
    scanf("%d%d", &b, &c);
    add_edge(a, b, c);
  }
  ans = 0;
  subtree_size[1] = n;
  solve_subproblem(1);
  printf("%I64d", ans);
}
