#include <iostream>
#include <queue>
#include <tuple>
#include <vector>
#include <algorithm>
using namespace std;

class MergeTech {
public:
	int minval[1 << 18];
	int sum[1 << 18];
	int group[1 << 18];
	vector<int> G[1 << 18];

	void init(int sz) {
		for (int i = 0; i < sz; i++) {
			group[i] = i;
			minval[i] = i;
			sum[i] = 0;
			G[i].push_back(i);
		}
	}
	void unite(int u, int v) {
		u = group[u]; v = group[v];
		if (G[u].size() < G[v].size()) swap(u, v);
		for (int i = 0; i < G[v].size(); i++) {
			G[u].push_back(G[v][i]);
			group[G[v][i]] = u;
			minval[u] = min(minval[u], G[v][i]);
		}
		sum[u] += sum[v]; sum[v] = 0;
		G[v].clear();
	}
	int getval(int pos) {
		return minval[group[pos]];
	}
};

struct Fraction {
	long long p1, p2;
};

bool operator<(const Fraction& a1, const Fraction& a2) {
	if (a1.p1 * a2.p2 < a1.p2 * a2.p1) return true;
	return false;
}

bool operator==(const Fraction& a1, const Fraction& a2) {
	if (a1.p1 * a2.p2 == a1.p2 * a2.p1) return true;
	return false;
}

// 入力
int N, P[1 << 18], V[1 << 18];
int S[1 << 18];

// 最強部分木を求めるパート
Fraction dp[1 << 18];
MergeTech Z;
vector<int> X[1 << 18];
vector<int> XX[1 << 18];
vector<int> Y;

// 計算パート
Fraction G[1 << 18];
int dp1[1 << 18], dp2[1 << 18];

void dfs(int pos, Fraction V) {
	for (int i : X[pos]) {
		if (!(dp[i] < V)) { Y.push_back(i); continue; }
		dfs(i, V);
	}
}

void dfs2(int pos) {
	dp1[pos] = 1;
	if (V[pos] == 1) dp2[pos] = 1;
	for (int i : XX[pos]) {
		dfs2(i);
		dp1[pos] += dp1[i];
		dp2[pos] += dp2[i];
	}
}

int main() {
	// Step #1. 入力
	cin >> N;
	for (int i = 2; i <= N; i++) cin >> P[i];
	for (int i = 1; i <= N; i++) cin >> V[i];

	// Step #2. 木の調整
	for (int i = 1; i <= N; i++) {
		if (V[i] == 1) S[i] = i;
		if (V[i] == 0) S[i] = S[P[i]];
	}
	for (int i = 1; i <= N; i++) {
		if (V[i] == 1) P[i] = S[P[i]];
	}
	for (int i = 2; i <= N; i++) { if (P[i] >= 1) X[P[i]].push_back(i); }
	
	// Step #3. 最強部分木を求める
	priority_queue<pair<Fraction, int>, vector<pair<Fraction, int>>, greater<pair<Fraction, int>>> Q;
	Z.init(N + 2);
	for (int i = 1; i <= N; i++) Z.sum[i] = V[i];
	for (int i = 1; i <= N; i++) Q.push(make_pair(Fraction{ 1LL * V[i], 1LL }, i));
	while (!Q.empty()) {
		int pos = Q.top().second;
		Fraction vals = Q.top().first; Q.pop();
		if (dp[pos].p1 + dp[pos].p2 >= 1LL) continue;
		dp[pos] = vals;
		if (P[pos] >= 1) {
			Z.unite(pos, P[pos]);
			int cx = Z.getval(pos);
			int idx = Z.group[pos];
			int F1 = Z.sum[idx], F2 = Z.G[idx].size();
			Q.push(make_pair(Fraction{ F1, F2 }, cx));
		}
	}

	// Step #4. 最強部分木の頂点を根とする
	/*vector<int> LY, LZ;
	for (int i = 1; i <= N; i++) { if (P[i] == 0) LY.push_back(i); }
	while (LY.size() >= 1) {
		Y.clear();
		for (int i : LY) dfs(i, dp[i]);
		for (int i : LY) LZ.push_back(i);
		LY = Y;
	}
	for (int i : LZ) P[i] = 0;
	for (int i = 1; i <= N; i++) { if (P[i] >= 1) XX[P[i]].push_back(i); }

	// Step #5. 計算前の準備
	for (int i = 1; i <= N; i++) { if (P[i] == 0) dfs2(i); }
	for (int i = 1; i <= N; i++) {
		G[i] = Fraction{ 1LL * dp2[i], 1LL * dp1[i] };
	}*/

	// Step #6. 本計算
	priority_queue<tuple<int, Fraction, int>, vector<tuple<int, Fraction, int>>, greater<tuple<int, Fraction, int>>> Q2;
	for (int i = 1; i <= N; i++) {
		if (P[i] == 0) Q2.push(make_tuple(V[i], dp[i], i));
	}
	vector<int> val;
	while (!Q2.empty()) {
		int pos = get<2>(Q2.top()); Q2.pop();
		val.push_back(V[pos]);
		for (int i : X[pos]) Q2.push(make_tuple(V[i], dp[i], i));
	}

	// Step #7. 出力
	long long Answer = 0, rets = 0;
	for (int i = 0; i < val.size(); i++) {
		if (val[i] == 1) rets++;
		if (val[i] == 0) Answer += rets;
	}
	cout << Answer << endl;
	return 0;
}

Measured memory_bytes: 57192