#include <bits/stdc++.h>
// iostream is too mainstream
#include <cstdio>
// bitch please
#include <iostream>
#include <algorithm>
#include <cstdlib>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <stack>
#include <list>
#include <cmath>
#include <iomanip>
#include <time.h>
#define dibs reserve
#define OVER9000 1234567890
#define ALL_THE(CAKE,LIE) for(auto LIE =CAKE.begin(); LIE != CAKE.end(); LIE++)
#define tisic 47
#define soclose 1e-8
#define chocolate win
// so much chocolate
#define patkan 9
#define ff first
#define ss second
#define abs(x) ((x < 0)?-(x):x)
#define uint unsigned int
#define dbl long double
#define pi 3.14159265358979323846
using namespace std;
// mylittledoge

typedef long long cat;

#ifdef DONLINE_JUDGE
	// palindromic tree is better than splay tree!
	#define lld I64d
#endif

struct aratio {
	cat cnt[2];
	int dep;
	aratio() : cnt{} {}
	aratio(cat v, int dep) : cnt{v, 1}, dep{dep} {}

	aratio operator+(const aratio & R) const {
		aratio ret = R;
		ret.cnt[0] += cnt[0], ret.cnt[1] += cnt[1];
		ret.dep = min(dep, R.dep);
		return ret;
	}

	bool operator<(const aratio & R) const {
		if(cnt[0] == 0 && R.cnt[0] == 0) {
			if(cnt[1] == R.cnt[1]) return dep < R.dep;
			return cnt[1] > R.cnt[1];
		}
		if(cnt[0] * R.cnt[1] == cnt[1] * R.cnt[0]) return dep < R.dep;
		return (cnt[0] * R.cnt[1] < cnt[1] * R.cnt[0]);
	}

	bool operator==(const aratio & R) const {
		return cnt[0] == R.cnt[0] && cnt[1] == R.cnt[1] && dep == R.dep;
	}

	bool operator!=(const aratio & R) const {
		return !(*this == R);
	}
};

int main() {
	cin.sync_with_stdio(0);
	cin.tie(0);
	cout << fixed << setprecision(10);
	int N;
	cin >> N;
	vector<int> P(N), V(N);
	vector< vector<int> > G(N);
	for(int i = 1; i < N; i++) {
		cin >> P[i];
		G[--P[i]].push_back(i);
	}
	for(int i = 0; i < N; i++) cin >> V[i];

	vector< vector<int> > G1(N);
	vector<int> VS1(N, 0), par1(N), dep1(N, 0);
	for(int i = N-1; i >= 0; i--) {
		if(V[i] == 0 && i > 0) VS1[i] = 1;
		ALL_THE(G[i], it)
			if(V[*it] == 0) VS1[i] += VS1[*it];
	}
	for(int i = 0; i < N; i++) ALL_THE(G[i], it) {
		par1[*it] = (i == 0 || V[i] == 1) ? i : par1[i];
		dep1[*it] = dep1[par1[*it]] + 1;
		if(V[*it] == 1) G1[par1[*it]].push_back(*it);
	}

	priority_queue< pair<aratio, int> > q;
	vector<aratio> best_ratio(N);
	for(int i = 0; i < N; i++) if(i == 0 || V[i] == 1) {
		best_ratio[i] = aratio(VS1[i], dep1[i]);
		q.push({best_ratio[i], i});
	}
	vector<int> top(N);
	for(int i = 0; i < N; i++) top[i] = i;
	while(!q.empty()) {
		pair<aratio, int> p = q.top();
		q.pop();
		if(best_ratio[p.ss] != p.ff || top[p.ss] != p.ss) continue;
		// merge with parent
		int v = (p.ss == 0) ? -1 : par1[p.ss];
		while(v != -1 && top[v] != v) v = top[v];
		if(v != -1) {
			best_ratio[v] = best_ratio[v] + p.ff;
			q.push({best_ratio[v], v});
		}
		top[p.ss] = (v == -1) ? -1 : v;
		int u = par1[p.ss];
		while(u != -1 && top[u] != top[p.ss]) {
			v = top[u];
			top[u] = top[p.ss];
			u = v;
		}
	}

	vector<int> seq;
	set< pair<aratio, int> > cand;
	cand.insert(make_pair(best_ratio[0], 0));
	while(!cand.empty()) {
		int v = cand.rbegin()->ss;
		seq.push_back(V[v]);
		for(int j = 0; j < VS1[v]; j++) seq.push_back(0);
		cand.erase(--cand.end());
		ALL_THE(G1[v], it) cand.insert(make_pair(best_ratio[*it], *it));
	}

	cat inv = 0, cnt1 = 0;
	for(int i = 0; i < N; i++) {
		if(seq[i] == 0) inv += cnt1;
		else cnt1++;
	}
	cout << inv << "\n";
	return 0;}

// look at my code
// my code is amazing


Measured memory_bytes: 40296