#include <bits/stdc++.h>
using namespace std;
const int MAXN = 1e5 + 15, LG = 17;
struct fen {
  int bit[MAXN];
  void upd(int p, int v) {
    for (p++; p < MAXN; p += p & -p) bit[p] += v;
  }
  int get(int x) {
    int ret = 0;
    for (x++; x; x -= x & -x) ret += bit[x];
    return ret;
  }
} FN;
void pre_dfs(int);
int build(int);
int f_cen(int);
void init(int, int);
void add(int, int);
int get_dist(int, int);
long long calc(vector<pair<int, int>>);
vector<pair<int, int>> _(int, int);
pair<int, int> lca(int, int);
bool ch;
pair<int, int> par[LG][MAXN];
vector<pair<int, int>> pr[MAXN];
vector<int> adj[MAXN], sub[MAXN], g[MAXN];
int n, w, l, cen;
int sz[MAXN], level[MAXN];
bool block[MAXN];
long long ans[MAXN], local;
int32_t main() {
  ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0);
  cerr << "HELLO WORLD :)\n";
  cin >> n >> l >> w;
  for (int i = 1; i < n; i++) {
    int p, c;
    cin >> p >> c;
    p--;
    par[0][i] = {p, c};
    adj[p].push_back(i);
  }
  pre_dfs(0);
  cen = build(0);
  calc(pr[cen]);
  return cout << local << '\n', false;
}
void pre_dfs(int v) {
  sz[v] = 1;
  for (int i = 1; i < LG; i++)
    par[i][v] = {par[i - 1][par[i - 1][v].first].first,
                 par[i - 1][v].second + par[i - 1][par[i - 1][v].first].second};
  for (auto u : adj[v]) {
    level[u] = level[v] + 1;
    pre_dfs(u);
    sz[v] += sz[u];
  }
}
pair<int, int> lca(int u, int v) {
  if (level[u] < level[v]) swap(u, v);
  int sm = 0, dif = level[u] - level[v];
  for (int i = 0; i < LG; i++)
    if (dif >> i & 1) sm += par[i][u].second, u = par[i][u].first;
  if (u == v) return {u, sm};
  for (int i = LG - 1; ~i; i--)
    if (par[i][v].first != par[i][u].first) {
      sm += par[i][v].second + par[i][u].second;
      u = par[i][u].first;
      v = par[i][v].first;
    }
  sm += par[0][v].second + par[0][u].second;
  return {par[0][v].first, sm};
}
int get_dist(int u, int v) {
  return level[v] + level[u] - 2 * level[lca(u, v).first];
}
void init(int v, int p) {
  int x = sz[v];
  for (;; v = par[0][v].first) {
    sz[v] -= x;
    if (v == p) return;
  }
}
int f_cen(int v) {
  int ss = sz[v];
  bool flag = 1;
  while (flag) {
    flag = 0;
    for (auto u : adj[v])
      if (!block[u] && (sz[u] << 1) > ss) {
        v = u;
        flag = 1;
        break;
      }
  }
  return v;
}
int build(int v) {
  int root = v;
  v = f_cen(root);
  init(v, root);
  block[v] = 1;
  sub[v].push_back(v);
  pr[v].push_back({0, 0});
  for (auto u : adj[v])
    if (!block[u]) add(v, build(u));
  if (v != root) add(v, build(root));
  ans[v] = calc(pr[v]) - 1;
  for (auto u : g[v]) ans[v] -= calc(_(u, v));
  local += (ans[v] >> 1);
  return v;
}
long long calc(vector<pair<int, int>> vec) {
  int p2 = 0;
  long long ret = 0;
  sort(vec.begin(), vec.end());
  for (int p1 = (int)vec.size() - 1; ~p1; p1--) {
    while (p2 < (int)vec.size() && vec[p2].first + vec[p1].first <= w)
      FN.upd(vec[p2].second, 1), p2++;
    if (vec[p1].second <= l) ret += FN.get(l - vec[p1].second);
  }
  for (int i = 0; i < p2; i++) FN.upd(vec[i].second, -1);
  return ret;
}
vector<pair<int, int>> _(int u, int v) {
  vector<pair<int, int>> mem;
  for (auto i : sub[u]) mem.push_back({lca(i, v).second, get_dist(i, v)});
  return mem;
}
void add(int v, int u) {
  g[v].push_back(u);
  for (auto i : sub[u]) {
    sub[v].push_back(i);
    pr[v].push_back({lca(i, v).second, get_dist(i, v)});
  }
  ans[v] -= ans[u];
}
