use proconio::input;
// dbg {{{
#[allow(dead_code)]
mod dbg {
    use std::fmt::{Debug, Formatter};

    #[derive(Clone)]
    pub struct Tabular<'a, T: Debug>(pub &'a [Vec<T>]);
    impl<'a, T: Debug> Debug for Tabular<'a, T> {
        fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
            for i in 0..self.0.len() {
                writeln!(f, "{:2} | {:?}", i, &self.0[i])?;
            }
            Ok(())
        }
    }

    #[derive(Clone)]
    pub struct BooleanTable<'a>(pub &'a [Vec<bool>]);
    impl<'a> Debug for BooleanTable<'a> {
        fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
            for i in 0..self.0.len() {
                writeln!(f, "{:2} | {:?}", i, BooleanSlice(&self.0[i]))?;
            }
            Ok(())
        }
    }

    #[derive(Clone)]
    pub struct BooleanSlice<'a>(pub &'a [bool]);
    impl<'a> Debug for BooleanSlice<'a> {
        fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
            write!(
                f,
                "{}",
                self.0
                    .iter()
                    .map(|&b| if b { '#' } else { '.' })
                    .collect::<String>()
            )?;
            Ok(())
        }
    }
}
// }}}

fn mex(a: &[usize]) -> usize {
    let mut g = vec![false; a.len() + 1];
    for &x in a {
        if x <= a.len() {
            g[x] = true;
        }
    }
    (0..=a.len()).find(|&i| !g[i]).unwrap()
}

fn double_mex(a: &[usize]) -> (usize, usize) {
    let mut g = vec![false; a.len() + 2];
    for &x in a {
        if x <= a.len() + 1 {
            g[x] = true;
        }
    }
    let i0 = (0..=a.len()).find(|&i| !g[i]).unwrap();
    let i1 = (i0 + 1..=a.len() + 1).find(|&i| !g[i]).unwrap();
    (i0, i1)
}

fn main() {
    input!(n: usize, prt: [proconio::marker::Usize1; n]);
    let cycle: Vec<usize> = {
        let mut ckd = vec![false; n];
        let mut seq = vec![0];
        loop {
            let p = prt[*seq.last().unwrap()];
            seq.push(p);
            if ckd[p] {
                let s = (0..seq.len() - 1).find(|&s| seq[s] == p).unwrap();
                break seq[s..].iter().copied().rev().collect();
            }
            ckd[p] = true;
        }
    };

    let mut belongs_to_cycle = vec![false; n];
    cycle.iter().for_each(|&x| belongs_to_cycle[x] = true);

    let mut g = vec![vec![]; n];
    for (x, p) in prt.iter().copied().enumerate() {
        g[p].push(x);
    }

    fn dfs(x: usize, g: &[Vec<usize>]) -> usize {
        mex(g[x]
            .iter()
            .map(|&y| dfs(y, g))
            .collect::<Vec<_>>()
            .as_slice())
    }

    let cycle = cycle
        .iter()
        .map(|&root| {
            double_mex(
                g[root]
                    .iter()
                    .copied()
                    .filter(|&subroot| !belongs_to_cycle[subroot])
                    .map(|subroot| dfs(subroot, &g))
                    .collect::<Vec<_>>()
                    .as_slice(),
            )
        })
        .collect::<Vec<_>>();

    let &(s0, s1) = cycle.first().unwrap();
    for &s in &[s0, s1] {
        let mut g = s;
        for &(g0, g1) in cycle.iter().skip(1) {
            g = if g == g0 { g1 } else { g0 };
        }
        if g == s {
            println!("POSSIBLE");
            std::process::exit(0);
        }
    }
    println!("IMPOSSIBLE");
}


Measured memory_bytes: 18956