#include <iostream>
#include <vector>
using namespace std;
const int INF = 1000*1000*1000;
vector<vector<int>> adj;
vector<pair<int, int>> intervals;
vector<int> parity, depth;
void DFS1(int node, int parent)
{
for(int i = 0; i < adj[node].size(); i++){
int newNode = adj[node][i];
depth[newNode] = depth[node] + 1;
DFS1(newNode, node);
intervals[node].first = max(intervals[node].first, intervals[newNode].first-1);
intervals[node].second = min(intervals[node].second, intervals[newNode].second+1);
if(intervals[node].first > intervals[node].second || (parity[node] != -1 && parity[node] == parity[newNode])){
cout << "NEM";
exit(0);
}
if(parity[newNode] != -1){
parity[node] = 1 - parity[newNode];
}
}
}
void DFS2(int node, int parent)
{
intervals[node].first = max(intervals[node].first, intervals[parent].first-1);
intervals[node].second = min(intervals[node].second, intervals[parent].second+1);
if(intervals[node].first > intervals[node].second || (parity[node] != -1 && parity[node] == parity[parent])){
cout << "NEM";
exit(0);
}
if(parity[parent] != -1){
parity[node] = 1 - parity[parent];
}
for(int i = 0; i < adj[node].size(); i++){
int newNode = adj[node][i];
DFS2(newNode, node);
}
}
int main()
{
int N;
cin >> N;
adj.resize(N+1);
for(int i = 1; i <= N; i++){
int p;
cin >> p;
adj[p].push_back(i);
}
intervals.assign(N+1, {0, INF});
parity.assign(N+1, -1);
for(int i = 1; i <= N; i++){
int val;
cin >> val;
if(val != -1){
intervals[i] = {val, val};
parity[i] = val%2;
}
}
depth.assign(N+1, -1);
depth[1] = 1;
DFS1(1, 0);
DFS2(1, 0);
cout << "IGEN\n";
if(intervals[1].first == 0 && intervals[1].second == INF){
for(int i = 1; i <= N; i++){
cout << depth[i] << " ";
}
}
else{
for(int i = 1; i <= N; i++){
if(intervals[i].first == 0 && parity[i] == 1){
cout << 1 << " ";
}
else{
cout << intervals[i].first << " ";
}
}
}
return 0;
}