#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef long double ld;
typedef pair<ll, ll> pll;
typedef pair<int, int> pii;
typedef vector<int> vi;
#define rep(i, a, b) for(int i = a; i < (b); ++i)
#define all(x) x.begin(), x.end()
#define sz(x) (int)(x).size()
constexpr ll inf = 4e18;
mt19937 mt(time(0));
struct segtree {
ll nt;
vector<pll> tree;
vector<ll> lz_add;
segtree(ll n) {
nt = 1;
while (nt < n) nt *= 2;
tree = vector<pll>(2*nt, pll(-inf, -inf));
lz_add = vector<ll>(2*nt);
for (ll i = 0; i < n; i++) {
tree[nt+i] = pll(-inf, i);
}
for (ll i = nt; i--;) {
tree[i] = max(tree[2*i], tree[2*i+1]);
}
}
void prop(ll k) {
tree[k].first += lz_add[k];
if (k < nt) {
lz_add[2*k] += lz_add[k];
lz_add[2*k+1] += lz_add[k];
}
lz_add[k] = 0;
}
pll get_max() {
return tree[1];
}
void range_add(ll l, ll r, ll v) { return range_add(1, 0, nt-1, l, r, v); }
void range_add(ll k, ll tl, ll tr, ll l, ll r, ll v) {
prop(k);
if (r < tl || l > tr) return;
if (l <= tl && r >= tr) {
lz_add[k] += v;
prop(k);
return;
}
ll mid = tl + (tr - tl) / 2;
range_add(2*k, tl, mid, l, r, v);
range_add(2*k+1, mid+1, tr, l, r, v);
tree[k] = max(tree[2*k], tree[2*k+1]);
}
void set(ll i, ll v) { return set(1, 0, nt-1, i, v); }
void set(ll k, ll tl, ll tr, ll i, ll v) {
prop(k);
if (i < tl || i > tr) return;
if (tl == tr) {
tree[k].first = v;
return;
}
ll mid = tl + (tr - tl) / 2;
set(2*k, tl, mid, i, v);
set(2*k+1, mid+1, tr, i, v);
tree[k] = max(tree[2*k], tree[2*k+1]);
}
ll get(ll i) { return get(1, 0, nt-1, i); }
ll get(ll k, ll tl, ll tr, ll i) {
prop(k);
if (tl == tr) return tree[k].first;
ll mid = tl + (tr - tl) / 2;
return i <= mid ? get(2*k, tl, mid, i) : get(2*k+1, mid+1, tr, i);
}
void print() {
for (ll i = 1; i < nt; i++) prop(i);
for (ll i = nt; i < 2*nt; i++) {
prop(i);
if (tree[i].first > -inf/2) cerr << tree[i].first << ' ';
else cerr << "- ";
}
cerr << endl;
}
};
struct tree_dsu {
vector<ll> p, lnk;
tree_dsu(vector<ll> &p) : p(p), lnk(sz(p)) {
iota(all(lnk), 0ll);
}
ll find(ll i) {
if (lnk[i] != i) lnk[i] = find(lnk[i]);
return lnk[i];
}
void erase(ll i) {
if (lnk[i] == i) lnk[i] = p[i];
}
};
void solve() {
ll n, s; cin >> n >> s; n++;
vector<ll> x(n), p(n+1, n);
vector<vector<ll>> adj(n);
for (ll i = 1; i < n; i++) {
cin >> x[i] >> p[i];
adj[p[i]].push_back(i);
}
vector<ll> t(n), siz(n, 1), ord;
auto dfs = [&](auto &oink, ll i) -> void {
t[i] = sz(ord);
ord.push_back(i);
for (auto &e : adj[i]) {
oink(oink, e);
siz[i] += siz[e];
}
};
dfs(dfs, 0);
ord.push_back(n);
t.push_back(n);
tree_dsu dsu(p);
segtree tree(n), val(n+1);
tree.set(0, s);
val.set(0, s);
val.set(n, inf);
while (true) {
auto [vi, i] = tree.get_max();
i = ord[i];
if (vi < 0) break;
ll u = i, v = dsu.find(p[u]);
ll diff = min(vi, val.get(t[v])) - val.get(t[u]);
assert(diff < 1e12);
tree.range_add(t[u], t[u] + sz(adj[u]) - 1, diff);
val.range_add(t[u], t[u] + sz(adj[u]) - 1, diff);
while (val.get(t[v]) <= vi) {
dsu.erase(u);
u = v, v = dsu.find(p[v]);
diff = min(vi, val.get(t[v])) - val.get(t[u]);
assert(diff < 1e12);
tree.range_add(t[u], t[u] + siz[u] - 1, diff);
val.range_add(t[u], t[u] + siz[u] - 1, diff);
}
tree.set(t[i], -inf);
for (auto &e : adj[i]) {
tree.set(t[e], vi + x[e]);
val.set(t[e], vi + x[e]);
}
}
cout << val.get(0) - s << '\n';
}
int main() {
ios::sync_with_stdio(0); cin.tie(0);
solve();
}