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-----
4
2 3 4 1

-----Sample Output-----
POSSIBLE

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

```python

USER_FILENAME = "<user_code>"
import sys, json, builtins
import math, heapq, bisect, itertools, functools, collections, statistics, fractions, decimal, operator, array, random, re, string, os, pathlib
try:
    import resource as _res
except Exception:
    _res = None
from collections import Counter, defaultdict, deque, OrderedDict
from functools import lru_cache, reduce
from itertools import accumulate, permutations, combinations, product
from math import gcd, ceil, floor, sqrt
from decimal import Decimal
try:
    from typing import *
except Exception:
    pass
try:
    sys.setrecursionlimit(1_000_000)
except Exception:
    pass
try:
    import site as _site
    try:
        _sys_sites = _site.getsitepackages() if hasattr(_site, "getsitepackages") else []
        for _p in _sys_sites:
            if _p and _p not in sys.path:
                sys.path.append(_p)
    except Exception:
        pass
    try:
        _usp = _site.getusersitepackages()
        if isinstance(_usp, str):
            _usp = [_usp]
        for _p in _usp:
            if _p and _p not in sys.path:
                sys.path.append(_p)
    except Exception:
        pass
except Exception:
    pass

ns = {"__name__": "__main__"}
for _k, _v in list(globals().items()):
    if not _k.startswith("_"):
        ns[_k] = _v
_CODE = 'from collections import deque\n\nN=int(input())\nIN=[[] for i in range(N)]\nOUT=[-1 for i in range(N)]\np=list(map(int,input().split()))\nfor i in range(N):\n    IN[p[i]-1].append(i)\n    OUT[i]=p[i]-1\n\ndeg=[len(IN[i]) for i in range(N)]\n\ndeq=deque([v for v in range(N) if deg[v]==0])\nres=[]\nwhile deq:\n    v=deq.popleft()\n    res.append(v)\n    deg[OUT[v]]-=1\n    if deg[OUT[v]]==0:\n        deq.append(OUT[v])\n\nif len(res)==N:\n    print("POSSIBLE")\n    return\n\nstart=-1\nfor i in range(N):\n    if deg[i]>0:\n        start=i\n        break\n\ncycle=[start]\nwhile True:\n    nv=OUT[cycle[-1]]\n    if nv!=start:\n        cycle.append(nv)\n    else:\n        break\n\n\ndp=[-1]*N\nfor v in res:\n    mex=[False]*(len(IN[v])+1)\n    for pv in IN[v]:\n        if dp[pv]<=len(IN[v]):\n            mex[dp[pv]]=True\n    for i in range(len(mex)):\n        if not mex[i]:\n            dp[v]=i\n            break\n\nm0=-1\nm1=-1\nmex=[False]*(len(IN[start])+2)\nfor pv in IN[start]:\n    if dp[pv]!=-1 and dp[pv]<=len(IN[v])+1:\n        mex[dp[pv]]=True\nfor i in range(len(mex)):\n    if not mex[i]:\n        if m0==-1:\n            m0=i\n        else:\n            m1=i\n            break\n\n#m0\ndp[start]=m0\nfor i in range(1,len(cycle)):\n    v=cycle[i]\n    temp=-1\n    mex=[False]*(len(IN[v])+1)\n    for pv in IN[v]:\n        if dp[pv]<=len(IN[v]):\n            mex[dp[pv]]=True\n    for i in range(len(mex)):\n        if not mex[i]:\n            dp[v]=i\n            break\nmex=[False]*(len(IN[start])+2)\nfor pv in IN[start]:\n    if dp[pv]!=-1 and dp[pv]<=len(IN[v])+1:\n        mex[dp[pv]]=True\ncheck=-1\nfor i in range(len(mex)):\n    if not mex[i]:\n        check=i\n        break\nif check==m0:\n    print("POSSIBLE")\n    return\n\nfor v in cycle:\n    dp[v]=-1\n\n#m1\ndp[start]=m1\nfor i in range(1,len(cycle)):\n    v=cycle[i]\n    temp=-1\n    mex=[False]*(len(IN[v])+1)\n    for pv in IN[v]:\n        if dp[pv]<=len(IN[v]):\n            mex[dp[pv]]=True\n    for i in range(len(mex)):\n        if not mex[i]:\n            dp[v]=i\n            break\nmex=[False]*(len(IN[start])+2)\nfor pv in IN[start]:\n    if dp[pv]!=-1 and dp[pv]<=len(IN[start])+1:\n        mex[dp[pv]]=True\ncheck=-1\nfor i in range(len(mex)):\n    if not mex[i]:\n        check=i\n        break\nif check==m1:\n    print("POSSIBLE")\n    return\n\nprint("IMPOSSIBLE")\n'
_co = compile(_CODE, USER_FILENAME, "exec")
exec(_co, ns, ns)

```

Measured memory_bytes: