Appleman has a tree with n vertices. Some of the vertices (at least one) are colored black and other vertices are colored white.

Consider a set consisting of k (0 ≤ k < n) edges of Appleman's tree. If Appleman deletes these edges from the tree, then it will split into (k + 1) parts. Note, that each part will be a tree with colored vertices.

Now Appleman wonders, what is the number of sets splitting the tree in such a way that each resulting part will have exactly one black vertex? Find this number modulo 1000000007 (109 + 7).

Input

The first line contains an integer n (2 ≤ n ≤ 105) — the number of tree vertices. 

The second line contains the description of the tree: n - 1 integers p0, p1, ..., pn - 2 (0 ≤ pi ≤ i). Where pi means that there is an edge connecting vertex (i + 1) of the tree and vertex pi. Consider tree vertices are numbered from 0 to n - 1.

The third line contains the description of the colors of the vertices: n integers x0, x1, ..., xn - 1 (xi is either 0 or 1). If xi is equal to 1, vertex i is colored black. Otherwise, vertex i is colored white.

Output

Output a single integer — the number of ways to split the tree modulo 1000000007 (109 + 7).

Examples

Input

3
0 0
0 1 1


Output

2


Input

6
0 1 1 0 4
1 1 0 0 1 0


Output

1


Input

10
0 1 2 1 4 4 4 0 8
0 0 0 1 0 1 1 0 0 1


Output

27
import java.io.DataInputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.InputMismatchException;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.PriorityQueue;
import java.util.Queue;
import java.util.Random;
import java.util.Scanner;
import java.util.Stack;
import java.util.StringTokenizer;
import java.util.TreeMap;
import java.util.TreeSet;

public class main {
	private static InputStream stream;
	private static byte[] buf = new byte[1024];
	private static int curChar;
	private static int numChars;
	private static SpaceCharFilter filter;
	private static PrintWriter pw;
	private static long max = Long.MIN_VALUE;
	private static long mod = 1000000000 + 7;
	private static boolean flag=false;
	private static int count=0;
	private static void soln() {
		int n=nextInt();
		LinkedList<Integer>[] l=new LinkedList[n];
		for(int i=0;i<n;i++)
			l[i]=new LinkedList<>();
		for(int i=0;i<n-1;i++){
			int p=nextInt();
			l[p].add(0,i+1);
			l[i+1].add(0,p);
		}
		int[] arr=nextIntArray(n);
		long[][] dp=new long[n][2];
		DFS(0,-1,l,arr,dp);
		pw.println(dp[0][0]);
	}
	private static void DFS(int cur,int prev,LinkedList<Integer>[] l,int[] arr,long[][] dp){
		Iterator<Integer> i=l[cur].listIterator();
		//System.out.println(cur);
		long x1=1;
		long x2=1;
		long[][] arr1=new long[l[cur].size()][2];
		int j=0;
		while(i.hasNext()){
			int x=i.next();
			if(x!=prev){
				DFS(x,cur,l,arr,dp);
				x1=(x1*((dp[x][0]+dp[x][1])%mod))%mod;
				//x2=(x2*dp[x][1])%mod;
				arr1[j][0]=dp[x][0];
				arr1[j][1]=dp[x][1];
				j++;
			}
		}
		if(arr[cur]==0){
			dp[cur][1]=x1;
			for(int k=0;k<j;k++){
				dp[cur][0]=(dp[cur][0]+((arr1[k][0]*((x1*pow((arr1[k][0]+arr1[k][1])%mod,mod-2,mod))%mod))%mod))%mod;
			}
			//dp[cur][0]=(dp[cur][0]-x2+mod)%mod;
		}else{
			dp[cur][0]=x1;
			dp[cur][1]=0;
		}
	}
	public static class Segment {
		private long[] tree;
		private long[] lazy;
		private int size;
		//private int[] s;
		private int n;
		private class node{
			private int a;
			private int b;
			private int c;
			public node(int x,int y,int z){
				a=x;
				b=y;
				c=z;
			}
		}
		public Segment(int n){
			//this.base=arr;
			int x = (int) (Math.ceil(Math.log(n) / Math.log(2)));
	        size = 2 * (int) Math.pow(2, x) - 1;
			tree=new long[size];
			lazy=new long[size];
			//s=new int[size];
			this.n=n;
			//build(0,0,n-1);
		}
		private void build(int id,int l,int r){
			//pw.println(1);
			if(r==l){
				tree[id]=0;
				//s[id]=1;
				return;
			}
			int mid=l+(r-l)/2;
			//System.out.println(2*id+1+" "+l+" "+mid);
			build(2*id+1,l,mid);
			//System.out.println(2*id+2+" "+(mid+1)+" "+r);
			build(2*id+2,mid+1,r);
			//s[id]=s[2*id+1]+s[2*id+2];
			//System.out.println(s[id]+" "+(l+1)+" "+(r+1));
		}
		public long query(int l,int r){
			return queryUtil(l,r,0,0,n-1);
		}
		private long queryUtil(int x,int y,int id,int l,int r){
			if(l>y || x>r) 
				return 0;
			System.out.println((l+1)+" "+(r+1)+" "+tree[id]+" "+lazy[id]+" "+1);
			shift(id,l,r);
			if(x <= l && r<=y)
				return tree[id];
			int mid=l+(r-l)/2;
			System.out.println((l+1)+" "+(r+1)+" "+tree[id]+" "+lazy[id]+" "+2);
			return queryUtil(x,y,2*id+1,l,mid)+queryUtil(x,y,2*id+2,mid+1,r);
		}
		/*private void cnt(int id,int l,int r,HashSet<Integer> set){
			if(tree[id]!=0){
				set.add(tree[id]);
				return;
			}
			if(r==l)
				return;
			int mid=l+(r-l)/2;
			cnt(2*id+1,l,mid,set);
			cnt(2*id+2,mid+1,r,set);
		}*/
		public void update(int i,int colour,int id,int l,int r){
			if(i<l || i>r){
				return;
			}
			if(l==r){
				tree[id]=colour;
				return;
			}
			int mid=l+(r-l)/2;
			//shift(id);
			update(i,colour,2*id+1,l,mid);
			update(i,colour,2*id+2,mid+1,r);
			tree[id]=Math.max(tree[2*id+1],tree[2*id+2]);
		}
		public void update(int x,int y,long colour,int id,int l,int r){
			if(x>r || l>y){
				//tree[id]=s[id]*(lazy[id]);
				return;
			}
			shift(id,l,r);
			if(x<=l && r<=y){
				tree[id]+=((long)(r-l+1))*colour;
				if(l!=r){
					lazy[2*id+1]+=colour;
					lazy[2*id+2]+=colour;
				}
				//System.out.println((l+1)+" "+(r+1)+" "+colour+" "+tree[id]+" "+1);
				return;
			}
			int mid=l+((r-l)>>1);
			//shift(id);
			update(x,y,colour,(id<<1)+1,l,mid);
			update(x,y,colour,(id<<1)+2,mid+1,r);
			tree[id]+=((long)(Math.min(y,r)-Math.max(x,l)+1))*colour;
			//tree[id]=tree[2*id+1]+tree[2*id+2];
			//System.out.println((l+1)+" "+(r+1)+" "+colour+" "+tree[id]+" "+2);
		}
		private void shift(int id,int l,int r){
			if(lazy[id]!=0){
				if(l!=r){
					lazy[2*id+1]+=lazy[id];
					lazy[2*id+2]+=lazy[id];
				}
				tree[id]+=((long)(r-l+1))*lazy[id];
				lazy[id]=0;
				System.out.println((l+1)+" "+(r+1)+" "+tree[id]+" "+lazy[id]+" "+3);
			}
		}
	}

