use std::io;
use std::io::{Read, BufReader};
use std::cmp;

fn next_token<R: Read>(reader: &mut R) -> Vec<u8> {
    let mut buf: [u8; 1] = [0];
    let mut read_chars = false;
    let mut ret: Vec<u8> = vec![];

    loop {
        if reader.read(&mut buf).unwrap() == 0 {
            break;
        } else {
            if buf[0] == '\r' as u8 || buf[0] == '\n' as u8 || buf[0] == ' ' as u8 {
                if read_chars {
                    break;
                }
            } else {
                read_chars = true;
                ret.push(buf[0]);
            }
        }
    };
    ret
}
fn next_i64<R: Read>(reader: &mut R) -> i64 {
    let token = next_token(reader);
    let mut ret: i64 = 0;
    let mut sgn = false;

    for c in token {
        if '0' as u8 <= c && c <= '9' as u8 {
            ret = ret * 10 + (c - ('0' as u8)) as i64;
        } else if '-' as u8 == c {
            sgn = true;
        }
    };
    ret * if sgn { -1 } else { 1 }
}
fn next_i32<R: Read>(reader: &mut R) -> i32 {
    next_i64(reader) as i32
}

fn assign_sign(v: usize, rt: usize, tree: &Vec<Vec<usize>>, ans: &mut Vec<i32>) {
    let mut x = 1;
    for &w in &tree[v] {
        if w == rt {
            continue;
        }
        assign_sign(w, v, tree, ans);
        x ^= 1;
    }
    ans[v] = x;
}
fn make_aux_graph(v: usize, rt: usize, tree: &Vec<Vec<usize>>, aux: &mut Vec<Vec<usize>>) -> usize {
    let mut last_ch: Option<usize> = None;
    for &w in &tree[v] {
        if w == rt {
            continue;
        }
        let free = make_aux_graph(w, v, tree, aux);
        match last_ch {
            Some(l) => {
                aux[l].push(free);
                aux[free].push(l);
                last_ch = None;
            },
            None => {
                last_ch = Some(free);
            }
        }
    }
    match last_ch {
        Some(l) => l,
        None => v
    }
}
fn decide_ans(v: usize, sto: i32, aux: &Vec<Vec<usize>>, ans: &mut Vec<i32>) {
    if ans[v] != -2 {
        return;
    }
    ans[v] = sto;
    for &w in &aux[v] {
        decide_ans(w, -sto, aux, ans);
    }
}
fn main() {
    let buf = &mut BufReader::new(io::stdin());

    let n = next_i32(buf) as usize;
    let mut a = vec![vec![]; n];
    let mut b = vec![vec![]; n];
    let mut ra = 0;
    let mut rb = 0;

    for i in 0..n {
        let par = next_i32(buf);
        if par != -1 {
            let par = (par - 1) as usize;
            a[i].push(par);
            a[par].push(i);
        } else {
            ra = i;
        }
    }
    for i in 0..n {
        let par = next_i32(buf);
        if par != -1 {
            let par = (par - 1) as usize;
            b[i].push(par);
            b[par].push(i);
        } else {
            rb = i;
        }
    }

    let mut sgn_a = vec![0; n];
    let mut sgn_b = vec![0; n];

    assign_sign(ra, n, &a, &mut sgn_a);
    assign_sign(rb, n, &b, &mut sgn_b);
    
    if sgn_a != sgn_b {
        println!("IMPOSSIBLE");
        return;
    }

    println!("POSSIBLE");
    let mut aux = vec![vec![]; n];
    make_aux_graph(ra, n, &a, &mut aux);
    make_aux_graph(rb, n, &b, &mut aux);

    let mut ans = vec![-2; n];
    for i in 0..n {
        if sgn_a[i] == 0 {
            ans[i] = 0;
        } else {
            decide_ans(i, 1, &aux, &mut ans);
        }
    }

    for i in 0..n {
        if i == n - 1 {
            println!("{}", ans[i]);
        } else {
            print!("{} ", ans[i]);
        }
    }
}


Measured memory_bytes: 32636