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.
#include <bits/stdc++.h>
using namespace std;
const int INFL = (int)1e9;
const long long int INFLL = (long long int)1e18;
const double INFD = numeric_limits<double>::infinity();
const double PI = 3.14159265358979323846;
bool nearlyeq(double x, double y) { return abs(x - y) < 1e-9; }
bool inrange(int x, int t) { return x >= 0 && x < t; }
long long int rndf(double x) {
  return (long long int)(x + (x >= 0 ? 0.5 : -0.5));
}
long long int floorsqrt(double x) {
  long long int m = (long long int)sqrt(x);
  return m + (m * m <= (long long int)(x) ? 0 : -1);
}
long long int ceilsqrt(double x) {
  long long int m = (long long int)sqrt(x);
  return m + ((long long int)x <= m * m ? 0 : 1);
}
long long int rnddiv(long long int a, long long int b) {
  return (a / b + (a % b * 2 >= b ? 1 : 0));
}
long long int ceildiv(long long int a, long long int b) {
  return (a / b + (a % b == 0 ? 0 : 1));
}
long long int gcd(long long int m, long long int n) {
  if (n == 0)
    return m;
  else
    return gcd(n, m % n);
}
struct tree_t {
  int n;
  vector<pair<int, int>> edges;
  vector<long long int> vals;
  vector<long long int> costs;
};
class Tree {
 private:
  struct node {
    int id;
    vector<int> childs;
    int parent = -1;
    int deg = -1;
    int eid = -1;
    int subtree_n = 1;
    int visited = -1;
    int departed = -1;
    long long int val;
    long long int cost;
    bool operator<(const node &another) const {
      return deg != another.deg ? deg < another.deg : id < another.id;
    }
  };
  struct edgeinfo {
    int eid;
    int to;
    long long int cost;
  };
  int n;
  static const long long int init_val = 0;
  static const long long int init_cost = 1;
  vector<vector<edgeinfo>> edges;
  vector<vector<int>> sparse_ancestors;
  void tree_construction() {
    leaves = {};
    queue<int> que;
    que.push(root);
    while (que.size()) {
      int a = que.front();
      que.pop();
      deg_order.push_back(a);
      if (a == Tree::root) nodes[a].deg = 0;
      int leaf_flag = true;
      for (int i = 0; i < (int)edges[a].size(); i++) {
        int b = edges[a][i].to;
        if (nodes[b].deg != -1) {
          nodes[a].parent = b;
          nodes[a].eid = edges[a][i].eid;
          nodes[a].cost = edges[a][i].cost;
          nodes[a].deg = nodes[b].deg + 1;
        } else {
          leaf_flag = false;
          nodes[a].childs.push_back(b);
          que.push(b);
        }
      }
      if (leaf_flag) leaves.push_back(a);
    }
    for (int i = (int)n - 1; i >= 0; i--) {
      int a = deg_order[i];
      for (int j = 0; j < (int)nodes[a].childs.size(); j++) {
        int b = nodes[a].childs[j];
        nodes[a].subtree_n += nodes[b].subtree_n;
      }
    }
  }
  void solve_sparse_ancestors() {
    sparse_ancestors.resize(n);
    vector<int> current_ancestors;
    stack<int> stk;
    stk.push(Tree::root);
    int time_stamp = 1;
    while (stk.size()) {
      int a = stk.top();
      stk.pop();
      nodes[a].visited = time_stamp++;
      for (int i = 1; i <= (int)(current_ancestors.size()); i *= 2) {
        sparse_ancestors[a].push_back(
            current_ancestors[current_ancestors.size() - i]);
      }
      if (nodes[a].childs.size()) {
        for (int i = 0; i < (int)nodes[a].childs.size(); i++) {
          stk.push(nodes[a].childs[i]);
        }
        current_ancestors.push_back(a);
      } else {
        nodes[a].departed = time_stamp++;
        while (current_ancestors.size() &&
               (stk.empty() ||
                nodes[stk.top()].parent != current_ancestors.back())) {
          nodes[current_ancestors.back()].departed = time_stamp++;
          current_ancestors.pop_back();
        }
      }
    }
    return;
  }
  bool is_ancestor(int descendant, int ancestor) {
    return nodes[ancestor].visited < nodes[descendant].visited &&
           nodes[descendant].departed < nodes[ancestor].departed;
  }
  int get_ancestor(int descendant, int k) {
    if (k == 0) return descendant;
    int l = (int)log2(k);
    if (l >= sparse_ancestors[descendant].size())
      return -1;
    else
      return get_ancestor(sparse_ancestors[descendant][l], k - (1 << l));
  }
  template <typename bsargv_t>
  int binary_search_upper_ancestor(int descendant, const bsargv_t &bsargv,
                                   bool (*evalfunc)(int, const bsargv_t &)) {
    if (evalfunc(descendant, bsargv)) return descendant;
    if (descendant == root) return -1;
    for (int i = 0; i < (int)sparse_ancestors[descendant].size(); i++) {
      if (evalfunc(sparse_ancestors[descendant][i], bsargv)) {
        if (i == 0)
          return binary_search_upper_ancestor(sparse_ancestors[descendant][0],
                                              bsargv, evalfunc);
        else
          return binary_search_upper_ancestor(
              sparse_ancestors[descendant][i - 1], bsargv, evalfunc);
      }
    }
    return binary_search_upper_ancestor(sparse_ancestors[descendant].back(),
                                        bsargv, evalfunc);
  }
  template <typename bsargv_t>
  int binary_search_lower_ancestor(int descendant, const bsargv_t &bsargv,
                                   bool (*evalfunc)(int, const bsargv_t &)) {
    if (!evalfunc(descendant, bsargv)) return -1;
    if (descendant == root) return root;
    for (int i = 0; i < (int)sparse_ancestors[descendant].size(); i++) {
      if (!evalfunc(sparse_ancestors[descendant][i], bsargv)) {
        if (i == 0)
          return descendant;
        else
          return binary_search_lower_ancestor(
              sparse_ancestors[descendant][i - 1], bsargv, evalfunc);
      }
    }
    return binary_search_lower_ancestor(sparse_ancestors[descendant].back(),
                                        bsargv, evalfunc);
  }
  static bool evalfunc(int id, const vector<bool> &done) {
    if (done[id])
      return false;
    else
      return true;
  }

