#include <bits/stdc++.h>
using namespace std;
template <class T>
void _R(T &x) {
  cin >> x;
}
void _R(int &x) { scanf("%d", &x); }
void _R(int64_t &x) { scanf("%lld", &x); }
void _R(double &x) { scanf("%lf", &x); }
void _R(char &x) { scanf(" %c", &x); }
void _R(char *x) { scanf("%s", x); }
void R() {}
template <class T, class... U>
void R(T &head, U &...tail) {
  _R(head);
  R(tail...);
}
template <class T>
void _W(const T &x) {
  cout << x;
}
void _W(const int &x) { printf("%d", x); }
void _W(const int64_t &x) { printf("%lld", x); }
void _W(const double &x) { printf("%.16f", x); }
void _W(const char &x) { putchar(x); }
void _W(const char *x) { printf("%s", x); }
template <class T, class U>
void _W(const pair<T, U> &x) {
  _W(x.first);
  putchar(' ');
  _W(x.second);
}
template <class T>
void _W(const vector<T> &x) {
  for (auto i = x.begin(); i != x.end(); _W(*i++))
    if (i != x.cbegin()) putchar(' ');
}
void W() {}
template <class T, class... U>
void W(const T &head, const U &...tail) {
  _W(head);
  putchar(sizeof...(tail) ? ' ' : '\n');
  W(tail...);
}
int MOD = 1e9 + 7;
void ADD(long long &x, long long v) {
  x = (x + v) % MOD;
  if (x < 0) x += MOD;
}
const int SIZE = 2e5 + 10;
int P[SIZE], V[SIZE];
vector<int> e[SIZE];
long long an;
struct Frac {
  long long one, zero;
  Frac() { one = zero = 0; }
  bool empty() { return one == 0 && zero == 0; }
  bool operator<(const Frac &b) const { return one * b.zero < zero * b.one; }
} head[SIZE];
multiset<Frac> H[SIZE], *ptr[SIZE];
void merge(int x, int y) {
  if (head[x].empty()) {
    head[x] = head[y];
    ptr[x] = ptr[y];
    return;
  }
  if (ptr[x]->size() < ptr[y]->size()) {
    swap(ptr[x], ptr[y]);
    swap(head[x], head[y]);
  }
  if (head[x].one == 0 && head[y].one == 0) {
    head[x].zero += head[y].zero;
  } else {
    Frac hx = head[x], hy = head[y];
    for (auto it = ptr[x]->begin(); it != ptr[x]->end(); it++) {
      if (*it < hx) {
        hx.zero += it->zero;
        hx.one += it->one;
      } else
        break;
    }
    for (auto it = ptr[y]->begin(); it != ptr[y]->end(); it++) {
      if (*it < hy) {
        hy.zero += it->zero;
        hy.one += it->one;
      } else
        break;
    }
    if (hy < hx) {
      bool done = 0;
      for (auto it = ptr[x]->begin(); it != ptr[x]->end(); it++) {
        if (*it < head[x]) {
          head[x].zero += it->zero;
          head[x].one += it->one;
          an -= head[x].zero * it->one;
        } else {
          done = 1;
          ptr[x]->erase(ptr[x]->begin(), it);
          break;
        }
      }
      if (!done) ptr[x]->clear();
      ptr[x]->insert(head[x]);
      head[x] = head[y];
    } else {
      ptr[y]->insert(head[y]);
    }
  }
  for (auto v : *ptr[y]) {
    ptr[x]->insert(v);
  }
}
void print(int x) {
  ;
  ;
  for (auto v : *ptr[x]) {
    ;
  }
}
void dfs(int x) {
  ptr[x] = &H[x];
  if (((int)(e[x]).size()) == 0) {
    if (V[x] == 1)
      head[x].one = 1;
    else
      head[x].zero = 1;
    return;
  }
  for (int y : e[x]) {
    dfs(y);
    merge(x, y);
  }
  if (V[x] == 0) {
    if (head[x].one == 0) {
      head[x].zero++;
    } else {
      while (!ptr[x]->empty() && *ptr[x]->begin() < head[x]) {
        auto me = *ptr[x]->begin();
        ptr[x]->erase(ptr[x]->begin());
        an -= head[x].zero * me.one;
        head[x].zero += me.zero;
        head[x].one += me.one;
      }
      ptr[x]->insert(head[x]);
      head[x].one = 0;
      head[x].zero = 1;
    }
  } else {
    head[x].one++;
  }
}
int main() {
  int N;
  R(N);
  for (int i = (2); i <= (N); ++i) {
    R(P[i]);
    e[P[i]].push_back(i);
  }
  for (int i = (1); i <= (N); ++i) R(V[i]);
  dfs(1);
  long long now = head[1].one;
  an += head[1].zero * now;
  for (auto x : *ptr[1]) {
    now += x.one;
    an += now * x.zero;
  }
  W(an);
  return 0;
}
