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.util.List;
import java.io.IOException;
import java.util.Arrays;
import java.util.InputMismatchException;
import java.util.ArrayList;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 */
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        InputReader in = new InputReader(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        TaskB solver = new TaskB();
        solver.solve(1, in, out);
        out.close();
    }
}

class TaskB {
    int solved[][];
    final int MOD = 1000000007;
    int count(SparseGraph G, int V,boolean painted[], int hasPainted) {
        if(solved[V][hasPainted]!=-1)
            return solved[V][hasPainted];

        int ans = 0;

        ArrayList<Edge> E = (ArrayList<Edge>) G.getIncidentEdges(V);
        if(E.size() ==0) {
            if(hasPainted>0 && !painted[V] || hasPainted ==0 && painted[V])
                return 0;
            else
                return 1;
        }
        long [] A = new long[E.size()];
        long [] B = new long[E.size()];
        long [] C = new long[E.size()];
        int j = 0;
        for(Edge e: E) {
            A[j] = count(G,e.to,painted,1);
            B[j] = count(G,e.to,painted,0);
            ++j;
        }


        long temp = 1;
        for (int i=0;i<B.length;i++) {
            temp = (temp*(A[i]+B[i]))%MOD;
            C[i] = (int)temp;
        }

        long prev = 1;
        for(int i=B.length-2;i>=0;i--) {
            C[i + 1] = (int)((prev * (C[i]))%MOD);
            prev = (prev*(A[i+1]+B[i+1]))%MOD;

        }
        C[0] = (int)prev;




        long prodB = 1;
        long prodA = 1;
        long prodAB = 1;
        for(int i=0;i<B.length;i++) {
            prodB = (prodB * B[i])%MOD;
            prodA = (prodA * A[i])%MOD;
            prodAB = (prodAB * (A[i]+B[i])%MOD)%MOD;
        }

        if(hasPainted>0 && painted[V]) {
            return solved[V][hasPainted] = (int)prodAB;
        } else if(hasPainted>0 && !painted[V]) {
            long ans1 = 0;
            for(int i=0;i<A.length;i++) {
                ans1 = (ans1 + (C[i]*A[i])%MOD)%MOD;
            }
            return solved[V][hasPainted] = (int)ans1;

        } else if(hasPainted==0 && !painted[V]) {
            return solved[V][hasPainted] = (int)prodAB;
        } else {
            return solved[V][hasPainted] = 0;
        }


    }
    public void solve(int testNumber, InputReader in, PrintWriter out) {
        int n =in.nextInt();
        SparseGraph G = new SparseGraph(n,n);

        for(int i=0;i<n-1;i++) {
            int pi = in.nextInt();
            G.addEdge(pi,i+1);
        }

        boolean[] painted = new boolean[n];
        for(int i=0;i<n;i++) {
            int xi = in.nextInt();
            painted[i] = (xi==1)?true:false;
        }

        solved = new int[n][2];
        for(int i=0;i<n;i++)
            Arrays.fill(solved[i], -1);

        out.println(count(G,0,painted,1));

    }
}

class SparseGraph extends   Graph
{
    public int []From;
    public int []To;
    public int Head[];
    public int Next[];

    public int Weight[];
    int edgeCapacity;



    public SparseGraph(int vertexCount,int edgeCapacity)
    {
        if(edgeCapacity>0) {
            From = new int[edgeCapacity];
            To = new int[edgeCapacity];
            Next = new int[edgeCapacity];
            Arrays.fill(Next, -1);

        }
        Head = new int[vertexCount];
        Arrays.fill(Head, -1);
        this.edgeCapacity=edgeCapacity;

        this.vertexCount=vertexCount;
        edgeCount=0;
    }



    public void addEdge(int from, int to) {
        From[edgeCount]=from;
        To[edgeCount]=to;
        Next[edgeCount]=Head[from];
        Head[from]=edgeCount;
        ++edgeCount;

    }


    public List<Edge> getIncidentEdges(int vertexId)
    {
       ArrayList<Edge> list=new ArrayList<Edge>();
       int p=Head[vertexId];
       while(p!=-1) {
           Edge e=new Edge(To[p]);
           if(Weight!=null)  {
               e.weight = Weight[p];
           }
           list.add(e);
           p=Next[p];
       }
        return list;
    }


}

class Edge implements Comparable<Edge>
{
   int from;
   public int to;
   public int weight;

    public  Edge(int to)
    {
        //this.from=from;
        this.to=to;
    }
    public Edge(int to,int weight)
    {
       this(to);
       this.weight=weight;
    }
    public Edge(int from,int to,int weight)
    {
        this(to);
        this.from=from;
        this.weight=weight;
    }
    public int compareTo(Edge edge)
    {
        if(this.weight< edge.weight)
        {
            return -1;
        }
        else if(this.weight==edge.weight && this.to==edge.to && this.from==edge.from) {
            return 0;
        }
        else return 1;
    }


}

class InputReader {

    private InputStream stream;
    int curCharIndex = 0;
    int charsInBuf = 0;
     byte buf[] = new byte[16*1024];

    public InputReader(InputStream stream) {
        this.stream = stream;
    }


    public int readChar() {

        if (curCharIndex >= charsInBuf) {
            curCharIndex = 0;
            try {
                charsInBuf = stream.read(buf);
            } catch (IOException e) {
                throw new InputMismatchException();
            }
            if (charsInBuf <= 0)
                return -1;
        }
        return buf[curCharIndex++];
    }


    public int nextInt() {

        int c;
        do {
            c = readChar();
        }while(isWhitespace(c));

        int sign = 1;
        if (c == '-') {
            c = readChar();
            sign = -1;

        }
        int res = 0;
        do {
            res *= 10;
            res += c - '0';
            c = readChar();
        } while (!isWhitespace(c) && c!=-1);
        return sign * res;
    }


    /*
    * For the purpose of compatibilty with Chelper Chrome extension
     */


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

abstract class Graph
{
    public int vertexCount;
    public int edgeCount;


}

