#include <functional>
#include <array>
#include <utility>
#include <new>
#include <vector>
#include <stack>
#include <cstdio>
#include <map>
#include <queue>
#include <iterator>
template<typename T> struct ScanfSpecifier{};
#define DEF(T,V) template<> struct ScanfSpecifier<T>{static constexpr const char* value = V;};
DEF(char*,"%s")DEF(int,"%d")DEF(double,"%lf")DEF(float,"%f")DEF(char,"%c")DEF(const char*,"%s")DEF(unsigned long,"%lu")DEF(unsigned int, "%u")
#ifdef _MSC_VER
DEF(long long int,"%I64d")
#else
DEF(long long int,"%lld")
#endif
#undef DEF
template<typename T> int RD(T& arg){return std::scanf(ScanfSpecifier<T>::value, &arg);}
template<int S> int RD(char (&arg)[S]){return std::scanf("%s", arg);}
int RD(char* arg){return std::scanf("%s", arg);}
template<> int RD<char>(char& arg){return std::scanf(" %c", &arg);}
template<typename T, typename... Args> int RD(T& arg1, Args&... args) {return RD(arg1) + RD(args...);}
template<typename T> T RD(){T ret; RD(ret); return ret;}
template<typename It> void RDV(It begin, It end) { while(begin != end) RD(*begin++); }
template<typename C> void RDV(C& c) {RDV(std::begin(c), std::end(c));}
template<typename T> void WT(T arg) {std::printf(ScanfSpecifier<T>::value, arg); }
template<typename T, typename U> void WT(std::pair<T, U> arg) {std::printf("("); WT(arg.first); std::printf(", "); WT(arg.second); std::printf(")");}
template<typename... Args> void WT(Args... args) { int alc = 0; int dummy[] = {((alc++? std::printf(" "): 0), WT(args), 0)...}; }

template<typename... Args> void WTL(Args... args) { WT(args...); std::printf("\n"); }
template<typename It> void WTV(It begin, It end) { int alc = 0; while(begin != end) (alc++? std::printf(" "): 0), WT(*begin++); }
template<typename C> void WTV(const C& c) {WTV(std::begin(c), std::end(c));}
template<typename It> void WTVL(It begin, It end) { WTV(begin, end); std::printf("\n"); }
template<typename C> void WTVL(const C& c) {WTVL(std::begin(c), std::end(c));}

#define _M_VARGS_NUM_IMPL(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, N, ...) N
#define _M_VARGS_NUM(...) _M_VARGS_NUM_IMPL(__VA_ARGS__, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1)
#define _W1(_1) (#_1[0] == '"' || #_1[0] == '\''? WT("", _1, ""): WT('[', #_1, '=', _1, ']'))
#define _W2(_1, _2) (_W1(_1), _W1(_2))
#define _W3(_1, _2, _3) (_W1(_1), _W2(_2, _3))
#define _W4(_1, _2, _3, _4) (_W1(_1), _W3(_2, _3, _4))
#define _W5(_1, _2, _3, _4, _5) (_W1(_1), _W4(_2, _3, _4, _5))
#define _W6(_1, _2, _3, _4, _5, _6) (_W1(_1), _W5(_2, _3, _4, _5, _6))
#define _W7(_1, _2, _3, _4, _5, _6, _7) (_W1(_1), _W6(_2, _3, _4, _5, _6, _7))
#define _W8(_1, _2, _3, _4, _5, _6, _7, _8) (_W1(_1), _W7(_2, _3, _4, _5, _6, _7, _8))
#define _WW_IMPL2(num, ...) _W ## num(__VA_ARGS__)
#define _WW_IMPL(num, ...) _WW_IMPL2(num, __VA_ARGS__)
#define WW(...) (std::printf("(%03d) ", __LINE__), _WW_IMPL(_M_VARGS_NUM(__VA_ARGS__), __VA_ARGS__), WTL(""))


namespace XX
{
    int mmReset = 0;
    
    void resetMemory(){++mmReset;}


