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

#pragma GCC diagnostic ignored "-Wincompatible-pointer-types"
#define _USE_MATH_DEFINES

#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include <math.h>
#include <time.h>

#define BIG 2000000007
#define VERYBIG 200000000000007LL

#define MOD 1000000007
typedef uint64_t ull;
typedef  int64_t sll;

#define N_MAX 2000
#define M_MAX 200000

ull n, m;

ull a[N_MAX];
ull b[N_MAX];

bool isreached[100][100];
bool isreachable[100][100];

void set1nize (ull v, bool *array[]) {
	sll i, j, ki;

	for (i = 0; i < n; i++) {
		for (j = 0; j < v; j++) {
			for (ki = j; ki <= 50; ki += v) {
				if (array[i][ki]) {
					array[i][j] = true;
					break;
				}
			}
		}

		// (j-k loop) =~ 50
	}

	return;
}

bool is0able (ull v) {
	sll i, j;

	bool *isreachable_ARG[100];
	for (i = 0; i < n; i++) {
		isreachable_ARG[i] = isreachable[i];

		for (j = 0; j <= 50; j++) {
			isreachable[i][j] = isreached[i][j];
		}
	}

	while (--v) {
		set1nize(v, isreachable_ARG);
	}

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

ull solve () {
	sll i, j, ki;
	// ull result = 0;
	sll result = 0;
	// double result = 0;
	// ull maybe = 0;
	sll maybe = 0;
	// ull sum = 0;
	sll sum = 0;
	ull item;
	ull *dpcell;

	bool *isreached_ARG[100];
	for (i = 0; i < n; i++) {
		isreached_ARG[i] = isreached[i];
	}

	for (i = 0; i < n; i++) {
		for (j = 0; j <= 50; j++) {
			isreached[i][j] = false;
		}
		isreached[i][a[i]] = true;
	}

	if (!is0able(51)) goto fail;

	result = 0;
	for (i = 50; i >= 1; i--) {
		if (!is0able(i)) {
			result |= (1ULL << i);
			set1nize(i, isreached_ARG);
		}
	}

	printf("%llu\n", result);

	return 0;

	fail:
	puts("-1");
	return 1;
}

int32_t main (void) {
	int32_t i, j;
	int32_t x, y;

	scanf("%llu", &n);
	for (i = 0; i < n; i++) {
		scanf("%llu", &a[i]);
	}
	for (i = 0; i < n; i++) {
		scanf("%llu", &b[i]);
	}
	solve();

	return 0;
}