	private static class DSU{
		int[] parent;
		public DSU(int n){
			parent=new int[n];
			for(int i=0;i<n;i++)
				parent[i]=i;
		}
		int find(int i){
	        while(parent[i] !=i){
	        	parent[i]=parent[parent[i]];
	        	i=parent[i];
	        }
	        return i;
	    }
		void Union(int x, int y){
	        int xset = find(x);
	        int yset = find(y);
	        parent[yset]=yset;
	        parent[xset] = yset;
	    }
	}
	private static class Edge implements Comparable<Edge>{
		int x;
		int y;
		int w;
		public Edge(int a,int b,int c){
			x=a; y=b; w=c;
		}
		@Override
		public int compareTo(Edge o) {
			return o.w-this.w;
		}
	}
	/*static class Suffix implements Comparable<Suffix>{
		int index;
		int[] rank=new int[2];
		@Override
		public int compareTo(Suffix arg0){
			return (this.rank[0]==arg0.rank[0])?(this.rank[1]<arg0.rank[1]?-1:1):(this.rank[0]<arg0.rank[0]?-1:1);
		}	
	}
	private static int[] buildSuffix(String s,int n){
		Suffix[] arr=new Suffix[n];
		for(int i=0;i<n;i++)
			arr[i]=new Suffix();
		for(int i=0;i<n;i++){
			arr[i].index=i;
			arr[i].rank[0]=s.charAt(i)-'a';
			arr[i].rank[1]=((i+1)<n)?(s.charAt(i+1)-'a'):-1;
		}
		Arrays.sort(arr);
		//for(int i=0;i<n;i++)
			//System.out.print(arr[i].index);
		int[] ind=new int[n];
		for(int k=4;k<2*n;k=k*2){
			int rank=0;
			int p_rank=arr[0].rank[0];
			arr[0].rank[0]=rank;
			ind[arr[0].index]=0;
			for(int i=1;i<n;i++){
				if (arr[i].rank[0] == p_rank && arr[i].rank[1] == arr[i-1].rank[1]) {
	                p_rank = arr[i].rank[0];
	                arr[i].rank[0] = rank;
	            }
	            else{
	                p_rank = arr[i].rank[0];
	                arr[i].rank[0] = ++rank;
	            }
	            ind[arr[i].index] = i;
	        }
			for(int i=0;i<n;i++){
				int n_index=arr[i].index + k/2;
				arr[i].rank[1]=(n_index<n)?arr[ind[n_index]].rank[0] : -1;
			}
			Arrays.sort(arr);
		}
		int[] suffixArr=new int[n];
		for(int i=0;i<n;i++)
			suffixArr[i]=arr[i].index;
		return suffixArr;
	}*/
	private static long pow(long a, long b, long c) {
		if (b == 0)
			return 1;
		long p = pow(a, b / 2, c);
		p = (p * p) % c;
		return (b % 2 == 0) ? p : (a * p) % c;
	}
	