    template<int BLOCKSIZE, int INITBUF = 1 << 24>
    class MemoryManager
    {
        public:
            static constexpr const int INIT = INITBUF / BLOCKSIZE;

            static MemoryManager* inst()
            {
                static MemoryManager ret;
                return &ret;
            }
            
            void reset()
            {
                if(mmReset != _cnt)
                {
                    _cnt = mmReset;
                    _ptr = nullptr;
                    _size = INIT * BLOCKSIZE;
                    _pos = _idx = 0;
                }
            }
            void* alloc()
            {
                reset();


                void* ret;
                if(_ptr)
                {
                    ret = _ptr;
                    _ptr = *static_cast<void**>(_ptr);
                }
                else 
                {
                    if(_pos == _size) 
                    {
                        _pos = 0;
                        ++_idx;
                        _size <<= 1;
                        if(!_buf[_idx])
                            _buf[_idx] = new char[std::max(_size, 1)];
                    }

                    ret = _buf[_idx] + _pos;
                    _pos += BLOCKSIZE;
                }

                return ret;
            }

            void dealloc(void* p)
            {
                *static_cast<void**>(p) = _ptr;
                _ptr = p;
            }

            ~MemoryManager()
            {
//                for(int i = 1; i <= _idx; i++)
//                    delete []_buf[i];
            }

        private:

            MemoryManager() { _buf[0] = _init; }

            char _init[INIT * BLOCKSIZE];
            int _size = INIT * BLOCKSIZE;
            int _idx = 0;
            int _pos = 0;
            char* _buf[32] = {};
            void* _ptr = nullptr;
            int _cnt = 0;
    };

    template<typename T>
    struct BlockAllocater
    {
        void* operator new(std::size_t count) { return MemoryManager<sizeof(T)>::inst()->alloc(); }
        void operator delete(void* ptr) { return MemoryManager<sizeof(T)>::inst()->dealloc(ptr); }
    };
    template<typename T>
    struct NullNode
    {
        static T nullnode;
        static T* null() { return &nullnode; }
        bool isNull(){return this == null();}
    };

    template<typename T>
    T NullNode<T>::nullnode;
}




namespace XX
{
    template<typename... EdgeTs>
    struct Graph
    {    
        public:
            struct Edge: public EdgeTs...
            {
                int from, to;
                Edge(int f, int t, EdgeTs... args) :from(f), to(t), EdgeTs(args)...  {}
                Edge(){}
            };

            struct Node:public Edge, BlockAllocater<Node>
            {
                Node* next;
                template<typename... Args> Node(Node* nn, Args... args) :next(nn),Edge(args...) {}
            };

            typedef Node* EdgeIdx;

            std::vector<Node*> adjlist;
            int numVertex;

            void _dealloc(Node* node) { if(node) { _dealloc(node->next); delete node; } }

            Graph(int v = 0) :adjlist(v) {}
//            ~Graph(){for(Node* node: adjlist)_dealloc(node);}

            int size(){return adjlist.size();}
            void resize(int size){adjlist.resize(size);}
            EdgeIdx add(int from, int to, EdgeTs... args) { return adjlist[from] = new Node{adjlist[from], from, to, args...}; }

            Node& operator[](EdgeIdx idx){return idx->e;}
            struct Enumerator
            {
                struct It
                {
                    Node* ptr;
                    Node& operator*(){return *ptr;}
                    void operator++(){ptr = ptr->next;}
                    bool operator!=(const It& other){return ptr != other.ptr;}
                }b, e;
                It begin(){return b;}
                It end(){return e;}
            };
            struct AllEnumerator
            {
                struct It
                {
                    Node* ptr;
                    int v;
                    Graph& g;
                    Node& operator*(){return *ptr;}
                    void operator++()
                    {
                        ptr = ptr->next; 
                        while(!ptr && ++v < g.size())
                            ptr = g.adjlist[v];
                    }
                    bool operator!=(const It& other){return ptr != other.ptr;}
                };
                Graph& g;
                It begin()
                {
                    for(int i = 0; i < g.size(); i++)
                        if(g.adjlist[i])
                            return {g.adjlist[i], i, g};
                    return end();
                }
                It end(){return {nullptr, 0, g};}
            };
            Enumerator adj(int v) { return {adjlist[v], nullptr}; }
            Enumerator adj(EdgeIdx idx) { return {idx, nullptr}; }
            AllEnumerator edges() { return {*this}; }
            Enumerator operator[](int idx){return adj(idx);}
    };
}





