#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cmath>
#include <cstring>

using namespace std;

const int N=125005;
const int P=998244353;
const int INF=0x3f3f3f3f;
const long long INFll=0x3f3f3f3f3f3f3f3fll;

struct edge{
	int v;
	edge *next;
}pool[N],*h[N];

struct task{
	long long w; //cost
	int val;
	int lim;
	inline task(){}
	inline task(long long _w,int _val,int _lim){
		w=_w;
		val=_val;
		lim=_lim;
	}
	inline bool operator<(const task &z)const{
		if(val*z.w==z.val*w) return val>z.val;
		return val*z.w>z.val*w;
	}
}c[N],d[6000005];

int n,D,top=-1,Index;
int a[N],p[N];
int size[N];
long long sum[N];
long long X;
long long f[N],g[N];
long long ans;

inline void addedge(int u,int v){
	edge *tmp=&pool[++top];
	tmp->v=v;tmp->next=h[u];h[u]=tmp;
}

inline void dfs(int u,int pre){
	sum[u]=a[u];
	size[u]=1;
	for(edge *tmp=h[u];tmp!=NULL;tmp=tmp->next){
		int v=tmp->v;
		if(v==pre) continue;
		dfs(v,u);
		size[u]+=size[v];
		sum[u]+=sum[v];
	}
	c[++Index]=task(sum[u],size[u],((u==1)?INF:D));
}

#define upd(x,y) x=min(x,y)

void init(){
	scanf("%d%lld%d%d",&n,&X,&D,&a[1]);
	for(int i=2;i<=n;i++) scanf("%d%d",&a[i],&p[i]),addedge(p[i],i);
	dfs(1,0);
	sort(c+1,c+n+1);
	/*
	for(int i=1;i<=n;i++){
		
		//printf("%d : %d %lld %d\n",i,c[i].val,c[i].w,c[i].lim);
		
		if(cursum+c[i].lim*c[i].w>X){
			for(int j=1;j<i;j++){
				if(c[j].lim>n){
					X-=(c[j].lim-n)*c[j].w;
					ans+=(c[j].lim-n)*c[j].val;
					//c[j].lim=n*n;
				}
			}
			long long tmp=(X-cursum)/c[i].w;
			if(tmp>n){
				X-=(tmp-n)*c[i].w;
				ans+=(tmp-n)*c[i].val;
				//c[i].lim=n*n;
			}
			break;
	 	}
	}
	printf("cur:%lld %lld\n",X,ans);
	*/
	/*
	for(int i=1;i<=n;i++){
		for(int j=0;j<N;j++) g[j]=f[j];
		for(int j=0;j<N;j++){
			for(int k=1;k<=min(c[i].lim,n*n);k++){
				if(j+c[i].val*k>=N) break;
				upd(g[j+c[i].val*k],f[j]+c[i].w*k);
			}
		}
		for(int j=0;j<N;j++) f[j]=g[j];
	}
	*/
	
	Index=0;
	//for(int i=1;i<=n;i++) upd(c[i].lim,n);
	for(int i=1;i<=n;i++){
		int base=1;
		while(base-1<=min(c[i].lim,50)){
			d[++Index]=task(c[i].w*base,c[i].val*base,1);//,printf("(%lld,%d)\n",d[i].w,d[i].val);
			base<<=1;
		}
		base>>=1;
		base=(min(c[i].lim,50)-(base-1));
		d[Index]=task(c[i].w*base,c[i].val*base,1);
	}
	for(int i=1;i<N;i++) f[i]=INFll;
	for(int i=1;i<=Index;i++){
		for(int j=N-1-d[i].val;j>=0;j--){
			if(j+d[i].val>=N) break;
			upd(f[j+d[i].val],f[j]+d[i].w);
		}
	}
	
	//for(int i=0;i<=n*n;i++) printf("%lld ",f[i]); printf("\n");
	for(int i=1;i<=n;i++) c[i].lim-=min(c[i].lim,50);
	for(int k=0;k<N;k++){
		if(f[k]>X) continue;
		X-=f[k];
		long long qwq=0,cursum=0,tmp=0;
		for(int i=1;i<=n;i++){
		
			//printf("%d : %d %lld %d\n",i,c[i].val,c[i].w,c[i].lim);
			/*
			if(cursum+c[i].lim*c[i].w>X){
				long long tmp=(X-cursum)/c[i].w;
				qwq+=tmp*c[i].val;
				cursum+=tmp*c[i].w;
		 	}
		 	else cursum+=c[i].lim*c[i].w,qwq+=c[i].lim*c[i].val;
		 	*/
		 	
			tmp=(X-cursum)/c[i].w;
			if(tmp>c[i].lim){
				cursum+=c[i].lim*c[i].w;
				qwq+=c[i].lim*c[i].val;
			}
			else{
				cursum+=tmp*c[i].w;
				qwq+=tmp*c[i].val;
			}
		}
		//cout<<qwq<<endl;
		X+=f[k];
		ans=max(ans,k+qwq);            
	}
	/*
	for(int i=0;i<N;i++){
		if(f[i]>X){
			ans+=(i-1);
			break;
		}
	}
	*/
	printf("%lld\n",ans);
}

int main(){
	init();
	return 0;
}

Measured memory_bytes: 11520