#define _USE_MATH_DEFINES
#include "bits/stdc++.h"
using namespace std;
#define FOR(i,j,k) for(int (i)=(j);(i)<(int)(k);++(i))
#define rep(i,j) FOR(i,0,j)
#define each(x,y) for(auto &(x):(y))
#define mp make_pair
#define MT make_tuple
#define all(x) (x).begin(),(x).end()
#define debug(x) cout<<#x<<": "<<(x)<<endl
#define smax(x,y) (x)=max((x),(y))
#define smin(x,y) (x)=min((x),(y))
#define MEM(x,y) memset((x),(y),sizeof (x))
#define sz(x) (int)(x).size()
#define RT return
#define vv(a,b,c,d) vector<vector<a> >(b,vector<a>(c,d))
#define vvv(a,b,c,d,e) vector<vector<vector<a> > >(b,vv(a,c,d,e))
using ll = long long;
using pii = pair<int, int>;
using vi = vector<int>;
using vll = vector<ll>;

vector<int> topologicalSort(const vector<vector<int> > &graph) {
    int V = (int)graph.size(), cur = 0;
    vector<int> deg(V), res(V);
    stack<int> stk;
    for (int i = 0; i < V; ++i)
        for (int v : graph[i])deg[v]++;
    for (int i = 0; i < V; ++i)if (deg[i] == 0)stk.push(i);
    while (!stk.empty()) {
        int v = stk.top(); stk.pop();
        res[cur++] = v;
        for (int w : graph[v])if (!--deg[w])stk.push(w);
    }
    return cur == V ? res : vector<int>();
}

class TarjanSCC {
public:
    TarjanSCC() {}
    TarjanSCC(const vector<vector<int> > &G)
        : V(int(G.size())), stamp(0), cnt(0), vis(V), id(V), low(V)
    {
        for (int i = 0; i<V; ++i) {
            if (!vis[i]) {
                dfs(G, i);
            }
        }
    }
    /*
    頂点uはどの強連結成分に属するか。
    0~count-1のいずれかを返す。
    */
    int get(int u) {
        return id[u];
    }
    /*
    頂点u, vは同じ強連結成分に属するか。
    */
    bool same(int u, int v) {
        return id[u] == id[v];
    }
    int count() {
        return cnt;
    }
private:
    int V, stamp, cnt;
    vector<bool> vis;
    vector<int> id, low;
    stack<int> st;
    void dfs(const vector<vector<int> > &G, int u) {
        vis[u] = true;
        low[u] = ++stamp;
        st.push(u);
        int lowest = low[u];
        for (const auto to : G[u]) {
            if (!vis[to]) {
                dfs(G, to);
            }
            lowest = min(lowest, low[to]);
        }
        if (lowest < low[u]) {
            low[u] = lowest;
            return;
        }
        int v;
        do {
            v = st.top();
            st.pop();
            id[v] = cnt;
            low[v] = INT_MAX;
        } while (u != v);
        cnt++;
    }
};

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout << fixed << setprecision(20);

    int N;
    cin >> N;
    
    vector<vi> G(N);
    rep(i, N) {
        int p; cin >> p;
        --p;
        G[p].push_back(i);
    }

    vi rev(N, -1);
    TarjanSCC scc(G);
    vector<vi> H(N);
    vi nex(N, -1);
    rep(i, N) {
        int u = scc.get(i);
        rev[u] = i;
        each(j, G[i]) {
            int v = scc.get(j);
            if (u != v)H[u].push_back(v);
            else nex[j] = i;
        }
    }

    vi vs = topologicalSort(H);
    reverse(all(vs));
    vi dp(N, -1);

    auto grundy = [&](int u) {
        set<int> S;
        each(v, G[u])S.insert(dp[v]);
        for (dp[u] = 0; S.count(dp[u]); ++dp[u]);
    };

    each(i, vs) {
        int u = rev[i];
        if (u == -1 || dp[u]!=-1)continue;
        if (nex[u]==-1) {
            grundy(u);
        } else {
            set<int> S, T;
            each(v, G[u]) 
                S.insert(dp[v]);
            for (int j = 0; sz(T) < 2; ++j)if (!S.count(j))T.insert(j);
            int ok = 0;
            each(x, T) {
                int v = nex[u];
                dp[u] = x;
                while (v != u) {
                    grundy(v);
                    v = nex[v];
                }
                grundy(u);
                if (dp[u] == x) {
                    ok = 1;
                    break;
                }
            }

            if (!ok) {
                cout << "IMPOSSIBLE" << endl;
                return 0;
            }
        }
    }

    cout << "POSSIBLE" << endl;
}

Measured memory_bytes: 28740