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::<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<_, i32> = aa.iter()
        .fold(HashMap::new(), |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 mp = aa.iter().collect::<BTreeSet<_>>().into_iter().enumerate()
        .map(|(a, b)| (b, a)).collect::<HashMap<_, _>>();
    let a2: Vec<_> = aa.iter().map(|a| mp[a]).collect();
    let b2: Vec<_> = bb.iter().map(|b| mp[b]).collect();
    // let mut dests = b2.iter().enumerate()
    //     .fold(HashMap::new(), |mut acc, (a, b)| { (acc.entry(b).or_insert(Vec::new())).push(a); acc });
    let mut dests: Vec<Vec<_>> = b2.iter().enumerate()
        .fold(vec![Vec::new(); n + 1], |mut acc, (a, &b)| { acc[b].push(a); acc });
    let mut q: VecDeque<_> = std::iter::once(n).collect();
    let mut rems: HashSet<_> = (0..n + 1).collect();
    let mut ans = n;
    #[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];
            for &dest in &dests[s_num] {
                q.push_back(dest);
            }
            dests[s_num].clear();
            // 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;
        }
    }
    println!("{}", ans);
}