#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<string>
#include<algorithm>
#include<cmath>
#include<queue>
#include<vector>
#include<stack>
using namespace std;

#define REP(i,n) for(int i=0;(i)<(n);(i)++)
#define ll long long

pair<int, int> cost[1003];
vector<int, int> adj[1003];

int color[1003];//0は未訪問　1は訪問済み
int N;

int dp[5015];//その部分木の黒コストをiにしたときの白コスト




int makedp(int node) {
	int ta = cost[node].first;

	REP(i, ta + 1) dp[i] = -1;//初期化
	dp[0] = 0;

	for (int i = 0;i < adj[node].size();i++) {
		int nxt = adj[node][i];
		if (color[nxt] == 0) continue;//まだ更新されてないノードは参照しない

		for (int j = ta;j >= 0;j--) {
			if (dp[j] == -1) continue;
			
			int tmp1 = dp[j] + cost[nxt].first;
			int tmp2 = dp[j] + cost[nxt].second;

			dp[j] = -1;

			if (j + cost[nxt].first <= ta) dp[j + cost[nxt].first] = tmp2;
			if (j + cost[nxt].second <= ta) dp[j + cost[nxt].second] = tmp1;
		}
	}


	int minv = 0;
	for (int i = 0;i <= ta;i++) {
		if (dp[i] == -1) continue;
		minv = min(minv, dp[i]);
	}

	return minv;
}

void dfs() {
	REP(i, N + 1) color[i] = 0;

	stack<int> S;
	stack<int> vis;
	
	S.push(1);
	color[1] = 1;

	while (!S.empty()) {
		int now = S.top(); S.pop();

		vis.push(now);

		for (int i = 0;i < adj[now].size();i++) {
			if (color[i] == 0) {
				S.push(adj[now][i]);
				color[i] = 1;
			}
		}
	}

	REP(i, N + 1) color[i] = 0;//再利用

	while (!vis.empty()) {
		int nxt = vis.top(); vis.pop();

		cost[nxt].second = makedp(nxt);

		color[nxt] = 1;//探索済み
	}
}

int main() {
	cin >> N;

	int P;
	for (int i = 2; i <= N; i++) {
		cin >> P;
		adj[i].push_back(P);
		adj[P].push_back(i);
	}

	int X;
	for (int i = 1;i <= N;i++) {
		cin >> X;
		cost[i].first = X;
	}

	dfs();

	if (cost[1].second == -1) {
		cout << "IMPOSSIBLE" << endl;
	}
	else cout << "POSSIBLE" << endl;

	return 0;
}