#include <bits/stdc++.h>

using namespace std;
typedef long long ll;

#define REP(i,n) for(int i=0;i<n;++i)
#define SORT(name) sort(name.begin(), name.end())
#define ZERO(p) memset(p, 0, sizeof(p))
#define MINUS(p) memset(p, -1, sizeof(p))

#define MOD 1000000007
#define INF 1000000000
#define MAX_N 1010
#define MAX_X 5010
#define UNKNOWN 0
#define WHITE 1
#define BLACK 2

int N;
vector<int> tree[MAX_N];    // 各頂点の持つ子
int X[MAX_N];               // 各頂点の持つ制限
int noX[MAX_N];             // X[v] じゃない方の色の各頂点を根とする部分木の合計
stack<int> st;              // 最深部から探索するためのスタック
queue<int> bfs;             // st 制作用

// tree[v] を i から見て重み合計が w の時最も X[v] に近かった値
// 無理なら -1 を返す
int dfs(int v, int i, int w) {
    if(i >= tree[v].size()) { return w; }
    int cand1 = X[tree[v][i]];
    int cand2 = noX[tree[v][i]];
    if(w + cand1 > X[v] && w + cand2 > X[v]) { return -1; }
    int ret1 = -1;
    int ret2 = -1;
    if(w + cand1 <= X[v]) { ret1 = dfs(v, i + 1, w + cand1); }
    if(w + cand2 <= X[v]) { ret2 = dfs(v, i + 1, w + cand2); }
    if(ret1 >= 0) {
        if(ret2 >= 0) { return max(ret1, ret2); }
        else { return ret1; }
    } else {
        if(ret2 >= 0) { return ret2; }
        else { return -1; }
    }
}

int dp[MAX_N][MAX_X];

int main()
{
    ZERO(X);
    ZERO(noX);

    cin >> N;
    for(int i = 1; i < N; ++i) {
        int tmp;
        cin >> tmp;
        tmp--;
        tree[tmp].push_back(i);
    }
    REP(i, N) {
        cin >> X[i];
    }

    // 最深部から探索するためのスタックを作成
    bfs.push(0);
    while(!bfs.empty()) {
        int v = bfs.front();
        bfs.pop();
        st.push(v);
        REP(i, tree[v].size()) {
            bfs.push(tree[v][i]);
        }
    }

    //Debug();

    // 一番深いところから重みと色を確定
    while(!st.empty()) {
        int v = st.top();   // 今見ている頂点
        st.pop();
        //printf("search %d\n", v+1);
        if(tree[v].size() == 0) {
            // 葉である。
            //printf("  leaf. weight %d\n", X[v]);
        } else {
            int XAndNoX = 0;    // X と noX の合計（= 白黒の重み合計）
            for(auto child : tree[v]) {
                XAndNoX += X[child];
                XAndNoX += noX[child];
            }
#if 0
            int ret = dfs(v, 0, 0);
#else
            ZERO(dp);
            REP(j, X[v]+1) {
                dp[tree[v].size()-1][j] = j;
                dp[tree[v].size()][j] = j;      // 一応
            }
            for(int i = tree[v].size() - 1; i >= 0; --i) {
                REP(j, X[v]+1) {
                    int cand1 = X[tree[v][i]];
                    int cand2 = noX[tree[v][i]];
                    if(j + cand1 > X[v] && j + cand2 > X[v]) {
                        dp[i][j] = -1;
                    }
                    int ret1 = -1;
                    int ret2 = -1;
                    if(j + cand1 <= X[v]) { ret1 = dp[i + 1][j + cand1]; }
                    if(j + cand2 <= X[v]) { ret2 = dp[i + 1][j + cand2]; }
                    if(ret1 >= 0) {
                        if(ret2 >= 0) { dp[i][j] = max(ret1, ret2); }
                        else { dp[i][j] = ret1; }
                    } else {
                        if(ret2 >= 0) { dp[i][j] = ret2; }
                        else {
                            dp[i][j] = -1;
                        }
                    }
                }
            }
            int ret = dp[0][0];
#endif
            if(ret == -1) {
                printf("IMPOSSIBLE\n");
                return 0;
            }
            noX[v] = XAndNoX - ret;
        }
    }
    printf("POSSIBLE\n");

    return 0;
}


Measured memory_bytes: 20224