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)

//ProblemC

#ifdef _MYPC
#include "mypc.h"
#endif // _MYPC

#include <iostream>
#include <string>
#include <vector>
#include <bitset>
#include <list>
#include <map>
#include <set>
#include <unordered_map>
#include <unordered_set>
#include <queue>
#include <stack>
#include <algorithm>
#include <numeric>
#include <functional>
#include <memory>
#include <complex>
#include <cstdio>
#include <cstring>
#include <cmath>

using namespace std;

//ProblemC

#define MAXN 50
#define MAXP 50

class Solve {
private:

	bool can(int a[], int b[], bool used[], int n) {
		bool path[MAXP + 1][MAXP + 1]{};
		for (int i = 1; i <= MAXP; i++) {
			for (int j = 1; j < MAXP; j++) {
				if (used[j]) {
					path[i][i % j] = true;
				}
			}
		}
		for (int i = 0; i <= MAXP; i++) {
			path[i][i] = true;
		}

		for (int k = 0; k <= MAXP; k++)
			for (int i = 0; i <= MAXP; i++)
				for (int j = 0; j <= MAXP; j++) {
					path[i][j] = path[i][j] || path[i][k] && path[k][j];
				}

		for (int i = 0; i < n; i++) {
			if (!path[a[i]][b[i]]) {
				return false;
			}
		}
		return true;
	}

	void solve() {
		int n;
		int a[MAXN], b[MAXN];

		cin >> n;
		for (int i = 0; i < n; i++) cin >> a[i];
		for (int i = 0; i < n; i++) cin >> b[i];

		bool must[MAXP]{};
		for (int i = 1; i < MAXP; i++) must[i] = true;

		if (!can(a, b, must, n)) {
			cout << -1 << endl;
			return;
		}

		for (int i = MAXP - 1; i >= 1; i--) {
			must[i] = false;
			if (!can(a, b, must, n)) {
				must[i] = true;
			}
		}

		long long rst = 0;
		for (int i = 1; i < MAXP; i++) if(must[i]) rst += 1LL << i;
		cout << rst << endl;

	}

public:
	Solve() { solve(); }
};

int main(int argc, char* argv[]) {
	unique_ptr<Solve> solve = make_unique<Solve>();
	return 0;
}