import java.util.*;
import java.io.*;
public class Main{
int[] value; //记录每个节点的值
int[][] rec; //记录每个节点上不同情况下的最大值
int ans=0; //记录和
int[][] child; //记录每个节点的所有子节点
private void dfs1(int index) {
rec[index][0]=value[index]; //赋初始值,0项记录该节点最开始的值
int lens=child[index].length; //计算该节点有几个子节点
for(int i=0;i<lens;i++) { //依次遍历子节点
int c=child[index][i];
dfs1(c); //普通递归,逐级向下
rec[index][0]=Math.max(rec[index][0], rec[c][0]); //比较子节点和父节点的值的大小,最大值记录到父节点0项中
if(rec[c][0]>rec[index][1]) { //次大值记录到父节点1项中
rec[index][2]=rec[index][1];
rec[index][1]=rec[c][0];
}else if(rec[c][0]>rec[index][2]) { //再次大值记录到父节点2项中
rec[index][2]=rec[c][0];
}
}
}
private void dfs2(int index,int maxOut) { //传入起始节点和该节点对应的其他节点最大的value(maxOut)
ans+=Math.abs(rec[index][0]-maxOut); //对每一个节点,都用他0项中记录的最大value减去maxOut,求绝对值,加到和里
maxOut=Math.max(maxOut,value[index]);
int lens=child[index].length;
for(int i=0;i<lens;i++){
int c=child[index][i]; //遍历子节点
if(rec[c][0]==rec[index][1])
dfs2(c,Math.max(maxOut,rec[index][2])); //如果c是次大值节点,用再次大值节点的值操作
else
dfs2(c,Math.max(maxOut,rec[index][1]));
}
}
private int[] add(int[] child,int index) { //因为不知道java用数组套动态数组的方法,所以只能给静态数组手动扩容
int[] child2=new int[child.length+1];
System.arraycopy(child, 0, child2, 0, child.length);
child2[child2.length-1]=index;
return child2;
}
public void init() throws IOException {
StreamTokenizer in = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
in.nextToken();
int n=(int) in.nval; //简单读取
child=new int[n][0];
value=new int[n];
rec=new int[n][3];
for(int i=1;i<n;i++){
in.nextToken();
int k=(int) in.nval; //找到i的父亲k
child[k]=add(child[k],i); //把i加到child[k]数组里,双层的,注意点
}
for(int i=0;i<n;i++){
in.nextToken();
value[i]=(int) in.nval;
}
dfs1(0); //记录每个节点的几个最大值
dfs2(0,0); //求和
}
public static void main(String[] args) throws IOException{
Main m=new Main();
m.init();
System.out.println(m.ans-m.rec[0][0]); //排除根节点
}
}