 public:
  vector<node> nodes;
  vector<int> deg_order;
  vector<int> leaves;
  int root;
  Tree(tree_t T, int root = -1) {
    n = T.n;
    nodes.resize(n);
    for (int i = 0; i < (int)n; i++) {
      nodes[i].id = i;
      nodes[i].val = (int)(T.vals.size()) > i ? T.vals[i] : init_val;
      nodes[i].cost = init_cost;
    }
    edges.resize(n);
    for (int i = 0; i < (int)n - 1; i++) {
      edges[T.edges[i].first].push_back(
          {i, T.edges[i].second,
           ((int)(T.costs.size()) > i ? T.costs[i] : init_cost)});
      edges[T.edges[i].second].push_back(
          {i, T.edges[i].first,
           ((int)(T.costs.size()) > i ? T.costs[i] : init_cost)});
    }
    if (root < 0) {
      int max_d = -1;
      for (int i = 0; i < (int)n; i++) {
        if ((int)(edges[i].size()) > max_d) {
          Tree::root = i;
          max_d = edges[i].size();
        }
      }
    } else {
      this->root = min(root, n - 1);
    }
    tree_construction();
    return;
  }
  int solve(long long int l, long long int s, vector<long long int> v) {
    solve_sparse_ancestors();
    for (int i = 1; i <= (int)deg_order.size() - 1; i++) {
      int a = deg_order[i];
      int b = nodes[a].parent;
      nodes[a].val += nodes[b].val;
    }
    int ret = 0;
    vector<bool> done(n);
    for (int i = (int)deg_order.size() - 1; i >= 0; i--) {
      int a = deg_order[i];
      if (done[a]) continue;
      ret++;
      int b = a;
      while (true) {
        if (b == -1) break;
        if (done[b]) break;
        if (nodes[a].val - nodes[b].val + v[b] > s) break;
        if (nodes[a].deg - nodes[b].deg + 1 > l) break;
        done[b] = true;
        b = nodes[b].parent;
      }
      if (!done[a]) return -1;
      b = binary_search_upper_ancestor<vector<bool>>(a, done, evalfunc);
      while (true) {
        if (b == -1) break;
        if (nodes[a].val - nodes[b].val + v[b] > s) break;
        if (nodes[a].deg - nodes[b].deg + 1 > l) break;
        done[b] = true;
        b = nodes[b].parent;
      }
    }
    return ret;
  }
};
int main() {
  tree_t T;
  cin >> T.n;
  long long int l, s;
  cin >> l >> s;
  vector<long long int> v;
  for (int i = 0; i < (int)T.n; i++) {
    long long int x;
    cin >> x;
    T.vals.push_back(x);
    v.push_back(x);
  }
  for (int i = 1; i <= (int)T.n - 1; i++) {
    int t;
    cin >> t;
    t--;
    T.edges.push_back({i, t});
  }
  Tree tree(T, 0);
  cout << tree.solve(l, s, v) << endl;
}
