#include<bits/stdc++.h>
using namespace std;
const int MAXN=3e5+5;
const long long INF=4e18;
struct segmenttree
{
long long lazy[MAXN*4];
pair<long long,int> seg[MAXN*4];
bool state;
pair<long long,int> merge(pair<long long,int> a,pair<long long,int> b)
{
if(!state) return min(a,b);
return max(a,b);
}
void down(int pos)
{
int val=lazy[pos];
seg[pos*2].first+=val,seg[pos*2+1].first+=val;
lazy[pos*2]+=val,lazy[pos*2+1]+=val,lazy[pos]=0;
}
void build(int l,int r,long long val,int pos)
{
if(l==r)
{
seg[pos]={val,l};
return ;
}
int mid=(l+r)/2;
build(l,mid,val,pos*2);
build(mid+1,r,val,pos*2+1);
seg[pos]=merge(seg[pos*2],seg[pos*2+1]);
}
void buildST(int n,bool st,long long val)
{
state=st;
build(1,n,val,1);
}
void update(int l,int r,int u,int v,long long val,int pos)
{
if(v<l||r<u) return ;
if(u<=l&&r<=v)
{
seg[pos].first+=val,lazy[pos]+=val;
return ;
}
int mid=(l+r)/2;
down(pos);
update(l,mid,u,v,val,pos*2);
update(mid+1,r,u,v,val,pos*2+1);
seg[pos]=merge(seg[pos*2],seg[pos*2+1]);
}
void updset(int l,int r,int i,long long val,int pos)
{
if(i<l||r<i) return ;
if(l==r)
{
seg[pos].first=val;
return ;
}
int mid=(l+r)/2;
down(pos);
updset(l,mid,i,val,pos*2);
updset(mid+1,r,i,val,pos*2+1);
seg[pos]=merge(seg[pos*2],seg[pos*2+1]);
}
pair<long long,int> get(int l,int r,int u,int v,int pos)
{
if(u<=l&&r<=v) return seg[pos];
int mid=(l+r)/2;
down(pos);
if(v<=mid) return get(l,mid,u,v,pos*2);
if(mid+1<=u) return get(mid+1,r,u,v,pos*2+1);
return merge(get(l,mid,u,v,pos*2),get(mid+1,r,u,v,pos*2+1));
}
};
vector<int> ds[MAXN],idx;
long long A[MAXN],fen[MAXN];
int L[MAXN],R[MAXN],eul[MAXN],root[MAXN],tdfs=0;
segmenttree sa,sb;
bool ck[MAXN];
void update(int i,int n,long long val) { for(;i<=n;i+=i&-i) fen[i]+=val; }
long long get(int i) { long long ans=0;for(;i;i-=i&-i) ans+=fen[i];return ans; }
void dfs(int i,int pre)
{
L[i]=R[i]=++tdfs,eul[tdfs]=i,root[i]=pre;
for(auto v:ds[i])
{
dfs(v,i);
R[i]=tdfs;
}
}
void dfs2(int i)
{
for(auto v:ds[i]) if(A[v]>=0) idx.push_back(v);
else dfs2(v);
}
int main()
{
// ios::sync_with_stdio(0);
// cin.tie(0);
// cout.tie(0);
long long n,s;
cin>>n>>s;
for(int i=1;i<=n;i++)
{
int res;
cin>>A[i]>>res;
ds[res].push_back(i);
}
dfs(0,0);
for(int i=1;i<=n;i++) update(L[i],tdfs,A[i]),update(R[i]+1,tdfs,-A[i]);
long long ps=s;
sa.buildST(tdfs,true,-INF);
sb.buildST(tdfs,false,INF);
sb.updset(1,tdfs,1,0,1);
while(sb.seg[1].first<=s)
{
int pos=eul[sb.seg[1].second];
sb.updset(1,tdfs,L[pos],INF,1);
dfs2(pos);
while(!ck[pos])
{
update(L[pos],tdfs,-A[pos]),update(R[pos]+1,tdfs,A[pos]);
sa.update(1,tdfs,L[pos],R[pos],-A[pos],1);
sb.update(1,tdfs,L[pos],R[pos],A[pos],1);
s+=A[pos],ck[pos]=true,pos=root[pos];
}
while(sa.seg[1].first>=0)
{
int pos2=sa.seg[1].second;
sb.updset(1,tdfs,pos2,-get(L[pos2]-1),1);
sa.updset(1,tdfs,pos2,-INF,1);
}
for(auto v:idx) if(get(L[v])<0) sa.updset(1,tdfs,L[v],get(L[v]),1);
else sb.updset(1,tdfs,L[v],-get(L[v]-1),1);
idx.clear();
}
cout<<s-ps;
}