Problem:
Score : 600 points

Problem Statement

Given are two sequences a=\{a_0,\ldots,a_{N-1}\} and b=\{b_0,\ldots,b_{N-1}\} of N non-negative integers each.

Snuke will choose an integer k such that 0 \leq k < N and an integer x not less than 0, to make a new sequence of length N, a'=\{a_0',\ldots,a_{N-1}'\}, as follows:

a_i'= a_{i+k \mod N}\ XOR \ x

Find all pairs (k,x) such that a' will be equal to b.

What is \mbox{ XOR }?

The XOR of integers A and B, A \mbox{ XOR } B, is defined as follows:

When A \mbox{ XOR } B is written in base two, the digit in the 2^k's place (k \geq 0) is 1 if either A or B, but not both, has 1 in the 2^k's place, and 0 otherwise.

For example, 3 \mbox{ XOR } 5 = 6. (In base two: 011 \mbox{ XOR } 101 = 110.)

Constraints

1 \leq N \leq 2 \times 10^5

0 \leq a_i,b_i < 2^{30}

All values in input are integers.

Input

Input is given from Standard Input in the following format:

N
a_0 a_1 ... a_{N-1}
b_0 b_1 ... b_{N-1}

Output

Print all pairs (k, x) such that a' and b will be equal, using one line for each pair, in ascending order of k (ascending order of x for pairs with the same k).

If there are no such pairs, the output should be empty.

Sample Input 1

3
0 2 1
1 2 3

Sample Output 1

1 3

If (k,x)=(1,3),

a_0'=(a_1\ XOR \ 3)=1

a_1'=(a_2\ XOR \ 3)=2

a_2'=(a_0\ XOR \ 3)=3

and we have a' = b.

Sample Input 2

5
0 0 0 0 0
2 2 2 2 2

Sample Output 2

0 2
1 2
2 2
3 2
4 2

Sample Input 3

6
0 1 3 7 6 4
1 5 4 6 2 3

Sample Output 3

2 2
5 5

Sample Input 4

2
1 2
0 0

Sample Output 4

No pairs may satisfy the condition.

Solution in C++14 (GCC 5.4.1) (judge verdict: Wrong Answer)

#pragma GCC optimize("Ofast")
#define _USE_MATH_DEFINES
#include "bits/stdc++.h"

using namespace std;

using u8 = uint8_t;
using u16 = uint16_t;
using u32 = uint32_t;
using u64 = uint64_t;
using i8 = int8_t;
using i16 = int16_t;
using i32 = int32_t;
using i64 = int64_t;

constexpr char newl = '\n';
constexpr double eps = 1e-10;

#define FOR(i,a,b) for (int i = (a); i < (b); i++)
#define F0R(i,b) FOR(i,0,b)
#define RFO(i,a,b) for (int i = ((b)-1); i >=(a); i--)
#define RF0(i,b) RFO(i,0,b)
//#define fi first
//#define se second
#define debug(x) cout << #x << ": " << x << '\n';
#define rng(a) a.begin(),a.end()
#define rrng(a) a.rbegin(),a.rend()

template<typename T1, typename T2> inline void chmin(T1& a, T2 b) { if (a > b) a = b; }
template<typename T1, typename T2> inline void chmax(T1& a, T2 b) { if (a < b) a = b; }
template<class T> void Print(vector<T> v) {
  F0R(i, v.size()) {
    cout << v[i] << ' ';
  }
  cout << newl;
}

#if 1



// INSERT ABOVE HERE
signed main() {
  cin.tie(0);
  ios_base::sync_with_stdio(false);

  int N;
  cin >> N;

  vector<u64> as(N), bs(N);
  F0R(i, N) {
    cin >> as[i];
  }
  F0R(i, N) {
    cin >> bs[i];
  }

  // 全探索 O(N^2)
#if 0
  F0R(k, N) {

    u64 x = as[k] ^ bs[0];
    bool match = true;
    FOR(i, 1, N) {
      int ik = i + k;
      if (ik > N - 1) ik -= N;

      if ((as[ik] ^ bs[i]) != x) {
        match = false;
        break;
      }
    }

    if (match) {
      cout << k << ' ' << x << newl;
    }
  }
#endif

  // 数列の、前後の数のxorをとる

  // A = a0^a1, a1^a2 ... aN-1^a0
  // B = b0^b1, b1^b2 ... bN-1^b0

  // すると、 A[i] == B[(i+k)%N] になるパターンを探せば良いだけになる

  // さて複数位置一致する場合は、AもBもともに、ある数列の n 回の繰り返しになっていないといけない
  // A = C x n, B = D x n
  // C[i] == B[(i+l)%(N/n)]

  vector<u64> cs(N), ds(N);
  cs[0] = as.back()^as[0];
  F0R(i, N-1) {
    cs[i+1] = as[i] ^ as[i + 1];
  }
  ds[0] = bs.back() ^ bs[0];
  F0R(i, N - 1) {
    ds[i+1] = bs[i] ^ bs[i + 1];
  }

  // 先頭からの文字列が、途中から反復していないか、
  // していればその文字数を記録する
  // ABCDABD
  // 0000120
  vector<int> ts(N);
  ts[0] = 0;
  FOR(i, 1, N) {
    int r = ts[i - 1];
    while (true) {
      if (ds[r] == ds[i]) {
        ts[i] = r + 1;
        break;
      }
      if (r == 0) {
        ts[i] = 0;
        break;
      }
      r = ts[r - 1];
    }
  }

  // cs内からdsを探す
  int skip = 0;
  for(int i=0;i<N;/*NOP*/) {

    bool match = true;
    FOR(j, skip, N) {
      int k = j + i;
      if (k >= N) k -= N;
      if (ds[j] != cs[k]) {
        match = false;

        i += j + 1;
        if (j > 0) {
          i -= ts[j - 1];
          skip = ts[j - 1];
        }
        else {
          skip = 0;
        }
        break;
      }
    }

    if (match) {
      cout << i << " " << (bs[0] ^ as[i]) << newl;
      i += N - ts.back();
      skip = ts.back();
    }
  }
}
#endif