#pragma GCC optimize ("O3")
#pragma GCC optimize ("unroll-loops")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#include <bits/stdc++.h>
using namespace std;

//#include <ext/pb_ds/tree_policy.hpp>
//#include <ext/pb_ds/assoc_container.hpp>
//#include <ext/rope>
//using namespace __gnu_pbds;
//using namespace __gnu_cxx;
//
//template<class T> using Tree = tree<T, null_type, less<T>, rb_t_tag,t_order_statistics_node_update>;
/***********************************************/
/* Dear online judge:
 * I've read the problem, and tried to solve it.
 * Even if you don't accept my solution, you should respect my effort.
 * I hope my code compiles and gets accepted.
 *  ___  __     _______    _______      
 * |\  \|\  \  |\  ___ \  |\  ___ \     
 * \ \  \/  /|_\ \   __/| \ \   __/|    
 *  \ \   ___  \\ \  \_|/__\ \  \_|/__  
 *   \ \  \\ \  \\ \  \_|\ \\ \  \_|\ \ 
 *    \ \__\\ \__\\ \_______\\ \_______\
 *     \|__| \|__| \|_______| \|_______|
 */
const long long mod = 1000000007;
//const long long mod = 998244353;

// watch this
//using ll = long long;
//typedef long long LL;
#define ll long long
#undef ll

const int mxN = 55;

vector<int> g[mxN];
int sz[mxN];
long long m[mxN];
long long sum[mxN];

long long X, D;

void dfs(int u) {
	sz[u] = 1;
	sum[u] = m[u];
	for (auto v : g[u])
		dfs(v), sum[u] += sum[v], sz[u] += sz[v];
}

bool cmp(int a, int b) {
	if (sum[a] * sz[b] != sum[b] * sz[a])
		return sum[a] * sz[b] < sum[b] * sz[a];
	return sz[a] > sz[b];
}

long long dp[2][mxN * mxN * mxN];

int main(int argc, char** argv) {
	//#ifdef ONLINE_JUDGE
	ios_base::sync_with_stdio(false);
	cin.tie(nullptr);
	//#endif

	int N, p;
//	N = 50, X = 1000000000, D = 1000000000;
	cin >> N >> X >> D;
	vector<int> a(N);
	for (int i = 1; i <= N; i++) {
		cin >> m[i];
//		m[i] = rand() + 1;
		if (i > 1)
			cin >> p,/*p = rand() % (i - 1) + 1,*/g[p].push_back(i);
		a[i - 1] = i;
	}
	dfs(1);
	sort(begin(a), end(a), cmp);
	vector<pair<int, int> > can;
	for (auto u : a) {
		long long mx = min((u == 1 ? X : D), X / sum[u]);
		if (mx)
			can.push_back( { u, min(mx, (long long) N) });
	}
	dp[0][0] = 0;
	for (int k = 1; k <= N * N; k++) {
		dp[0][k] = X + 1;
	}
	for (int i = 0; i < (int) can.size(); i++) {
		int d = i & 1;
		int o = !d;
		for (int j = 0; j <= N * N * N; j++)
			dp[o][j] = X + 1;
		for (int j = 0; j <= N * N * i; j++) {
			if (dp[d][j] >= X)
				continue;
			for (int k = 0; k <= can[i].second; k++) {
				dp[o][j + k * sz[can[i].first]] = min(
						dp[o][j + k * sz[can[i].first]],
						dp[d][j] + k * sum[can[i].first]);
			}
		}
	}
	long long res = 0;
	for (int tot = 0; tot <= N * N * N; tot++) {
		if (dp[((int) can.size()) & 1][tot] >= X)
			continue;
		long long cur = tot;
		long long curX = X - dp[((int) can.size()) & 1][tot];
		for (auto u : a) {
			long long mx = min((u == 1 ? X : D), curX / sum[u]);
			curX -= mx * sum[u];
			cur += mx * sz[u];
		}
		res = max(res, cur);
//		cerr << res << ' ' << cur << ' ' << curX << ' '
//				<< dp[((int) can.size()) & 1][tot] << '\n';
	}
	cout << res << '\n';
	return 0;
}