struct Range
{   
    struct It {   int num, step; int operator*(){return num;} void operator++(){num += step;} bool operator!=(const It& other){return num != other.num;} };
    Range(int ee):b(0),e(ee){}
    Range(int bb, int ee):b(bb), e(ee){}
    It begin(){return {b, (b < e? 1: -1)};}
    It end(){return {e, 0};}
    int b, e;
};

template<typename T> inline T& UMAX(T& x, T y){if(x < y)x = y; return x;}
template<typename T> inline T& UMIN(T& x, T y){if(y < x)x = y; return x;}
template<typename T, typename... Args> struct ArithmiticPromotion { typedef decltype(T() + typename ArithmiticPromotion<Args...>::type()) type; };
template<typename T, typename U> struct ArithmiticPromotion<T, U> { typedef decltype(T() + U()) type; };
template<typename T> struct ArithmiticPromotion<T, T> { typedef T type; };
template<typename T> struct ArithmiticPromotion<T> { typedef T type; };
template<typename T, typename U> typename ArithmiticPromotion<T, U>::type MAX(T a, U b) { return a < b? b: a; }
template<typename T, typename... Args> typename ArithmiticPromotion<T, Args...>::type MAX(T a, Args... args) { return MAX(a, MAX(args...)); }
template<typename T, typename U> typename ArithmiticPromotion<T, U>::type MIN(T a, U b) { return a < b? a: b; }
template<typename T, typename... Args> typename ArithmiticPromotion<T, Args...>::type MIN(T a, Args... args) { return MIN(a, MIN(args...)); }




namespace XX
{
    class StronglyConnectedComponent: public Graph<>
    {
        public:
            std::vector<int> component;
            std::vector<int> low;
            std::vector<int> dfn;
            std::vector<std::vector<int>> child;
            template<typename... Args>
            StronglyConnectedComponent(Graph<Args...>& g)
                :component(g.size()), low(g.size()), dfn(g.size())
            {
                int n = g.size();
                std::vector<bool> in(n);
                std::stack<int> stk;
                int alc = 0;
                int total = 0;
                std::function<int(int)> dfs = [&](int u)
                {
                    int order = ++alc;
                    dfn[u] = low[u] = order;
                    stk.push(u);
                    in[u] = true;
                    for(auto& e: g[u])
                    {
                        if(!low[e.to])
                            UMIN(low[u], dfs(e.to));
                        else if(in[e.to])
                            UMIN(low[u], dfn[e.to]);
                    }

                    if(low[u] == order)
                    {
                        int v;
                        do
                        {
                            v = stk.top();
                            stk.pop();
                            component[v] = total;
                            in[v] = false;
                        }
                        while(v != u);
                        total++;
                    }
                    return low[u];
                };
                for(int i = 0; i < n; i++)
                    if(!low[i])
                        dfs(i);
                resize(total);
                child.resize(total);
                for(int i = 0; i < n; i++)
                    child[component[i]].push_back(i);
                std::vector<int> buf(total);
                for(int c = 0; c < total; c++)
                    for(int ch: child[c])
                        for(auto& e: g[ch])
                        {
                            int toc = component[e.to];
                            if(toc != c && buf[toc] != c + 1)
                            {
                                buf[toc] = c + 1;
                                this->add(c, toc);
                            }
                        }
            }
    };

}






