#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
#include <deque>
#include <list>
#include <queue>
#include <stack>
#include <vector>
#include <utility>
#include <algorithm>
#include <map>
#include <set>
#include <complex>
#include <cmath>
#include <limits>
#include <climits>
#include <ctime>
#include <cassert>
#include <numeric>
#include <functional>
#include <bitset>

using namespace std;
using lint = long long int;
using ll = long long int;
using graph = vector<vector<int>>;
using wgraph = vector<vector<pair<int, lint>>>;
const lint INF = 1001001001001001LL;
const lint MOD = 1000000007LL;
int di[] = {-1, 0, 1, 0, -1, 1, 1, -1};
int dj[] = {0, 1, 0, -1, 1, 1, -1, -1};

void yes(){ cout << "yes" << endl; }
void Yes(){ cout << "Yes" << endl; }
void YES(){ cout << "YES" << endl; }
void no(){ cout << "no" << endl; }
void No(){ cout << "No" << endl; }
void NO(){ cout << "NO" << endl; }
void possible(){ cout << "possible" << endl; }
void Possible(){ cout << "Possible" << endl; }
void POSSIBLE(){ cout << "POSSIBLE" << endl; }
void impossible(){ cout << "impossible" << endl; }
void Impossible(){ cout << "Impossible" << endl; }
void IMPOSSIBLE(){ cout << "IMPOSSIBLE" << endl; }

#define rep(i,n) for(int i = 0; i < (n); i++)
#define rrep(i,n) for(int i = 1; i <= (n); i++)
#define drep(i,n) for(int i = (n)-1; i >= 0; i--)
#define srep(i,s,t) for(int i = s; i < t; i++)
#define all(a) a.begin(),a.end()
#define rall(a) a.rbegin(),a.rend()


bool f(graph g, int val, int idx, vector<int> a, vector<int> d, vector<int> p){
  a[idx] = val;
  int cur = p[idx];
  while(a[cur] == -1){
    set<int> vec;
    rep(i, g[cur].size()){
      int nxt = g[cur][i];
      if(a[nxt] == -1) continue;
      vec.insert(a[nxt]);
    }
    if(a[p[cur]] != -1) vec.insert(a[p[cur]]);
    int num = -1;
    rep(i, 100){
      if(vec.find(i) == vec.end()){
        num = i;
        break;
      }
    }

    a[cur] = num;
    cur = p[cur];
  }

  rep(i, a.size()) cerr << a[i] << " ";
  cerr << endl;

  // validation

  rep(i, a.size()){
    set<int> st;
    cerr << i << " " << a[i] << endl;
    rep(j, g[i].size()){
      st.insert(a[g[i][j]]);
      cerr << g[i][j] << " ";
    }
    cerr << endl;
    rep(x, a[i]){
      if(st.find(x) == st.end()){
        return false;
      }
    }
  }
  return true; 
}


int main(){
  
  int n; cin >> n;
  graph g(n);
  vector<int> d(n, 0);
  queue<int> que;
  vector<int> p(n);
  rep(i, n){
    int in; cin >> in;
    in--;
    p[i] = in;
    g[p[i]].push_back(i);
    d[p[i]]++;
  }

  vector<int> a(n, -1);
  
  rep(i, n){
    if(d[i] == 0) que.push(i);
  }

  while(!que.empty()){
    int cur = que.front();
    que.pop();
    d[p[cur]]--;
    if(d[p[cur]] == 0) que.push(p[cur]);
    // 隣接頂点をなめる
    set<int> vec;
    rep(i, g[cur].size()){
      int nxt = g[cur][i];
      if(a[nxt] == -1){
        continue;
      }
      vec.insert(a[nxt]);
    }
    if(a[p[cur]] != -1) vec.insert(a[p[cur]]);
    rep(i, 100){
      if(vec.find(i) == vec.end()){
        a[cur] = i;
        break;
      }
    }
  }
  

  int idx = 0;
  rep(i, n){
    if(a[i] == -1){
      idx = i;
      break;
    }
  }

  set<int> st;
  rep(i, g[idx].size()){
    int nxt = g[idx][i];
    if(a[nxt] == -1) continue;
    st.insert(a[nxt]);
  }
  if(a[p[idx]] != -1) st.insert(a[p[idx]]);
  int val = -1;
  rep(i, 100){
    if(st.find(i) == st.end()){
      val = i;
      break;
    }
  }

  rep(i, a.size()) cerr << a[i] << " ";
  cerr << endl;

  // val pr val + 1
  if(f(g, val, idx, a, d, p) or f(g, val + 1, idx, a, d, p)) POSSIBLE();
  else IMPOSSIBLE();
  
  return 0;
}


Measured memory_bytes: 28652