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: Wrong Answer)

#![allow(unused_imports)]
#![allow(non_snake_case)]
use std::cmp::*;
use std::collections::*;
use std::io::Write;

#[allow(unused_macros)]
macro_rules! debug {
    ($($e:expr),*) => {
        #[cfg(debug_assertions)]
        $({
            let (e, mut err) = (stringify!($e), std::io::stderr());
            writeln!(err, "{} = {:?}", e, $e).unwrap()
        })*
    };
}

fn solve_single() -> (Vec<Vec<u64>>, Vec<Vec<usize>>) {
    let max_idx = 51usize;
    let mut dp = vec![vec![std::u64::MAX; max_idx]; max_idx];
    let mut next = vec![vec![std::usize::MAX; max_idx]; max_idx];
    for i in 0..max_idx {
        dp[i][i] = 0;
    }
    for i in 0..max_idx {
        for j in 0..i {
            for k in 1..i {
                if dp[i % k][j] != std::u64::MAX {
                    let new = dp[i % k][j] + 2u64.pow(k as u32);
                    if new < dp[i][j] {
                        next[i][j] = k;
                        dp[i][j] = new;
                    }
                }
            }
        }
    }
    // println!("{:?}", dp);
    (dp, next)
}

fn solve_one_step(
    a: &mut Vec<usize>,
    b: &Vec<usize>,
    dp: &Vec<Vec<u64>>,
    next: &Vec<Vec<usize>>,
) -> usize {
    let mut next_candidate = vec![];
    for i in 0..a.len() {
        if a[i] == b[i] {
            continue;
        }
        next_candidate.push((next[a[i]][b[i]], i));
    }
    next_candidate.sort();
    'outer: for i in 0..next_candidate.len() {
        let current_use = next_candidate[i].0;
        for j in i + 1..next_candidate.len() {
            let idx = next_candidate[j].1;
            if dp[a[idx] % current_use][b[idx]] >= dp[a[idx]][b[idx]] {
                continue 'outer;
            }
            return current_use;
        }
    }
    next_candidate.last().unwrap().0
}

fn main() {
    let n = read::<usize>();
    let mut a = read_vec::<usize>();
    let b = read_vec::<usize>();
    let (dp, next) = solve_single();

    if (0..n).any(|i| dp[a[i]][b[i]] == std::u64::MAX) {
        println!("-1");
        return;
    }

    let mut ans = 0;
    while (0..n).any(|i| a[i] != b[i]) {
        let current_use = solve_one_step(&mut a, &b, &dp, &next);
        // debug!(current_use);
        for i in 0..n {
            if dp[a[i] % current_use][b[i]] <= dp[a[i]][b[i]] {
                a[i] %= current_use;
            }
        }
        // debug!(a);
        ans += 2u64.pow(current_use as u32);
    }
    println!("{:?}", ans);
}

fn read<T: std::str::FromStr>() -> T {
    let mut s = String::new();
    std::io::stdin().read_line(&mut s).ok();
    s.trim().parse().ok().unwrap()
}

fn read_vec<T: std::str::FromStr>() -> Vec<T> {
    read::<String>()
        .split_whitespace()
        .map(|e| e.parse().ok().unwrap())
        .collect()
}