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 SZ(x) ((int) (x).size())
using namespace std;

void noSol() {
    cout << "-1\n";
    exit(0);
}

template<class T>
vector<T> sorted(const vector<T>& a) {
    vector<T> b = a;
    sort(b.begin(), b.end());
    return b;
}

vector<int> cc;
vector<vector<int>> graph;

int dfs(int node, int ccc) {
    cc[node] = ccc;
    int ret = 1;
    for (int to: graph[node]) {
        if (cc[to] == -1) {
            ret += dfs(to, ccc);
        }
    }
    return ret;
}

int solve(vector<int> a, vector<int> b) {
    vector<int> all = a;
    all.insert(all.end(), b.begin(), b.end());
    sort(all.begin(), all.end());
    all.erase(unique(all.begin(), all.end()), all.end());
    for (int& x: a) {
        x = lower_bound(all.begin(), all.end(), x) - all.begin();
    }
    for (int& x: b) {
        x = lower_bound(all.begin(), all.end(), x) - all.begin();
    }
    int n = SZ(a);
    cc = vector<int>(n, -1);
    graph = vector<vector<int>>(n);
    for (int i = 0; i < n; ++i) {
        if (a[i] != b[i]) {
            graph[a[i]].push_back(b[i]);
            graph[b[i]].push_back(a[i]);
        }
    }
    int ccc = 0;
    int ans = 0;
    for (int i = 0; i < n; ++i) {
        if (cc[i] == -1 && !graph[i].empty()) {
            ans += dfs(i, ccc++);
        }
    }
    ans += ccc;
    return ans;
}

int main() {
    #ifdef LOCAL_RUN
    freopen("task.in", "r", stdin);
    freopen("task.out", "w", stdout);
    //freopen("task.err", "w", stderr);
    #endif // ONLINE_JUDGE
    ios::sync_with_stdio(false);
    cin.tie(0);

    int n;
    cin >> n;
    vector<int> a(n), b(n);
    for (int i = 0; i < n; ++i) {
        cin >> a[i];
    }
    for (int i = 0; i < n; ++i) {
        cin >> b[i];
    }
    const int INF = 0x3f3f3f3f;
    int ans = INF;
    if (sorted(a) == sorted(b)) {
        ans = solve(a, b);
        set<int> s;
        int x = 0;
        for (int val: a) x ^= val;
        for (int i = 0; i < n; ++i) {
            if (a[i] != b[i] && a[i] == x) {
                ans--;
                break;
            }
        }
        cout << ans << '\n';
    } else {
        map<int, int> ma, mb;
        int x = 0;
        for (int val: a) x ^= val;
        for (int val: a) ma[val]++;
        for (int val: b) mb[val]++;
        int add = 0;
        for (const pair<int, int>& p: ma) {
            add += max(0, p.second - mb[p.first]);
        }
        if (add > 1) {
            noSol();
        }
        int bad = -1;
        for (const pair<int, int>& p: ma) {
            if (p.second > mb[p.first]) {
                bad = p.first;
                break;
            }
        }
        if (bad == x) {
            noSol();
        }
        int pos = -1;
        for (int i = 0; i < n; ++i) {
            if (a[i] == bad && a[i] != b[i] && b[i] != x) {
                pos = i;
                swap(x, a[i]);
                break;
            }
        }
        if (pos != -1) {
            int ans = solve(a, b) - 1;
            for (int i = 0; i < n; ++i) {
                if (a[i] != b[i] && a[i] == x && cc[i] != cc[pos]) {
                    ans--;
                    break;
                }
            }
            cout << ans << '\n';
        } else {
            for (int i = 0; i < n; ++i) {
                if (a[i] == bad && a[i] != b[i]) {
                    pos = i;
                    swap(x, a[i]);
                    break;
                }
            }
            int ans = solve(a, b) + 1;
            for (int i = 0; i < n; ++i) {
                if (a[i] == a[pos]) {
                    ans--;
                    break;
                }
            }
            for (int i = 0; i < n; ++i) {
                if (a[i] != b[i] && a[i] == x && cc[i] != cc[pos]) {
                    ans--;
                    break;
                }
            }
            cout << ans << '\n';
        }
    }
}