Problem:
Score : 1000 points

Problem Statement

There is a sequence of length N: a = (a_1, a_2, ..., a_N).
Here, each a_i is a non-negative integer.

Snuke can repeatedly perform the following operation:

Let the XOR of all the elements in a be x. Select an integer i (1 ≤ i ≤ N) and replace a_i with x.

Snuke's objective is to match a with another sequence b = (b_1, b_2, ..., b_N).
Here, each b_i is a non-negative integer.

Determine whether the objective is achievable, and find the minimum necessary number of operations if the answer is positive.

Constraints

2 ≤ N ≤ 10^5

a_i and b_i are integers.

0 ≤ a_i, b_i < 2^{30}

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

If the objective is achievable, print the minimum necessary number of operations.
Otherwise, print -1 instead.

Sample Input 1

3
0 1 2
3 1 0

Sample Output 1

2

At first, the XOR of all the elements of a is 3.
If we replace a_1 with 3, a becomes (3, 1, 2).

Now, the XOR of all the elements of a is 0.
If we replace a_3 with 0, a becomes (3, 1, 0), which matches b.

Sample Input 2

3
0 1 2
0 1 2

Sample Output 2

0

Sample Input 3

2
1 1
0 0

Sample Output 3

-1

Sample Input 4

4
0 1 2 3
1 0 3 2

Sample Output 4

5

Solution in C++14 (GCC 5.4.1) (judge verdict: Accepted)

#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
 
using namespace std;
using namespace __gnu_pbds;
 
#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define fbo find_by_order
#define ook order_of_key
 
typedef long long ll;
typedef pair<ll,ll> ii;
typedef vector<ll> vi;
typedef long double ld; 
typedef tree<ll, null_type, less<ll>, rb_tree_tag, tree_order_statistics_node_update> pbds;
typedef set<ll>::iterator sit;
typedef map<ll,ll>::iterator mit;

ll a[100011];
ll b[100011];

struct DSU
{
	int S;
	
	struct node
	{
		int p; ll sum;
	};
	vector<node> dsu;
	
	DSU(int n)
	{
		S = n;
		for(int i = 0; i < n; i++)
		{
			node tmp;
			tmp.p = i; tmp.sum = 0;
			dsu.pb(tmp);
		}
	}
	
	void reset(int n)
	{
		dsu.clear();
		S = n;
		for(int i = 0; i < n; i++)
		{
			node tmp;
			tmp.p = i; tmp.sum = 0;
			dsu.pb(tmp);
		}
	}
	
	int rt(int u)
	{
		if(dsu[u].p == u) return u;
		dsu[u].p = rt(dsu[u].p);
		return dsu[u].p;
	}
	
	void merge(int u, int v)
	{
		u = rt(u); v = rt(v);
		if(u == v) return ;
		if(rand()&1) swap(u, v);
		dsu[v].p = u;
		dsu[u].sum += dsu[v].sum;
	}
	
	bool sameset(int u, int v)
	{
		if(rt(u) == rt(v)) return true;
		return false;
	}
	
	ll getstat(int u)
	{
		return dsu[rt(u)].sum;
	}
};

bool used[100001];
bool req[100001];
int main()
{
	ios_base::sync_with_stdio(0); cin.tie(0);
	int n; cin>>n;
	vector<ll> v1,v2;
	for(int i=0;i<n;i++)
	{
		cin>>a[i];
		a[n]^=a[i];
		v1.pb(a[i]);
	}
	v1.pb(a[n]);
	for(int i=0;i<n;i++)
	{
		cin>>b[i];
		b[n]^=b[i];
		v2.pb(b[i]);
	}
	v2.pb(b[n]);
	sort(v1.begin(),v1.end());
	sort(v2.begin(),v2.end());
	for(int i=0;i<=n;i++)
	{
		if(v1[i]!=v2[i])
		{
			cout<<-1<<'\n';
			return 0;
		}
	}
	//swap a[n] with a[i] how many times to reach b?
	v1.erase(unique(v1.begin(),v1.end()),v1.end());
	int ans=0;
	for(int i = 0; i <= n; i++)
	{
		a[i]=lower_bound(v1.begin(),v1.end(),a[i])-v1.begin();
		b[i]=lower_bound(v1.begin(),v1.end(),b[i])-v1.begin();
		if(i<n&&a[i]!=b[i]) ans++;
		if(a[i]!=b[i])
		{
			req[a[i]]=req[b[i]]=1;
		}
	}
	DSU dsu(int(v1.size()));
	for(int i=0;i<=n;i++)
	{
		dsu.merge(a[i],b[i]);
	}
	for(int i=0;i<v1.size();i++)
	{
		if(dsu.rt(i)==i)
		{
			used[i]=1;
		}
	}
	int holy1 = dsu.rt(a[n]);
	int holy2 = dsu.rt(b[n]);
	for(int i=0;i<v1.size();i++)
	{
		if(i!=holy1&&i!=holy2&&req[i]&&used[i]) ans++;
	}
	cout<<ans<<'\n';
}