#include <bits/stdc++.h>
#pragma GCC optimize("Ofast")
#pragma GCC target( \
    "sse,sse2,sse3,ssse3,sse4,sse4.1,sse4.2,popcnt,mmx,avx,tune=native")
using namespace std;
const int MOD = 1000000007;
const int UNDEF = -1;
const int INF = 1 << 30;
template <typename T>
inline bool chkmax(T &aa, T bb) {
  return aa < bb ? aa = bb, true : false;
}
template <typename T>
inline bool chkmin(T &aa, T bb) {
  return aa > bb ? aa = bb, true : false;
}
int rint();
char rch();
long long rlong();
const int mn = 1e6 + 4;
long long a[mn];
int oa[mn];
unsigned int b[mn];
int p[mn];
int n;
unsigned int hia = 0;
bool fint(unsigned int t) {
  if ((unsigned int)hia > (unsigned int)t) return false;
  for (int x = 1; x < n; x++) b[x] = oa[x];
  for (int x = 0; x <= n - 2; x++) {
    int par = p[x];
    if (b[x] < t) {
      b[par] += b[x];
      if (b[par] > t) return false;
    }
  }
  return (b[n - 1] == t);
}
bool f(long long t) {
  if (t + hia < UINT_MAX) return fint(t);
  for (int x = 1; x < n; x++) a[x] = oa[x];
  for (int x = 0; x <= n - 2; x++) {
    int par = p[x];
    if (a[x] < t) {
      a[par] += a[x];
      if (a[par] > t) return false;
    }
  }
  return (a[n - 1] == t);
}
vector<pair<long long, int> > pliv;
void compress(vector<long long> &v) {
  sort(v.begin(), v.end());
  int cnt = 1;
  for (int i = 1; i < v.size(); i++) {
    if (v[i] != v[i - 1]) {
      pliv.push_back(make_pair(v[i - 1], cnt));
      cnt = 1;
    } else
      cnt++;
  }
  if (cnt) pliv.push_back(make_pair(v.back(), cnt));
}
long long gt;
int gocc;
void countOcc(int vl, int vr, long long kl, long long kr) {
  if (vl > vr || kl > kr) return;
  if (vl == vr) {
    if (kl == kr) {
      if (pliv[vl].first == kl) gocc += pliv[vl].second;
    } else {
      if (0 == pliv[vl].first % gt) gocc += pliv[vl].second;
    }
    return;
  }
  int vmid = (vl + vr) / 2;
  if (kl == kr) {
    if (pliv[vmid].first >= kl) {
      countOcc(vl, vmid, kl, kl);
      return;
    } else {
      countOcc(vmid + 1, vr, kl, kl);
      return;
    }
  } else {
    long long kmid = (pliv[vmid].first / gt) * gt;
    countOcc(vl, vmid, kl, kmid);
    countOcc(vmid + 1, vr, kmid + gt, kr);
  }
}
long long suma = 0;
bool can(int g, long long d) {
  gt = d;
  gocc = 0;
  countOcc(0, pliv.size() - 1, d, suma);
  return gocc == g;
}
const int slim = 1e6 / 180;
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  n = rint();
  for (int y = 1; y <= n; y++) {
    unsigned int got = rint();
    chkmax(hia, got);
    oa[n - y] = got;
    suma += got;
  }
  a[0] = b[0] = oa[0];
  for (int y = 2; y <= n; y++) {
    p[n - y] = n - rint();
  }
  map<long long, int, greater<long long> > h;
  {
    long long d = hia;
    if (f(d)) h[d] = 0;
  };
  for (int g = n / 2; g >= slim; g--) {
    if (suma % g == 0) {
      long long d = suma / g;
      if (f(d)) h[d] = 0;
    }
  }
  vector<long long> sumsubtree(n);
  for (int x = 0; x < n; x++) sumsubtree[x] = oa[x];
  for (int x = 0; x <= n - 2; x++) sumsubtree[p[x]] += sumsubtree[x];
  compress(sumsubtree);
  for (int g = slim - 1; g >= 2; g--) {
    if (suma % g == 0) {
      long long d = suma / g;
      if (d >= hia && can(g, d)) h[d] = 0;
    }
  }
  h[suma] = 1;
  int final = 0;
  for (auto it = h.begin(); it != h.end(); ++it) {
    int add = it->second;
    final += add;
    if (final >= MOD) final -= MOD;
    auto jt = it;
    ++jt;
    for (; jt != h.end(); ++jt) {
      if (it->first % (jt->first) != 0) continue;
      int ans = jt->second + add;
      if (ans >= MOD) ans -= MOD;
      jt->second = ans;
    }
  }
  printf("%d\n", final);
}
static char stdinBuffer[1024];
static char *stdinDataEnd = stdinBuffer + sizeof(stdinBuffer);
static const char *stdinPos = stdinDataEnd;
void readAhead(size_t amount) {
  size_t remaining = stdinDataEnd - stdinPos;
  if (remaining < amount) {
    memmove(stdinBuffer, stdinPos, remaining);
    size_t sz = fread(stdinBuffer + remaining, 1,
                      sizeof(stdinBuffer) - remaining, stdin);
    stdinPos = stdinBuffer;
    stdinDataEnd = stdinBuffer + remaining + sz;
    if (stdinDataEnd != stdinBuffer + sizeof(stdinBuffer)) *stdinDataEnd = 0;
  }
}
int rint() {
  readAhead(16);
  int x = 0;
  bool neg = false;
  while (*stdinPos == ' ' || *stdinPos == '\n') ++stdinPos;
  if (*stdinPos == '-') {
    ++stdinPos;
    neg = true;
  }
  while (*stdinPos >= '0' && *stdinPos <= '9') {
    x *= 10;
    x += *stdinPos - '0';
    ++stdinPos;
  }
  return neg ? -x : x;
}
char rch() {
  readAhead(16);
  while (*stdinPos == ' ' || *stdinPos == '\n') ++stdinPos;
  char ans = *stdinPos;
  ++stdinPos;
  return ans;
}
long long rlong() {
  readAhead(32);
  long long x = 0;
  bool neg = false;
  while (*stdinPos == ' ' || *stdinPos == '\n') ++stdinPos;
  if (*stdinPos == '-') {
    ++stdinPos;
    neg = true;
  }
  while (*stdinPos >= '0' && *stdinPos <= '9') {
    x *= 10;
    x += *stdinPos - '0';
    ++stdinPos;
  }
  return neg ? -x : x;
}
