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;
mt19937 gen_rand;
template <typename T, typename U>
ostream &operator<<(ostream &os, pair<T, U> &a) {
  os << "(";
  os << a.first << ", ";
  os << a.second;
  os << ")";
  return os;
}
template <typename T>
ostream &operator<<(ostream &os, vector<T> &a) {
  os << "{";
  bool was = false;
  for (auto &x : a) {
    if (was) {
      os << ", ";
    }
    was = true;
    os << x;
  }
  os << "}";
  return os;
}
template <typename T>
inline void debug(const char *sdbg, T x) {
  cerr << "The value of " << sdbg << " is " << x << "\n";
};
template <typename T, typename... U>
inline void debug(const char *sdbg, T h, U... t) {
  cerr << "The value of ";
  while (*sdbg != ',') {
    cerr << *sdbg++;
  }
  cerr << " is " << h << "\n";
  debug(sdbg + 1, t...);
  cerr << "\n";
}
template <typename T>
T abs(T x) {
  if (x < 0) {
    return -x;
  } else {
    return x;
  }
}
template <typename T>
T sqr(T x) {
  return x * x;
};
const long long INF_FOR_SHORT_TIME = (long long)(1e9);
template <typename T>
T mul(T a, T b, T m) {
  if (a <= INF_FOR_SHORT_TIME && b <= INF_FOR_SHORT_TIME) {
    return (a * b) % m;
  }
  T q = (long long)((long double)a * (long double)b / (long double)m);
  T r = a * b - q * m;
  return (r + 5 * m) % m;
}
template <typename T, typename U>
T binpow(T a, U n, T MOD) {
  T res = 1;
  while (n) {
    if (n & 1) {
      res = mul(res, a, MOD);
    }
    a = mul(a, a, MOD);
    n >>= 1;
  }
  return res;
};
template <typename T>
int sign(T x) {
  if (x < 0) {
    return -1;
  } else if (x > 0) {
    return 1;
  } else {
    return 0;
  }
};
template <typename T>
T gcd(T a, T b) {
  if (a > b) {
    swap(a, b);
  }
  while (a) {
    b %= a;
    swap(a, b);
  }
  return b;
};
template <typename T>
bool uin(T &a, T b) {
  if (a > b) {
    a = b;
    return true;
  }
  return false;
};
template <typename T>
bool uax(T &a, T b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
};
const int maxn = 1e5 + 5;
const int lg = 20;
const long long inf = 1e18;
int n, L;
long long S;
long long t[4 * maxn];
long long t_add[4 * maxn];
int cid = 0;
int w[maxn];
vector<int> down[maxn];
long long sum[maxn];
int up[maxn];
int p[maxn][lg];
long long dp[maxn];
int id[maxn], rb[maxn];
long long dp_sum[maxn];
vector<int> rm[maxn];
long long left(long long v) {
  assert(2 * v < 4 * maxn);
  return 2 * v;
}
long long right(long long v) {
  assert(2 * v + 1 < 4 * maxn);
  return 2 * v + 1;
}
void push(long long v, long long l, long long r) {
  t[v] += t_add[v];
  if (l != r) {
    t_add[left(v)] += t_add[v];
    t_add[right(v)] += t_add[v];
  }
  t_add[v] = 0;
}
void set_tree(long long v, long long l, long long r, long long pos,
              long long x) {
  push(v, l, r);
  if (l == r) {
    t[v] = x;
    t_add[v] = 0;
    return;
  }
  long long m = (l + r) / 2;
  if (pos <= m) {
    set_tree(left(v), l, m, pos, x);
    push(right(v), m + 1, r);
  } else {
    set_tree(right(v), m + 1, r, pos, x);
    push(left(v), l, m);
  }
  t[v] = min(t[left(v)], t[right(v)]);
}
void add_tree(long long v, long long l, long long r, long long nl, long long nr,
              long long x) {
  push(v, l, r);
  if (l > r || nl > nr) {
    return;
  }
  if (l == nl && r == nr) {
    t_add[v] += x;
    push(v, l, r);
    return;
  }
  long long m = (l + r) / 2;
  add_tree(left(v), l, m, nl, min(m, nr), x);
  add_tree(right(v), m + 1, r, max(m + 1, nl), nr, x);
  t[v] = min(t[left(v)], t[right(v)]);
}
long long get_tree(long long v, long long l, long long r, long long nl,
                   long long nr) {
  push(v, l, r);
  if (l > r || nl > nr) {
    return inf;
  }
  if (l == nl && r == nr) {
    return t[v];
  }
  long long m = (l + r) / 2;
  long long res = inf;
  uin(res, get_tree(left(v), l, m, nl, min(m, nr)));
  uin(res, get_tree(right(v), m + 1, r, max(nl, m + 1), nr));
  t[v] = min(t[left(v)], t[right(v)]);
  return res;
}
inline long long get_sum(int v) { return v == -1 ? 0 : sum[v]; }
void preprocess(int v, int pr = -1) {
  sum[v] = get_sum(pr) + w[v];
  p[v][0] = pr;
  up[v] = v;
  id[v] = rb[v] = cid++;
  for (int i = 1; i < lg; i++)
    p[v][i] = p[v][i - 1] == -1 ? -1 : p[p[v][i - 1]][i - 1];
  int dist = L - 1;
  for (int i = lg - 1; i >= 0; i--) {
    if (p[up[v]][i] == -1 || (1 << i) > dist) continue;
    if (get_sum(v) - get_sum(p[up[v]][i]) + w[p[up[v]][i]] <= S) {
      dist -= 1 << i;
      up[v] = p[up[v]][i];
    }
  }
  rm[up[v]].push_back(v);
  for (int u : down[v]) {
    preprocess(u, v);
    rb[v] = max(rb[v], rb[u]);
  }
}
void build_tree(int v, int l, int r) {
  t[v] = inf;
  if (l == r) return;
  int mid = (l + r) / 2;
  build_tree(2 * v, l, mid);
  build_tree(2 * v + 1, mid + 1, r);
}
inline void upd(int v) { dp[v] = 1 + get_tree(1, 0, maxn - 1, id[v], rb[v]); }
inline void add(int v) {
  set_tree(1, 0, maxn - 1, id[v], 0);
  add_tree(1, 0, maxn - 1, id[v], rb[v], dp_sum[v] - dp[v]);
}
inline void remove(int v) { set_tree(1, 0, maxn - 1, id[v], inf); }
void solve(int v) {
  for (int u : down[v]) {
    solve(u);
    dp_sum[v] += dp[u];
  }
  add(v);
  dp[v] = maxn;
  upd(v);
  add_tree(1, 0, maxn - 1, id[v], rb[v], -dp[v]);
  for (int u : rm[v]) remove(u);
}
int main() {
  scanf("%d%d%lld", &n, &L, &S);
  for (int i = 0; i < n; i++) {
    scanf("%d", &w[i]);
    if (w[i] > S) {
      printf("-1");
      return 0;
    }
  }
  for (int i = 1; i < n; i++) {
    int j;
    scanf("%d", &j);
    down[--j].push_back(i);
  }
  preprocess(0);
  build_tree(1, 0, maxn - 1);
  solve(0);
  printf("%lld", dp[0]);
}
