#include <bits/stdc++.h>
using namespace std;
template <class T>
T inf() {
  return (numeric_limits<T>::max() >> 1);
}
FILE *file_in = stdin, *file_out = stdout;
struct NORMAL_IN {
  bool cnt;
  NORMAL_IN() : cnt(true) {}
  operator int() const { return cnt; }
  NORMAL_IN &operator>>(int &n) {
    cnt = fscanf(file_in, "%d", &n) != EOF;
    return *this;
  }
  NORMAL_IN &operator>>(unsigned int &n) {
    cnt = fscanf(file_in, "%u", &n) != EOF;
    return *this;
  }
  NORMAL_IN &operator>>(long long &n) {
    cnt = fscanf(file_in, "%lld", &n) != EOF;
    return *this;
  }
  NORMAL_IN &operator>>(unsigned long long &n) {
    cnt = fscanf(file_in, "%llu", &n) != EOF;
    return *this;
  }
  NORMAL_IN &operator>>(double &n) {
    cnt = fscanf(file_in, "%lf", &n) != EOF;
    return *this;
  }
  NORMAL_IN &operator>>(long double &n) {
    cnt = fscanf(file_in, "%Lf", &n) != EOF;
    return *this;
  }
  NORMAL_IN &operator>>(char *c) {
    cnt = fscanf(file_in, "%s", c) != EOF;
    return *this;
  }
  NORMAL_IN &operator>>(string &s) {
    s.clear();
    for (bool r = false;;) {
      const char c = getchar();
      if (c == EOF) {
        cnt = false;
        break;
      }
      const int t = isspace(c);
      if (!r and !t) r = true;
      if (r) {
        if (!t)
          s.push_back(c);
        else
          break;
      }
    }
    return *this;
  }
  template <class T>
  NORMAL_IN &operator>>(vector<T> &v) {
    int n;
    fscanf(file_in, "%d", &n);
    for (int i = 0; i < (int)(n); ++i) {
      T t;
      *this >> t;
      v.push_back(t);
    }
  }
} normal_in;
struct NORMAL_OUT {
  NORMAL_OUT &operator<<(const int &n) {
    fprintf(file_out, "%d", n);
    return *this;
  }
  NORMAL_OUT &operator<<(const unsigned int &n) {
    fprintf(file_out, "%u", n);
    return *this;
  }
  NORMAL_OUT &operator<<(const long long &n) {
    fprintf(file_out, "%lld", n);
    return *this;
  }
  NORMAL_OUT &operator<<(const unsigned long long &n) {
    fprintf(file_out, "%llu", n);
    return *this;
  }
  NORMAL_OUT &operator<<(const double &n) {
    fprintf(file_out, "%lf", n);
    return *this;
  }
  NORMAL_OUT &operator<<(const long double &n) {
    fprintf(file_out, "%Lf", n);
    return *this;
  }
  NORMAL_OUT &operator<<(const char c[]) {
    fprintf(file_out, "%s", c);
    return *this;
  }
  NORMAL_OUT &operator<<(const string &s) {
    fprintf(file_out, "%s", s.c_str());
    return *this;
  }
} normal_out;
template <class Weight>
struct edge {
  int src, dst, rev;
  Weight weight;
  edge(int src, int dst, Weight weight = 1, int rev = -1)
      : src(src), dst(dst), weight(weight), rev(rev) {}
};
template <class Weight>
bool operator<(const edge<Weight> &e, const edge<Weight> &f) {
  return e.weight != f.weight ? e.weight > f.weight
         : e.src != f.src     ? e.src < f.src
                              : e.dst < f.dst;
}
template <class Weight>
struct matrix : vector<vector<Weight> > {
  matrix(const array<int, 2> &a, Weight w = 0)
      : vector<vector<Weight> >(a[0], vector<Weight>(a[1], w)) {}
  matrix(const array<int, 1> &a, Weight w = 0)
      : vector<vector<Weight> >(a[0], vector<Weight>(a[0], 0)) {}
  matrix() {}
};
template <class Weight>
struct graph : vector<vector<edge<Weight> > > {
  Weight inf{::inf<Weight>()};
  graph() {}
  graph(const int &n) : vector<vector<edge<Weight> > >(n) {}
  void _add_edge(int from, int to, Weight w, int rev = -1) {
    if (this->size() < from + 1) this->resize(from + 1);
    this->at(from).push_back(edge<Weight>(from, to, w, rev));
  }
};
template <class Weight>
void addBiEdge(graph<Weight> &g, const pair<int, int> &e, Weight w = 1) {
  const int &from = e.first, &to = e.second;
  g._add_edge(from, to, w, g[to].size());
  g._add_edge(to, from, w, g[from].size() - 1);
}
template <class Weight>
void addEdge(graph<Weight> &g, const pair<int, int> &e, Weight w = 1) {
  const int &from = e.first, &to = e.second;
  g._add_edge(from, to, w);
}
int main() {
  int N;
  normal_in >> N;
  graph<int> g(N);
  vector<int> X(N);
  for (int i = 0; i < (int)(N - 1); ++i) {
    int p;
    normal_in >> p;
    p--;
    addBiEdge(g, {i + 1, p});
  }
  for (int i = 0; i < (int)(N); ++i) normal_in >> X[i];
  vector<long long> sum_min(N);
  bool flag = true;
  function<void(int, int)> dfs = [&](int u, int p) {
    for (const auto &e : g[u]) {
      if (e.dst == p) continue;
      dfs(e.dst, u);
    }
    if (!flag) return;
    vector<vector<bool> > dp(2, vector<bool>(X[u] + 1, false));
    dp[0][0] = true;
    long long all_sum = 0;
    for (auto &&e : g[u]) {
      if (e.dst == p) continue;
      dp[1].assign(X[u] + 1, false);
      int v = e.dst;
      all_sum += sum_min[v] + X[v];
      for (int i = 0; i <= (int)(X[u]); ++i) {
        if (!dp[0][i]) continue;
        int j;
        j = i + sum_min[v];
        if (j <= X[u]) {
          dp[1][j] = true;
        }
        j = i + X[v];
        if (j <= X[u]) {
          dp[1][j] = true;
        }
      }
      swap(dp[1], dp[0]);
    }
    long long t = X[u];
    while (t >= 0 and !dp[0][t]) t--;
    if (t < 0) {
      flag = false;
      return;
    }
    sum_min[u] = all_sum - t;
    return;
  };
  dfs(0, -1);
  if (!flag) {
    normal_out << "IMPOSSIBLE"
               << "\n";
  } else {
    normal_out << "POSSIBLE"
               << "\n";
  }
  while (1) cout << "hoge";
}
