#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
 
using tpl = tuple<int, int, int>;
typedef pair<int,int> pii;

void fastStream(){cin.tie(0);std::ios_base::sync_with_stdio(0);}


int N;
int P[200100];
vector<int> G[200100];
vector<int> rG[200100];

int nexts[200100];
bool used[200100];
bool is_loop[200100];
int A[200100];

int get_grundy(int pos){
    set<int> s;
    for(int to : G[pos]){
        s.insert(A[to]);
    }
    for(int i = 0; ; i++){
        if(s.count(i) == 0){
            return i;
        }
    }
}

void detect_loop(int pos){
    used[pos] = true;
    for(int to : rG[pos]){
        if(!used[to]){
            nexts[pos] = to;
            detect_loop(to);
        }
        else{
            // toからposまで閉路
            int cnt = 0;
            int c = to;
            while(1){
                is_loop[c] = true;
                cnt++;
                if(c == pos) break;
                c = nexts[c];
            }
        }
    }
}

void rec(int pos){
    set<int> s;
    for(int to : G[pos]){
        rec(to);
        s.insert(A[to]);
    }
    
    for(int i = 0; ; i++){
        if(s.count(i) == 0){
            A[pos] = i;
            break;
        }
    }
}

int main(){

    cin >> N;
    for(int i = 0; i < N; i++){
        int p;
        cin >> p;
        p--;
        rG[i].push_back(p);
        G[p].push_back(i);
    }
    
    memset(nexts, -1, sizeof(nexts));

    detect_loop(0);

    for(int i = 0; i < N; i++){
        if(is_loop[i] && G[i].size() > 1){
            // 葉から順番に割り当てを行う
            for(int to : G[i]){
                if(is_loop[to]) continue;
                rec(to);
            }

        }
    }

    // loopの構成要素を1つ選び、そこに可能な割り当てを行う
    // 残りの要素
    int start = -1;
    for(int i = 0; i < N; i++){
        if(is_loop[i]){
            start = i;
            break;
        }
    }

    // startに割り当てる要素を決定
    set<int> st;
    for(int to : G[start]){
        if(is_loop[to]) continue;
        st.insert(A[to]);
    }



    vector<int> v;
    int cnt = 0;
    for(int i = 0; ; i++){
        if(st.count(i) == 0){
            if(cnt == 0){
                v.push_back(i);
                cnt++;
            }
            else if(cnt == 1){
                v.push_back(i);
                break;
            }
        }
    }


    // startにvalを割り当て、他にも値を割り当てていく
    for(int val : v){
        // cout << start << " " << val << endl;
        for(int i = 0; i < N; i++){
            if(is_loop[i]){
                A[i] = -1;
            }
        }

        A[start] = val;
        // startから逆にloopをたどっていく
        int cpos = start;
        while(1){
            int npos = -1;
            for(int to : rG[cpos]){
                if(is_loop[to]){
                    npos = to;
                    break;
                }
            }

            cpos = npos;

            if(cpos == start) break;

            A[cpos] = get_grundy(cpos);
            // cout << cpos << " " << A[cpos] << endl;
        }

        // startが正しい割り当てになっているかもう一度確かめる
        int check = get_grundy(start);
        if(check == A[start]){
            cout << "POSSIBLE" << endl;
            return 0;
        }
    }

    cout << "IMPOSSIBLE" << endl;

    return 0;
}


Measured memory_bytes: 30720