You are given a rooted tree on n vertices, its root is the vertex number 1. The i-th vertex contains a number w_i. Split it into the minimum possible number of vertical paths in such a way that each path contains no more than L vertices and the sum of integers w_i on each path does not exceed S. Each vertex should belong to exactly one path.

A vertical path is a sequence of vertices v_1, v_2, …, v_k where v_i (i ≥ 2) is the parent of v_{i - 1}.

Input

The first line contains three integers n, L, S (1 ≤ n ≤ 10^5, 1 ≤ L ≤ 10^5, 1 ≤ S ≤ 10^{18}) — the number of vertices, the maximum number of vertices in one path and the maximum sum in one path.

The second line contains n integers w_1, w_2, …, w_n (1 ≤ w_i ≤ 10^9) — the numbers in the vertices of the tree.

The third line contains n - 1 integers p_2, …, p_n (1 ≤ p_i < i), where p_i is the parent of the i-th vertex in the tree.

Output

Output one number — the minimum number of vertical paths. If it is impossible to split the tree, output -1.

Examples

Input

3 1 3
1 2 3
1 1


Output

3

Input

3 3 6
1 2 3
1 1


Output

2

Input

1 1 10000
10001


Output

-1

Note

In the first sample the tree is split into \{1\},\ \{2\},\ \{3\}.

In the second sample the tree is split into \{1,\ 2\},\ \{3\} or \{1,\ 3\},\ \{2\}.

In the third sample it is impossible to split the tree.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;

/**
 * @author Don Li
 */
public class SplitTheTree2 {
    
    int N = (int) 1e5 + 10;
    int LOG = 18;
    long INF = (long) 1e18;
    
    int n, L;
    long S;
    int[] w = new int[N];
    int[] par = new int[N];
    int[][] G;
    
    int timer = 0;
    int[] id = new int[N], rb = new int[N];
    long[] sum = new long[N];
    int[][] anc = new int[N][LOG];
    int[] up = new int[N];
    List<Integer>[] rm = new List[N];
    
    long[] dp = new long[N];
    long[] dp_sum = new long[N];
    
    long[] t = new long[N * 4];
    long[] lazy = new long[N * 4];
    
    void solve() {
        n = in.nextInt(); L = in.nextInt(); S = in.nextLong();
        for (int i = 0; i < n; i++) w[i] = in.nextInt();
        par[0] = -1;
        for (int i = 1; i < n; i++) par[i] = in.nextInt() - 1;
        int[] fr = new int[n - 1], to = new int[n - 1];
        for (int i = 0; i < n - 1; i++) {
            fr[i] = i + 1;
            to[i] = par[i + 1];
        }
        G = build_graph(n, fr, to);
        
        for (int i = 0; i < n; i++) {
            if (w[i] > S) {
                out.println(-1);
                return;
            }
        }
        
        dfs(0, 0);
        
        build_tree(0, 0, n);
        
        dfs_solve(0);
        out.println(dp[0]);
    }
    
    
    void dfs_solve(int u) {
        for (int v : G[u]) {
            if (v != par[u]) {
                dfs_solve(v);
                dp_sum[u] += dp[v];
            }
        }
        add(u);
        dp[u] = n;
        upd(u);
        add_tree(0, 0, n, id[u], rb[u] + 1, -dp[u]);
        if (rm[u] != null) for (int v : rm[u]) remove(v);
    }
    
    void remove(int u) {
        set_tree(0, 0, n, id[u], INF);
    }
    
    void upd(int u) {
        dp[u] = 1 + get_tree(0, 0, n, id[u], rb[u] + 1);
    }
    
    void add(int u) {
        set_tree(0, 0, n, id[u], 0);
        add_tree(0, 0, n, id[u], rb[u] + 1, dp_sum[u] - dp[u]);
    }
    
