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 Java8 (OpenJDK 1.8.0) (judge verdict: Wrong Answer)

import java.io.*;
import java.util.*;

public class Main {

	static class Number implements Comparable<Number> {
		int val, pos;

		public Number(int val, int pos) {
			this.val = val;
			this.pos = pos;
		}

		@Override
		public int compareTo(Number o) {
			return Integer.compare(val, o.val);
		}
	}
	
	int get(int[] p, int v) {
		return p[v] == v ? v : (p[v] = get(p, p[v]));
	}
	
	boolean unite(int a, int b, int[] p){
		a = get(p, a);
		b = get(p, b);
		if (a == b) {
			return false;
		}
		p[a] = b;
		return true;
	}
	
	int go(int[] a, int[] b) {
		int n = a.length;
		Number[] na = new Number[n];
		Number[] nb = new Number[n];
		int sz = 0;
		for (int i = 0; i < n; i++) {
			if (a[i] != b[i]) {
				na[sz] = new Number(a[i], i);
				nb[sz] = new Number(b[i], i);
				sz++;
			}
		}
		na = Arrays.copyOf(na, sz);
		nb = Arrays.copyOf(nb, sz);
		
		Arrays.sort(na);
		Arrays.sort(nb);
		
		int[] p = new int[n];
		for (int i = 0; i < n; i++) {
			p[i] = i;
		}
		
		int comps = sz;
		
		for (int i = 0; i < sz; i++) {
			int j = i;
			while (j < sz && na[i].val == na[j].val) {
				j++;
			}
			
			for (int k = i; k < j; k++) {
				if (nb[k].val != na[k].val) {
					return Integer.MAX_VALUE;
				}
			}
			
			for (int k = i; k + 1 < j; k++) {
				if (unite(na[k].pos, na[k + 1].pos, p)) {
					comps--;
				}
				if (unite(nb[k].pos, nb[k + 1].pos, p)) {
					comps--;
				}
			}
			
			if (unite(na[j - 1].pos, nb[i].pos, p)) {
				comps--;
			}
			
			i = j;
		}
		
		return sz + comps;
	}

	void submit() {
		int n = nextInt();
		int[] a = new int[n];
		int[] b = new int[n];

		for (int i = 0; i < n; i++) {
			a[i] = nextInt();
		}

		for (int i = 0; i < n; i++) {
			b[i] = nextInt();
		}

		int xor = 0;
		for (int x : a) {
			xor ^= x;
		}

		long delta = 0;

		for (int x : a) {
			delta -= x;
		}

		for (int y : b) {
			delta += y;
		}

		int ret = Integer.MAX_VALUE;

		for (int i = 0; i < n; i++) {
			if (b[i] == xor) {
				long newVal = b[i] + delta;
				if (newVal >= 0 && newVal < (1L << 30)) {
					int[] newB = b.clone();
					newB[i] = (int) newVal;
					ret = Math.min(ret, Math.max(go(a, newB) - 1, 0));
				}
			}
		}

		ret = Math.min(ret, go(a, b));
		if (ret < 1_000_000) {
			out.println(ret);
		} else {
			out.println(-1);
		}
	}

	void preCalc() {

	}

	void stress() {

	}

	void test() {

	}

	Main() throws IOException {
		br = new BufferedReader(new InputStreamReader(System.in));
		out = new PrintWriter(System.out);
		preCalc();
		submit();
		// stress();
		// test();
		out.close();
	}

	static final Random rng = new Random();

	static int rand(int l, int r) {
		return l + rng.nextInt(r - l + 1);
	}

	public static void main(String[] args) throws IOException {
		new Main();
	}

	BufferedReader br;
	PrintWriter out;
	StringTokenizer st;

	String nextToken() {
		while (st == null || !st.hasMoreTokens()) {
			try {
				st = new StringTokenizer(br.readLine());
			} catch (IOException e) {
				throw new RuntimeException(e);
			}
		}
		return st.nextToken();
	}

	String nextString() {
		try {
			return br.readLine();
		} catch (IOException e) {
			throw new RuntimeException(e);
		}
	}

	int nextInt() {
		return Integer.parseInt(nextToken());
	}

	long nextLong() {
		return Long.parseLong(nextToken());
	}

	double nextDouble() {
		return Double.parseDouble(nextToken());
	}
}