#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
struct B {
ll cost, gain;
bool operator<(const B& x) const { return cost > x.cost || (cost == x.cost && gain < x.gain); }
};
int main() {
ios_base::sync_with_stdio(0), cin.tie(0);
ll n, s; cin >> n >> s;
vector<vector<int>> adj(n+1);
vector<ll> c(n+1);
for (int i = 1; i <= n; i++) {
ll cost, p; cin >> cost >> p;
c[i] = cost;
adj[p].push_back(i);
}
vector<priority_queue<B>> pqs(n+1);
auto dfs = [&](auto dfs, int u = 0) -> void {
auto &pq = pqs[u];
B cur = B{max(-c[u], 0ll), c[u]};
if (!adj[u].size()) {
if (c[u] > 0) pq.push(cur);
return;
}
for (int v : adj[u]) {
dfs(dfs, v);
auto &pq2 = pqs[v];
if (pq.size() < pq2.size()) pq.swap(pq2);
while (pq2.size()) pq.push(pq2.top()), pq2.pop();
}
while (pq.size()) {
B oth = pq.top();
if (cur.gain <= 0) {
pq.pop();
cur = B{max(cur.cost, oth.cost-cur.gain), cur.gain+oth.gain};
}
else {
if (cur.cost > oth.cost) {
pq.pop();
cur = B{cur.cost, cur.gain+oth.gain};
}
else {
pq.push(cur);
break;
}
}
}
if (!pq.size()) pq.push(cur);
if (pq.top().gain <= 0 && pq.size() == 1) pq.pop();
};
dfs(dfs);
auto &pq = pqs[0];
ll ans = 0;
while (pq.size()) {
auto [cost, gain] = pq.top(); pq.pop();
if (s+ans >= cost) ans += gain;
}
cout << ans << endl;
}