#include <bits/stdc++.h>

using namespace std;

#define fcout(d) cout << fixed << setprecision(d)
#define rep(i,n) for(int i = 0; i < (n); ++i)
#define rep1(i,n) for(int i = 1; i <= (n); ++i)
#define repU(i,s,t) for(int i = (s); i <= (t); ++i)
#define repD(i,t,s) for(int i = (t); i >= (s); --i)
#define all(v)  begin(v),end(v)
#define clr(v) fill(all(v),0)
#define l_bnd lower_bound
#define u_bnd upper_bound
#define puf push_front
#define pub push_back
#define pof pop_front
#define pob pop_back
#define mkp make_pair
#define mkt make_tuple
#define fir first
#define sec second
#define q_ceil(n,d) ((n - 1)/(d) + 1)
#define parity(a,b) (((a)^(b)) & 1 ^ 1)

typedef long long ll;
typedef unsigned long long ull;
typedef double db;

const pair<int,int> DIR[] = { {1,0},{0,1},{-1,0},{0,-1},{1,1},{-1,1},{-1,-1},{1,-1} };
const int INF_32 = (1 << 30) - 1;
const ll INF_64 = (1LL << 62) - 1;
const int MOD = 1e9 + 7;

template<class Abel> struct D_Graph {
	int V,E;
	Abel INF;
	vector<vector<pair<int,Abel>>> adj;
	vector<vector<pair<int,Abel>>> adj_inv;

	D_Graph(int V_size = 0, Abel dist_max = INF_32) : INF(dist_max)
	{
		init(V_size);
	}

	void init(int V_size) {
		V = V_size, E = 0;
		adj.clear();
		adj_inv.clear();
		adj.resize(V + 1);
		adj_inv.resize(V + 1);
		adj[0].resize(V);
		for(int i = 1; i <= V; ++i){
			adj[0][i - 1] = {i,0};
			adj[i].reserve(min(V,100));
			adj_inv[i].reserve(min(V,100));
		}
	}

	int deg_out(int v) { return adj[v].size(); }

	int deg_in(int v) { return adj_inv[v].size(); }

	bool is_leaf(int v) { return deg_out(v) == 0; }

	bool is_root(int v) { return deg_in(v) == 0; }

	void add_edge(int from, int to, Abel cost = 1) {
		adj[from].push_back({to,cost});
		adj_inv[to].push_back({from,cost});
		++E;
	}

	bool erase_edge(int from, int to, Abel cost = 1) {
		sort_adj(from);
		auto it = lower_bound(begin(adj[from]),end(adj[from]),make_pair(to,cost));
		if(it != end(adj[from]) && *it == make_pair(to,cost)){
			adj[from].erase(it);
			sort_adj(to);
			it = lower_bound(begin(adj_inv[to]),end(adj_inv[to]),make_pair(from,cost));
			adj_inv[to].erase(it);
			return 1;
		}
		return 0;
	}

	void sort_adj() {
		for(int i = 0; i <= V; ++i) sort_adj(i);
	}

	void sort_adj(int v) {
		sort(begin(adj[v]),end(adj[v]));
		sort(begin(adj_inv[v]),end(adj_inv[v]));
	}

	bool is_cncted(int from, int to) {
		if(from == to) return 1;
		queue<int> que;
		que.push(from);
		bool *vis = (bool*)malloc(sizeof(bool) * (V + 1));
		fill(vis,vis + V + 1,0);
		vis[from] = 1;
		while(!que.empty()){
			int t = que.front();
			que.pop();
			for(auto e : adj[t]){
				int u = e.first;
				if(u == to) return 1;
				if(!vis[u]){
					que.push(u);
					vis[u] = 1;
				}
			}
		}
		return 0;
	}

	void dijkstra(vector<Abel> &dist, int src) {
		dist.clear();
		dist.assign(V + 1,INF);
		priority_queue<pair<Abel,int>,vector<pair<Abel,int>>,greater<pair<Abel,int>>> que;
		que.push({0,src});
		while(!que.empty()){
			int d = que.top().first;
			int v = que.top().second;
			que.pop();
			if(dist[v] <= d) continue;
			dist[v] = d;
			for(auto e : adj[v]) que.push({e.second + d,e.first});
		}
	}

	bool is_cyclic() {
		vector<int> s;
		return !tsort(s);
	}

	bool tsort(vector<int> &seq, bool idx_ord = 0) {
		seq.clear();
		seq.reserve(V + 1);
		sort_adj();
		vector<int> in(V + 1);
		for(int i = 0; i <= V; ++i) in[i] = deg_in(i);
		stack<int> rt;
		rt.push(0);
		while(!rt.empty()){
			int r = rt.top();
			rt.pop();
			for(auto e : adj[r]){
				int v = e.first;
				if(r) --in[v];
				if(!in[v]){
					rt.push(v);
					if(idx_ord){
						auto pos = begin(seq);
						bool det = 0;
						for(auto i = begin(seq); i < end(seq); ++i){
							if(!det && v > *i) ++pos;
							else det = 1;
							auto u = lower_bound(begin(adj[*i]),end(adj[*i]),make_pair(v,-INF));
							if(u < end(adj[*i]) && u->first == v){
								pos = i + 1;
								det = 0;
							}
						}
						seq.insert(pos,v);
					}else{
						seq.push_back(v);
					}
				}
			}
		}
		if(seq.size() == V) return 1;
		return 0;
	}

	void scc(vector<int> &label){
		label.assign(V + 1,0);
		stack<int> s;
		vector<int> low(V + 1);
		vector<int> idx(V + 1);
		int l = 0,c = 0;
		dfs(0,c,l,s,label,low,idx);
	}

	void dfs(int v, int &cnt, int &l, stack<int> &s, vector<int> &label, vector<int> &low, vector<int> &idx){
		s.push(v);
		idx[v] = low[v] = cnt++;
		for(auto e : adj[v]){
			int u = e.first;
			if(label[u]) continue;
			if(!idx[u]) dfs(u,cnt,l,s,label,low,idx);
			low[v] = min(low[v],low[u]);
		}
		if(idx[v] == low[v]){
			++l;
			for(int t = 0; t != v; s.pop()){
				t = s.top();
				label[t] = l;
			}
		}
	}
};

int main(){
	cin.tie(0);
ios::sync_with_stdio(false);

int n,a[50],b[50];
cin >> n;
rep(i,n){ cin >> a[i]; ++a[i]; }
rep(i,n){ cin >> b[i]; ++b[i]; }
vector<int> s;
D_Graph<int> G(51);
rep1(i,50)rep1(j,50) G.add_edge(j + 1,j % i + 1);
repD(e,50,1){
	rep1(i,50) G.erase_edge(i + 1,i % e + 1);
	rep(i,n){
		if(!G.is_cncted(a[i],b[i])){
			rep1(i,50) G.add_edge(i + 1,i % e + 1);
			s.pub(e);
			break;
		}
	}
}
if(s.size() == 50){
	rep(i,n) if(!G.is_cncted(a[i],b[i])){
		cout << -1 << endl;
		return 0;
	}
}
ll ans = 0;
for(int k : s) ans += 1ll << k;
cout << ans << endl;
}


Measured memory_bytes: 512