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()
}

fn main() {
    let _ = read::<i32>();
    let aa = readv::<i32>();
    let bb = readv::<i32>();
    let x = aa.iter().fold(0, |acc, &a| acc ^ a);
    let mut a2: HashMap<i32, i32> = HashMap::new();
    // let (aa, bb) = aa.iter().zip(bb.iter()).filter(|a, b| a != b).unzip();
    let (mut aa, bb): (Vec<i32>, Vec<i32>) = aa.iter().zip(bb.iter()).filter(|&(&a, &b)| a != b).unzip();
    let n = aa.len() as i32;
    aa.push(x);
    for &a in &aa {
        *a2.entry(a).or_insert(0) += 1;
    }
    for &b in &bb {
        match a2.get(&b) {
            Some(&rem) if rem > 0 => { a2.insert(b, rem - 1); },
            _ => {
                println!("{}", -1);
                return;
            }
        };
    }
    // #[cfg(local)] println!("{}: {:?}", "a2", a2);

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