#include <bits/stdc++.h>
using namespace std;
const long long maxn = 1e6 + 10, N = 500 + 10, SQRT = 300, base = 800287,
                mod = 1e9 + 7, INF = 1e9 + 1, lg = 23;
const long double eps = 1e-4;
long long n, L, W, ans, sz[maxn], h[maxn], dist[maxn], fen[maxn];
vector<pair<long long, long long> > edges[maxn];
vector<long long> ask[maxn];
vector<pair<long long, long long> > query, tmp;
bool death[maxn];
long long bs(long long k) {
  if (!(long long)query.size() || k >= (query.back()).first) {
    return (long long)query.size();
  }
  long long l = -1, r = (long long)query.size() - 1;
  while (l < r - 1) {
    long long m = (l + r) / 2;
    if (query[m].first > k) {
      r = m;
    } else {
      l = m;
    }
  }
  return r;
}
void dfs1(long long v, long long par = -1) {
  sz[v] = 1;
  for (auto u : edges[v]) {
    if (u.first != par && !death[u.first]) {
      h[u.first] = h[v] + 1;
      dist[u.first] = dist[v] + u.second;
      dfs1(u.first, v);
      sz[v] += sz[u.first];
    }
  }
}
long long dfs2(long long v, long long par = -1) {
  long long res = 0;
  if (par != -1) {
    query.push_back({dist[v], h[v]});
  }
  for (auto u : edges[v]) {
    if (u.first != par && !death[u.first]) {
      res += (h[u.first] <= L && dist[u.first] <= W);
      res += dfs2(u.first, v);
    }
  }
  return res;
}
void dfs3(long long v, long long par = -1) {
  if (par != -1) {
    long long id = bs(W - dist[v]);
    ask[id].push_back(L - h[v]);
  }
  for (auto u : edges[v]) {
    if (u.first != par && !death[u.first]) {
      dfs3(u.first, v);
    }
  }
}
void add(long long p, long long val) {
  for (; p < maxn; p += (p & -p)) {
    fen[p] += val;
  }
}
long long get(long long p) {
  long long res = 0;
  for (; p > 0; p -= (p & -p)) {
    res += fen[p];
  }
  return res;
}
void calc(long long v) {
  long long res = 0;
  tmp.clear();
  h[v] = dist[v] = 0, dfs1(v);
  tmp.push_back({1, v});
  for (auto u : edges[v]) {
    if (!death[u.first]) {
      tmp.push_back({-1, u.first});
    }
  }
  for (auto q : tmp) {
    query.clear();
    long long type = q.first, vv = q.second, par = (vv == v ? -1 : v);
    dfs2(vv, par), sort(query.begin(), query.end());
    for (long long i = 0; i <= (long long)query.size(); ++i) {
      ask[i].clear();
    }
    dfs3(vv, par);
    for (long long i = 0; i <= (long long)query.size(); ++i) {
      for (auto u : ask[i]) {
        res += type * get(u);
      }
      if (i == (long long)query.size()) {
        break;
      }
      add(query[i].second, 1);
    }
    for (long long i = 0; i < (long long)query.size(); ++i) {
      add(query[i].second, -1);
    }
  }
  res /= 2;
  ans += res + dfs2(v);
}
long long find_centroid(long long v, long long total, long long par = -1) {
  for (auto u : edges[v]) {
    if (u.first != par && !death[u.first] && sz[u.first] > total / 2) {
      return find_centroid(u.first, total, v);
    }
  }
  return v;
}
inline void make_centroidtree(long long v) {
  dfs1(v);
  long long u = find_centroid(v, sz[v]);
  death[u] = 1;
  calc(u);
  for (auto r : edges[u]) {
    if (!death[r.first]) {
      make_centroidtree(r.first);
    }
  }
}
int32_t main() {
  ios::sync_with_stdio(0);
  cin.tie(0);
  cin >> n >> L >> W;
  for (long long i = 1; i < n; ++i) {
    long long x, y;
    cin >> x >> y;
    x--;
    edges[i].push_back({x, y});
    edges[x].push_back({i, y});
  }
  make_centroidtree(0);
  cout << ans << '\n';
}
