#include <bits/stdc++.h>

using namespace std;

#define MAXN 200001
#define MAXM 32

struct Query
{
    int l,r,idx,val;
};

int n;
int a[MAXN],b[MAXN],pref[MAXN];
int seg[MAXM][MAXN*4];
vector<int> pos;
vector<Query> queries;

struct TrieNode
{
    int value,count;
    TrieNode *arr[2];
};

TrieNode *newNode()
{
    TrieNode *temp=new TrieNode;
    temp->value=0;temp->count=0;
    temp->arr[0]=temp->arr[1]=NULL;
    return temp;
}

void insert(TrieNode *root,int prexor)
{
    TrieNode *temp=root;
    for (int i=MAXM-1;i>=0;i--)
    {
        bool val=prexor&(1<<i);
        if (temp->arr[val]==NULL) temp->arr[val]=newNode();
        temp=temp->arr[val];temp->count++;
    }
    temp->value=prexor;
}

int query(TrieNode *root,int prexor)
{
    TrieNode *temp=root;
    for (int i=MAXM-1;i>=0;i--)
    {
        bool val=prexor&(1<<i);
        if (temp->arr[1-val]!=NULL) temp=temp->arr[1-val];
        else if (temp->arr[val]!=NULL) temp=temp->arr[val];
    }
    return prexor^(temp->value);
}

bool remove(TrieNode *root,int val,int bit)
{
    TrieNode *temp=root;
    if (!temp) return false;
    if (bit<0) return true;
    int vred=val&(1<<bit);
    if (remove(temp->arr[vred],val,bit-1))
    {
        temp->arr[vred]->count--;
        if (temp->arr[vred]->count==0) temp->arr[vred]=NULL;
    }
    return true;
}

void build(int bit,int node,int l,int r)
{
    if (l==r)
    {
        if (b[l]&(1<<bit)) seg[bit][node]=-1;
        else seg[bit][node]=l;
    }
    else
    {
        int mid=(l+r)/2;
        build(bit,2*node,l,mid);
        build(bit,2*node+1,mid+1,r);
        seg[bit][node]=max(seg[bit][2*node],seg[bit][2*node+1]);
    }
}

int query(int bit,int node,int l,int r,int a,int b)
{
    if (a>b) return -1;
    if (l==a and r==b) return seg[bit][node];
    int mid=(l+r)/2;
    return max(query(bit,2*node,l,mid,a,min(b,mid)),query(bit,2*node+1,mid+1,r,max(a,mid+1),b));
}

int main()
{
    cin>>n;pref[0]=0;
    for (int i=1;i<=n;i++) {cin>>a[i];pref[i]=pref[i-1]^a[i];}
    for (int i=1;i<=n;i++) cin>>b[i];
    for (int i=0;i<MAXM;i++) build(i,1,1,n);
    for (int i=1;i<=n;i++)
    {
        for (int bit=0;bit<MAXM;bit++)
        {
            if (!(b[i]&(1<<bit))) continue;
            int val=query(bit,1,1,n,1,i);
            if (val!=-1) pos.push_back(val);
        }
        pos.push_back(0);pos.push_back(i);
        sort(pos.begin(),pos.end());
        pos.erase(unique(pos.begin(),pos.end()),pos.end());
        int trenval=b[i];
        for (int j=pos.size()-2;j>=0;j--) {queries.push_back({pos[j],pos[j+1]-1,i,trenval});trenval=trenval&b[pos[j]];}
        pos.clear();
    }
    int block_size=(int)sqrt(n);
    auto mo_cmp=[&](Query a,Query b)
    {
		int block_a=a.l/block_size;
		int block_b=b.l/block_size;
		if (block_a==block_b) return a.r<b.r;
		return block_a<block_b;
	};
	sort(queries.begin(),queries.end(),mo_cmp);
	TrieNode *root=newNode();
	auto obrisi=[&](int idx) {
	    remove(root,pref[idx],MAXM-1);
	};
	auto add=[&](int idx) {
	    insert(root,pref[idx]);
	};
	int mo_left=0,mo_right=0;insert(root,pref[0]);
	int ans=0;
	for (int i=0;i<queries.size();i++)
    {
        int left=queries[i].l,right=queries[i].r;
        while (mo_left<left) obrisi(mo_left++);
		while (mo_left>left) add(--mo_left);
		while (mo_right<right) add(++mo_right);
		while (mo_right>right) obrisi(mo_right--);
		ans=max(ans,queries[i].val*query(root,pref[queries[i].idx]));
    }
    cout<<ans<<endl;
}