#include <bits/stdc++.h>   #pragma GCC optimize( Ofast )   #pragma GCC target( sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native )   using namespace std;   struct BIT {     vector<int> tree;     BIT(int sz) { tree = vector<int>(sz + 1, 0); }     void upd(int idx, int v) {       for (idx++; idx < tree.size(); idx += idx & -idx) {         tree[idx] += v;       }     }     int query(int idx) {       int res = 0;       for (idx++; idx > 0; idx -= idx & -idx) {         res += tree[idx];       }       return res;     }   };   int n, l, ss[100000];   long long w, res;   bool solved[100000];   vector<pair<int, long long> > adj[100000];   void dfs1(int node, int par = -1) {     ss[node] = 1;     for (const pair<int, long long> edge : adj[node]) {       int next = edge.first;       if (next != par && !solved[next]) {         dfs1(next, node);         ss[node] += ss[next];       }     }   }   int find(int node) {     dfs1(node);     int par = -1;     int total = ss[node];     while (1) {       bool breakout = true;       for (const pair<int, long long> edge : adj[node]) {         int next = edge.first;         if (!solved[next] && next != par && ss[next] * 2 > total) {           par = node;           node = next;           breakout = false;           break;         }       }       if (breakout) {         break;       }     }     return node;   }   vector<pair<int, long long> > combine(       vector<vector<pair<int, long long> > >& vec) {     vector<pair<int, long long> > res;     for (const vector<pair<int, long long> > v : vec) {       res.insert(res.end(), (v).begin(), (v).end());     }     return res;   }   long long count(const vector<pair<int, long long> >& _v) {     vector<pair<int, long long> > v(_v);     sort((v).begin(), (v).end(),          [](pair<int, long long>& a, pair<int, long long>& b) -> bool {            return make_pair(a.second, a.first) < make_pair(b.second, b.first);          });     vector<int> fVals;     for (const pair<int, long long> p : v) {       fVals.push_back(p.first);     }     sort((fVals).begin(), (fVals).end());     long long ret = 0;     int j = 0;     BIT x(fVals.size());     for (int i = (v.size()) - 1; i >= 0; i--) {       while (j < i && v[j].second + v[i].second <= w) {         x.upd(lower_bound((fVals).begin(), (fVals).end(), v[j++].first) -                   fVals.begin(),               1);       }       if (j > i) {         x.upd(lower_bound((fVals).begin(), (fVals).end(), v[--j].first) -                   fVals.begin(),               -1);       }       ret += x.query(upper_bound((fVals).begin(), (fVals).end(), l - v[i].first) -                      fVals.begin() - 1);     }     return ret;   }   void dfs2(int node, int par, vector<pair<int, long long> >& v, int depth = 0,             long long depth2 = 0) {     v.push_back(make_pair(depth, depth2));     for (const pair<int, long long> edge : adj[node]) {       int next = edge.first;       if (next != par && !solved[next]) {         dfs2(next, node, v, depth + 1, depth2 + edge.second);       }     }   }   void solve(int node) {     node = find(node);     vector<vector<pair<int, long long> > > vec;     vec.push_back(vector<pair<int, long long> >(1, make_pair(0, 0)));     for (const pair<int, long long> edge : adj[node]) {       int next = edge.first;       if (!solved[next]) {         vec.push_back(vector<pair<int, long long> >());         dfs2(next, node, vec.back(), 1, edge.second);       }     }     for (vector<pair<int, long long> >& v : vec) {       res -= count(v);     }     res += count(combine(vec));     solved[node] = true;     for (const pair<int, long long> edge : adj[node]) {       int next = edge.first;       if (!solved[next]) {         solve(next);       }     }   }   int main() {     ios::sync_with_stdio(false);     cin.tie(0);     cin >> n >> l >> w;     for (int i = 0; i < (n - 1); i++) {       int p;       long long weight;       cin >> p >> weight;       p--;       adj[p].push_back(make_pair(i + 1, weight));       adj[i + 1].push_back(make_pair(p, weight));     }     solve(0);     cout << res <<   n ;   }   