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;
template <typename elemType>
inline void Read(elemType &T) {
  elemType X = 0, w = 0;
  char ch = 0;
  while (!isdigit(ch)) {
    w |= ch == '-';
    ch = getchar();
  }
  while (isdigit(ch)) X = (X << 3) + (X << 1) + (ch ^ 48), ch = getchar();
  T = (w ? -X : X);
}
struct edge {
  int Next, to;
};
edge G[200010];
int head[100010], Deep[100010], Anc[100010][20], Len[100010];
long long Value[100010], Sum[100010][20], PreSum[100010];
int N, L, cnt = 2, Ans = 0;
long long S;
inline void Add_Edge(int u, int v) {
  G[cnt].to = v;
  G[cnt].Next = head[u];
  head[u] = cnt++;
}
void DFS_Init(int u, int fa) {
  Anc[u][0] = fa;
  Sum[u][0] = Value[fa];
  for (int i = 1; i < 20; ++i) {
    Anc[u][i] = Anc[Anc[u][i - 1]][i - 1];
    Sum[u][i] = Sum[Anc[u][i - 1]][i - 1] + Sum[u][i - 1];
  }
  for (int i = head[u]; i; i = G[i].Next) {
    int v = G[i].to;
    if (v == fa) continue;
    Deep[v] = Deep[u] + 1;
    DFS_Init(v, u);
  }
  return;
}
int GetPos(int u, long long SUM, int LEN) {
  int v = u;
  long long temp = 0;
  for (register int i = 19; i >= 0; --i) {
    if (temp + Sum[u][i] <= SUM && Deep[v] - Deep[Anc[u][i]] <= LEN) {
      temp += Sum[u][i];
      u = Anc[u][i];
    }
  }
  return Deep[v] - Deep[u];
}
void DFS(int u, int fa) {
  int Count = 0;
  int MaxLen = 0, MaxV = 0;
  for (int i = head[u]; i; i = G[i].Next) {
    int v = G[i].to;
    if (v == fa) continue;
    DFS(v, u);
    int temp = GetPos(v, S - PreSum[v], L - Len[v]);
    if (temp > MaxLen) {
      MaxLen = temp;
      MaxV = v;
    }
    ++Count;
  }
  if (MaxLen == 0) {
    ++Ans;
    PreSum[u] = Value[u];
    Len[u] = 1;
    return;
  }
  PreSum[u] = Value[u] + PreSum[MaxV];
  Len[u] = Len[MaxV] + 1;
  return;
}
int main() {
  Read(N);
  Read(L);
  Read(S);
  long long MaxValue = -1;
  for (register int i = 1; i <= N; ++i) {
    Read(Value[i]);
    MaxValue = max(MaxValue, Value[i]);
  }
  for (register int v = 2; v <= N; ++v) {
    int u;
    Read(u);
    Add_Edge(u, v);
    Add_Edge(v, u);
  }
  if (MaxValue > S) {
    printf("-1\n");
    return 0;
  }
  DFS_Init(1, 0);
  DFS(1, 0);
  printf("%d\n", Ans);
  return 0;
}
