Problem:
Score : 800 points

Problem Statement

There is a directed graph with N vertices and N edges. The vertices are numbered 1, 2, ..., N.

The graph has the following N edges: (p_1, 1), (p_2, 2), ..., (p_N, N), and the graph is weakly connected. Here, an edge from Vertex u to Vertex v is denoted by (u, v), and a weakly connected graph is a graph which would be connected if each edge was bidirectional.

We would like to assign a value to each of the vertices in this graph so that the following conditions are satisfied. Here, a_i is the value assigned to Vertex i.

Each a_i is a non-negative integer.

For each edge (i, j), a_i \neq a_j holds.

For each i and each integer x(0 ≤ x < a_i), there exists a vertex j such that the edge (i, j) exists and x = a_j holds.

Determine whether there exists such an assignment.

Constraints

2 ≤ N ≤ 200 000

1 ≤ p_i ≤ N

p_i \neq i

The graph is weakly connected.

Input

Input is given from Standard Input in the following format:

N
p_1 p_2 ... p_N

Output

If the assignment is possible, print POSSIBLE; otherwise, print IMPOSSIBLE.

Sample Input 1

4
2 3 4 1

Sample Output 1

POSSIBLE

The assignment is possible: {a_i} = {0, 1, 0, 1} or {a_i} = {1, 0, 1, 0}.

Sample Input 2

3
2 3 1

Sample Output 2

IMPOSSIBLE

Sample Input 3

4
2 3 1 1

Sample Output 3

POSSIBLE

The assignment is possible: {a_i} = {2, 0, 1, 0}.

Sample Input 4

6
4 5 6 5 6 4

Sample Output 4

IMPOSSIBLE

Solution in C++14 (GCC 5.4.1) (judge verdict: Accepted)

/*#include <ext/pb_ds/assoc_container.hpp> 
#include <ext/pb_ds/tree_policy.hpp>*/
#include <bits/stdc++.h>

using namespace std;
//using namespace __gnu_pbds;
 
typedef long long ll;
typedef vector<int> vi;
typedef pair<int, int> pii;
//typedef tree<int,null_type,less<int>,rb_tree_tag,tree_order_statistics_node_update> ordered_set;

#define FOR(i, a, b) for (int i=a; i<b; i++)
#define F0R(i, a) for (int i=0; i<a; i++)
#define FORd(i,a,b) for (int i = (b)-1; i >= a; i--)
#define F0Rd(i,a) for (int i = (a)-1; i >= 0; i--)
 
#define mp make_pair
#define pb push_back
#define f first
#define s second
#define lb lower_bound
#define ub upper_bound

const int MOD = 1000000007;
double PI = 4*atan(1);

int N, x, p[200001], visit[200001], num[200001], vnum[200001];
int incycle[200001];
set<int> uni[200001];
vi child[200001], cycle;

void dfs(int node, int po) {
	if (visit[node] == 0) {
		visit[node] = po;
		dfs(p[node],po);
	} else if (visit[node] == po) x = node;
}

void solve(int x) {
	for (int y: child[x]) {
		solve(y);
		uni[x].insert(num[y]);
	}
	for (int i = 0;;++i) {
		if (uni[x].find(i) == uni[x].end()) {
			num[x] = i;
			return;
		}
	}
}

bool test1() {
	int tmp[200001];
	tmp[0] = num[cycle[0]];
	FOR(i,1,cycle.size()) {
		if (tmp[i-1] == num[cycle[i]]) tmp[i] = vnum[cycle[i]];
		else tmp[i] = num[cycle[i]];
	}
	int t = -1;
	if (tmp[cycle.size()-1] == num[cycle[0]]) t = vnum[cycle[0]];
	else t = num[cycle[0]];
	return (t == tmp[0]);
}

bool test2() {
	int tmp[200001];
	tmp[0] = vnum[cycle[0]];
	FOR(i,1,cycle.size()) {
		if (tmp[i-1] == num[cycle[i]]) tmp[i] = vnum[cycle[i]];
		else tmp[i] = num[cycle[i]];
	}
	int t = -1;
	if (tmp[cycle.size()-1] == num[cycle[0]]) t = vnum[cycle[0]];
	else t = num[cycle[0]];
	return (t == tmp[0]);
}

int main() {
	cin >> N;
	FOR(i,1,N+1) cin >> p[i];
	FOR(i,1,N+1) dfs(i,i);
	
	cycle.pb(x); incycle[x] = 1;
	for (int cur = p[x]; cur != x; cur = p[cur]) {
		cycle.pb(cur);
		incycle[cur] = 1;
	}
	FOR(i,1,N+1) if (!incycle[i]) child[p[i]].pb(i);
	FOR(i,1,N+1) vnum[i] = -1;
	
	for (int x: cycle) {
		solve(x);
		for (int i = num[x]+1;;++i) if (uni[x].find(i) == uni[x].end()) {
			vnum[x] = i;
			break;
		}
	}
	if (test1() || test2()) {
		cout << "POSSIBLE";
		return 0;
	}
	cout << "IMPOSSIBLE";
}