#include <iostream>
#include <fstream>
#include <sstream>
#include <string.h>
#include <algorithm>
#include <cmath>
#include <assert.h>
#include <stack>
#include <queue>
#include <list>
#include <vector>
#include <map>
#include <set>

//#define DEBUG 1

#define int long long
#define for0(i,n) for (int i=0; i<n; i++)
#define iter(c) for(auto it=c.begin(); it!=c.end(); it++)
#define vec(x) vector< x >
#define pb push_back
#define ms(a,z) memset(a,z,sizeof(a));
#define mp make_pair
#define X first
#define Y second
#define sqr(x) 1LL*(x)*(x)
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
#define all(a) a.begin(),a.end()
#define sz(x) (int)(x).size()
#ifdef int
#define read(x) scanf("%lld",&x);
#else
#define read(x) scanf("%d",&x);
#endif

#ifdef DEBUG
#define nl cout<<"\n";
#define pr(x) cout<<(x)<<" ";
#define prl(x) cout<<#x " = "<<x<<endl;
#define prp(x) cout<<"("<<(x).first<<" "<<(x).second<<") ";
#define printv(v) {for(int _=0; _<sz(v); _++) cout<<v[_]<<" "; cout<<"\n";}
#define printa(a,s) {for (int _=0; _<s; _++) cout<<a[_]<<" "; cout<<"\n";}
#define print2D(a,m,n) {for (int _=0; _<m; _++) {for (int __=0; __<n; __++) cout<<a[_][__]<<" "; cout<<"\n";} cout<<"\n";}
#define debug cout<<"ok at line "<<__LINE__<<endl;
#else
#define nl
#define pr(x)
#define prl(x)
#define prp(x)
#define printv(v)
#define printa(a,s)
#define print2D(a,m,n)
#define debug
#endif
#define MAXN 200000

using namespace std;

typedef long long ll;

const int INF = 2147483647;
const long long INFL = 9223372036854775807LL;
const double EPSILON = 0.00000001;
const long long MOD = 1000000007;

vector<int> children[MAXN+5];
int cycle_next[MAXN+5];
int parent[MAXN+5];
bool processed[MAXN+5];
int outdegree[MAXN+5];
int val[MAXN+5];
vector<int> poss_vals[MAXN+5];
set<int> used_vals[MAXN+5];

void process_node(int nd)
{
    processed[nd] = true;
    set<int> possible_vals;
    for0(i,sz(children[nd])+1)
        possible_vals.insert(i);
    
    int cnt_unknown = 0;
    iter(children[nd]) {
        if (val[*it] != -1) {
            if (used_vals[nd].find(val[*it]) == used_vals[nd].end()) {
                possible_vals.erase(val[*it]);
                used_vals[nd].insert(val[*it]);
            }
            else {
                set<int>::iterator max_val = possible_vals.end(); max_val--;
                possible_vals.erase(max_val);
            }
        }
        else {
            cnt_unknown++;
            cycle_next[nd] = *it;
        }
    }
    assert(cnt_unknown == 1);
    iter(possible_vals) {
        poss_vals[nd].pb(*it);
    } 
}


bool visited[2*MAXN+5];

void dfs(int node, vector< vector<int> > & adj, vector<int> & node_order)
{
    for (int i=0; i<sz(adj[node]); i++) {
        int next = adj[node][i];
        if (!visited[next]) {
            visited[next] = true;
            dfs(next, adj, node_order);
        }
    }
    node_order.push_back(node);
}

vector<vector<int> > scc(vector< vector<int> > & adj, vector< vector<int> > adj_rev)
{
    vector<int> node_order;
    ms(visited,false);
    for (int i=0; i<sz(adj); i++) {
        if (!visited[i]) {
            visited[i] = true;
            dfs(i, adj, node_order);
        }
    }
    //printv(node_order);

    ms(visited,false);
    vector<vector<int> > all_sccs;
    for (int i=sz(node_order)-1; i>=0; i--) {
        int node = node_order[i];
        if (!visited[node]) {
            visited[node] = true;
            vector<int> cur_scc;
            dfs(node, adj_rev, cur_scc);
            //printv(cur_scc);
            all_sccs.push_back(cur_scc);
        }
    }

    return all_sccs;
}

