Problem:
Score : 700 points

Problem Statement

Aoki is playing with a sequence of numbers a_{1}, a_{2}, ..., a_{N}. Every second, he performs the following operation :

Choose a positive integer k. For each element of the sequence v, Aoki may choose to replace v with its remainder when divided by k, or do nothing with v. The cost of this operation is 2^{k} (regardless of how many elements he changes).

Aoki wants to turn the sequence into b_{1}, b_{2}, ..., b_{N} (the order of the elements is important). Determine if it is possible for Aoki to perform this task and if yes, find the minimum cost required.

Constraints

1 \leq N \leq 50

0 \leq a_{i}, b_{i} \leq 50

All values in the input are integers.

Input

Input is given from Standard Input in the following format:

N
a_{1} a_{2} ... a_{N}
b_{1} b_{2} ... b_{N}

Output

Print the minimum cost required to turn the original sequence into b_{1}, b_{2}, ..., b_{N}. If the task is impossible, output -1 instead.

Sample Input 1

3
19 10 14
0 3 4

Sample Output 1

160

Here's a possible sequence of operations :

Choose k = 7. Replace 19 with 5, 10 with 3 and do nothing to 14. The sequence is now 5, 3, 14.

Choose k = 5. Replace 5 with 0, do nothing to 3 and replace 14 with 4. The sequence is now 0, 3, 4.

The total cost is 2^{7} + 2^{5} = 160.

Sample Input 2

3
19 15 14
0 0 0

Sample Output 2

2

Aoki can just choose k = 1 and turn everything into 0. The cost is 2^{1} = 2.

Sample Input 3

2
8 13
5 13

Sample Output 3

-1

The task is impossible because we can never turn 8 into 5 using the given operation.

Sample Input 4

4
2 0 1 8
2 0 1 8

Sample Output 4

0

Aoki doesn't need to do anything here. The cost is 0.

Sample Input 5

1
50
13

Sample Output 5

137438953472

Beware of overflow issues.

Solution in Rust (1.15.1) (judge verdict: Accepted)

use std::cmp;

fn main() {
    let s = std::io::stdin();
    let mut sc = Scanner { stdin: s.lock() };
    let n = sc.read();
    let a: Vec<usize> = sc.vec(n);
    let b: Vec<usize> = sc.vec(n);

    if !check(50, &a, &b, &vec![]) {
        println!("-1");
        return;
    }

    let mut ans = vec![];
    for k in (1..51).rev() {
        if !check(k - 1, &a, &b, &ans) {
            ans.push(k);
        }
    }

    println!("{}", ans.into_iter().map(|i| 1 << i).sum::<usize>());
}

fn check(k: usize, a: &Vec<usize>, b: &Vec<usize>, ans: &Vec<usize>) -> bool {
    let max = cmp::max(*a.iter().max().unwrap(), *b.iter().max().unwrap());
    let mut w = vec![vec![false; max + 1]; max + 1];
    for &a in a.iter() {
        w[a][a] = true;
    }

    for &k in ans.iter() {
        for i in 0..(max + 1) {
            w[i][i % k] = true;
        }
    }
    for k in 1..(k + 1) {
        for i in 0..(max + 1) {
            w[i][i % k] = true;
        }
    }
    for k in 0..(max + 1) {
        w[k][k] = true;
    }

    for k in 0..(max + 1) {
        for i in 0..(max + 1) {
            for j in 0..(max + 1) {
                if w[i][k] && w[k][j] {
                    w[i][j] = true;
                }
            }
        }
    }

    b.iter().enumerate().all(|(i, &b)| w[a[i]][b])
}

pub struct Scanner<R> {
    stdin: R,
}

impl<R: std::io::Read> Scanner<R> {
    pub fn read<T: std::str::FromStr>(&mut self) -> T {
        use std::io::Read;
        let buf = self
            .stdin
            .by_ref()
            .bytes()
            .map(|b| b.unwrap())
            .skip_while(|&b| b == b' ' || b == b'\n')
            .take_while(|&b| b != b' ' && b != b'\n')
            .collect::<Vec<_>>();
        unsafe { std::str::from_utf8_unchecked(&buf) }
            .parse()
            .ok()
            .expect("Parse error.")
    }
    pub fn vec<T: std::str::FromStr>(&mut self, n: usize) -> Vec<T> {
        (0..n).map(|_| self.read()).collect()
    }
    pub fn chars(&mut self) -> Vec<char> {
        self.read::<String>().chars().collect()
    }
}