	private static class Pair implements Comparable<Pair> {
		int x;
		int y;
		int z;
		public Pair(int a,int b,int c) {
			x=a;y=b;z=c;
		}
		@Override
		public int compareTo(Pair arg0) {
			return (this.x!=arg0.x)?(this.x-arg0.x):((this.y!=arg0.y)?(this.y-arg0.y):(this.z-arg0.z));
		}
	}

	private static int gcd(int a1, int a2) {
		if (a2 == 0)
			return a1;
		return gcd(a2, a1 % a2);
	}

	private static long max(long a, long b) {
		if (a > b)
			return a;
		return b;
	}

	private static long min(long a, long b) {
		if (a < b)
			return a;
		return b;
	}

	public static void main(String[] args) throws Exception {
		new Thread(null,new Runnable(){
			@Override
			public void run() {
				InputReader(System.in);
				pw = new PrintWriter(System.out);
				soln();
				pw.close();
			}
		},"1",1<<26).start();
	}

	public static void InputReader(InputStream stream1) {
		stream = stream1;
	}

	private static boolean isWhitespace(int c) {
		return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
	}

	private static boolean isEndOfLine(int c) {
		return c == '\n' || c == '\r' || c == -1;
	}

	private static int read() {
		if (numChars == -1)
			throw new InputMismatchException();
		if (curChar >= numChars) {
			curChar = 0;
			try {
				numChars = stream.read(buf);
			} catch (IOException e) {
				throw new InputMismatchException();
			}
			if (numChars <= 0)
				return -1;
		}
		return buf[curChar++];
	}

	private static int nextInt() {
		int c = read();
		while (isSpaceChar(c))
			c = read();
		int sgn = 1;
		if (c == '-') {
			sgn = -1;
			c = read();
		}
		int res = 0;
		do {
			if (c < '0' || c > '9')
				throw new InputMismatchException();
			res *= 10;
			res += c - '0';
			c = read();
		} while (!isSpaceChar(c));
		return res * sgn;
	}

	private static long nextLong() {
		int c = read();
		while (isSpaceChar(c))
			c = read();
		int sgn = 1;
		if (c == '-') {
			sgn = -1;
			c = read();
		}
		long res = 0;
		do {
			if (c < '0' || c > '9')
				throw new InputMismatchException();
			res *= 10;
			res += c - '0';
			c = read();
		} while (!isSpaceChar(c));
		return res * sgn;
	}

	private static String nextToken() {
		int c = read();
		while (isSpaceChar(c))
			c = read();
		StringBuilder res = new StringBuilder();
		do {
			res.appendCodePoint(c);
			c = read();
		} while (!isSpaceChar(c));
		return res.toString();
	}

	private static String nextLine() {
		int c = read();
		while (isSpaceChar(c))
			c = read();
		StringBuilder res = new StringBuilder();
		do {
			res.appendCodePoint(c);
			c = read();
		} while (!isEndOfLine(c));
		return res.toString();
	}

	private static int[] nextIntArray(int n) {
		int[] arr = new int[n];
		for (int i = 0; i < n; i++) {
			arr[i] = nextInt();
		}
		return arr;
	}

	private static long[] nextLongArray(int n) {
		long[] arr = new long[n];
		for (int i = 0; i < n; i++) {
			arr[i] = nextLong();
		}
		return arr;
	}

	private static void pArray(int[] arr) {
		for (int i = 0; i < arr.length; i++) {
			System.out.print(arr[i] + " ");
		}
		System.out.println();
		return;
	}

	private static void pArray(long[] arr) {
		for (int i = 0; i < arr.length; i++) {
			System.out.print(arr[i] + " ");
		}
		System.out.println();
		return;
	}

	private static boolean isSpaceChar(int c) {
		if (filter != null)
			return filter.isSpaceChar(c);
		return isWhitespace(c);
	}

	private interface SpaceCharFilter {
		public boolean isSpaceChar(int ch);
	}
}