typedef vector<int> Clause;

class TwoSAT
{
public:
    vector<int> asgn;
    queue<int> assumps;
    int cur_lit, cur_cls;
    vector<Clause> clauses;
    vector< vector<int> > adj, adj_rev, cls_by_lit;
    vector<int> cls_size;

    TwoSAT() {
        cur_lit = 1;
        cur_cls = 0;
    }

    int next_lit() {
        cls_by_lit.push_back(vector<int>());
        cls_by_lit.push_back(vector<int>());
        adj.push_back(vector<int>());
        adj.push_back(vector<int>());
        adj_rev.push_back(vector<int>());
        adj_rev.push_back(vector<int>());
        asgn.push_back(2);
        int lit = cur_lit;
        cur_lit += 2;
        return lit;
    }

    int add_clause(Clause cls) {
        //pr("adding clause") printv(cls) 
        if (sz(cls) == 1) {
            assumps.push(cls[0]);
            return 0;
        }
        else {
            int cls_id = cur_cls++;
            clauses.push_back(cls);
            cls_size.push_back(sz(cls));
            for (int i=0; i<sz(cls); i++) {
                assert(cls[i] < cur_lit);
                cls_by_lit[cls[i]].push_back(cls_id);
            }
            return cls_id;
        }
    }

    int add_clause(set<int> cls) {
        vector<int> cls_vec;
        for (set<int>::iterator it=cls.begin(); it!=cls.end(); it++)
            cls_vec.push_back(*it);
        return add_clause(cls_vec);
    }

    bool solve()
    {
        //set assignment for single-literal clauses (assumps)
        while (!assumps.empty()) {
            int lit = assumps.front();
            assumps.pop();
            //pr("Processing assumption") pr(lit) nl
            //printv(asgn)
            int id = lit>>1;
            if (asgn[id] != 2 && asgn[id] != (lit&1))
                return false;
            asgn[id] = lit&1;
            //pr("setting literal") pr(lit) pr("to") pr(asgn[id]) nl

            //mark all clauses with this literal as satisfied
            iter(cls_by_lit[lit]) {
                //pr("marking as sat clause") printv(clauses[*it])
                cls_size[*it] = 0;
            }

            //decrement sizes of all clauses with the negation of this literal
            iter(cls_by_lit[lit^1]) {
                cls_size[*it]--;
                //pr("decrementing size of clause") printv(clauses[*it])
                if (cls_size[*it] == 1) {
                    //find the unassigned  literal in this clause
                    for (int i=0; i<sz(clauses[*it]); i++) {
                        int id = clauses[*it][i]>>1;
                        if (asgn[id] == 2) {
                            //pr("enqueuing literal") pr(clauses[*it][i]) nl
                            assumps.push(clauses[*it][i]);
                            break;
                        }
                    }
                }
            }
        }

        //build implication graph from remaining size-2 clauses
        for (int i=0; i<sz(clauses); i++) {
            if (cls_size[i] == 2) {
                int lit1=-1, lit2=-1;
                for (int j=0; j<sz(clauses[i]); j++) {
                    int id = clauses[i][j]>>1;
                    if (asgn[id] == 2) {
                        lit2 = lit1;
                        lit1 = clauses[i][j];
                    }
                }
                //pr(lit1) pr(lit2) nl
                assert(lit1 != -1 && lit2 != -1);
                adj[lit1^1].push_back(lit2);
                adj_rev[lit2].push_back(lit1^1);
                adj[lit2^1].push_back(lit1);
                adj_rev[lit1].push_back(lit2^1);
            }
        }

        //find strongly connected components in topological order
        vector< vector<int> > sccs = scc(adj, adj_rev);
        for (int i=sz(sccs)-1; i>=0; i--) {
            if (sz(sccs[i]) == 1 && sz(adj[sccs[i][0]]) == 0 && sz(adj_rev[sccs[i][0]]) == 0)
                continue;
            //pr("scc") printv(sccs[i])
            //pr("asgn") printv(asgn)
            int scc_val=2;
            //find currently assigned value of this scc, if any

            for (int j=0; j<sz(sccs[i]); j++) {
                int lit = sccs[i][j];
                int id = sccs[i][j]>>1;
                if (asgn[id] != 2) {
                    int lit_val = asgn[id]^(lit&1)^1; //complemented literals are assigned opposite value
                    if (scc_val != 2 && lit_val != scc_val) {
                        //all literals in the scc must have the same value
                        return false;
                    }
                    scc_val = lit_val;
                }
            }
            if (scc_val == 2)
                scc_val = 1;
            //prl(scc_val)

            //set all literals in this scc to scc_val
            for (int j=0; j<sz(sccs[i]); j++) {
                int lit = sccs[i][j];
                int id = sccs[i][j]>>1;
                int asgn_val = scc_val^(lit&1)^1; //complemented literals are assigned opposite value
                //pr(lit) pr(asgn_val) nl
                if (asgn[id] == 2) {
                    asgn[id] = asgn_val;
                }
                else if (asgn[id] != asgn_val) {
                    return false;
                }
            }
            //printv(asgn)
        }

        return true;
    }

