#include <bits/stdc++.h>
const int INF = 1e9;
using namespace std;
template <typename T, typename U>
ostream& operator<<(ostream& os, const pair<T, U>& p) {
  cout << '(' << p.first << ' ' << p.second << ')';
  return os;
}
template <typename T>
void dpite(T a, T b) {
  return;
}
template <typename T>
void pite(T a, T b) {
  for (T ite = a; ite != b; ite++) cout << (ite == a ? "" : " ") << *ite;
  cout << '\n';
}
template <typename T>
bool chmax(T& a, T b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}
template <typename T>
bool chmin(T& a, T b) {
  if (a > b) {
    a = b;
    return true;
  }
  return false;
}
void ios_init() {
  ios::sync_with_stdio(false);
  cin.tie(0);
}
class Edge {
 public:
  int to = -1;
  long long cost = -1;
  Edge() {}
  Edge(int x, long long y) {
    to = x;
    cost = y;
  }
  bool operator<(const Edge& x) const {
    if (cost != x.cost) return cost < x.cost;
    return to < x.to;
  }
  bool operator>(const Edge& x) const {
    if (cost != x.cost) return cost > x.cost;
    return to > x.to;
  }
};
class Graph {
 private:
  vector<vector<Edge> > v;
  int n;

 public:
  Graph(int x) {
    n = x;
    v = vector<vector<Edge> >(x);
  }
  Graph() {}
  vector<Edge>& operator[](int x) { return v[x]; }
  const vector<Edge>& operator[](int x) const { return v[x]; }
  int size() const { return n; }
  void add_edge(int from, const Edge& e) { v[from].push_back(e); }
  void add_edge(int from, int to, long long cost = -1) {
    add_edge(from, Edge(to, cost));
  }
  void add_uedge(int from, int to, long long cost = -1) {
    add_edge(from, to, cost);
    add_edge(to, from, cost);
  }
};
vector<int> getTreeOrder(const Graph& g, int root) {
  vector<int> res;
  function<void(int p, int pre)> func = [&](int p, int pre) {
    for (auto& e : g[p]) {
      if (e.to != pre) {
        func(e.to, p);
      }
    }
    res.push_back(p);
  };
  func(root, -1);
  return res;
}
vector<int> getTreePar(const Graph& g, int root) {
  vector<int> par(g.size(), root);
  function<void(int p, int pre)> func = [&](int p, int pre) {
    par[p] = pre;
    for (auto& e : g[p]) {
      if (e.to != pre) {
        func(e.to, p);
      }
    }
  };
  func(root, root);
  return par;
}
class GraphVizualizer {
  int cnt;

 public:
  GraphVizualizer() { cnt = 0; }
  void operator()(const Graph& g, bool with_dir = true, bool with_cap = false) {
    ofstream ofs("./out.dot");
    if (!with_dir)
      ofs << "graph graph_name {" << '\n';
    else
      ofs << "digraph graph_name {" << '\n';
    for (int i = 0; i < (int)g.size(); ++i) {
      ofs << "    " << i << "[];" << '\n';
    }
    for (int i = 0; i < (int)g.size(); i++) {
      if (!g[i].size()) continue;
      for (const auto& e : g[i]) {
        if (!with_dir) {
          if (e.to > i) ofs << "    " << i << " -- " << e.to;
        } else
          ofs << "    " << i << " -> " << e.to;
        if (with_cap) {
          ofs << " [ label = \"" << (e.cost == INF ? "inf" : to_string(e.cost))
              << "\"];";
        }
        if (with_dir or e.to > i) ofs << '\n';
      }
    }
    ofs << "}" << '\n';
    ofs.close();
    string cmd = "dot -T png out.dot > ";
    cmd = cmd + "sample" + to_string(cnt) + ".png";
    system(cmd.c_str());
    cnt++;
  }
};
int main() {
  ios_init();
  int n;
  while (cin >> n) {
    Graph g(n);
    vector<int> par(n, -1);
    for (int i = (0); i < (n - 1); ++i) {
      cin >> par[i + 1];
      par[i + 1]--;
      g.add_uedge(i + 1, par[i + 1]);
    }
    vector<int> x(n);
    for (int i = (0); i < (n); ++i) cin >> x[i];
    auto topo = getTreeOrder(g, 0);
    dpite((topo).begin(), (topo).end());
    vector<int> csum(n);
    dpite((csum).begin(), (csum).end());
    string ans = "POSSIBLE";
    for (auto&& p : topo) {
      vector<bool> dp(x[p] + 1, false);
      dp[0] = true;
      long long int sum = 0;
      for (auto&& e : g[p]) {
        if (e.to == par[p]) continue;
        auto dpn = dp;
        auto dpnn = dp;
        for (int i = (int((dp).size()) - x[e.to]) - 1; i >= 0; i--) {
          dpnn[i + x[e.to]] = dp[i];
        }
        for (int i = (int((dpn).size()) - (csum[e.to] - x[e.to])) - 1; i >= 0;
             i--) {
          dpn[i + (csum[e.to] - x[e.to])] = dp[i];
        }
        for (int i = (0); i < (int((dp).size())); ++i)
          dp[i] = dpn[i] or dpnn[i];
        csum[p] += csum[e.to];
      }
      true;
      dpite((dp).begin(), (dp).end());
      bool hoge = true;
      for (int i = (int((dp).size())) - 1; i >= 0; i--) {
        if (dp[i]) {
          csum[p] += x[p] - i;
          hoge = false;
          break;
        }
      }
      if (hoge) {
        ans = "IMPOSSIBLE";
      }
    }
    dpite((csum).begin(), (csum).end());
    cout << ans << '\n';
  }
  return 0;
}
