#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;   }