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.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Arrays;
import java.util.PriorityQueue;
import java.util.AbstractQueue;
import java.io.IOException;
import java.util.ArrayList;
import java.io.UncheckedIOException;
import java.util.List;
import java.util.AbstractCollection;
import java.io.Closeable;
import java.io.Writer;
import java.io.OutputStreamWriter;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 */
public class Main {
    public static void main(String[] args) throws Exception {
        Thread thread = new Thread(null, new TaskAdapter(), "", 1 << 27);
        thread.start();
        thread.join();
    }

    static class TaskAdapter implements Runnable {
        @Override
        public void run() {
            InputStream inputStream = System.in;
            OutputStream outputStream = System.out;
            FastInput in = new FastInput(inputStream);
            FastOutput out = new FastOutput(outputStream);
            ESplitTheTree solver = new ESplitTheTree();
            solver.solve(1, in, out);
            out.close();
        }
    }

    static class ESplitTheTree {
        int l;
        long s;

        public void solve(int testNumber, FastInput in, FastOutput out) {
            int n = in.readInt();
            l = in.readInt();
            s = in.readLong();
            Node[] nodes = new Node[n + 1];
            for (int i = 1; i <= n; i++) {
                nodes[i] = new Node();
                nodes[i].id = i;
                nodes[i].w = in.readInt();
                nodes[i].lct = new LCTNode();
                if (nodes[i].w > s) {
                    out.println(-1);
                    return;
                }
            }

            for (int i = 2; i <= n; i++) {
                Node p = nodes[in.readInt()];
                nodes[i].next.add(p);
                p.next.add(nodes[i]);

                LCTNode.join(nodes[i].lct, p.lct);
            }

            dfs(nodes[1], null, 0);
            PriorityQueue<Node> pq = new PriorityQueue<>(n, (a, b) -> -(a.depth - b.depth));
            pq.addAll(Arrays.asList(nodes).subList(1, nodes.length));

            int cost = 0;
            while (!pq.isEmpty()) {
                Node head = pq.remove();
                LCTNode.splay(head.lct);
                if (head.lct.handled) {
                    continue;
                }
                Node top = find(head);
                LCTNode.findRoute(head.lct, top.lct);
                LCTNode.splay(head.lct);
                head.lct.setHandled();
                cost++;
            }

            out.println(cost);
        }

        public Node find(Node root) {
            Node trace = root;
            for (int i = 20 - 1; i >= 0; i--) {
                if (trace.jumps[i] == null) {
                    continue;
                }
                if (root.depth - trace.jumps[i].depth + 1 <= l &&
                        root.presum - trace.jumps[i].presum + trace.jumps[i].w <= s) {
                    trace = trace.jumps[i];
                }
            }
            return trace;
        }

        public void dfs(Node root, Node p, int depth) {
            root.jumps[0] = p;
            for (int i = 0; root.jumps[i] != null; i++) {
                root.jumps[i + 1] = root.jumps[i].jumps[i];
            }
            root.depth = depth;
            root.presum = root.w;
            if (p != null) {
                root.presum += p.presum;
            }
            for (Node node : root.next) {
                if (node == p) {
                    continue;
                }
                dfs(node, root, depth + 1);
            }
        }

    }

    static class FastInput {
        private final InputStream is;
        private byte[] buf = new byte[1 << 13];
        private int bufLen;
        private int bufOffset;
        private int next;

        public FastInput(InputStream is) {
            this.is = is;
        }

        private int read() {
            while (bufLen == bufOffset) {
                bufOffset = 0;
                try {
                    bufLen = is.read(buf);
                } catch (IOException e) {
                    bufLen = -1;
                }
                if (bufLen == -1) {
                    return -1;
                }
            }
            return buf[bufOffset++];
        }

        public void skipBlank() {
            while (next >= 0 && next <= 32) {
                next = read();
            }
        }

        public int readInt() {
            int sign = 1;

            skipBlank();
            if (next == '+' || next == '-') {
                sign = next == '+' ? 1 : -1;
                next = read();
            }

            int val = 0;
            if (sign == 1) {
                while (next >= '0' && next <= '9') {
                    val = val * 10 + next - '0';
                    next = read();
                }
            } else {
                while (next >= '0' && next <= '9') {
                    val = val * 10 - next + '0';
                    next = read();
                }
            }

            return val;
        }

        public long readLong() {
            int sign = 1;

            skipBlank();
            if (next == '+' || next == '-') {
                sign = next == '+' ? 1 : -1;
                next = read();
            }

            long val = 0;
            if (sign == 1) {
                while (next >= '0' && next <= '9') {
                    val = val * 10 + next - '0';
                    next = read();
                }
            } else {
                while (next >= '0' && next <= '9') {
                    val = val * 10 - next + '0';
                    next = read();
                }
            }

            return val;
        }

    }

