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;
using ll = long long;
const ll INF = 1e18;
struct segtree {
  int n;
  vector<ll> tree, mod;
  segtree() {}
  segtree(int n) : n(n), tree(4 * n, INF), mod(4 * n) {}
  inline void push(int v, int vl, int vr) {
    if (!mod[v]) return;
    tree[v] += mod[v];
    if (vr - vl > 1) {
      mod[2 * v] += mod[v];
      mod[2 * v + 1] += mod[v];
    }
    mod[v] = 0;
  }
  inline void add(int l, int r, ll delta) { update(1, 0, n, l, r, delta); }
  void update(int v, int vl, int vr, int l, int r, ll delta) {
    push(v, vl, vr);
    if (r <= vl || vr <= l) return;
    if (l <= vl && vr <= r) {
      mod[v] += delta;
      return;
    }
    int vm = (vl + vr) / 2;
    update(2 * v, vl, vm, l, r, delta);
    update(2 * v + 1, vm, vr, l, r, delta);
    push(2 * v, vl, vm);
    push(2 * v + 1, vm, vr);
    tree[v] = min(tree[2 * v], tree[2 * v + 1]);
  }
  inline ll get_min(int l, int r) { return get(1, 0, n, l, r); }
  ll get(int v, int vl, int vr, int l, int r) {
    push(v, vl, vr);
    if (r <= vl || vr <= l) return INF;
    if (l <= vl && vr <= r) return tree[v];
    int vm = (vl + vr) / 2;
    return min(get(2 * v, vl, vm, l, r), get(2 * v + 1, vm, vr, l, r));
  }
};
const int LG = 19;
int n, l;
ll s;
vector<vector<int>> g;
int timer;
vector<int> p, tin, tout;
vector<vector<pair<int, ll>>> to;
vector<vector<int>> dont_use_ends;
segtree tree;
vector<ll> dp;
void init(int v) {
  tin[v] = timer++;
  for (int level = 0; level < LG - 1; level++) {
    to[level + 1][v].first = to[level][to[level][v].first].first;
    to[level + 1][v].second =
        to[level][to[level][v].first].second + to[level][v].second;
  }
  for (auto u : g[v]) {
    to[0][u] = {v, p[v]};
    init(u);
  }
  tout[v] = timer;
}
void dfs(int v) {
  ll sum = 0;
  for (auto u : g[v]) {
    dfs(u);
    sum += dp[u];
  }
  dp[v] = min(sum, tree.get_min(tin[v], tout[v]) + sum) + 1;
  tree.add(tin[v], tin[v] + 1, -tree.get_min(tin[v], tin[v] + 1));
  for (auto u : dont_use_ends[v]) tree.add(tin[u], tin[u] + 1, INF);
  tree.add(tin[v], tout[v], sum - dp[v]);
}
int main() {
  ios::sync_with_stdio(false), cin.tie(nullptr);
  cin >> n >> l >> s;
  p.resize(n);
  for (auto &x : p) {
    cin >> x;
    if (x > s) {
      cout << "-1\n";
      return 0;
    }
  }
  g.resize(n);
  for (int i = 1; i < n; i++) {
    int p;
    cin >> p;
    p--;
    g[p].push_back(i);
  }
  to.resize(LG, vector<pair<int, ll>>(n));
  tin.resize(n);
  tout.resize(n);
  init(0);
  dont_use_ends.resize(n);
  for (int i = 0; i < n; i++) {
    ll left_sum = s - p[i];
    int left_dist = l - 1;
    int where = i;
    for (int j = LG - 1; j >= 0; j--)
      if (left_sum >= to[j][where].second && left_dist >= (1 << j)) {
        left_sum -= to[j][where].second;
        left_dist -= (1 << j);
        where = to[j][where].first;
      }
    dont_use_ends[where].push_back(i);
  }
  tree = segtree(2 * n);
  dp.resize(n);
  dfs(0);
  cout << dp[0] << '\n';
}
