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: Wrong Answer)

#include <bits/stdc++.h>

#define _overload(_1,_2,_3,name,...) name
#define _rep(i,n) _range(i,0,n)
#define _range(i,a,b) for(int i=int(a);i<int(b);++i)
#define rep(...) _overload(__VA_ARGS__,_range,_rep,)(__VA_ARGS__)

#define _rrep(i,n) _rrange(i,n,0)
#define _rrange(i,a,b) for(int i=int(a)-1;i>=int(b);--i)
#define rrep(...) _overload(__VA_ARGS__,_rrange,_rrep,)(__VA_ARGS__)

#define _all(arg) begin(arg),end(arg)
#define uniq(arg) sort(_all(arg)),(arg).erase(unique(_all(arg)),end(arg))
#define getidx(ary,key) lower_bound(_all(ary),key)-begin(ary)
#define clr(a,b) memset((a),(b),sizeof(a))
#define bit(n) (1LL<<(n))
#define popcount(n) (__builtin_popcountll(n))

using namespace std;

template<class T>bool chmax(T &a, const T &b) { return (a < b) ? (a = b, 1) : 0;}
template<class T>bool chmin(T &a, const T &b) { return (b < a) ? (a = b, 1) : 0;}

using ll = long long;
using R = long double;
const R EPS = 1e-9L; // [-1000,1000]->EPS=1e-8 [-10000,10000]->EPS=1e-7
inline int sgn(const R& r) {return (r > EPS) - (r < -EPS);}
inline R sq(R x) {return sqrt(max(x, 0.0L));}

const int dx[8] = {1, 0, -1, 0, 1, -1, -1, 1};
const int dy[8] = {0, 1, 0, -1, 1, 1, -1, -1};

// Problem Specific Parameter:
int n;
int a[100010], b[100010], axor = 0, bxor = 0;

bool check(){
	vector<int> ca,cb;
	rep(i,n) ca.push_back(a[i]);
	rep(i,n) cb.push_back(b[i]);
	sort(begin(ca),end(ca));
	sort(begin(cb),end(cb));
	rep(i,n) if(ca[i]!=cb[i]) return false;
	return true;
}

// Description: 素集合を管理するデータ構造 
// TimeComplexity: 初期化$\mathcal{O}(n)$ 更新$\mathcal{O}(\log n)$
// Verifyed: AOJ DSL_1_A

struct Union_find{
	Union_find(int n){par.resize(n),iota(_all(par),0);}
	int find(int x){return (par[x]==x)?x:par[x]=find(par[x]);}
	void unite(int a,int b){a=find(a),b=find(b);par[a]=b;}
	bool same(int a,int b){return find(a)==find(b);}
	vector<int> par;
};


int main(void) {
	cin >> n;
	rep(i, n) cin >> a[i],axor^=a[i];
	rep(i, n) cin >> b[i],bxor^=b[i];

	a[n] = axor;
	b[n] = bxor;
	n++;

	if(check()==false){
		cout << -1 << endl;
		return 0;
	}

	vector<int> val;
	rep(i,n) val.push_back(a[i]);
	uniq(val);
	const int m = val.size();

	Union_find uf(m);

	rep(i,n-1){
		const int ai = getidx(val,a[i]);
		const int bi = getidx(val,b[i]);
		uf.unite(ai,bi);
	}

	map<int,int> group;
	rep(i,n-1){
		const int ai = getidx(val,a[i]);
		group[uf.find(ai)]++;
	}

	int ans = 0;
	
	for(auto &it:group){
		if(it.second == 1) continue;
		ans+=it.second + 1;
	}

	{
		const int ai = getidx(val,a[n-1]);
		if(group.find(uf.find(ai))!=end(group)) ans--;
	}

	cout << ans << endl;	

	return 0;
}