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 C# (Mono 4.6.2.0) (judge verdict: Wrong Answer)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace AGC022C {
    class Program {
        static void Main(string[] args) {
            int N = int.Parse(Console.ReadLine());
            int[] inputA = Console.ReadLine().Split(' ').Select(s => int.Parse(s)).ToArray();
            int[] inputB = Console.ReadLine().Split(' ').Select(s => int.Parse(s)).ToArray();
            bool flagg = false;
            for(int i = 0; i < N; i++) {
                if(inputA[i] != inputB[i]){
                    flagg = true;
                }
            }
            if (flagg) {
                bool[,] dp = new bool[N, 51];
                for (int i = 0; i < N; i++) {
                    dp[i, inputB[i]] = true;
                }
                int max = -1;
                for (int i = 1; i <= 25; i++) {
                    for (int j = 0; j < N; j++) {
                        for (int k = 0; k < 51; k++) {
                            if (dp[j, k % i]) {
                                dp[j, k] = true;
                            }
                        }
                    }
                    bool flag = true;
                    for (int j = 0; j < N; j++) {
                        if (!dp[j, inputA[j]]) {
                            flag = false;
                        }
                    }
                    if (flag) {
                        max = i;
                        break;
                    }
                }
                bool ok = (max == -1) ? false : true;
                long ans = 0;
                if (ok) {
                    bool[] flags = Enumerable.Repeat(true, max).ToArray();
                    for (int l = max; l >= 1; l--) {
                        dp = new bool[N, 51];
                        for (int i = 0; i < N; i++) {
                            dp[i, inputB[i]] = true;
                        }
                        for (int i = 1; i <= max; i++) {
                            if (i != max) {
                                if (i == l || !flags[i - 1]) {
                                    continue;
                                }
                            }
                            //Console.WriteLine(i);
                            for (int j = 0; j < N; j++) {
                                for (int k = 0; k < 51; k++) {
                                    if (dp[j, k % i]) {
                                        dp[j, k] = true;
                                    }
                                }
                            }
                        }
                        bool flag = true;
                        for (int j = 0; j < N; j++) {
                            if (!dp[j, inputA[j]]) {
                                flag = false;
                            }
                        }
                        //Console.WriteLine(flag);
                        if (flag) {
                            flags[l - 1] = false;
                        }
                    }
                    for (int i = 0; i < max; i++) {
                        //Console.WriteLine(flags[max - i - 1]);
                        if (i == 0 || flags[max - i - 1]) {
                            ans = (ans + 1) << 1;
                        } else {
                            ans = ans << 1;
                        }
                    }
                }
                if (ok) {
                    Console.WriteLine(ans);
                } else {
                    Console.WriteLine(-1);
                }
            } else {
                Console.WriteLine(0);
            }
        }

        //nが素数かどうか判定します
        private static int IsPrime(int n) {
            for (int i = 2; i < Math.Sqrt(n); i++) {
                if (n % i == 0) {
                    return i;
                }
            }
            return -1;
        }

        //重み付きグラフ用の辺です
        class Edge {
            public int to;
            public int cost;
        }
    }
}