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 (GCC 5.4.1) (judge verdict: Accepted)

#include <stdio.h>
#include <stdlib.h>

#define datatype pair

typedef struct {
	int val;
	int pos;
}pair;

//比較関数
int compare(datatype a, datatype b){
	if(a.val < b.val){
		return -1;
	}
	else if(a.val > b.val){
		return 1;
	}
	else{
		return 0;
	}
}

int root(int a, int *array){
	if(array[a] == a){
		return a;
	}
	else{
		array[a] = root(array[a], array);
		return array[a];
	}
}

void combine(int a, int b, int *array, int *array_rank){
	int a_root = root(a, array);
	int b_root = root(b, array);
	if(a_root == b_root){
		return;
	}
	else if(array_rank[a_root] < array_rank[b_root]){
		array[a_root] = b_root;
		array_rank[b_root] += array_rank[a_root];
	}
	else{
		array[b_root] = a_root;
		array_rank[a_root] += array_rank[b_root];
	}
}

//昇順
void sort_sub(datatype *origin, int left, int right, datatype *tmp){
	if(right - left > 1){
		int i, j, k, half = (left + right) / 2;
		sort_sub(origin, left, half, tmp);
		sort_sub(origin, half, right, tmp);
		for(i = left; i < right; i++){
			tmp[i] = origin[i];
		}
		for(i = left, j = left, k = half; i < right; i++){
			if((compare(tmp[j], tmp[k]) <= 0 && j < half) || k == right){
				origin[i] = tmp[j];
				j++;
			}
			else{
				origin[i] = tmp[k];
				k++;
			}
		}
	}
}

void sort(datatype *origin, int N){
	datatype *tmp = (datatype *)malloc(sizeof(datatype) * N);
	sort_sub(origin, 0, N, tmp);
}

int main(){
	int N, x, i, j, k, prev;
	scanf("%d", &N);
	int *a0 = (int *)malloc(sizeof(int) * (N + 1));
	int *b0 = (int *)malloc(sizeof(int) * (N + 1));
	int *a = (int *)malloc(sizeof(int) * (N + 1));
	int *b = (int *)malloc(sizeof(int) * (N + 1));
	x = 0;
	for(i = 0; i < N; i++){
		scanf("%d", &a0[i]);
		x ^= a0[i];
	}
	a0[N] = x;
	x = 0;
	for(i = 0; i < N; i++){
		scanf("%d", &b0[i]);
		x ^= b0[i];
	}
	b0[N] = x;
	for(i = 0, j = 0; i < N; i++){
		if(a0[i] != b0[i]){
			a[j] = a0[i];
			b[j] = b0[i];
			j++;
		}
	}
	a[j] = a0[N];
	b[j] = b0[N];
	N = j;
	if(N == 0){
		printf("0\n");
		return 0;
	}
	pair *a2 = (pair *)malloc(sizeof(pair) * (N + 1));
	pair *b2 = (pair *)malloc(sizeof(pair) * (N + 1));
	for(i = 0; i <= N; i++){
		a2[i].val = a[i];
		b2[i].val = b[i];
		a2[i].pos = i;
		b2[i].pos = i;
	}
	sort(a2, N + 1);
	sort(b2, N + 1);
	for(i = 0, j = -1, prev = -1; i <= N; i++){
		if(a2[i].val != b2[i].val){
			printf("-1\n");
			return 0;
		}
		if(prev != a2[i].val){
			j++;
		}
		prev = a2[i].val;
		a[a2[i].pos] = j;
		b[b2[i].pos] = j;
	}
	j++;
	int *uni = (int *)malloc(sizeof(int) * j);
	int *uni_rank = (int *)malloc(sizeof(int) * j);
	int *exist = (int *)malloc(sizeof(int) * j);
	for(i = 0; i < j; i++){
		uni[i] = i;
		uni_rank[i] = 1;
		exist[i] = -1;
	}
	for(i = 0; i <= N; i++){
		combine(a[i], b[i], uni, uni_rank);
	}
	for(i = 0, k = 0; i < j; i++){
		if(exist[root(i, uni)] == -1){
			exist[root(i, uni)] = 1;
			k++;
		}
	}
	printf("%d\n", N + k - 1);
	return 0;
}