// Slower C++ solution:
#include<bits/stdc++.h>

using namespace std;



typedef long long lint;

typedef long double louble;



template<typename T1,typename T2> inline T1 max(T1 a,T2 b){return a<b?b:a;}

template<typename T1,typename T2> inline T1 min(T1 a,T2 b){return a<b?a:b;}



const char lf = '\n';



namespace ae86

{

	const int bufl = 1 << 15;



	char buf[bufl],*s=buf,*t=buf;



	inline int fetch()

	{

		if(s==t){t=(s=buf)+fread(buf,1,bufl,stdin);if(s==t)return EOF;}

		return *s++;

	}



	inline int ty()

	{

		int a=0;int b=1,c=fetch();

		while(!isdigit(c))b^=c=='-',c=fetch();

		while(isdigit(c))a=a*10+c-48,c=fetch();

		return b?a:-a;

	}

}

using ae86::ty;



const int _ = 200007;



struct cxk

{

	lint c0,c1;

	cxk(lint c0_=0,lint c1_=0){c0=c0_,c1=c1_;}

	friend cxk operator + (cxk a,cxk b){return cxk(a.c0+b.c0,a.c1+b.c1);}

	friend int operator < (cxk a,cxk b){return a.c1*b.c0<a.c0*b.c1;}

}ps[_];



int n,fa[_]={0},bfa[_]={0},val[_],bval[_]={0};



int findbfa(int x)

{

	return x==bfa[x]?x:bfa[x]=findbfa(bfa[x]);

}



set<pair<cxk,int>> s;



int main()

{

	ios::sync_with_stdio(0),cout.tie(nullptr);



	n=ty();

	for(int i=2;i<=n;i++)fa[i]=ty();

	for(int i=1;i<=n;i++)val[i]=ty();



	for(int i=1;i<=n;i++)bfa[i]=i,ps[i]=cxk(val[i]==0,val[i]==1),s.emplace(ps[i],i);



	lint ans=0;

	while(!s.empty())

	{

		int a=(*s.begin()).second;

		s.erase(s.begin());

		if(a==1)continue;

		int aa=findbfa(fa[a]);

		bfa[a]=aa,ans+=ps[aa].c1*ps[a].c0,s.erase(make_pair(ps[aa],aa));

		ps[aa]=ps[aa]+ps[a],s.emplace(ps[aa],aa);

	}

	cout<<ans<<lf;



	return 0;

}


// Faster C++ solution for the same problem (measured speedup: 4.281626227546521x):
#include<bits/stdc++.h>

using namespace std;

#define ll long long

#define REP(i,a,b) for(int i=(a),_end_=(b);i<=_end_;i++)

#define DREP(i,a,b) for(int i=(a),_end_=(b);i>=_end_;i--)

#define EREP(i,u) for(int i=start[u];i;i=e[i].next)

#define fi first

#define se second

#define mkr(a,b) make_pair(a,b)

#define SZ(A) ((int)A.size())

template<class T>inline void chkmin(T &a,T b){ if(a>b)a=b;}

template<class T>inline void chkmax(T &a,T b){ if(a<b)a=b;}

inline void myassert(bool a,string s){ if(!a)cerr<<s<<endl,exit(0);}

inline int read()

{

	int s=0,f=1;char ch=getchar();

	while(!isdigit(ch) && ch!='-')ch=getchar();

	if(ch=='-')ch=getchar(),f=-1;

	while(isdigit(ch))s=s*10+ch-'0',ch=getchar();

	return ~f?s:-s;

}



const int maxn=2e5+20;

int n,fa[maxn],v[maxn];

int ff[maxn];



struct node {

	int num1,num0,id;

};



inline bool operator <(node a,node b)

{

	ll A=1ll*a.num1*b.num0,B=1ll*b.num1*a.num0;

	return A!=B?A<B:a.id<b.id;

}



set<node>s;



int num[maxn][2];



int fin(int x){ return x==ff[x]?x:ff[x]=fin(ff[x]);}



inline void init()

{

	n=read();

	REP(i,2,n)fa[i]=read();

	REP(i,1,n)ff[i]=i;

	REP(i,1,n)num[i][v[i]=read()]++;

	REP(i,2,n)

	{

		node x=(node){num[i][1],num[i][0],i};

		s.insert(x);

	}

}



ll ans;



inline void doing()

{

	while(!s.empty())

	{

		node t=*s.begin(); s.erase(t);

		int x=t.id,fat=fin(fa[x]);

		if(fat>1)s.erase((node){num[fat][1],num[fat][0],fat});

		ans+=1ll*num[fat][1]*num[x][0];

		REP(op,0,1)num[fat][op]+=num[x][op];

		ff[x]=fat;

		if(fat>1)s.insert((node){num[fat][1],num[fat][0],fat});

	}

	printf("%lld\n",ans);

}



int main()

{

	init();

	doing();

	return 0;

}