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>
#pragma GCC optimize("Ofast")
#pragma GCC optimize("no-stack-protector")
#pragma GCC optimize("unroll-loops")
#pragma GCC optimize("fast-math")
using namespace std;
template <typename T>
void uin(T &a, T b) {
  if (b < a) a = b;
}
template <typename T>
void uax(T &a, T b) {
  if (b > a) a = b;
}
const long long maxn = 100 * 1000 + 228, INF = 1e16 + 228;
long long n, L, S;
long long w[maxn], p[maxn][20], h[maxn], sum[maxn], lb[maxn], rb[maxn],
    sz[maxn], timer = 0;
vector<long long> g[maxn];
void zhfs(long long v) {
  if (v == 1)
    h[v] = 0;
  else
    h[v] = h[p[v][0]] + 1;
  sum[v] = sum[p[v][0]] + w[v];
  for (long long k = 1; k < 20; ++k) {
    p[v][k] = p[p[v][k - 1]][k - 1];
  }
  lb[v] = ++timer;
  sz[v] = 1;
  for (long long to : g[v]) {
    zhfs(to);
    sz[v] += sz[to];
  }
  rb[v] = lb[v] + sz[v] - 1;
}
struct node {
  long long mn;
  long long mod;
  long long l, r;
  node() { mn = mod = l = r = 0; }
};
vector<node> d;
void build(long long l, long long r, long long v = 1) {
  d[v].l = l;
  d[v].r = r;
  if (l == r) return;
  long long m = (l + r) >> 1;
  build(l, m, v << 1);
  build(m + 1, r, v << 1 | 1);
}
void init(long long n) {
  long long ss = 1;
  while (ss < n) ss <<= 1;
  ss <<= 1;
  d.resize(ss + 3, node());
  build(1, n);
}
long long gets(long long v) { return d[v].mn + d[v].mod; }
void push(long long v) {
  if (d[v].mod) {
    d[v << 1].mod += d[v].mod;
    d[v << 1 | 1].mod += d[v].mod;
    d[v].mod = 0;
    d[v].mn = min(gets(v << 1), gets(v << 1 | 1));
  }
}
void update(long long l, long long r, long long x, long long v = 1) {
  if (l > r || d[v].l > r || d[v].r < l) return;
  if (l <= d[v].l && d[v].r <= r) {
    d[v].mod += x;
  } else {
    push(v);
    update(l, r, x, v << 1);
    update(l, r, x, v << 1 | 1);
    d[v].mn = min(gets(v << 1), gets(v << 1 | 1));
  }
}
void Set(long long pos, long long x, long long v = 1) {
  if (d[v].l == d[v].r) {
    d[v].mn = x;
    d[v].mod = 0;
    return;
  }
  long long m = (d[v].l + d[v].r) >> 1;
  push(v);
  if (pos <= m)
    Set(pos, x, v << 1);
  else
    Set(pos, x, v << 1 | 1);
  d[v].mn = min(gets(v << 1), gets(v << 1 | 1));
}
long long get(long long l, long long r, long long v = 1) {
  if (l > r || d[v].l > r || d[v].r < l) return INF;
  if (l <= d[v].l && d[v].r <= r) return gets(v);
  push(v);
  return min(get(l, r, v << 1), get(l, r, v << 1 | 1));
}
long long get_up(long long v) {
  long long k = 19;
  long long st = v;
  while (k >= 0) {
    if (h[st] - h[p[v][k]] + 1 <= L &&
        sum[st] - sum[p[v][k]] + w[p[v][k]] <= S) {
      v = p[v][k];
    }
    --k;
  }
  while (v != 1 && h[st] - h[p[v][0]] + 1 <= L &&
         sum[st] - sum[p[v][0]] + w[p[v][0]] <= S)
    v = p[v][0];
  return v;
}
vector<long long> woops[maxn];
long long up[maxn];
void prepare() {
  for (long long v = 1; v <= n; ++v) {
    up[v] = get_up(v);
    woops[up[v]].push_back(v);
  }
}
long long dp[maxn], dp_sum[maxn];
void dfs(long long v) {
  for (long long to : g[v]) {
    dfs(to);
    dp_sum[v] += dp[to];
  }
  dp[v] = min(dp_sum[v] + 1, 1 + get(lb[v], rb[v]) + dp_sum[v]);
  update(lb[v], rb[v], dp_sum[v] - dp[v]);
  for (long long u : woops[v]) {
    Set(lb[u], INF);
  }
}
void solve() {
  cin >> n >> L >> S;
  bool ok = 1;
  for (long long i = 1; i <= n; ++i) {
    cin >> w[i];
    if (w[i] > S) ok = 0;
  }
  for (long long i = 2; i <= n; ++i) {
    cin >> p[i][0];
    g[p[i][0]].push_back(i);
  }
  if (!ok) {
    cout << -1 << '\n';
    return;
  }
  p[1][0] = 1;
  zhfs(1);
  prepare();
  init(n);
  dfs(1);
  cout << dp[1] << '\n';
}
signed main() {
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  solve();
  return 0;
}
