//const int K = 2551, N = 51;
//ll subtree_sz[N], subtree_cost[N];
//vi adj[N];
//void dfs(int u){
//    subtree_sz[u] = 1;
//    for(int v : adj[u]){
//        dfs(v);
//        subtree_sz[u] += subtree_sz[v];
//        subtree_cost[u] += subtree_cost[v];
//    }
//}
//bool comp(int i, int j){
//    return (ll)subtree_sz[i]*subtree_cost[j] > (ll)subtree_sz[j]*subtree_cost[i];
//}
//int n;
//vl calc(vi taken, bool maximize){
//    vl cost(K,(maximize ? 0 : INF));
//    cost[0] = 0;
//    rep(i,1,n)
//        rep(take,min(51,taken[i]))
//            per(got,K){
//                int new_got = got+subtree_sz[i];
//                ll new_cost = cost[got]+subtree_cost[i];
//                if(new_got < K)
//                    if(maximize)
//                        cost[new_got] = max(cost[new_got],new_cost);
//                    else
//                        cost[new_got] = min(cost[new_got],new_cost);
//            }
//    return cost;
//}
//void __(){
//    int x,d;
//    cin >> n >> x >> d;
//    vi taken(n+1),remaining(n+1);
//    cin >> subtree_cost[1];
//    rep(i,2,n){
//        int p;
//        cin >> subtree_cost[i] >> p;
//        adj[p].pb(i);
//    }
//    dfs(1);
//    remaining[1] = x/subtree_cost[1];
//    rep(i,2,n)
//        remaining[i] = d;
//    vi order(n);
//    iota(all(order),1);
//    sort(all(order),comp);
//    ll ans = 0;
//    for(int u : order){
//        int take = min(int(x/subtree_cost[u]),remaining[u]);
//        taken[u] += take;
//        remaining[u] -= take;
//        x -= take*subtree_cost[u];
//        ans += (ll)take*subtree_sz[u];
//    }
//    vl dp1 = calc(taken,true);
//    vl dp2 = calc(remaining,false);
//    ll optimized_ans = ans;
//    rep(i,K)
//        rep(j,K)
//            if(x + dp1[i] - dp2[j] >= 0)
//                optimized_ans = max(optimized_ans, ans - i + j);
//    print optimized_ans;
//}
#include <numeric>
#include <iomanip>
#include <algorithm>
#include <cassert>
#include <vector>
#include <utility>
#include <iostream>
#include <string>
#define pb push_back
#define REP_INT(i,l,r) for(int i = (l); i <= (r); ++i)
#define REP_ZERO_INT(i,r) for(int i = 0; i < (r); ++i)
#define GET_REP_MACRO(_1,_2,_3,_4,NAME,...) NAME
#define rep(...) GET_REP_MACRO(__VA_ARGS__,REP_ANY,REP_INT,REP_ZERO_INT)(__VA_ARGS__)
#define PER_ZERO_INT(i,r) for(int i = (r)-1; i >= 0; --i)
#define GET_PER_MACRO(_1,_2,_3,_4,NAME,...) NAME
#define per(...) GET_PER_MACRO(__VA_ARGS__,PER_ANY,PER_INT,PER_ZERO_INT)(__VA_ARGS__)
#define all(v) (v).begin(), (v).end()
#define sz(v) ll(v.size())
#define T1 template<typename T> static
using namespace std;
typedef long long ll;
typedef vector<ll> vl;
typedef vector<int> vi;
const ll INF = ll(2e18) + 666;
T1 ostream& operator<<(ostream& stream, const vector<T>& t);
T1 istream& read(T, T, istream& = cin);
struct _print {
    string sep,end;
    bool space;
    ostream &stream;
    _print(string _sep=" ",string _end="\n",
            ostream &_stream = cout) 
        : sep(_sep),end(_end),space(false),
            stream(_stream) {}
    ~_print() { stream << end; }

    template <typename T>
        _print &operator , (const T &t) {
            if (space) stream << sep;
            space = true;
            stream << t;
            return *this;
        }
};
#define print _print(),
const int K = 2551, N = 51;
ll subtree_sz[N], subtree_cost[N];
vi adj[N];
void dfs(int u){
    subtree_sz[u] = 1;
    for(int v : adj[u]){
        dfs(v);
        subtree_sz[u] += subtree_sz[v];
        subtree_cost[u] += subtree_cost[v];
    }
}
bool comp(int i, int j){
    return (ll)subtree_sz[i]*subtree_cost[j] > (ll)subtree_sz[j]*subtree_cost[i];
}
int n;
vl calc(vi taken, bool maximize){
    vl cost(K,(maximize ? 0 : INF));
    cost[0] = 0;
    rep(i,1,n)
        rep(take,min(51,taken[i]))
            per(got,K){
                int new_got = got+subtree_sz[i];
                ll new_cost = cost[got]+subtree_cost[i];
                if(new_got < K)
                    if(maximize)
                        cost[new_got] = max(cost[new_got],new_cost);
                    else
                        cost[new_got] = min(cost[new_got],new_cost);
            }
    return cost;
}
void __(){
    int x,d;
    cin >> n >> x >> d;
    vi taken(n+1),remaining(n+1);
    cin >> subtree_cost[1];
    rep(i,2,n){
        int p;
        cin >> subtree_cost[i] >> p;
        adj[p].pb(i);
    }
    dfs(1);
    remaining[1] = x/subtree_cost[1];
    rep(i,2,n)
        remaining[i] = d;
    vi order(n);
    iota(all(order),1);
    sort(all(order),comp);
    ll ans = 0;
    for(int u : order){
        int take = min(int(x/subtree_cost[u]),remaining[u]);
        taken[u] += take;
        remaining[u] -= take;
        x -= take*subtree_cost[u];
        ans += (ll)take*subtree_sz[u];
    }
    vl dp1 = calc(taken,true);
    vl dp2 = calc(remaining,false);
    ll optimized_ans = ans;
    rep(i,K)
        rep(j,K)
            if(x + dp1[i] - dp2[j] >= 0)
                optimized_ans = max(optimized_ans, ans - i + j);
    print optimized_ans;
}
int main(){
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    cout << fixed << setprecision(15);
        __();
}



Measured memory_bytes: 256