fn gcd(m: i32, n: i32) -> i32 {
    let r;
    let (mm, nn) : (i32,i32);
    if n > m {
        mm = n;
        nn = m;
    } else {
        mm = m;
        nn = n;
    }
    if nn == 0  || mm == nn {
        return mm;
    }
    r = mm - nn;
    if r % nn == 0 {
        if r > nn {
            return nn
        } else {
            return r
        }
    }
    gcd(nn, r)
}

fn collect_divisor(n: i32) -> Vec<i32> {
    let mut primes = vec![];
    let mut cur = n;
    let mut i = 2_i32;
    // assert(n != 0);
    if n == 1 {
        primes.push(1);
        return primes;
    }
    while i != cur {
        if cur % i  == 0 {
            primes.push(i);
            cur /= i;
            continue;
        }
        i += 1;
    }
    primes.push(cur);
    // println!("primes = {:?}", primes);
    let divs = enum_div(1, &primes, 0);
    divs
}

fn enum_div(base: i32, v:&Vec<i32>, idx:i32) -> Vec<i32> {
    if idx as usize == v.len() {
        return vec![base];
    }
    let mut l = enum_div(v[idx as usize] * base, v, idx+1);
    let mut r = enum_div(                  base, v, idx+1);
    let mut ret = vec![];
    ret.append(&mut l);
    ret.append(&mut r);
    ret.sort();
    ret.dedup();
    ret
}

fn sieve_fn(n: i32) -> Vec<i32> {
    let mut primes = vec![];
    let mut sqr_n = (n as f64).sqrt().ceil() as i32;
    sqr_n += 1;

    for i in 0 .. sqr_n {
        primes.push(i);
    }
    for i in 2 .. sqr_n {
        if primes[i as usize] == -1 {
            continue
        }
        for j in i+1 .. sqr_n {
            if primes[j as usize] == -1 {
                continue
            }
            if j % i == 0 {
                primes[j as usize] = -1;
            }
        }
    }
    return primes
}

macro_rules! input {
    (source = $s:expr, $($r:tt)*) => {
        let mut iter = $s.split_whitespace();
        let mut next = || { iter.next().unwrap() };
        input_inner!{next, $($r)*}
    };
    ($($r:tt)*) => {
        let stdin = std::io::stdin();
        let mut bytes = std::io::Read::bytes(std::io::BufReader::new(stdin.lock()));
        let mut next = move || -> String{
            bytes
                .by_ref()
                .map(|r|r.unwrap() as char)
                .skip_while(|c|c.is_whitespace())
                .take_while(|c|!c.is_whitespace())
                .collect()
        };
        input_inner!{next, $($r)*}
    };
}

macro_rules! input_inner {
    ($next:expr) => {};
    ($next:expr, ) => {};

    ($next:expr, $var:ident : $t:tt $($r:tt)*) => {
        let $var = read_value!($next, $t);
        input_inner!{$next $($r)*}
    };
}

macro_rules! read_value {
    ($next:expr, ( $($t:tt),* )) => {
        ( $(read_value!($next, $t)),* )
    };

    ($next:expr, [ $t:tt ; $len:expr ]) => {
        (0..$len).map(|_| read_value!($next, $t)).collect::<Vec<_>>()
    };

    ($next:expr, chars) => {
        read_value!($next, String).chars().collect::<Vec<char>>()
    };

    ($next:expr, usize1) => {
        read_value!($next, usize) - 1
    };

    ($next:expr, $t:ty) => {
        $next().parse::<$t>().expect("Parse error")
    };
}

fn main() {
    input! {
        n : usize,
        xs : [ i32 ; n ],
    }
    let res;
    if n == 2 {
        let gcd_v1 = gcd(xs[0], xs[1]);
        res = collect_divisor(gcd_v1);
    } else {
        let gcd_v1 = gcd(xs[0], xs[1]);
        let gcd_v2 = gcd(xs[1], xs[2]);
        let gcd_v = gcd(gcd_v1, gcd_v2);
        // println!("{} {} {}", gcd_v1, gcd_v2, gcd_v);
        res = collect_divisor(gcd_v);
    }
    println!("{}", do_format(&res).trim_right());
}

fn do_format(vec: &Vec<i32>) -> String {
    vec.iter()
        .map(|i| i.to_string() + "\n" )
        .collect::<String>()
}


Measured memory_bytes: 5040