#include <bits/stdc++.h>

using namespace std;

#define MAXN 200001
#define MAXM 32
#define int long long

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

int n;
int a[MAXN],b[MAXN],pref[MAXN];
int seg[MAXN*4];
map<int,int> mapa;
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 node,int l,int r)
{
    if (l==r) seg[node]=b[l];
    else
    {
        int mid=(l+r)/2;
        build(2*node,l,mid);build(2*node+1,mid+1,r);
        seg[node]=seg[2*node]&seg[2*node+1];
    }
}

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

int32_t 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];
    build(1,1,n);
    if (n<=2000)
    {
        int ans=0;
        for (int i=1;i<=n;i++)
        {
            for (int j=i;j<=n;j++) ans=max(ans,(pref[j]^pref[i-1])*query(1,1,n,i,j));
        }
        cout<<ans<<endl;return 0;
    }
    int bra=0;
    for (int i=1;i<=n;i++) bra+=(a[i]==1);
    if (bra==n)
    {
        int ans=0;
        for (int i=1;i<=n;i++) ans=max(ans,b[i]);
        cout<<ans<<endl;return 0;
    }
    bra=0;
    for (int i=1;i<=n;i++) bra+=(a[i]<=500);
    if (bra==n)
    {
        mapa[0]=0;int ans=0;
        for (int i=1;i<=n;i++)
        {
            for (int value=0;value<512;value++)
            {
                int xorvalue=value^pref[i];
                if (mapa.find(xorvalue)==mapa.end()) continue;
                int poz=mapa[xorvalue]+1;
                ans=max(ans,value*query(1,1,n,poz,i));
            }
            mapa[pref[i]]=i;
        }
        cout<<ans<<endl;return 0;
    }
    int brb=0;
    for (int i=1;i<=n;i++) brb+=(b[i]==1);
    if (brb==n)
    {
        TrieNode *root=newNode();insert(root,0);
        int ans=0;
        for (int i=1;i<=n;i++) {ans=max(ans,query(root,pref[i]));insert(root,pref[i]);}
        cout<<ans<<endl;return 0;
    }
    brb=0;
    for (int i=1;i<=n;i++) brb+=(b[i]<=3);
    if (brb==n)
    {
        for (int i=1;i<=n;i++)
        {
            if (b[i]==0) continue;
            if (b[i]==1 or b[i]==2)
            {
                int l=1,r=i-1,rez=i;
                while (l<=r)
                {
                    int mid=(l+r)/2;
                    if (query(1,1,n,mid,i)==b[i]) {rez=mid;r=mid-1;}
                    else l=mid+1;
                }
                queries.push_back({rez-1,i-1,i,b[i]});
            }
            else
            {
                int l=1,r=i-1,rez=i;
                while (l<=r)
                {
                    int mid=(l+r)/2;
                    if (query(1,1,n,mid,i)==3) {rez=mid;r=mid-1;}
                    else l=mid+1;
                }
                queries.push_back({rez-1,i-1,i,3});int poz=rez;
                b[i]=b[rez-1];l=1,r=rez-1,rez=rez-1;
                while (l<=r)
                {
                    int mid=(l+r)/2;
                    if (query(1,1,n,mid,i)==b[i]) {rez=mid;r=mid-1;}
                    else l=mid+1;
                }
                queries.push_back({rez-1,poz-2,i,b[i]});
            }
        }
        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;return 0;
    }
    return 0;
}