#include <bits/stdc++.h>
using namespace std;
const int MAXN = 1e5 + 50;
int tree[MAXN];
int sum(int p) {
  p++;
  int res = 0;
  while (p > 0) {
    res += tree[p];
    p -= (p & -p);
  }
  return res;
}
void update(int p, int val, int n) {
  p++;
  while (p <= n) {
    tree[p] += val;
    p += (p & -p);
  }
}
int n, L, W;
struct Node {
  int to, w;
};
vector<Node> adj[MAXN];
void readInput() {
  cin >> n >> L >> W;
  for (int i = 2; i <= n; i++) {
    int p, w;
    cin >> p >> w;
    adj[i].push_back({p, w});
    adj[p].push_back({i, w});
  }
}
bool vis[MAXN];
int sz[MAXN];
void dfsSize(int v, int p) {
  sz[v] = 1;
  for (auto c : adj[v])
    if (!vis[c.to] && c.to != p) {
      dfsSize(c.to, v);
      sz[v] += sz[c.to];
    }
}
int findCtr(int v, int p, int size) {
  for (auto c : adj[v])
    if (!vis[c.to] && c.to != p && sz[c.to] > size / 2)
      return findCtr(c.to, v, size);
  return v;
}
int dsum[MAXN], wsum[MAXN];
long long calc(int v, int p) {
  long long cnt = 0;
  vector<pair<int, int> > t;
  queue<pair<int, int> > que;
  que.emplace(v, p);
  while (!que.empty()) {
    int v, p;
    tie(v, p) = que.front();
    que.pop();
    t.emplace_back(dsum[v], wsum[v]);
    for (auto c : adj[v])
      if (!vis[c.to] && c.to != p) {
        dsum[c.to] = dsum[v] + 1;
        wsum[c.to] = wsum[v] + c.w;
        que.emplace(c.to, v);
      }
  }
  sort(t.begin(), t.end(),
       [](const pair<int, int> &a, const pair<int, int> &b) {
         return a.second < b.second;
       });
  int pos = 0;
  for (int i = (int)t.size() - 1; i >= 0; i--) {
    while (pos < (int)t.size() && t[pos].second + t[i].second <= W)
      update(t[pos++].first, 1, n + 1);
    cnt += sum(L - t[i].first);
  }
  for (auto e : t)
    if (2 * e.first <= L && 2 * e.second <= W) cnt--;
  for (int i = 0; i < pos; i++) update(t[i].first, -1, n + 1);
  return cnt / 2;
}
long long decompose() {
  long long cnt = 0;
  queue<int> que;
  que.push(1);
  while (!que.empty()) {
    int v = que.front();
    que.pop();
    dfsSize(v, -1);
    int ctr = findCtr(v, -1, sz[v]);
    dsum[ctr] = wsum[ctr] = 0;
    cnt += calc(ctr, -1);
    for (auto c : adj[ctr])
      if (!vis[c.to]) {
        dsum[c.to] = 1, wsum[c.to] = c.w;
        cnt -= calc(c.to, ctr);
      }
    vis[ctr] = true;
    for (auto c : adj[ctr])
      if (!vis[c.to]) que.push(c.to);
  }
  return cnt;
}
int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  readInput();
  cout << decompose() << endl;
}
