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: Wrong Answer)

#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <vector>
#include <queue>
#define N 500005
#define rint register int
using namespace std;

int tot = 0, fir[N], nxt[N << 1], to[N << 1];

inline void addEdge(int u, int v) {
    nxt[++tot] = fir[u], fir[u] = tot, to[tot] = v;
}

int n, vis[N], nx[N], inc[N], cntc, cir[N], val[N], use[N];

inline void dfs(int u) {
    if (vis[u]) return ;
    if (nx[u]) {
        if (cntc) return ;
        cir[++cntc] = u, inc[u] = 1;
        for (rint i = nx[u]; i != u; i = nx[i])
            cir[++cntc] = i, inc[i] = 1;
        return ;
    } for (rint i = fir[u]; i; i = nxt[i])
        nx[i] = to[i], dfs(to[i]);
    vis[u] = 1;
}

void getmex(int u) {
    for (rint i = fir[u], v; i; i = nxt[i]) {
        v = to[i];
        if (inc[v]) continue;
        getmex(v);
        use[val[v]] = 1;
    }
    while (use[val[u]]) ++val[u];
    for (rint i = fir[u]; i; i = nxt[i])
        if (!inc[to[i]]) use[val[to[i]]] = 0;
}

int main() {
    cin >> n;
    for (rint i = 1, u; i <= n; ++i)
        scanf("%d", &u), addEdge(u, i);
    for (rint i = 1; i <= n; ++i) dfs(i);
    for (rint i = 1; i <= cntc; ++i) getmex(cir[i]);
    bool check = 1;
    for (rint i = 1; i < cntc; ++i)
        if (val[cir[i]] != val[cir[i + 1]]) check = 0;
    if (check && cntc % 2) puts("IMPOSSIBLE");
    else puts("IMPOSSIBLE");
    return 0;
}