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.*;
import java.util.*;
import java.util.List;

public class Main {
    private static StringTokenizer st;
    private static BufferedReader br;
    public static long MOD = 1000000007;

    public static void print(Object x) {
        System.out.println(x + "");
    }
    public static String join(List<?> x, String space) {
        StringBuilder sb = new StringBuilder();
        for (Object elt : x) {
            sb.append(elt);
            sb.append(space);
        }
        return sb.toString();
    }

    public static String nextToken() throws IOException {
        while (st == null || !st.hasMoreTokens()) {
            st = new StringTokenizer(br.readLine().trim());
        }
        return st.nextToken();
    }
    public static double nextDouble() throws IOException {
        return Double.parseDouble(nextToken());
    }
    public static long nextLong() throws IOException {
        return Long.parseLong(nextToken());
    }
    public static int nextInt() throws IOException {
        return Integer.parseInt(nextToken());
    }
    public static List<Double> nextDoubles(int n) throws IOException{
        List<Double> lst = new ArrayList<Double>();
        for (int i = 0; i < n; i++) {
            lst.add(nextDouble());
        }
        return lst;
    }
    public static List<Integer> nextInts(int n) throws IOException{
        List<Integer> lst = new ArrayList<Integer>();
        for (int i = 0; i < n; i++) {
            lst.add(nextInt());
        }
        return lst;
    }
    public static List<Long> nextLongs(int n) throws IOException{
        List<Long> lst = new ArrayList<Long>();
        for (int i = 0; i < n; i++) {
            lst.add(nextLong());
        }
        return lst;
    }

    public static List<Long> emptyList(int n, long val) {
        List<Long> lst = new ArrayList<Long>();
        for (int i = 0; i < n; i++) {
            lst.add(val);
        }
        return lst;
    }

    public static void solve(int x, List<List<Integer>> children, List<Boolean> black, List<Long> sol0, List<Long> sol1) {
        if (black.get(x)) {
            long sol = 1;
            for (Integer child : children.get(x)) {
                if (black.get(child)) sol *= sol0.get(child);
                else sol *= (sol1.get(child) + sol0.get(child)) % MOD;
                sol = sol % MOD;
            }
            //print("Sol0 for " + x + " is " + sol);
            sol0.set(x, sol);
        } else {
            if (children.get(x).size() == 0) {
                sol0.set(x, 1L);
                sol1.set(x, 0L);
            } else {
                List<Long> opt0 = new ArrayList<Long>();
                List<Long> opt1 = new ArrayList<Long>();
                for (Integer child : children.get(x)) {
                    if (black.get(child)) {
                        opt0.add(sol0.get(child));
                        opt1.add(sol0.get(child));
                    } else {
                        opt0.add(sol0.get(child) + sol1.get(child));
                        opt1.add(sol1.get(child));
                    }
                }

                List<Long> upTo0 = new ArrayList<Long>();
                List<Long> downTo0 = new ArrayList<Long>();
                long temp = 1;
                for (long val : opt0) {
                    temp *= val;
                    temp = temp % MOD;
                    upTo0.add(temp);
                }
                temp = 1;
                for (int i = opt0.size() - 1; i >= 0; i--) {
                    temp *= opt0.get(i);
                    temp = temp % MOD;
                    downTo0.add(temp);
                }
                Collections.reverse(downTo0);
                //print("Arrays:");
                //print(join(opt0, " "));
                //print(join(upTo0, " "));
                //print(join(downTo0, " "));

                sol0.set(x, downTo0.get(0));
                long soln1 = 0;
                for (int i = 0; i < opt0.size(); i++) {
                    long left = (i == 0) ? 1 : upTo0.get(i - 1);
                    long right = (i == opt0.size() - 1) ? 1 : downTo0.get(i + 1);
                    soln1 += ((left * right) % MOD) * opt1.get(i);
                    soln1 = soln1 % MOD;
                }
                sol1.set(x, soln1);
            }

            //print("Sols for " + x + " are " + sol0.get(x) + ", " + sol1.get(x));
        }
    }

    public static void main(String[] args) throws Exception {
        boolean debug = false;
        InputStream in = System.in;
        if (debug) {
            in = new FileInputStream("input.in");
        }
        br = new BufferedReader(new InputStreamReader(in));

        int n = nextInt();
        List<List<Integer>> children = new ArrayList<List<Integer>>();
        for (int i = 0; i < n; i++) {
            children.add(new ArrayList<Integer>());
        }
        for (int i = 1; i < n; i++) {
            int p = nextInt();
            children.get(p).add(i);
        }
        //0 is root
        int ROOT = 0;

        List<Boolean> black = new ArrayList<Boolean>();
        for (int i = 0; i < n; i++) {
            if (nextInt() == 0) {
                black.add(false);
            } else {
                black.add(true);
            }
        }

        List<Long> sol0 = emptyList(n, -1);
        List<Long> sol1 = emptyList(n, -1);
        List<Integer> stack = new ArrayList<Integer>();
        stack.add(ROOT);
        while (stack.size() > 0) {
            int last = stack.get(stack.size() - 1);
            boolean childrenDone = true;
            for (Integer child : children.get(last)) {
                if (sol0.get(child) == -1) {
                    stack.add(child);
                    childrenDone = false;
                }
            }

            if (!childrenDone) continue;
            stack.remove(stack.size() - 1);
            solve(last, children, black, sol0, sol1);
        }

        if (black.get(ROOT)) {
            print(sol0.get(ROOT));
        } else {
            print(sol1.get(ROOT));
        }
    }
}
