#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <set>
#include <map>
#include <queue>
#include <random>
#include <chrono>

using namespace std;

typedef long long ll;
typedef long double ld;
#define fastInp cin.tie(0); cout.tie(0); ios_base::sync_with_stdio(0);

const ll SIZE = 1e5 * 2 + 100, INF = 1e9 + 10, MOD = 1e9 + 7;

vector<ll> vec, ans, cur;

mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());

vector<vector<ll>> gr;
ll par[SIZE];
bool used[SIZE];

void input() {
    ll n, l;
    cin >> n;
    gr.resize(n);

    for (int i = 0; i < n; i++) {
        ll pr;
        cin >> pr;
        pr--;
        gr[pr].push_back(i);
    }
}

void rand_test() {
    gr.clear();
    ll n = rand() % 20 + 2;
    gr.resize(n);
    for (int i = 0; i < n; i++) {
        ll pr = rand() % n;
        gr[pr].push_back(i);
    }
}

vector<ll> way;
set<ll> s;
bool flag = false;

void dfs(int v, int st) {
    used[v] = 1;

    for (auto to : gr[v]) {
        if (!used[to]) {
            par[to] = v;
            dfs(to, st);
        }
        else if (!flag && to == st) {
            flag = true;
            ll u = v;
            while (u != to) {
                way.push_back(u);
                u = par[u];
            }
            way.push_back(to);
        }
    }
}

ll vals[SIZE], sv[SIZE], nxt[SIZE];

void tree(int v) {
    vector<ll> mex;
    for (auto to : gr[v]) {
        if (s.find(to) == s.end()) {
            tree(to);
            mex.push_back(vals[to]);
        }
    }

    mex.push_back(SIZE);
    sort(mex.begin(), mex.end());

    ll pr = -1;
    for (int i = 0; i < mex.size(); i++) {
        if (pr + 1 < mex[i]) {
            vals[v] = pr + 1;
            break;
        }
        pr = mex[i];
    }

    mex.push_back(vals[v]);
    sort(mex.begin(), mex.end());

    pr = -1;
    for (int i = 0; i < mex.size(); i++) {
        if (pr + 1 < mex[i]) {
            nxt[v] = pr + 1;
            break;
        }
        pr = mex[i];
    }
}

bool check() {
    bool flag = true;
    for (int i = 0; i < gr.size(); i++) {
        set<ll> s;
        for (auto to : gr[i]) {
            s.insert(vals[to]);
        }
        for (int j = 0; j < vals[i]; j++) {
            if (s.find(j) == s.end()) flag = false;
        }
        if (s.find(vals[i]) != s.end()) flag = false;
    }

    return flag;
}

void sol() {
    flag = false;
    way.clear();
    s.clear();
    for (int i = 0; i < gr.size(); i++) {
        used[i] = 0;
        par[i] = 0;
    }
    ll n = gr.size();
    for (int i = 0; i < n; i++) {
        if (!used[i]) dfs(i, i);
    }
    for (auto cur : way) s.insert(cur);
    
    for (auto cur : way) {
        tree(cur);
    }

    bool flag = false;
    for (int i = 0; i < n; i++) sv[i] = vals[i];

    for (int i = 0; i < 2; i++) {
        for (int i = 0; i < n; i++) vals[i] = sv[i];
        ll v = way[0];
        if (i == 1) vals[v] = nxt[v];
        for (int j = 1; j < way.size(); j++) {
            ll u = way[j], pr = way[j - 1];
            if (vals[u] == vals[pr]) vals[u] = nxt[u];
        }

        if (check()) flag = true;
    }

    if (flag) {
        cout << "POSSIBLE";
    }
    else {
        cout << "IMPOSSIBLE";
    }
}


int main()
{
    fastInp;

    ll t;
    t = 1;

    while (t--) {
        input();
        sol();
    }

    return 0;
}

Measured memory_bytes: 46664