namespace XX
{
    template<typename... EdgeTs>
    std::vector<int> topologicalsort(Graph<EdgeTs...>& g)
    {
        std::vector<int> deg(g.size());
        for(auto& e: g.edges())
            deg[e.to]++;

        std::vector<int> ret(deg.size());
        unsigned len = 0;
        std::queue<int> que;
        for(unsigned i = 0; i < deg.size(); i++)
            if(deg[i] == 0)
                que.push(i);

        while(que.size())
        {
            int u = que.front();
            que.pop();
            ret[len++] = u;
            for(auto& e: g[u])
                if(--deg[e.to] == 0)
                    que.push(e.to);
        }

        if(len < ret.size())
            ret.resize(len);
        return ret;
    }
}


namespace XX
{
    struct TwoSAT
    {
        Graph<> imp;
        int varnum;
        std::vector<bool> assignment;
        TwoSAT(int n):imp(2 * n), varnum(n), assignment(n){}

        void add(int v1, bool neg1, int v2, bool neg2)
        {
            imp.add(v1 * 2 + !neg1, v2 * 2 + neg2);
            imp.add(v2 * 2 + !neg2, v1 * 2 + neg1);
        }

        void add(int v1, bool neg1)
        {
            imp.add(v1 * 2 + !neg1, v1 * 2 + neg1);
        }

        operator bool(){return satisfiable();}

        bool check()
        {
            StronglyConnectedComponent scc(imp);
            for(int i = 0; i < varnum; i++)
                if(scc.component[2 * i] == scc.component[2 * i + 1])
                    return false;
            return true;
        }
        bool solve()
        {
            StronglyConnectedComponent scc(imp);
            for(int i = 0; i < varnum; i++)
                if(scc.component[2 * i] == scc.component[2 * i + 1])
                    return false;

            std::vector<bool> done(varnum);
            auto ts = topologicalsort(scc);
            for(int i = ts.size() - 1; i >= 0; i--)
                for(int c: scc.child[ts[i]])
                    if(!done[c >> 1])
                    {
                        done[c >> 1] = true;
                        assignment[c >> 1] = !(c & 1);
                    }
            return true;
        }
        bool operator[](int idx){return assignment[idx];}
        bool satisfiable() { return assignment.size(); }
    };
}





//alias
using RG = Range;
using XX::Graph;
using SCC = XX::StronglyConnectedComponent;
using XX::topologicalsort;
using XX::TwoSAT;
//RD[L],RDV[L],WT[L],WTV[L] for i/o
//template
#include <vector>
#include <string>
#include <cstring>
#include <queue>
#include <set>
#include <map>
#include <cstdlib>
#include <algorithm>
#include <functional>
using namespace std;

typedef long long int ll;

const int SIZE = 200009;

int value[SIZE];
int timestamp = 0;
int table[SIZE];
bool done[SIZE];
int main()
{
    int N;
    RD(N);

    Graph<> g(N);
    Graph<> g2(N);

    for(int i: RG(N))
    {
        int p;
        RD(p);
        g.add(i, p - 1);
        g2.add(p - 1, i);
    }

    auto topo = topologicalsort(g);
    memset(value, -1, sizeof(value));

    for(int u: topo)
    {
        ++timestamp;
        for(auto e: g2[u])
            table[value[e.to]] = timestamp;
        
        while(table[++value[u]] == timestamp)
            ;

        done[u] = true;
    }

    TwoSAT sat(N);

    for(int u: RG(N))
        if(!done[u])
        {
            ++timestamp;
            for(auto e: g2[u])
                if(done[e.to]) 
                    table[value[e.to]] = timestamp;

            while(table[++value[u]] == timestamp)
                ;
        }

    for(int u: RG(N))
        if(!done[u])
            for(auto e: g[u])
            {
                int v = e.to;
                for(int d1: RG(2))
                    for(int d2: RG(2))
                    {
                        if(d2 && value[u] + d1 != value[v])
                            sat.add(u, !d1, v, 0);
                        if(value[u] + d1 == value[v] + d2)
                            sat.add(u, !d1, v, !d2);
                    }
            }
    if(sat.check())
        WTL("POSSIBLE");
    else
        WTL("IMPOSSIBLE");
}






Measured memory_bytes: 50048