    static class LCTNode {
        public static final LCTNode NIL = new LCTNode();
        LCTNode left = NIL;
        LCTNode right = NIL;
        LCTNode father = NIL;
        LCTNode treeFather = NIL;
        boolean reverse;
        int id;
        boolean handled;
        boolean dirty;

        static {
            NIL.left = NIL;
            NIL.right = NIL;
            NIL.father = NIL;
            NIL.treeFather = NIL;
        }

        public void setHandled() {
            handled = true;
            dirty = true;
        }

        public static void access(LCTNode x) {
            LCTNode last = NIL;
            while (x != NIL) {
                splay(x);
                x.right.father = NIL;
                x.right.treeFather = x;
                x.setRight(last);
                x.pushUp();

                last = x;
                x = x.treeFather;
            }
        }

        public static void makeRoot(LCTNode x) {
            access(x);
            splay(x);
            x.reverse();
        }

        public static void join(LCTNode y, LCTNode x) {
            makeRoot(x);
            x.treeFather = y;
        }

        public static void findRoute(LCTNode x, LCTNode y) {
            makeRoot(y);
            access(x);
        }

        public static void splay(LCTNode x) {
            if (x == NIL) {
                return;
            }
            LCTNode y, z;
            while ((y = x.father) != NIL) {
                if ((z = y.father) == NIL) {
                    y.pushDown();
                    x.pushDown();
                    if (x == y.left) {
                        zig(x);
                    } else {
                        zag(x);
                    }
                } else {
                    z.pushDown();
                    y.pushDown();
                    x.pushDown();
                    if (x == y.left) {
                        if (y == z.left) {
                            zig(y);
                            zig(x);
                        } else {
                            zig(x);
                            zag(x);
                        }
                    } else {
                        if (y == z.left) {
                            zag(x);
                            zig(x);
                        } else {
                            zag(y);
                            zag(x);
                        }
                    }
                }
            }

            x.pushDown();
            x.pushUp();
        }

        public static void zig(LCTNode x) {
            LCTNode y = x.father;
            LCTNode z = y.father;
            LCTNode b = x.right;

            y.setLeft(b);
            x.setRight(y);
            z.changeChild(y, x);

            y.pushUp();
        }

        public static void zag(LCTNode x) {
            LCTNode y = x.father;
            LCTNode z = y.father;
            LCTNode b = x.left;

            y.setRight(b);
            x.setLeft(y);
            z.changeChild(y, x);

            y.pushUp();
        }

        public String toString() {
            return "" + id;
        }

        public void pushDown() {
            if (reverse) {
                reverse = false;

                LCTNode tmpNode = left;
                left = right;
                right = tmpNode;

                left.reverse();
                right.reverse();
            }

            if (dirty) {
                left.setHandled();
                right.setHandled();
                dirty = false;
            }

            left.treeFather = treeFather;
            right.treeFather = treeFather;
        }

        public void reverse() {
            reverse = !reverse;
        }

        public void setLeft(LCTNode x) {
            left = x;
            x.father = this;
        }

        public void setRight(LCTNode x) {
            right = x;
            x.father = this;
        }

        public void changeChild(LCTNode y, LCTNode x) {
            if (left == y) {
                setLeft(x);
            } else {
                setRight(x);
            }
        }

        public void pushUp() {
        }

    }

    static class FastOutput implements AutoCloseable, Closeable {
        private StringBuilder cache = new StringBuilder(10 << 20);
        private final Writer os;

        public FastOutput(Writer os) {
            this.os = os;
        }

        public FastOutput(OutputStream os) {
            this(new OutputStreamWriter(os));
        }

        public FastOutput println(int c) {
            cache.append(c).append('\n');
            return this;
        }

        public FastOutput flush() {
            try {
                os.append(cache);
                os.flush();
                cache.setLength(0);
            } catch (IOException e) {
                throw new UncheckedIOException(e);
            }
            return this;
        }

        public void close() {
            flush();
            try {
                os.close();
            } catch (IOException e) {
                throw new UncheckedIOException(e);
            }
        }

        public String toString() {
            return cache.toString();
        }

    }

    static class Node {
        List<Node> next = new ArrayList<>();
        Node[] jumps = new Node[20];
        int id;
        int w;
        long presum;
        int depth;
        LCTNode lct;

        public String toString() {
            return "" + id;
        }

    }
}

