//chockolateman
#include<bits/stdc++.h>
using namespace std;
const long long INF = 1000000000000000LL;
long long N,a[300005],par[300005],p[300005],s[300005],lead[300005],dp[300005],tin[300005],tout[300005],timer,rev_tin[300005];
long long S,d[300005],prof[300005],ans;
bool used[300005],active[300005];
vector<long long> adj[300005],active_edge[300005];
stack<long long> to_buy;
void dfs1(long long v)
{
tin[v] = ++timer;
rev_tin[timer] = v;
prof[v] = prof[par[v]] + a[v];
d[v] = min(d[par[v]],prof[v]);
if(par[v]==0)
d[v] = prof[v];
for(auto u : adj[v])
{
if(u != par[v])
dfs1(u);
}
tout[v] = timer;
}
struct Node
{
long long maxim,pos,lazy = 0;
}st[1200005];
Node combine(Node left,Node right)
{
Node ret;
if(left.maxim >= right.maxim)
{
ret.maxim = left.maxim;
ret.pos = left.pos;
}
else
{
ret.maxim = right.maxim;
ret.pos = right.pos;
}
return ret;
}
void build(long long v = 1,long long start = 1,long long end = N)
{
if(start==end)
{
st[v].maxim = d[rev_tin[start]];
st[v].pos = rev_tin[start];
st[v].lazy = 0;
return;
}
long long mid = (start + end)/2;
build(2*v,start,mid);
build(2*v+1,mid+1,end);
st[v] = combine(st[2*v],st[2*v+1]);
}
void propagate(long long v,long long start,long long end);
void update(long long l,long long r,long long val,long long v = 1,long long start = 1,long long end = N)
{
if(start==l && end==r)
{
st[v].maxim += val;
st[v].lazy += val;
return;
}
propagate(v,start,end);
long long mid = (start + end)/2;
if(r <= mid)
update(l,r,val,2*v,start,mid);
else if(l > mid)
update(l,r,val,2*v+1,mid+1,end);
else
{
update(l,mid,val,2*v,start,mid);
update(mid+1,r,val,2*v+1,mid+1,end);
}
st[v] = combine(st[2*v],st[2*v+1]);
}
void propagate(long long v,long long start,long long end)
{
if(st[v].lazy)
{
long long mid = (start + end)/2;
update(start,mid,st[v].lazy,2*v,start,mid);
update(mid+1,end,st[v].lazy,2*v+1,mid+1,end);
st[v].lazy = 0;
}
}
void activate(long long pos,long long v = 1,long long start = 1,long long end = N)
{
if(start==end)
{
st[v].maxim = -INF;
st[v].pos = 0;
return;
}
propagate(v,start,end);
long long mid = (start + end)/2;
if(pos <= mid)
activate(pos,2*v,start,mid);
else
activate(pos,2*v+1,mid+1,end);
st[v] = combine(st[2*v],st[2*v+1]);
}
long long find_Sett(long long i)
{
if(p[i]==i)
return i;
p[i] = find_Sett(p[i]);
return p[i];
}
bool is_Same_Sett(long long i,long long j)
{
return find_Sett(i) == find_Sett(j);
}
long long dp_Sett(long long i)
{
return dp[find_Sett(i)];
}
void union_Sett(long long i,long long j)
{
if(is_Same_Sett(i,j))
return;
long long x = find_Sett(i);
long long y = find_Sett(j);
if(s[x] < s[y])
swap(x,y);
p[y] = x;
s[x] += s[y];
dp[x] += dp[y];
lead[x] = min(lead[x],lead[y]);
}
void open(long long v)
{
activate(tin[v]);
active[v] = true;
dp[v] = a[v];
s[v] = 1;
p[v] = v;
lead[v] = v;
for(auto u : adj[v])
if(u != par[v] && active[u] && dp_Sett(u) > 0)
{
active_edge[v].push_back(u);
active_edge[u].push_back(v);
union_Sett(v,u);
}
while(dp_Sett(v) >= 0)
{
long long x = find_Sett(v);
if(used[par[lead[x]]])
{
to_buy.push(lead[x]);
break;
}
if(active[par[lead[x]]])
{
active_edge[par[lead[x]]].push_back(lead[x]);
active_edge[lead[x]].push_back(par[lead[x]]);
union_Sett(x,par[lead[x]]);
}
else
break;
}
}
void dfs2(long long v) //buy
{
S += a[v];
ans += a[v];
update(tin[v],tout[v],-a[v]);
used[v] = true;
for(auto u : active_edge[v])
if(u != par[v])
dfs2(u);
}
int main()
{
scanf("%lld%lld",&N,&S);
for(long long i = 1 ; i <= N ; i++)
{
scanf("%lld%lld",&a[i],&par[i]);
if(par[i] != 0)
{
adj[i].push_back(par[i]);
adj[par[i]].push_back(i);
}
}
for(long long i = 1 ; i <= N ; i++)
if(par[i]==0)
{
dfs1(i);
}
used[0] = true;
build();
bool moved = true;
while(moved)
{
moved = false;
while(st[1].pos > 0 && st[1].maxim + S >= 0)
{
moved = true;
open(st[1].pos);
}
if(!to_buy.empty())
{
moved = true;
long long v = to_buy.top();
to_buy.pop();
if(!used[v])
dfs2(v);
}
}
printf("%lld\n",ans);
return 0;
}