    int get_asgn(int lit) {
        return asgn[lit>>1];
    }
};


int32_t main()
{
    #ifdef DEBUG
    freopen("D.txt","r",stdin);
    //freopen("","w",stdout);
    #endif

    int n; read(n);
    ms(outdegree,0);
    for0(i,n) {
        int x; read(x);
        x--;
        children[x].pb(i);
        parent[i] = x;
        outdegree[x]++;
    }
    
    ms(processed,false);
    ms(val,-1);
    queue<int> q;
    for0(i,n) {
        if (outdegree[i] == 0)
            q.push(i);
    }
    while (!q.empty()) {
        int top = q.front(); q.pop();
        processed[top] = true;
        outdegree[parent[top]]--;
        if (outdegree[parent[top]] == 0)
            q.push(parent[top]);
        
        for (int x=0; x<=sz(children[top]); x++)
            used_vals[top].insert(x);
        iter(children[top]) {
            used_vals[top].erase(val[*it]);
        }
        val[top] = *(used_vals[top].begin());
    }
    printa(val,n);
    
    int cycle_start;
    for0(i,n) {
        if (!processed[i]) {
            cycle_start = i;
            process_node(i);
        }
    }
    
    int cur = cycle_start;
    TwoSAT twosat = TwoSAT();
    int cur_lit = twosat.next_lit();
    do {
        int nxt = cycle_next[cur];
        int next_lit;
        if (nxt == cycle_start)
            next_lit = 1;
        else 
            next_lit = twosat.next_lit();
        //prl(cur);
        //prl(cur_lit) prl(next_lit)
        
        //assert(sz(poss_vals[cur]) == 2);
        //assert(sz(poss_vals[nxt]) == 2);
        for0(i,2) {
            int val = poss_vals[cur][i];
            bool possible = true;
            //if node cur is set to val, make sure all values from 0 to val-1 are covered
            for (int x=0; x<val; x++) {
                if (used_vals[cur].find(x) == used_vals[cur].end()) {
                    //check if either of the next possible values are x 
                    if (poss_vals[nxt][0] == x) {
                        twosat.add_clause(vector<int>({cur_lit^i^1, next_lit})); //cur_lit^i => next_lit 
                    }
                    else if (poss_vals[nxt][1] == x) {
                        twosat.add_clause(vector<int>({cur_lit^i^1, next_lit^1})); //cur_lit^i => ~next_lit
                    }
                    else 
                        possible = false;
                }
            }
            if (!possible) {
                twosat.add_clause(vector<int>({cur_lit^i^1})); //force cur_lit^i to 0
            }
            for0(j,2) {
                if (poss_vals[cur][i] == poss_vals[nxt][j]) {
                    twosat.add_clause(vector<int>({cur_lit^i^1, next_lit^j^1})); //cur_lit^i => ~next_lit^j
                }
            }
        }
        cur = nxt;
        cur_lit = next_lit;
        //nl
    } while (cur != cycle_start);
    
    bool sat = twosat.solve();
    if (sat) 
        cout<<"POSSIBLE"<<endl;
    else 
        cout<<"IMPOSSIBLE"<<endl;
    
    return 0;
}


Measured memory_bytes: 139876