#![allow(unused_imports)]

use proconio::{input, fastout};
use proconio::marker::*;
use std::collections::HashSet;

#[fastout]
fn main() {
    input! {
    n: usize,
    mut a: [usize; n]
    }
    let mut l2 = vec![0; 1000005];
    l2[1] = 2;
    let mut is_pc = true;
    for i in 2..=1000000 {
        if l2[i] == 0 {
            for j in 1.. {
                let k = i * j;
                if k >= l2.len(){
                    break;
                }
                l2[k] = i;
            }
        }
    }
    let mut d = HashSet::new();
    for i in 0..n {
        let mut t = a[i];
        let mut dt = HashSet::new();
        while t != 1 {
            if l2[t] == 0 {
                print!("{}",a[i]);
            }
            dt.insert(l2[t]);
            t /= l2[t];
        }
        if !d.intersection(&dt).collect::<HashSet<_>>().is_empty() {
            is_pc = false;
            break;
        } else {
            d = d.union(&dt).copied().collect();
        }


    }
    if is_pc {
        print!("pairwise coprime");
        return;
    }
    let mut t = a[0];
    for i in 0..n {
        t = gcd(&a[i], &t);
    }
    if t == 1 {
        print!("setwise coprime");
        return;
    }
    print!("not coprime")
}

// O(log(N))
fn gcd(a: &usize, b: &usize) -> usize {
    let (mut x, mut y) = if a < b { (*b, *a) } else { (*a, *b) };
    let mut r = x % y;
    while r != 0 {
        x = y;
        y = r;
        r = x % y;
    }
    y
}

use std::cmp::Ordering;
use alga::linear::Similarity;

pub trait BinarySearch<T> {
    fn lower_bound(&self, x: &T) -> usize;
    fn upper_bound(&self, x: &T) -> usize;
}

impl<T: Ord> BinarySearch<T> for [T] {
    fn lower_bound(&self, x: &T) -> usize {
        let mut low = 0;
        let mut high = self.len();

        while low != high {
            let mid = (high + low) / 2;
            match self[mid].cmp(x) {
                Ordering::Less => {
                    low = mid + 1;
                }
                Ordering::Equal | Ordering::Greater => {
                    high = mid;
                }
            }
        }
        low
    }
    fn upper_bound(&self, x: &T) -> usize {
        let mut low = 0;
        let mut high = self.len();
        while low != high {
            let mid = (low + high) / 2;
            match self[mid].cmp(x) {
                Ordering::Less | Ordering::Equal => {
                    low = mid + 1;
                }
                Ordering::Greater => {
                    high = mid;
                }
            }
        }
        low
    }
}

