#include <iostream>
#include <string>
#include <vector>
#include <queue>
#include <deque>
#include <algorithm>
#include <set>
#include <map>
#include <bitset>
#include <cmath>
#include <functional>
#include <iomanip>
#define vll vector<ll>
#define vvvl vector<vvl>
#define vvl vector<vector<ll>>
#define VV(a, b, c, d) vector<vector<d> >(a, vector<d>(b, c))
#define VVV(a, b, c, d) vector<vvl>(a, vvl(b, vll (c, d)));
#define re(c, b) for(ll c=0;c<b;c++)
#define all(obj) (obj).begin(), (obj).end()
typedef long long int ll;
typedef long double ld;
using namespace std;

//-------------------------------------------------------------------
struct Graph{
  int MAX_V = 0;
  vvl G = VV(0, 0, 0, ll);
  vvl rG = VV(0, 0, 0, ll);
  vector<bool> used;
  vector<int> cmp;
  vector<int> vs;
  Graph(ll V){
    MAX_V = V;
    for(int i=0;i<V;i++){
      G.push_back(vector<ll>());
      rG.push_back(vector<ll>());
    }
    used.resize(V, false);
    cmp.resize(V, 0);
  }
  void add_edge(int from, int to){ G[from].push_back(to), rG[to].push_back(from);}
  void dfs(int v){
    used[v] = true;
    for(int i=0;i<G[v].size();i++) if(!used[G[v][i]]) dfs(G[v][i]);
    vs.push_back(v);
  }
  void rdfs(int v, int k){
    used[v] = true;
    cmp[v] = k;
    for(int i=0;i<rG[v].size();i++) if(!used[rG[v][i]]) rdfs(rG[v][i], k);
  }
  int scc(int V){
    for(int i=0;i<MAX_V;i++) used[i] = false;
    vs.clear();
    for(int i=0;i<MAX_V;i++) if(!used[i]) dfs(i);
    for(int i=0;i<MAX_V;i++) used[i] = false;
    int k = 0;
    for(int i=vs.size()-1;i>=0;i--) if(!used[vs[i]]) rdfs(vs[i], k++);
    return k;
  }
};
//-------------------------------------------------------------------
vector<int> cmp;
vvl scc = VV(300000, 0, 0, ll); // cmp=iの要素リスト
vvl T = VV(300000, 0, 0, ll); //閉路のない圧縮後のグラフ
vvl G = VV(300000, 0, 0, ll);
vll grundy(300000, -1);

struct Merge{
  set<vll> lr;
  ll INF = 1000000000000000009;
  vll remove(ll a, ll b){
    if(a>b) swap(a, b);
    auto itr = lr.lower_bound(vll{b+1, 0});
    if(itr==lr.begin()) return vll{a, b};
    itr--;
    ll lef = a, ri = b;
    while((*itr)[1]>=a){
      ll now_x = (*itr)[0], now_y = (*itr)[1];
      lef = min(lef, now_x), ri = max(ri, now_y);
      if(itr==lr.begin()){
        lr.erase(itr);
        break;
      }
      itr--;
      lr.erase(vll{now_x, now_y});
    }
    return vll{lef, ri};
  }
  void merge(ll a, ll b){lr.insert(remove(a, b));}

  vll get(ll a){
    auto itr = lr.lower_bound(vll{a+1, a+1});
    if(lr.size()==0||itr==lr.begin()) return vll{INF, INF};
    itr--;
    if((*itr)[1]<a) return vll{INF, INF};
    return *itr;
  }
  bool same(ll a, ll b){
    if(get(a)[0]==-1) return false;
    return get(a)[0]==get(b)[0];
  }
};

void err(){
  std::cout << "IMPOSSIBLE" << '\n';
  exit(0);
}
vector<ll> par(300000, -1);

void dfs(ll now){
  if(grundy[now]!=-1) return;
  ll c = cmp[now];
  //閉路がある場合
  if(scc[c].size()>1){
    //圧縮後の次の頂点を先に評価
    for(auto to:T[cmp[now]]) if(cmp[to]!=c) dfs(to);
    //強連結成分内で評価
    //grundyの候補は2つ
    ll root = scc[c][0];
    ll X = -1, Y = -1, go = -1;
    vector<bool> gr(300000, 0);
    for(auto to:G[root]){
      if(grundy[to]==-1) {
        go = to;
        continue;//閉路のもの
      }
      gr[grundy[to]] = 1;
    }
    for(int i=0;i<300000;i++){
      if(!gr[i]){
        if(X==-1) X = i;
        else{
          Y = i;
          break;
        }
      }
    }
    //goがXを塞ぐとYになる,それ以外はX

    // case 1
    ll tmp = par[root];
    grundy[root] = X;
    while(tmp!=root){
      Merge mg;
      for(auto to:G[tmp]) mg.merge(grundy[to], grundy[to]+1);
      if(mg.lr.size()==0) grundy[tmp] = 0;
      else{
        vll fst = (*mg.lr.begin());
        if(fst[0]!=0) grundy[tmp] = 0;
        else grundy[tmp] = fst[1];
      }
      tmp = par[tmp];
    }
    if(grundy[go]!=X) return;
    
    // reset
    for(int i=0;i<scc[c].size();i++) grundy[scc[c][i]] = -1;
    // case 2
    grundy[root] = Y;
    tmp = par[root];
    while(tmp!=root){
      Merge mg;
      for(auto to:G[tmp]) mg.merge(grundy[to], grundy[to]+1);
      if(mg.lr.size()==0) grundy[tmp] = 0;
      else{
        vll fst = (*mg.lr.begin());
        if(fst[0]!=0) grundy[tmp] = 0;
        else grundy[tmp] = fst[1];
      }
      tmp = par[tmp];
    }
    if(grundy[go]!=X) err();
  }else{ //1頂点の場合
    Merge mg;
    for(auto to:G[now]){
      dfs(to);
      mg.merge(grundy[to], grundy[to]+1);
    }
    if(mg.lr.size()==0) grundy[now] = 0;
    else{
      vll fst = (*mg.lr.begin());
      if(fst[0]!=0) grundy[now] = 0;
      else grundy[now] = fst[1];
    }
  }
}

int main(int argc, char const *argv[]) {
  //矛盾が発生するとしたら強連結成分内
  ll n;std::cin >> n;
  Graph g(n+1);
  for(int i=1;i<=n;i++){
    ll a;scanf("%lld", &a);
    g.add_edge(a, i);
    par[i] = a;
    G[a].push_back(i);
  }
  g.scc(n+1);
  cmp = g.cmp;
  for(int i=1;i<=n;i++) scc[cmp[i]].push_back(i);
  for(int i=1;i<=n;i++) for(auto to:G[i]) T[cmp[i]].push_back(to);
  for(int i=1;i<=n;i++) dfs(i);
  std::cout << "POSSIBLE" << '\n';
  return 0;
}


Measured memory_bytes: 70300