#include<stdio.h>
#include<vector>
#include<algorithm>
#include<queue>
using namespace std;
#define SIZE 101010
#define INF 1000000
typedef pair<int, int>pii;
class maxflow
{
public:
	vector<int>pat[SIZE];
	vector<int>cap[SIZE];
	vector<int>rev[SIZE];
	vector<int>ed[SIZE];
	bool flag[SIZE];
	int dist[SIZE];
	int now[SIZE], ind[SIZE];
	int idx[SIZE];
	int flow;
	int gd;
	void adde(int s, int t, int cp, int d)//多重辺は消してから s->tの容量cpの辺をはる
	{
		pat[s].push_back(t);
		pat[t].push_back(s);
		cap[s].push_back(cp);
		cap[t].push_back(0);
		rev[s].push_back(pat[t].size() - 1);
		rev[t].push_back(pat[s].size() - 1);
		ed[s].push_back(d);
		ed[t].push_back(-1);
	}
	void blockflow(int node, int len, int go, int pt)//ブロックフローを求めて流す
	{
		if (pt == len)
		{
			if (node != go)return;
			int mini = INF, rr = -1;
			for (int i = 0; i < pt; i++)if (cap[now[i]][ind[i]] < mini)mini = cap[now[i]][ind[i]], rr = i;
			for (int i = 0; i < pt; i++)cap[now[i]][ind[i]] -= mini, cap[pat[now[i]][ind[i]]][rev[now[i]][ind[i]]] += mini;
			flow += mini;//mini==INFになったら非有界
			gd = rr;
			return;
		}
		now[pt] = node;
		for (int i = idx[node]; i < pat[node].size(); i++)
		{
			if (dist[pat[node][i]] == dist[node] + 1 && cap[node][i]>0)
			{
				ind[pt] = i;
				blockflow(pat[node][i], len, go, pt + 1);
				if (gd < pt)break;
				else gd = INF;
			}
			idx[node]++;
		}
	}
	void dinic(int st, int go, int num)//dinicのアルゴリズムで最大流を求める 変数flowにmaxflowの値が入る
	{
		flow = 0;
		for (;;)
		{
			queue<pii>que;
			fill(dist, dist + num, INF);
			fill(flag, flag + num, false);
			que.push(make_pair(st, 0));
			for (;;)
			{
				if (que.empty())break;
				pii z = que.front();
				que.pop();
				if (flag[z.first])continue;
				flag[z.first] = true;
				dist[z.first] = z.second;
				for (int i = 0; i < pat[z.first].size(); i++)
				{
					if (dist[pat[z.first][i]]>z.second + 1 && cap[z.first][i] > 0)
					{
						dist[pat[z.first][i]] = z.second + 1;
						que.push(make_pair(pat[z.first][i], z.second + 1));
					}
				}
			}
			if (dist[go] == INF)return;
			gd = INF;
			fill(idx, idx + SIZE, 0);
			blockflow(st, dist[go], go, 0);
		}
	}
	vector<int>getcut(int st, int go, int num)//頂点iがmincutのst側なら1 そうでなければ0
	{
		dinic(st, go, num);
		vector<int>ret;
		for (int i = 0; i < num; i++)ret.push_back(flag[i]);
		return ret;
	}
};
maxflow gr;
int pa[101010], pb[101010];
int da[101010], db[101010];
int ta[101010], tb[101010];
int main()
{
	int num;
	scanf("%d", &num);
	int ra, rb;
	for (int i = 0; i < num; i++)
	{
		int za;
		scanf("%d", &za);
		za--;
		if (za == -2)ra = i, pa[i] = -1;
		else pa[i] = za, da[za]++;
	}
	for (int i = 0; i < num; i++)
	{
		int za;
		scanf("%d", &za);
		za--;
		if (za == -2)rb = i, pb[i] = -1;
		else pb[i] = za, db[za]++;
	}
	for (int i = 0; i < num; i++)
	{
		ta[i] = 1 - da[i];
		tb[i] = 1 - db[i];
		if ((ta[i] - tb[i]) % 2)
		{
			printf("IMPOSSIBLE\n");
			return 0;
		}
		if (pa[i] != -1)gr.adde(i, pa[i], 2, i);
		if (pb[i] != -1)gr.adde(pb[i], i, 2, -1);
	}
	if (ra != rb)gr.adde(ra, rb, 2, ra);
	int mok = 0;
	for (int i = 0; i < num; i++)
	{
		if (ta[i] > tb[i])gr.adde(num, i, ta[i] - tb[i], -1), mok += ta[i] - tb[i];
		else gr.adde(i, num + 1, tb[i] - ta[i], -1);
	}
	gr.dinic(num, num + 1, num + 2);
	if (mok != gr.flow)printf("IMPOSSIBLE\n");
	else
	{
		printf("POSSIBLE\n");
		for (int i = 0; i < num; i++)
		{
			for (int j = 0; j < gr.pat[i].size(); j++)
			{
				if (gr.cap[i][j] == 0 && gr.ed[i][j] >= 0)
				{
					ta[gr.ed[i][j]] -= 2;
					if (gr.ed[i][j] != ra)ta[pa[gr.ed[i][j]]] += 2;
				}
			}
		}
		for (int i = 0; i < num; i++)printf("%d ", ta[i]);
		printf("\n");
	}
}

Measured memory_bytes: 33892