    void dfs(int u, int p) {
        id[u] = rb[u] = timer++;
        sum[u] = w[u] + sum[p];
        anc[u][0] = p;
        for (int i = 1; i < LOG; i++) anc[u][i] = anc[anc[u][i - 1]][i - 1];
        up[u] = u;
        for (int i = LOG - 1, dist = L - 1; i >= 0 && dist > 0; i--) {
            if (1 << i <= dist && sum[u] - sum[anc[up[u]][i]] + w[anc[up[u]][i]] <= S) {
                dist -= 1 << i;
                up[u] = anc[up[u]][i];
            }
        }
        if (rm[up[u]] == null) rm[up[u]] = new ArrayList<>();
        rm[up[u]].add(u);
        for (int v : G[u]) {
            if (v != p) {
                dfs(v, u);
                rb[u] = Math.max(rb[u], rb[v]);
            }
        }
    }
    
    long get_tree(int k, int l, int r, int a, int b) {
        if (a >= r || b <= l) return INF;
        if (a <= l && r <= b) return t[k];
        push_down(k);
        int m = (l + r) >> 1;
        return Math.min(get_tree(2 * k + 1, l, m, a, b), get_tree(2 * k + 2, m, r, a, b));
    }
    
    void add_tree(int k, int l, int r, int a, int b, long delta) {
        if (a >= r || b <= l) return;
        if (a <= l && r <= b) {
            t[k] += delta;
            lazy[k] += delta;
            return;
        }
        push_down(k);
        int m = (l + r) >> 1;
        add_tree(2 * k + 1, l, m, a, b, delta);
        add_tree(2 * k + 2, m, r, a, b, delta);
        t[k] = Math.min(t[2 * k + 1], t[2 * k + 2]);
    }
    
    void set_tree(int k, int l, int r, int pos, long val) {
        if (r - l == 1) {
            t[k] = val;
            return;
        }
        push_down(k);
        int m = (l + r) >> 1;
        if (pos < m) set_tree(2 * k + 1, l, m, pos, val);
        else set_tree(2 * k + 2, m, r, pos, val);
        t[k] = Math.min(t[2 * k + 1], t[2 * k + 2]);
    }
    
    void push_down(int k) {
        if (lazy[k] != 0) {
            t[2 * k + 1] += lazy[k];
            t[2 * k + 2] += lazy[k];
            lazy[2 * k + 1] += lazy[k];
            lazy[2 * k + 2] += lazy[k];
            lazy[k] = 0;
        }
    }
    
    void build_tree(int k, int l, int r) {
        if (r - l == 1) {
            t[k] = INF;
            return;
        }
        int m = (l + r) >> 1;
        build_tree(2 * k + 1, l, m);
        build_tree(2 * k + 2, m, r);
        t[k] = Math.min(t[2 * k + 1], t[2 * k + 2]);
    }
    
    int[][] build_graph(int n, int[] from, int[] to) {
        int[][] G = new int[n][];
        int[] cnt = new int[n];
        for (int i = 0; i < from.length; i++) {
            cnt[from[i]]++;
            cnt[to[i]]++;
        }
        for (int i = 0; i < n; i++) G[i] = new int[cnt[i]];
        for (int i = 0; i < from.length; i++) {
            G[from[i]][--cnt[from[i]]] = to[i];
            G[to[i]][--cnt[to[i]]] = from[i];
        }
        return G;
    }
    
    public static void main(String[] args) {
        in = new FastScanner(new BufferedReader(new InputStreamReader(System.in)));
        out = new PrintWriter(System.out);
        new SplitTheTree2().solve();
        out.close();
    }
    
    static FastScanner in;
    static PrintWriter out;
    
    static class FastScanner {
        BufferedReader in;
        StringTokenizer st;
        
        public FastScanner(BufferedReader in) {
            this.in = in;
        }
        
        public String nextToken() {
            while (st == null || !st.hasMoreTokens()) {
                try {
                    st = new StringTokenizer(in.readLine());
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            return st.nextToken();
        }
        
        public int nextInt() {
            return Integer.parseInt(nextToken());
        }
        
        public long nextLong() {
            return Long.parseLong(nextToken());
        }
        
        public double nextDouble() {
            return Double.parseDouble(nextToken());
        }
    }
}
