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 Rust (1.15.1) (judge verdict: Accepted)

#![allow(unused_imports)]
use std::io;
use std::cmp::*;
use std::collections::*;
#[allow(dead_code)]
const M: i64 = 1e9 as i64 + 7;

fn read_line() -> String {
    let stdin = io::stdin();
    let mut buf = String::new();
    stdin.read_line(&mut buf).unwrap();
    buf
}
#[allow(dead_code)]
fn read<T>() -> T where T: std::str::FromStr, T::Err : std::fmt::Debug {
    read_line().trim().parse().unwrap()
}
#[allow(dead_code)]
fn readv<T>() -> Vec<T> where T: std::str::FromStr, T::Err : std::fmt::Debug {
    read_line().split(' ').map(|a| a.trim().parse().unwrap()).collect()
}

use std::time::Instant;
fn main() {
    let _ = read::<usize>();
    let aa = readv::<usize>();
    let bb = readv::<usize>();
    let x = aa.iter().fold(0, |acc, &a| acc ^ a);
    let (mut aa, bb): (Vec<_>, Vec<_>) = aa.iter().zip(bb.iter()).filter(|&(&a, &b)| a != b).unzip();
    let n = aa.len();
    aa.push(x);
    let mut nums = HashMap::with_capacity(n + 1);
    for &a in &aa {
        *nums.entry(a).or_insert(0) += 1;
    }
    // let mut nums: HashMap<_, i32> = aa.iter()
    //     .fold(HashMap::with_capacity(n + 1), |mut acc, &a| { *acc.entry(a).or_insert(0) += 1; acc });
    for &b in &bb {
        *nums.entry(b).or_insert(0) -= 1;
        if nums[&b] < 0 {
            println!("{}", -1);
            return;
        }
    }

    let mut dests = bb.iter().enumerate()
        .fold(HashMap::new(), |mut acc, (a, b)| { (acc.entry(b).or_insert(Vec::new())).push(a); acc });
    let mut q: VecDeque<_> = std::iter::once(n).collect();
    let mut q2: VecDeque<_> = std::iter::once(n).collect();
    let mut rems: BTreeSet<_> = (0..n + 1).collect();
    let mut r2: HashSet<_> = (0..n + 1).collect();
    let mut ans = n;
    #[cfg(local)] println!("{}: {:?}", "(aa, bb)", (&aa, &bb));
    let mut cnt = 1;
    while !rems.is_empty() {
        if let Some(s_idx) = q2.pop_front() {
            cnt += s_idx;
        }
        while let Some(s_idx) = q.pop_front() {
            r2.remove(&s_idx);
            if !rems.remove(&s_idx) { continue; }
            let s_num = aa[s_idx];
            if let Some(destv) = dests.remove(&s_num) {
                for dest in destv {
                    q.push_back(dest);
                }
            }
        }
        if let Some(&rem) = rems.iter().next() {
            q.push_back(rem);
            ans += 1;
        }
        if let Some(&r) = r2.iter().next() {
            q2.push_back(r);
        }
    }
    if cnt > 1e18 as usize{
        println!("{}", "hoge");
    }
    println!("{}", ans);
}