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++14 (GCC 5.4.1) (judge verdict: Accepted)

#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
#include <algorithm>
#include <cmath>
#include <map>

using namespace std;

#define mp make_pair
#define pb push_back
#define ll long long

const int maxN = 55;
const int def = 51;

int n, i, j, a, b, bit;
int from[maxN], to[maxN];
bool can[maxN][maxN][maxN], aux[maxN];
bool act[maxN][maxN];
ll ans;

int main()
{
 //   freopen("test.in","r",stdin);

    cin >> n;
    for (i = 1; i <= n; i++) cin >> from[i];
    for (i = 1; i <= n; i++) cin >> to[i];

    for (i = 0; i <= def; i++) can[0][i][i] = true;
    for (i = 1; i <= def; i++) {
        for (a = 0; a <= def; a++) {
            for (b = 0; b <= a; b++) {
                can[i][a][b] |= can[i - 1][a][b];
                can[i][a][b] |= can[i - 1][a % i][b];
            }
        }
    }

    for (i = 1; i <= n; i++) {
        if (!can[def][from[i]][to[i]]) {
            printf("-1");
            return 0;
        }
    }

    for (i = 1; i <= n; i++) act[i][from[i]] = true;
    for (bit = def; bit > 0; bit--) {
        bool need = false;

        for (i = 1; i <= n; i++) {
            bool any = false;

            for (j = 0; j <= def; j++)
                if (act[i][j] && can[bit - 1][j][to[i]])
                    any = true;

            if (!any) need = true;
        }


        if (!need) {

            for (i = 1; i <= n; i++) {
                memcpy(aux, act[i], sizeof(aux));
                memset(act[i], 0, sizeof(aux));

                for (j = 0; j <= def; j++)
                    if (aux[j] && can[bit - 1][j][to[i]])
                        act[i][j] = true;
            }

        } else {
            ans |= 1LL << bit;

            for (i = 1; i <= n; i++) {
                memcpy(aux, act[i], sizeof(aux));
                memset(act[i], 0, sizeof(aux));

                for (j = 0; j <= def; j++) {
                    if (aux[j] && can[bit - 1][j][to[i]])
                        act[i][j] = true;

                    if (aux[j] && can[bit - 1][j % bit][to[i]])
                        act[i][j % bit] = true;
                }
            }
        }
    }

    cout << ans;



    return 0;
}