AtCoder Beginner Contest 150 - Xor Shift

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-----
3
0 2 1
1 2 3

-----Sample Output-----
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.

Source: atcoder | Difficulty: MEDIUM_HARD


Solutions:
LI = lambda : list(map(int, input().split()))
N = int(input())
A = LI()
B = LI()

def main():
	s = [A[i] ^ A[(i + 1) % N] for i in range(N)]
	t = [B[i] ^ B[(i + 1) % N] for i in range(N)] * 2
	w = [0] * N
	for i in range(1, N):
		j = w[i - 1]
		while j != 0 and s[i] != s[j]:
			j = w[j - 1]
		if s[i] == s[j]:
			w[i] = j + 1
		else:
			w[i] = 0
	k_list = []
	(i, j) = (0, 0)
	while i < N:
		while j < N and t[i + j] == s[j]:
			j += 1
		if j == N:
			k_list.append(-i % N)
		if j == 0:
			i += 1
		else:
			i += j - w[j - 1]
	k_list.sort()
	for k in k_list:
		x = A[k] ^ B[0]
		print(k, x)
main()


N = int(input())
A = [int(a) for a in input().split()]
B = [int(a) for a in input().split()]
AA = [A[i] ^ A[i - 1] for i in range(N)]
BB = [B[i] ^ B[i - 1] for i in range(N)]
P = 8128812823
K = 8128
invK = pow(K, P - 2, P)
KN = pow(K, N, P)
s = 0
for i in range(N):
	s = (s * K + AA[i]) % P
t = 0
for b in BB:
	t = (t * K + b) % P
ans = 0
for i in range(N)[::-1]:
	if t == s:
		j = N - 1 - i
		print(j, A[j] ^ B[0])
	t = (t + BB[i] * (KN - 1)) * invK % P


num = int(input())
a = list(map(int, input().split()))
b = list(map(int, input().split()))
c = []
d = []
for i in range(num):
	c.append(a[i] ^ a[(i + 1) % num])
	d.append(b[i] ^ b[(i + 1) % num])
c += c
table = [0]
k = 0
for i in range(1, num + 1):
	table.append(k)
	if i == num:
		continue
	if d[i] == d[k]:
		k += 1
	else:
		k = 0
i = 0
j = 0
k = 0
while k < num:
	while True:
		if c[i] == d[j]:
			if j == num - 1:
				print(k, a[k] ^ b[0])
				i += 1
				j = table[num]
				k = i - j
				break
			i += 1
			j += 1
		elif j != 0:
			j -= 1
		else:
			i += 1
			j = table[j]
			break
	k = i - j


n = int(input())
a = list(map(int, input().split()))
b = list(map(int, input().split()))
axor = [0] * n
bxor = [0] * n
for i in range(n - 1):
	axor[i] = a[i] ^ a[i + 1]
	bxor[i] = b[i] ^ b[i + 1]
axor[-1] = a[0] ^ a[-1]
bxor[-1] = b[0] ^ b[-1]

def MP(it):
	n = len(it)
	res = [0] * (n + 1)
	res[0] = -1
	j = -1
	for i in range(n):
		while j >= 0 and it[i] != it[j]:
			j = res[j]
		j += 1
		res[i + 1] = j
	return res
mp = MP(bxor)
txt = axor + axor
pattern = bxor
ans = list()
j = 0
for i in range(2 * n - 1):
	while j >= 0 and pattern[j] != txt[i]:
		j = mp[j]
	j += 1
	if j == n:
		k = i - j + 1
		x = b[0] ^ a[k]
		ans.append([k, x])
		j = mp[j]
for (k, x) in ans:
	print(k, x)


N = int(input())
A = list(map(int, input().split()))
B = list(map(int, input().split()))
A.append(A[0])
B.append(B[0])
AX = []
BX = []
for i in range(N):
	AX.append(A[i] ^ A[i + 1])
	BX.append(B[i] ^ B[i + 1])
AX += AX[:-1]
LEN = len(BX)
MP = [-1] * (LEN + 1)
NOW = -1
for i in range(LEN):
	while NOW >= 0 and BX[i] != BX[NOW]:
		NOW = MP[NOW]
	NOW += 1
	MP[i + 1] = NOW
LEN2 = len(AX)
MP_SEARCH = [0] * LEN2
NOW = 0
for i in range(LEN2):
	while NOW >= 0 and AX[i] != BX[NOW]:
		NOW = MP[NOW]
	NOW += 1
	MP_SEARCH[i] = NOW
	if NOW == LEN:
		NOW = MP[NOW]
for i in range(LEN2):
	if MP_SEARCH[i] == LEN:
		print(i - LEN + 1, A[i - LEN + 1] ^ B[0])


class RollingHash(object):
	__base1 = 1007
	__mod1 = 10 ** 9
	__base2 = 1009
	__mod2 = 10 ** 7

	def __init__(self, s):
		n = len(s)
		self.__s = s
		self.__n = n
		b1 = self.__base1
		m1 = self.__mod1
		b2 = self.__base2
		m2 = self.__mod2
		(H1, H2) = ([0] * (n + 1), [0] * (n + 1))
		(P1, P2) = ([1] * (n + 1), [1] * (n + 1))
		for i in range(n):
			H1[i + 1] = (H1[i] * b1 + s[i]) % m1
			H2[i + 1] = (H2[i] * b2 + s[i]) % m2
			P1[i + 1] = P1[i] * b1 % m1
			P2[i + 1] = P2[i] * b2 % m2
		self.__H1 = H1
		self.__H2 = H2
		self.__P1 = P1
		self.__P2 = P2

	@property
	def str(self):
		return self.__s

	@property
	def len(self):
		return self.__n

	def hash(self, l, r=None):
		m1 = self.__mod1
		m2 = self.__mod2
		if r is None:
			r = self.__n
		assert 0 <= l <= r <= self.__n
		hash1 = (self.__H1[r] - self.__P1[r - l] * self.__H1[l] % m1) % m1
		hash2 = (self.__H2[r] - self.__P2[r - l] * self.__H2[l] % m2) % m2
		return (hash1, hash2)

	@classmethod
	def lcp(cls, rh1, rh2, l1, l2, r1=None, r2=None):
		if r1 is None:
			r1 = rh1.__n
		if r2 is None:
			r2 = rh2.__n
		assert 0 <= l1 <= r1 <= rh1.__n and 0 <= l2 <= r2 <= rh2.__n
		L = 0
		R = min(r1 - l1, r2 - l2)
		if rh1.hash(l1, l1 + R) == rh2.hash(l2, l2 + R):
			return R
		while R - L > 1:
			H = (L + R) // 2
			if rh1.hash(l1, l1 + H) == rh2.hash(l2, l2 + H):
				L = H
		else:
			R = H
		return L

	@classmethod
	def search(cls, pattern, text):
		n = text.__n
		m = pattern.__n
		res = []
		for i in range(n - m + 1):
			if text.hash(i, i + m) == pattern.hash(0, m):
				res.append(i)
		return res

def resolve():
	N = int(input())
	A = list(map(int, input().split()))
	B = list(map(int, input().split()))
	dA = [A[i] ^ A[(i + 1) % N] for i in range(N)]
	dB = [B[i] ^ B[(i + 1) % N] for i in range(N)]
	dA += dA
	RHa = RollingHash(dA)
	RHb = RollingHash(dB)
	query = RHb.hash(0, N - 1)
	ans = []
	for i in range(N):
		val = RHa.hash(i, i + N - 1)
		if val == query:
			ans.append((i, A[i] ^ B[0]))
	ans.sort()
	for (k, x) in ans:
		print(k, x)
resolve()


import sys
input = sys.stdin.readline
n = int(input())
A = tuple(map(int, input().split()))
B = tuple(map(int, input().split()))
C = [0] * (3 * n)
for i in range(n):
	C[i] = B[i] ^ B[(i + 1) % n]
	C[i + n] = A[i] ^ A[(i + 1) % n]
	C[i + n + n] = C[i + n]

def z_algo(S):
	N = len(S)
	A = [0] * N
	A[0] = N
	(i, j) = (1, 0)
	while i < N:
		while i + j < N and S[j] == S[i + j]:
			j += 1
		A[i] = j
		if not j:
			i += 1
			continue
		k = 1
		while i + k < N and k + A[k] < j:
			A[i + k] = A[k]
			k += 1
		i += k
		j -= k
	return A
P = z_algo(C)
for (i, p) in enumerate(P[n:n + n]):
	if p >= n:
		x = A[i] ^ B[0]
		print(i, x)


class KMP:

	def __init__(self, P):
		self.P = P
		self.N = len(P)
		self.T = [0] * (self.N + 1)
		self._compile()

	def _compile(self):
		j = 0
		self.T[0] = -1
		for i in range(1, self.N):
			self.T[i] = j
			j += 1 if self.P[i] == self.P[j] else -j
		self.T[self.N] = j

	def search(self, S):
		NS = len(S)
		i = m = 0
		A = []
		while m + i < NS:
			if self.P[i] == S[m + i]:
				i += 1
				if i != self.N:
					continue
				A.append(m)
			m += i - self.T[i]
			i = max(0, self.T[i])
		return A
N = int(input())
A = list(map(int, input().split()))
B = list(map(int, input().split()))
C = [A[i] ^ A[(i + 1) % N] for i in range(N)]
D = [B[i] ^ B[(i + 1) % N] for i in range(N)]
C = C + C[:-1]
K = KMP(D).search(C)
for k in K:
	print(k, A[k] ^ B[0])


n = int(input())
a = list(map(int, input().split()))
a += a
b = list(map(int, input().split()))
aa = [a[i - 1] ^ a[i] for i in range(1, n * 2)]
bb = [b[i - 1] ^ b[i] for i in range(1, n)]
s = bb + aa
from random import randint
roli_mod = 1370757747362922367
roli_r = 1
roli_table = [0]
roli_rr = 1
for i in range(3 * (n - 1)):
	roli_table.append((roli_table[-1] + roli_rr * s[i]) % roli_mod)
	roli_rr *= roli_r
	roli_rr %= roli_mod

def roli_hash(i, j):
	return (roli_table[j + 1] - roli_table[i] + roli_mod) % roli_mod * pow(roli_r, roli_mod - 1 - i, roli_mod) % roli_mod

def roli_check(i1, j1, i2, j2):
	return roli_hash(i1, j1) == roli_hash(i2, j2)
ans = []
for k in range(n - 1, 2 * (n - 1) + 1):
	if roli_check(0, n - 2, k, k + (n - 1) - 1):
		ans.append(k - (n - 1))
for i in ans:
	print(i, a[i] ^ b[0])


import sys
from collections import Counter, defaultdict
buff_readline = sys.stdin.buffer.readline
readline = sys.stdin.readline

def read_int():
	return int(buff_readline())

def read_int_n():
	return list(map(int, buff_readline().split()))
gpw = None

class RH:

	def __init__(self, s, base, mod):
		self.base = base
		self.mod = mod
		l = len(s)
		self.h = h = [0] * (l + 1)
		tmp = 0
		for i in range(l):
			tmp = (tmp * base + s[i]) % mod
			h[i + 1] = tmp
		global gpw
		if gpw is None:
			self.pw = pw = [1] * (len(s) + 1)
			v = 1
			for i in range(l):
				pw[i + 1] = v = v * base % mod
			gpw = pw
		else:
			self.pw = gpw

	def calc(self, l, r):
		return (self.h[r] - self.h[l] * self.pw[r - l]) % self.mod

def slv(N, A, B):
	L = max(max(A), max(B)).bit_length()
	ah = []
	bh = []
	bnh = []
	for i in range(L):
		ta = []
		tb = []
		tbn = []
		for (a, b) in zip(A, B):
			ta.append(a >> i & 1)
			tb.append(b >> i & 1)
			tbn.append(tb[-1] ^ 1)
		ah.append(RH(ta, 641, 10 ** 9 + 7))
		bh.append(RH(tb, 641, 10 ** 9 + 7))
		bnh.append(RH(tbn, 641, 10 ** 9 + 7))
	ans = []
	x = [0] * N
	for i in range(L):
		for k in range(N):
			l = ah[i].calc(k, N)
			r = ah[i].calc(0, k)
			if x[k] is None:
				continue
			if l == bnh[i].calc(0, N - k) and r == bnh[i].calc(N - k, N):
				x[k] += 1 << i
			elif l == bh[i].calc(0, N - k) and r == bh[i].calc(N - k, N):
				pass
			else:
				x[k] = None
	for (k, xx) in enumerate(x):
		if xx is not None:
			ans.append('%d %d' % (k, xx))
	return ans

def main():
	N = read_int()
	A = read_int_n()
	B = read_int_n()
	print(*slv(N, A, B), sep='\n')
main()


import sys
read = sys.stdin.buffer.read
readline = sys.stdin.buffer.readline
readlines = sys.stdin.buffer.readlines
(n, *lst) = map(int, read().split())
al = lst[:n]
bl = lst[n:]

def convert(A):
	return [x ^ y for (x, y) in zip(A, A[1:])] + [A[-1] ^ A[0]]
a = convert(al)
b = convert(bl)

def Z_algorithm(s):
	n = len(s)
	z = [0] * n
	(l, r) = (0, 0)
	for i in range(1, n):
		if i <= r:
			z[i] = z[i - l] if z[i - l] < r - i else r - i - 1
		while i + z[i] < n and s[z[i]] == s[i + z[i]]:
			z[i] += 1
		if i + z[i] - 1 > r:
			(l, r) = (i, i + z[i] - 1)
	return z
Z = Z_algorithm(b + [-1] + a + a)[n + 1:n + n + 1]
K = [i for (i, x) in enumerate(Z) if x == n]
X = [al[k] ^ bl[0] for k in K]
print('\n'.join(('{} {}'.format(k, x) for (k, x) in zip(K, X))))


from collections import defaultdict, deque
from heapq import heappush, heappop
from itertools import permutations
import sys
import math
import bisect
import random

def LI():
	return [int(x) for x in sys.stdin.readline().split()]

def I():
	return int(sys.stdin.readline())

def LS():
	return [list(x) for x in sys.stdin.readline().split()]

def S():
	res = list(sys.stdin.readline())
	if res[-1] == '\n':
		return res[:-1]
	return res

def IR(n):
	return [I() for i in range(n)]

def LIR(n):
	return [LI() for i in range(n)]

def SR(n):
	return [S() for i in range(n)]

def LSR(n):
	return [LS() for i in range(n)]
sys.setrecursionlimit(1000000)
mod = 1000000007

def solve():

	def Z_algorithm(s):
		n = len(s)
		z = [0] * n
		z[0] = n
		c = 1
		for i in range(1, n):
			if i + z[i - c] < c + z[c]:
				z[i] = z[i - c]
			else:
				j = max(0, c + z[c] - i)
				while i + j < n and s[j] == s[i + j]:
					j += 1
				z[i] = j
				c = i
		return z
	n = I()
	a = LI()
	b = LI()
	a_xor = [a[i % n] ^ a[(i + 1) % n] for i in range(2 * n)]
	b_xor = [b[i % n] ^ b[(i + 1) % n] for i in range(n)]
	b_xor += a_xor
	z = Z_algorithm(b_xor)
	for k in range(n):
		i = n + k
		x = b[0] ^ a[k]
		if z[i] >= n:
			print(k, x)
	return
solve()


class MP:

	def __init__(self, p):
		self.pattern = p
		n = len(p)
		A = [-1] * (n + 1)
		j = -1
		for i in range(n):
			while j >= 0 and p[j] != p[i]:
				j = A[j]
			j += 1
			A[i + 1] = j
		self.border = A

	def findall(self, t):
		p = self.pattern
		A = self.border
		res = list()
		j = 0
		for i in range(len(t)):
			while j >= 0 and p[j] != t[i]:
				j = A[j]
			j += 1
			if j == len(p):
				res.append(i - j + 1)
				j = A[j]
		return res
n = int(input())
a = list(map(int, input().split()))
b = list(map(int, input().split()))
axor = [0] * n
bxor = [0] * n
for i in range(n - 1):
	axor[i] = a[i] ^ a[i + 1]
	bxor[i] = b[i] ^ b[i + 1]
axor[-1] = a[0] ^ a[-1]
bxor[-1] = b[0] ^ b[-1]
m = MP(bxor)
kls = m.findall(axor + axor[:-1])
for k in kls:
	x = b[0] ^ a[k]
	print(k, x)


def main():
	import sys
	input = sys.stdin.readline
	N = int(input())
	A = list(map(int, input().split()))
	B = list(map(int, input().split()))
	A.extend(A)
	mod1 = 10 ** 9 + 7
	mod2 = 10 ** 9 + 9
	b1 = 1007
	b2 = 2009
	H1 = H2 = 0
	for i in range(N - 1):
		tmp = B[i] ^ B[i + 1]
		H1 = (H1 + pow(b1, N - i - 2, mod1) * tmp) % mod1
		H2 = (H2 + pow(b2, N - i - 2, mod2) * tmp) % mod2
	h1 = h2 = 0
	for i in range(N - 1):
		tmp = A[i] ^ A[i + 1]
		h1 = (h1 + pow(b1, N - i - 2, mod1) * tmp) % mod1
		h2 = (h2 + pow(b2, N - i - 2, mod2) * tmp) % mod2
	if h1 == H1 and h2 == H2:
		print(0, A[0] ^ B[0])
	for k in range(1, N):
		tmp_plus = A[N + k - 2] ^ A[N + k - 1]
		tmp_minus = A[k - 1] ^ A[k]
		h1 = (h1 * b1 % mod1 + tmp_plus - tmp_minus * pow(b1, N - 1, mod1) % mod1) % mod1
		h2 = (h2 * b2 % mod2 + tmp_plus - tmp_minus * pow(b2, N - 1, mod2) % mod2) % mod2
		if h1 == H1 and h2 == H2:
			print(k, A[k] ^ B[0])
main()


class RollingHash:

	def __init__(self, s, base, mod):
		self.mod = mod
		self.pw = pw = [1] * (len(s) + 1)
		l = len(s)
		self.h = h = [0] * (l + 1)
		v = 0
		for i in range(l):
			h[i + 1] = v = (v * base + s[i]) % mod
		v = 1
		for i in range(l):
			pw[i + 1] = v = v * base % mod

	def get(self, l, r):
		return (self.h[r] - self.h[l] * self.pw[r - l]) % self.mod
N = int(input())
a = [int(i) for i in input().split()]
b = [int(i) for i in input().split()]
c = [a[i % N] ^ a[(i + 1) % N] for i in range(2 * N)]
d = [b[i] ^ b[(i + 1) % N] for i in range(N)]
P = RollingHash(c, 97, 10 ** 9 + 7)
Q = RollingHash(d, 97, 10 ** 9 + 7)
for k in range(N):
	if P.get(k, k + N) == Q.get(0, N):
		x = b[0] ^ a[k]
		print(k, x)


import sys
(BASE, MOD1, MOD2) = (1 << 30, (1 << 61) - 1, (1 << 31) - 1)

class RollingHash:

	def __init__(self, s, base, mod):
		self.mod = mod
		self.pw = pw = [1] * (len(s) + 1)
		l = len(s)
		self.h = h = [0] * (l + 1)
		v = 0
		for i in range(l):
			h[i + 1] = v = (v * base + s[i]) % mod
		v = 1
		for i in range(l):
			pw[i + 1] = v = v * base % mod

	def get(self, l, r):
		return (self.h[r] - self.h[l] * self.pw[r - l]) % self.mod

	def concatenate(self, l1, r1, l2, r2):
		return (self.get(l1, r1) * self.pw[r2 - l2] + self.get(l2, r2)) % self.mod
n = int(input())
a = list(map(int, input().split()))
b = list(map(int, input().split()))
if n == 1:
	print(0, a[0] ^ b[0])
	sys.exit()
x = [a[n - 1] ^ a[0]]
y = [b[n - 1] ^ b[0]]
for i in range(n - 1):
	x.append(a[i] ^ a[i + 1])
	y.append(b[i] ^ b[i + 1])
(rh1_x, rh1_y) = (RollingHash(x, BASE, MOD1), RollingHash(y, BASE, MOD1))
(rh2_x, rh2_y) = (RollingHash(x, BASE, MOD2), RollingHash(y, BASE, MOD2))
for k in range(n):
	if rh1_y.concatenate(n - k, n, 0, n - k) == rh1_x.get(0, n) and rh2_y.concatenate(n - k, n, 0, n - k) == rh2_x.get(0, n):
		print(k, a[0] ^ b[(n - k) % n])


def divisors(M):
	import math
	d = []
	i = 1
	while math.sqrt(M) >= i:
		if M % i == 0:
			d.append(i)
			if i ** 2 != M:
				d.append(M // i)
		i = i + 1
	d.sort()
	return d
import numpy as np
N = int(input())
a = list(map(int, input().split()))
b = list(map(int, input().split()))
A = np.array([a[i] ^ a[i - 1] for i in range(0, N)])
B = np.array([b[i] ^ b[i - 1] for i in range(0, N)])
d = divisors(N)
perioda = N
for i in range(0, len(d)):
	test = np.roll(A, -d[i])
	if all(test == A):
		perioda = min(perioda, d[i])
periodb = N
for i in range(0, len(d)):
	test = np.roll(B, -d[i])
	if all(test == B):
		periodb = min(periodb, d[i])
if perioda == periodb:
	A = A[:perioda]
	B = B[:periodb]
	kouho = []
	for i in range(0, len(B)):
		if A[i] == B[0]:
			kouho.append(i)
	ans = -1
	for i in range(0, len(kouho)):
		test = np.roll(A, -kouho[i])
		if all(test == B):
			ans = kouho[i]
			break
	if ans != -1:
		for i in range(0, N // perioda):
			print(ans + perioda * i, a[ans + perioda * i] ^ b[0])


import sys
read = sys.stdin.buffer.read
readline = sys.stdin.buffer.readline
readlines = sys.stdin.buffer.readlines
N = int(readline())
A = list(map(int, readline().split()))
B = list(map(int, readline().split()))

def convert(A):
	return [x ^ y for (x, y) in zip(A, A[1:])] + [A[-1] ^ A[0]]
C = convert(A)
D = convert(B)

def Z_algorithm(S):
	N = len(S)
	arr = [0] * N
	arr[0] = N
	(i, j) = (1, 0)
	while i < N:
		while i + j < N and S[j] == S[i + j]:
			j += 1
		arr[i] = j
		if not j:
			i += 1
			continue
		k = 1
		while i + k < N and k + arr[k] < j:
			arr[i + k] = arr[k]
			k += 1
		i += k
		j -= k
	return arr
Z = Z_algorithm(D + [-1] + C + C)[N + 1:N + N + 1]
K = [i for (i, x) in enumerate(Z) if x == N]
X = [A[k] ^ B[0] for k in K]
print('\n'.join(('{} {}'.format(k, x) for (k, x) in zip(K, X))))


def main():
	(mod, pow3, pow3i, p) = (2 ** 61 - 1, [1] * 400001, [1] * 200001, 1)
	i3 = pow(3, mod - 2, mod)
	for i in range(1, 400001):
		pow3[i] = p = p * 3 % mod
	p = 1
	for i in range(1, 200001):
		pow3i[i] = p = p * i3 % mod

	class rolling_hash:

		def __init__(self, seq, char_list=None):
			seq_size = self.seq_size = len(seq)
			mod = self.mod = 2 ** 61 - 1
			Hash = self.Hash = [0] * (seq_size + 1)
			for i in range(seq_size):
				Hash[i + 1] = (Hash[i] + (seq[i] + 1) * pow3[i]) % mod

		def calc_hash(self, l, r):
			return (self.Hash[r] - self.Hash[l]) * pow3i[l] % self.mod
	n = int(input())
	(a, b) = (list(map(int, input().split())), list(map(int, input().split())))
	memo = []
	a1 = rolling_hash([a[i - 1] ^ a[i] for i in range(n)] + [a[i - 1] ^ a[i] for i in range(n)])
	b_hash = rolling_hash([b[i - 1] ^ b[i] for i in range(n)]).calc_hash(0, n)
	for i in range(n):
		if a1.calc_hash(i, i + n) == b_hash:
			memo.append(i)
	b0 = b[0]
	for i in memo:
		x = b0 ^ a[i]
		print(i, x)
main()


import sys
input = sys.stdin.readline
N = int(input())
a = list(map(int, input().split()))
b = list(map(int, input().split()))

class KmpSearch:

	def __init__(self, word):
		self.word = word
		self.table = [0] * (len(word) + 1)
		self.table[0] = -1
		(i, j) = (0, 1)
		while j < len(self.word):
			matched = self.word[i] == self.word[j]
			if not matched and i > 0:
				i = self.table[i]
			else:
				if matched:
					i += 1
				j += 1
				self.table[j] = i

	def search(self, text):
		table = self.table
		word = self.word
		(i, p) = (0, 0)
		res = []
		while i < len(text):
			if text[i] == word[p]:
				i += 1
				p += 1
			elif p == 0:
				i += 1
			else:
				p = table[p]
			if p == len(word):
				res.append(i - p)
				p = table[p]
		return res
xa = [0] * N
xb = [0] * N
for i in range(N):
	xa[i] = a[i - 1] ^ a[i]
	xb[i] = b[i - 1] ^ b[i]
kmp = KmpSearch(xa)
res = kmp.search(xb + xb[:-1])
rres = []
for x in res:
	rres.append(((N - x) % N, a[0] ^ b[x]))
rres.sort(key=lambda x: (x[0], x[1]))
for r in rres:
	print(*r)


import sys
input = sys.stdin.readline
N = int(input())
a = [int(i) for i in input().split()]
b = [int(i) for i in input().split()]

class RollingHash:

	def __init__(self, x, base=26, mod=(1 << 61) - 1):
		self.hash = [0]
		self.pow = [1]
		self.mod = mod
		for xi in x:
			self.hash.append((self.hash[-1] * base + xi) % mod)
			self.pow.append(self.pow[-1] * base % mod)

	def get(self, l, r):
		return (self.hash[r] - self.hash[l] * self.pow[r - l]) % self.mod
da = [a[i] ^ a[(i + 1) % N] for i in range(N)] * 2
db = [b[i] ^ b[(i + 1) % N] for i in range(N)] * 2
RHa1 = RollingHash(da, base=1 << 30)
RHa2 = RollingHash(da, base=1 << 30, mod=(1 << 31) - 1)
RHb1 = RollingHash(db, base=1 << 30)
RHb2 = RollingHash(db, base=1 << 30, mod=(1 << 31) - 1)
hashb1 = RHb1.get(0, N)
hashb2 = RHb2.get(0, N)
for i in range(N):
	if RHa1.get(i, N + i) == hashb1 and RHa2.get(i, N + i) == hashb2:
		print(i, a[i] ^ b[0])


import sys
input = sys.stdin.readline

def Z_algorithm(s):
	N = len(s)
	Z_alg = [0] * N
	Z_alg[0] = N
	i = 1
	j = 0
	while i < N:
		while i + j < N and s[j] == s[i + j]:
			j += 1
		Z_alg[i] = j
		if j == 0:
			i += 1
			continue
		k = 1
		while i + k < N and k + Z_alg[k] < j:
			Z_alg[i + k] = Z_alg[k]
			k += 1
		i += k
		j -= k
	return Z_alg

def main():
	n = int(input())
	a = tuple(map(int, input().split()))
	b = tuple(map(int, input().split()))
	BAA = []
	for i in range(n - 1):
		BAA.append(b[i] ^ b[i + 1])
	BAA.append(b[0] ^ b[-1])
	BAA.append(-1)
	for i in range(n - 1):
		BAA.append(a[i] ^ a[i + 1])
	BAA.append(a[0] ^ a[-1])
	for i in range(n - 1):
		BAA.append(a[i] ^ a[i + 1])
	BAA.append(a[0] ^ a[-1])
	z = Z_algorithm(BAA)
	for k in range(n):
		if z[n + k + 1] >= n:
			print(k, b[0] ^ a[k])
main()


import sys
input = sys.stdin.readline

def KMP(sentence, word):
	ret = []

	def make_table(word):
		n = len(word)
		table = [0] * (n + 1)
		table[0] = -1
		j = -1
		for i in range(n):
			while j >= 0 and word[i] != word[j]:
				j = table[j]
			j += 1
			table[i + 1] = j
		return table
	table = make_table(word)
	sentence_size = len(sentence)
	word_size = len(word)
	m = 0
	i = 0
	while m + i < sentence_size:
		if word[i] == sentence[m + i]:
			i += 1
			if i == word_size:
				ret.append(m)
				m = m + i - table[i]
				i = table[i]
		else:
			m = m + i - table[i]
			if i > 0:
				i = table[i]
	return ret
n = int(input())
arr1 = list(map(int, input().split()))
arr2 = list(map(int, input().split()))
a = []
b = []
for i in range(n):
	a.append(arr1[i] ^ arr1[(i + 1) % n])
	b.append(arr2[i] ^ arr2[(i + 1) % n])
a = (a + a)[:-1]
ks = KMP(a, b)
if len(ks) == 0:
	exit()
ans = []
for k in ks:
	ans.append((k, arr2[0] ^ arr1[k % n]))
ans = sorted(ans, key=lambda x: x[1])
ans = sorted(ans, key=lambda x: x[0])
for (k, x) in ans:
	print(k, x)


def Z_algorithm(s):
	N = len(s)
	Z_alg = [0] * N
	Z_alg[0] = N
	i = 1
	j = 0
	while i < N:
		while i + j < N and s[j] == s[i + j]:
			j += 1
		Z_alg[i] = j
		if j == 0:
			i += 1
			continue
		k = 1
		while i + k < N and k + Z_alg[k] < j:
			Z_alg[i + k] = Z_alg[k]
			k += 1
		i += k
		j -= k
	return Z_alg
N = int(input())
a = list(map(int, input().split()))
b = list(map(int, input().split()))
A = [a[i] ^ a[i - 1] for i in range(0, N)]
B = [b[i] ^ b[i - 1] for i in range(0, N)]
data = B + ['?'] + A + A
s = Z_algorithm(data)
for i in range(N + 1, 2 * N + 1):
	if s[i] >= N:
		print(i - N - 1, a[i - N - 1] ^ b[0])


def Z(S):
	res = [0] * len(S)
	res[0] = len(S)
	i = 1
	j = 0
	while i < len(S):
		while i + j < len(S) and S[j] == S[i + j]:
			j += 1
		res[i] = j
		if j == 0:
			i += 1
			continue
		k = 1
		while i + k < len(S) and k + res[k] < j:
			res[i + k] = res[k]
			k += 1
		i += k
		j -= k
	return res
N = int(input())
a = list(map(int, input().split()))
b = list(map(int, input().split()))
S = [0] * N
T = [0] * N
for i in range(N):
	S[i] = a[i] ^ a[(i + 1) % N]
	T[i] = b[i] ^ b[(i + 1) % N]
s = 0
t = 0
for i in range(N):
	s += S[i]
	t += T[-i - 1]
	if s == t:
		break
ans = []
z = Z(S)
for j in range(N):
	if z[j] == N - j:
		ans.append([(j + i + 1) % N, a[0] ^ b[(-j - i - 1) % N]])
ans.sort()
if s != t:
	ans = []
for s in ans:
	print(*s)


from collections import defaultdict, deque, Counter
from heapq import heappush, heappop, heapify
import math
import bisect
import random
from itertools import permutations, accumulate, combinations, product
import sys
from pprint import pprint
from copy import deepcopy
import string
from bisect import bisect_left, bisect_right
from math import factorial, ceil, floor
from operator import mul
from functools import reduce
from pprint import pprint
sys.setrecursionlimit(2147483647)
INF = 10 ** 15

def LI():
	return list(map(int, sys.stdin.buffer.readline().split()))

def I():
	return int(sys.stdin.buffer.readline())

def LS():
	return sys.stdin.buffer.readline().rstrip().decode('utf-8').split()

def S():
	return sys.stdin.buffer.readline().rstrip().decode('utf-8')

def IR(n):
	return [I() for i in range(n)]

def LIR(n):
	return [LI() for i in range(n)]

def SR(n):
	return [S() for i in range(n)]

def LSR(n):
	return [LS() for i in range(n)]

def SRL(n):
	return [list(S()) for i in range(n)]

def MSRL(n):
	return [[int(j) for j in list(S())] for i in range(n)]
mod = 1000000007

def z_algorithm(S):
	l = len(S)
	A = [0] * l
	i = 1
	j = 0
	while i < l:
		while i + j < l and S[j] == S[i + j]:
			j += 1
		if not j:
			i += 1
			continue
		A[i] = j
		k = 1
		while l - i > k < j - A[k]:
			A[i + k] = A[k]
			k += 1
		i += k
		j -= k
	return A
n = I()
A = LI()
B = LI()
ax = [A[i % n] ^ A[(i + 1) % n] for i in range(2 * n)]
bx = [B[i % n] ^ B[(i + 1) % n] for i in range(n)]
z_box = z_algorithm(bx + ax)
for j in range(n, 2 * n):
	if z_box[j] >= n:
		print(j - n, B[0] ^ A[j - n])


def z_algorithm(s):
	a = [0] * len(s)
	i = 1
	j = 0
	a[0] = len(s)
	while i < len(s):
		while i + j < len(s) and s[j] == s[i + j]:
			j += 1
		a[i] = j
		if j == 0:
			i += 1
			continue
		k = 1
		while i + k < len(s) and k + a[k] < j:
			a[i + k] = a[k]
			k += 1
		i += k
		j -= k
	return a
n = int(input())
a = list(map(int, input().split()))
b = list(map(int, input().split()))
p = [0] * n
q = [0] * n
for i in range(n):
	p[i] = a[i] ^ a[(i + 1) % n]
	q[i] = b[i] ^ b[(i + 1) % n]
test = q + p + p
res = z_algorithm(test)
ans = []
for i in range(n, 2 * n):
	if res[i] >= n:
		ans.append((i - n, a[(i - n) % n] ^ b[0]))
ans = sorted(ans)
for i in ans:
	print(*i)


import sys
INF = float('inf')
B = 10 ** 7 + 7
MOD = 10 ** 9 + 7

def z_algorithm(S):
	N = len(S)
	Z = [0] * N
	c = 0
	for i in range(1, N):
		if i + Z[i - c] < c + Z[c]:
			Z[i] = Z[i - c]
		else:
			j = max(0, c + Z[c] - i)
			while i + j < N and S[j] == S[i + j]:
				j += 1
			Z[i] = j
			c = i
	Z[0] = len(S)
	return Z

def zfindall(text, pattern, separator='$'):
	N = len(pattern)
	conc = pattern + separator + text
	Z = z_algorithm(conc)
	return [i - N - 1 for i in range(len(conc)) if Z[i] == N]

def solve(N: int, a: 'List[int]', b: 'List[int]'):
	c = [a[i] ^ a[(i + 1) % N] for i in range(N)]
	d = [b[i] ^ b[(i + 1) % N] for i in range(N)] * 2
	i = -1
	k_cand = zfindall(d, c, separator=[-1])
	ans = []
	if len(k_cand) == 0:
		return
	if k_cand[0] % N == 0:
		print(0, b[0] ^ a[0])
		for k in k_cand[:0:-1]:
			if k < N:
				print(-k % N, b[0] ^ a[-k % N])
	else:
		for k in k_cand[::-1]:
			if k < N:
				print(-k % N, b[0] ^ a[-k % N])
	return

def main():

	def iterate_tokens():
		for line in sys.stdin:
			for word in line.split():
				yield word
	tokens = iterate_tokens()
	N = int(next(tokens))
	a = [int(next(tokens)) for _ in range(N - 1 - 0 + 1)]
	b = [int(next(tokens)) for _ in range(N - 1 - 0 + 1)]
	solve(N, a, b)
main()


def KMP_table(WW):
	TT = [-1] * (len(WW) + 2)
	ii = 2
	jj = 0
	TT[0] = -1
	TT[1] = 0
	while ii < len(WW) + 1:
		if WW[ii - 1] == WW[jj]:
			TT[ii] = jj + 1
			ii += 1
			jj += 1
		elif jj > 0:
			jj = TT[jj]
		else:
			TT[ii] = 0
			ii += 1
	return TT

def KMP(T):
	ret = -1
	m = 0
	i = 0
	RE = []
	while m + i < len(S):
		if W[i] == S[m + i]:
			i += 1
			if i == len(W):
				RE.append(m)
				m = m + i - T[i]
				if i > 0:
					i = T[i]
		else:
			m = m + i - T[i]
			if i > 0:
				i = T[i]
	return RE
N = int(input())
A = [int(a) for a in input().split()]
B = [int(a) for a in input().split()]
S = ([A[i] ^ A[i - 1] for i in range(N)] * 2)[:-1]
W = [B[i] ^ B[i - 1] for i in range(N)]
T = KMP_table(W)
for i in KMP(T):
	print(i, A[i] ^ B[0])


def main():
	(mod, pow3, p) = (2 ** 31 - 1, [1] * 200001, 1)
	i3 = pow(3, mod - 2, mod)
	for i in range(1, 200001):
		pow3[i] = p = p * 3 % mod

	def rolling_hash(seq):
		h = sum([(i + 1) * j for (i, j) in zip(seq, pow3[:-1])]) % mod
		H0s = [0] * n
		for (i, j) in enumerate(seq):
			H0s[i] = h
			h = (h - j - 1 + (j + 1) * pn) * i3 % mod
		return H0s
	n = int(input())
	(a, b) = (list(map(int, input().split())), list(map(int, input().split())))
	(pn, memo) = (pow3[n], [])
	a1 = [a[i - 1] ^ a[i] for i in range(n)]
	b1 = [b[i - 1] ^ b[i] for i in range(n)]
	b_hash = sum([(i + 1) * j for (i, j) in zip(b1, pow3[:-1])]) % mod
	A1 = rolling_hash(a1)
	for (i, j) in enumerate(A1):
		if j == b_hash:
			memo.append(i)
	b0 = b[0]
	for i in memo:
		x = b0 ^ a[i]
		print(i, x)
main()


import sys
from itertools import combinations, permutations, product, combinations_with_replacement, accumulate
from heapq import heapify, heappop, heappush, heappushpop
from bisect import bisect_left, bisect_right
from collections import Counter, defaultdict, deque
from math import sqrt, log, floor, ceil, factorial, cos, sin, pi
from fractions import gcd
from operator import mul
from functools import reduce
sys.setrecursionlimit(10 ** 8)
input = sys.stdin.readline
INF = float('inf')
LINF = 2 ** 63 - 1
NIL = -LINF
MOD = 10 ** 9 + 7
MGN = 4

def AST(exp: bool, msg: str=''):
	assert exp, msg

def TAST(exp: bool, msg=''):
	if exp is False:
		print('TAssertionError:', msg)
	while exp is False:
		pass

def II():
	return int(input())

def IF():
	return float(input())

def IS():
	return input().replace('\n', '')

def ILCI(n: int):
	return [II() for _ in range(n)]

def ILCF(n: int):
	return [IF() for _ in range(n)]

def ILI():
	return list(map(int, input().split()))

def ILLI(n: int):
	return [[int(j) for j in input().split()] for i in range(n)]

def ILF():
	return list(map(float, input().split()))

def ILLF(n: int):
	return [[float(j) for j in input().split()] for i in range(n)]

def LTOS(lst: list, sep: str=' '):
	return sep.join(map(str, lst))

def DEC(lst: list):
	return list(map(lambda x: x - 1, lst))

def INC(lst: list):
	return list(map(lambda x: x + 1, lst))

def z_algo(S: str) -> list:
	N = len(S)
	if N == 0:
		return []
	ln = [0] * N
	ln[0] = N
	i = 1
	w = 0
	while i < N:
		while i + w < N and S[w] == S[i + w]:
			w += 1
		ln[i] = w
		if w == 0:
			i += 1
		else:
			j = 1
			while i + j < N and j + ln[j] < w:
				ln[i + j] = ln[j]
				j += 1
			i += j
			w -= j
	return ln

def z_algo_search(S: str, W: str) -> list:
	lens = z_algo(W + S)
	if len(lens) == 0:
		return []
	SL = len(S)
	WL = len(W)
	slens = lens[WL:]
	res = []
	for i in range(SL):
		if slens[i] >= WL:
			res.append(i)
	return res

def xor_next(A: list) -> list:
	N = len(A)
	res = []
	for i in range(N - 1):
		res.append(A[i] ^ A[i + 1])
	res.append(A[-1] ^ A[0])
	return res

def main():
	N = II()
	A = ILI()
	B = ILI()
	C = xor_next(A)
	D = xor_next(B)
	pos = z_algo_search(C * 2, D)
	pos = list(filter(lambda x: x < N, pos))
	ans = []
	for i in pos:
		ans.append((i, A[i] ^ B[0]))
	for e in ans:
		print(e[0], e[1])
main()


def partial_match_table(word):
	table = [0] * (len(word) + 1)
	table[0] = -1
	(i, j) = (0, 1)
	while j < len(word):
		matched = word[i] == word[j]
		if not matched and i > 0:
			i = table[i]
		else:
			if matched:
				i += 1
			j += 1
			table[j] = i
	return table

def kmp_search(text, word):
	table = partial_match_table(word)
	(i, p) = (0, 0)
	results = []
	while i < len(text) and p < len(word):
		if text[i] == word[p]:
			i += 1
			p += 1
			if p == len(word):
				p = table[p]
				results.append((i - len(word), i))
		elif p == 0:
			i += 1
		else:
			p = table[p]
	return results
(N,) = map(int, input().split())
As = list(map(int, input().split()))
Bs = list(map(int, input().split()))
A = []
B = []
for i in range(2 * N - 1):
	A.append(As[i % N] ^ As[(i + 1) % N])
	if i < N:
		B.append(Bs[i % N] ^ Bs[(i + 1) % N])
for (k, l) in kmp_search(A, B):
	print(k, As[k] ^ Bs[0])


class RollingHash:

	def __init__(self, s: list, base: int=1007, mod: int=10 ** 9 + 7):
		self.s = s
		self.n = len(s)
		self.base = base
		self.mod = mod
		self.h_cum = [0] * (self.n + 1)
		self.b_pow = [1] * (self.n + 1)
		for (i, si) in enumerate(s):
			self.h_cum[i + 1] = (self.h_cum[i] * base + si % mod) % mod
			self.b_pow[i + 1] = self.b_pow[i] * base % mod

	def get_hash(self, l: int, r: int) -> int:
		hash_val = self.h_cum[r] - self.h_cum[l] * self.b_pow[r - l] % self.mod
		if hash_val < 0:
			hash_val += self.mod
		return hash_val
n = int(input())
a = tuple(map(int, input().split()))
b = tuple(map(int, input().split()))
a_xor = [a[i % n] ^ a[(i + 1) % n] for i in range(n)] * 2
b_xor = [b[i % n] ^ b[(i + 1) % n] for i in range(n)] * 2
a_xor_rh = RollingHash(a_xor)
b_xor_rh = RollingHash(b_xor)
b_hash = b_xor_rh.get_hash(0, n)
for k in range(n):
	if a_xor_rh.get_hash(k, k + n) == b_hash:
		x = a[k] ^ b[0]
		print(k, x)


N = int(input())
A = list(map(int, input().split()))
B = list(map(int, input().split()))
C = [a1 ^ a2 for (a1, a2) in zip(A, A[1:])] + [A[0] ^ A[-1]]
C = C + C
D = [b1 ^ b2 for (b1, b2) in zip(B, B[1:])] + [B[0] ^ B[-1]]
K = []
k = 0
while k < N:
	next_k = k
	is_first = True
	for i in range(N):
		if is_first and i > 0 and (C[k + i] == D[0]):
			next_k = k + i
			is_first = False
		if C[k + i] != D[i]:
			if next_k == k:
				k = k + i + 1
			elif D[k + i - next_k] == C[k + i]:
				k = next_k
			else:
				k = k + i + 1
			break
	if i == N - 1:
		K.append(k)
		if next_k == k:
			break
		else:
			k = next_k
			if len(K) == 2:
				diff = K[1] - K[0]
				while K[-1] < N:
					K.append(K[-1] + diff)
				_ = K.pop()
				break
for k in K:
	print(k, A[k] ^ B[0])


def z_algo(S):
	(i, j, n) = (1, 0, len(S))
	Z = [0] * n
	Z[0] = n
	while i < n:
		while i + j < n and S[j] == S[i + j]:
			j += 1
		if j == 0:
			i += 1
			continue
		Z[i] = j
		d = 1
		while i + d < n and d + Z[d] < j:
			Z[i + d] = Z[d]
			d += 1
		i += d
		j -= d
	return Z
N = int(input())
A = list(map(int, input().split()))
B = list(map(int, input().split()))
A_diff = []
a2 = A[-1]
for a in A:
	A_diff.append(a ^ a2)
	a2 = a
B_diff = []
b2 = B[-1]
for b in B:
	B_diff.append(b ^ b2)
	b2 = b
A_diff_2 = A_diff + A_diff[:-1]
Z = z_algo(A_diff_2)
A_diff_str = '_'.join(map(str, A_diff_2))
B_diff_str = '_'.join(map(str, B_diff))
idx = A_diff_str.find(B_diff_str)
if idx == -1:
	exit()
idx = A_diff_str[:idx].count('_')
Ans = []
b0 = B[-idx]
for (i, (z, a, b)) in enumerate(zip(Z, A, B)):
	if z >= N:
		Ans.append([(idx + i) % N, a ^ b0])
Ans.sort()
for (k, x) in Ans:
	print(f'{k} {x}')


def divisors(M):
	import math
	d = []
	i = 1
	while math.sqrt(M) >= i:
		if M % i == 0:
			d.append(i)
			if i ** 2 != M:
				d.append(M // i)
		i = i + 1
	d.sort()
	return d
N = int(input())
a = list(map(int, input().split()))
b = list(map(int, input().split()))
A = [a[i] ^ a[i - 1] for i in range(0, N)]
B = [b[i] ^ b[i - 1] for i in range(0, N)]
d = divisors(N)
perioda = N
for i in range(0, len(d)):
	test = [A[(j + d[i]) % N] for j in range(0, N)]
	if test == A:
		perioda = min(perioda, d[i])
periodb = N
for i in range(0, len(d)):
	test = [B[(j + d[i]) % N] for j in range(0, N)]
	if test == B:
		periodb = min(periodb, d[i])
if perioda == periodb:
	A = A[:perioda]
	B = B[:periodb]
	kouho = []
	for i in range(0, len(B)):
		if A[i] == B[0]:
			kouho.append(i)
	ans = -1
	for i in range(0, len(kouho)):
		test = [A[(j + kouho[i]) % perioda] for j in range(0, perioda)]
		if test == B:
			ans = kouho[i]
			break
	if ans != -1:
		for i in range(0, N // perioda):
			print(ans + perioda * i, a[ans + perioda * i] ^ b[0])


import sys
sys.setrecursionlimit(2147483647)
INF = 1 << 60
MOD = 10 ** 9 + 7
input = lambda : sys.stdin.readline().rstrip()

def Z(S):
	n = len(S)
	res = [0] * n
	res[0] = n
	l = r = 0
	for i in range(1, n):
		if res[i - l] < r - i:
			res[i] = res[i - l]
		else:
			l = i
			r = max(i, r)
			while r < n and S[r - l] == S[r]:
				r += 1
			res[i] = r - l
	return res

def resolve():
	n = int(input())
	A = list(map(int, input().split()))
	B = list(map(int, input().split()))
	C = [A[i] ^ A[(i + 1) % n] for i in range(n)]
	D = [B[i] ^ B[(i + 1) % n] for i in range(n)]
	prefix = Z(C + D + D)
	res = []
	for k in range(n):
		if prefix[n + k] >= n:
			res.append(((n - k) % n, A[0] ^ B[k]))
	res.sort()
	for pair in res:
		print(*pair)
resolve()


def solve(n, aaa, bbb):
	ccc = [a1 ^ a2 for (a1, a2) in zip(aaa, aaa[1:])] + [aaa[-1] ^ aaa[0]]
	ddd = [b1 ^ b2 for (b1, b2) in zip(bbb, bbb[1:])] + [bbb[-1] ^ bbb[0]]
	ans = []
	m = 2147483647
	g = 1000000007
	s = 0
	for c in ccc:
		s = (s * g + c) % m
	t = 0
	for d in ddd:
		t = (t * g + d) % m
	u = pow(g, n, m) - 1
	for i in range(n):
		if s == t:
			ans.append((i, aaa[i] ^ bbb[0]))
		s = (s * g - ccc[i] * u) % m
	ans.sort()
	return ans
n = int(input())
aaa = list(map(int, input().split()))
bbb = list(map(int, input().split()))
ans = solve(n, aaa, bbb)
print(''.join(('{} {}\n'.format(*answer) for answer in ans)))


import sys, queue, math, copy, itertools, bisect, collections, heapq

def main():
	MOD = 2 ** 89 - 1
	LI = lambda : [int(x) for x in sys.stdin.readline().split()]
	NI = lambda : int(sys.stdin.readline())
	N = NI()
	a = LI()
	b = LI()
	ax = []
	bx = []
	for i in range(N):
		ax.append(a[i - 1] ^ a[i])
		bx.append(b[i - 1] ^ b[i])
	az = 0
	bz = 0
	m = 2 ** 30
	for i in range(N):
		az = (az * m + ax[i]) % MOD
		bz = (bz * m + bx[i]) % MOD
	for i in range(N):
		if az == bz:
			print(i, a[i] ^ b[0])
		az = ((az - ax[i] * pow(m, N - 1, MOD)) * m + ax[i]) % MOD
main()


base = 123
mod = 10 ** 9 + 7
N = int(input())
a = list(map(int, input().split()))
b = list(map(int, input().split()))
base_m = pow(base, N - 1, mod)
ans = [True] * N
for k in range(30):
	tmp = []
	mask = 1 << k
	a_k = []
	a_k_r = []
	b_k = []
	for i in range(N):
		if a[i] & mask:
			a_k.append(1)
			a_k_r.append(0)
		else:
			a_k.append(0)
			a_k_r.append(1)
		if b[i] & mask:
			b_k.append(1)
		else:
			b_k.append(0)
	b_hash = b_k[0]
	a_hash = a_k[0]
	a_hash_r = a_k_r[0]
	for i in range(1, N):
		b_hash = (b_hash * base + b_k[i]) % mod
		a_hash = (a_hash * base + a_k[i]) % mod
		a_hash_r = (a_hash_r * base + a_k_r[i]) % mod
	for i in range(N):
		if a_hash == b_hash or a_hash_r == b_hash:
			pass
		else:
			ans[i] = False
		a_hash = ((a_hash - a_k[i] * base_m) * base + a_k[i]) % mod
		a_hash_r = ((a_hash_r - a_k_r[i] * base_m) * base + a_k_r[i]) % mod
for i in range(N):
	if ans[i]:
		x = a[i] ^ b[0]
		print(i, x)


import sys
sys.setrecursionlimit(10 ** 6)
int1 = lambda x: int(x) - 1
p2D = lambda x: print(*x, sep='\n')

def II():
	return int(sys.stdin.readline())

def MI():
	return map(int, sys.stdin.readline().split())

def LI():
	return list(map(int, sys.stdin.readline().split()))

def LLI(rows_number):
	return [LI() for _ in range(rows_number)]

def ZAlgorithm(aa):
	target = aa
	len_t = len(target)
	lcp = [-1] * len_t
	top = 1
	left = 0
	right = 0
	lcp[0] = 0
	while top < len_t:
		while top + right < len_t and target[right] == target[top + right]:
			right += 1
		lcp[top] = right
		left = 1
		if right == 0:
			top += 1
			continue
		while left + lcp[left] < right and left < right:
			lcp[top + left] = lcp[left]
			left += 1
		top += left
		right -= left
		left = 0
	return lcp

def main():
	inf = pow(2, 31)
	n = II()
	aa = LI()
	bb = LI()
	ax = [aa[i - 1] ^ aa[i] for i in range(n)]
	bx = [bb[i - 1] ^ bb[i] for i in range(n)]
	ll = ZAlgorithm(bx + [inf] + ax + ax[:-1])
	for (shift, lcp) in enumerate(ll[n + 1:]):
		if lcp == n:
			print(shift, aa[shift] ^ bb[0])
main()


from bisect import bisect_left
import sys
input = sys.stdin.readline

class Compress:

	def __init__(self, vs):
		self.xs = list(set(vs))
		self.xs.sort()

	def compress(self, x):
		return bisect_left(self.xs, x)

	def decompress(self, i):
		return self.xs[i]

def suffix_array(s):
	n = len(s)
	comp = Compress(s)
	t = [comp.compress(s[i]) for i in range(n)]
	cnt = [0] * n
	for i in range(n):
		cnt[t[i]] += 1
	for i in range(1, n):
		cnt[i] += cnt[i - 1]
	p = [0] * n
	for i in range(n):
		cnt[t[i]] -= 1
		p[cnt[t[i]]] = i
	c = [0] * n
	cl = 0
	for i in range(1, n):
		if s[p[i]] != s[p[i - 1]]:
			cl += 1
		c[p[i]] = cl
	pn = [0] * n
	cn = [0] * n
	h = 0
	while 1 << h < n:
		for i in range(n):
			pn[i] = p[i] - (1 << h)
			if pn[i] < 0:
				pn[i] += n
		cnt = [0] * n
		for i in range(n):
			cnt[c[pn[i]]] += 1
		for i in range(1, n):
			cnt[i] += cnt[i - 1]
		for i in range(n)[::-1]:
			cnt[c[pn[i]]] -= 1
			p[cnt[c[pn[i]]]] = pn[i]
		cn[p[0]] = 0
		cl = 0
		for i in range(1, n):
			cur = (c[p[i]], c[(p[i] + (1 << h)) % n])
			prev = (c[p[i - 1]], c[(p[i - 1] + (1 << h)) % n])
			if cur != prev:
				cl += 1
			cn[p[i]] = cl
		(c, cn) = (cn, c)
		h += 1
	return p

def bin_search(a, b, sa, lower):
	(lb, ub) = (-1, N)
	while ub - lb > 1:
		m = (lb + ub) // 2
		for i in range(N):
			j = (sa[m] + i) % N
			if a[i] < b[j]:
				ub = m
				break
			if a[i] > b[j]:
				lb = m
				break
		else:
			if lower:
				ub = m
			else:
				lb = m
	return ub
N = int(input())
a = list(map(int, input().split()))
b = list(map(int, input().split()))
c = [a[i] ^ a[(i + 1) % N] for i in range(N)]
d = [b[i] ^ b[(i + 1) % N] for i in range(N)]
sa = suffix_array(d)
lb = bin_search(c, d, sa, True)
ub = bin_search(c, d, sa, False)
ans = []
for j in range(lb, ub):
	k = (N - sa[j]) % N
	x = a[k] ^ b[0]
	ans.append((k, x))
ans.sort()
for (k, x) in ans:
	print(k, x)


import sys
from collections import Counter, defaultdict
buff_readline = sys.stdin.buffer.readline
readline = sys.stdin.readline

def read_int():
	return int(buff_readline())

def read_int_n():
	return list(map(int, buff_readline().split()))

class RollingHash:

	class RH:

		def __init__(self, s, base, mod):
			self.base = base
			self.mod = mod
			self.rev = pow(base, mod - 2, mod)
			l = len(s)
			self.h = h = [0] * (l + 1)
			tmp = 0
			for i in range(l):
				num = s[i]
				tmp = (tmp * base + num) % mod
				h[i + 1] = tmp
			self.pw = pw = [1] * (len(s) + 1)
			v = 1
			for i in range(l):
				pw[i + 1] = v = v * base % mod

		def calc(self, l, r):
			return (self.h[r] - self.h[l] * self.pw[r - l]) % self.mod

	@staticmethod
	def gen(a, b, num):
		result = set()
		while 1:
			import random
			import math
			random.seed()
			while 1:
				v = random.randint(a, b) // 2 * 2 + 1
				if v not in result:
					break
			for x in range(3, int(math.sqrt(v)) + 1, 2):
				if v % x == 0:
					break
			else:
				result.add(v)
				if len(result) == num:
					break
		return result

	def __init__(self, s, rand=False, num=5):
		if rand:
			bases = RollingHash.gen(2, 10 ** 3, num)
		else:
			assert num <= 10
			bases = [641, 103, 661, 293, 547, 311, 29, 457, 613, 599][:num]
		MOD = 10 ** 9 + 7
		self.rhs = [self.RH(s, b, MOD) for b in bases]

	def calc(self, l, r):
		return tuple((rh.calc(l, r) for rh in self.rhs))

def slv(N, A, B):
	a = []
	for i in range(N):
		a.append(A[i] ^ A[i - 1])
	b = []
	for i in range(N):
		b.append(B[i] ^ B[i - 1])
	b = b[:] + b[:]
	ah = RollingHash(a)
	bh = RollingHash(b)
	h = ah.calc(0, N)
	ans = []
	for k in range(N):
		if bh.calc(N - k, N - k + N) == h:
			ans.append('%d %d' % (k, A[0] ^ B[(N - k) % N]))
	return ans

def main():
	N = read_int()
	A = read_int_n()
	B = read_int_n()
	print(*slv(N, A, B), sep='\n')
main()


def main():
	mod = 2 ** 31 - 1
	pow3 = [1] * 200001
	p = 1
	i3 = pow(3, mod - 2, mod)
	for i in range(1, 200001):
		p = p * 3 % mod
		pow3[i] = p

	def rolling_hash(seq):
		h = 0
		for (i, j) in enumerate(seq):
			h += (j + 1) * pow3[i]
		h %= mod
		H0s = [0] * n
		for (i, j) in enumerate(seq):
			H0s[i] = h
			h = (h - j - 1 + (j + 1) * pn) * i3 % mod
		return H0s

	def rolling_hash2(seq):
		p = 0
		p2 = 0
		for (i, j) in enumerate(seq):
			p += (j + 1) * pow3[i]
			p2 += (2 - j) * pow3[i]
		return (p % mod, p2 % mod)
	n = int(input())
	a = list(map(int, input().split()))
	b = list(map(int, input().split()))
	m = max(a + b)
	a1 = [0] * n
	b1 = [0] * n
	memo = [0] * n
	cnt = n
	pn = pow3[n]
	for k in range(len(bin(m)) - 2):
		k2 = 2 ** k
		for (i, j) in enumerate(a):
			a1[i] = (j & k2) >> k
		for (i, j) in enumerate(b):
			b1[i] = (j & k2) >> k
		(b_hash, b_hash2) = rolling_hash2(b1)
		A1 = rolling_hash(a1)
		for (i, (j, k)) in enumerate(zip(memo, A1)):
			if j is None:
				continue
			elif k == b_hash:
				pass
			elif k == b_hash2:
				memo[i] += k2
			else:
				memo[i] = None
				cnt -= 1
		if cnt == 0:
			return
	for (i, j) in enumerate(memo):
		if j is not None:
			print(i, j)
main()


import sys
INF = float('inf')
base = 37
mod = 10 ** 9 + 9
pw = None

def rolling_hash(s):
	l = len(s)
	h = [0] * (l + 1)
	v = 0
	for i in range(l):
		h[i + 1] = v = (v * base + s[i]) % mod
	return h

def setup_pw(l):
	global pw
	pw = [1] * (l + 1)
	v = 1
	for i in range(l):
		pw[i + 1] = v = v * base % mod

def get(h, l, r):
	return (h[r] - h[l] * pw[r - l]) % mod

def solve(N: int, a: 'List[int]', b: 'List[int]'):
	c = [a[i] ^ a[(i + 1) % N] for i in range(N)]
	d = [b[i] ^ b[(i + 1) % N] for i in range(N)] * 2
	i = -1
	a1 = [0] * N
	a2 = [0] * N
	b1 = [0] * (2 * N)
	k_cand = [True] * N
	setup_pw(2 * N)
	for keta in range(30):
		mask = 1 << keta
		for (i, aa) in enumerate(a):
			a1[i] = (aa & mask) >> keta
			a2[i] = (~aa & mask) >> keta
		for (i, bb) in enumerate(b):
			b1[i] = (bb & mask) >> keta
			b1[i + N] = (bb & mask) >> keta
		P = rolling_hash(a1)
		Q = rolling_hash(a2)
		R = rolling_hash(b1)
		for i in range(N):
			if k_cand[i]:
				if not (get(P, 0, N) == get(R, i, i + N) or get(Q, 0, N) == get(R, i, i + N)):
					k_cand[i] = False
	ans = []
	if len(k_cand) == 0:
		return
	if k_cand[0] == True:
		print(0, b[0] ^ a[0])
		for (i, k) in enumerate(k_cand[:0:-1], start=1):
			if k:
				print(i, b[0] ^ a[i])
	else:
		for (i, k) in enumerate(k_cand[::-1], start=1):
			if k:
				print(i, b[0] ^ a[i])
	return

def main():

	def iterate_tokens():
		for line in sys.stdin:
			for word in line.split():
				yield word
	tokens = iterate_tokens()
	N = int(next(tokens))
	a = [int(next(tokens)) for _ in range(N - 1 - 0 + 1)]
	b = [int(next(tokens)) for _ in range(N - 1 - 0 + 1)]
	solve(N, a, b)
main()


import sys
input = sys.stdin.readline

class RollingHash:

	def __init__(self, s):
		self.length = len(s)
		self.base = 1009
		self.mod = (1 << 61) - 1
		self.hash = [0] * (self.length + 1)
		self.pow = [1] * (self.length + 1)
		for i in range(self.length):
			self.hash[i + 1] = (self.hash[i] + s[i]) * self.base % self.mod
			self.pow[i + 1] = self.pow[i] * self.base % self.mod

	def get(self, l, r):
		t = self.hash[r] - self.hash[l] * self.pow[r - l] % self.mod
		t = (t + self.mod) % self.mod
		return t
n = int(input())
a = [int(item) for item in input().split()]
b = [int(item) for item in input().split()]
a = a + a
diffa = []
diffb = []
for i in range(1, len(a)):
	diffa.append(a[i] ^ a[i - 1])
for i in range(1, len(b)):
	diffb.append(b[i] ^ b[i - 1])
RHa = RollingHash(diffa)
RHb = RollingHash(diffb)
query = RHb.get(0, n - 1)
ans = []
for i in range(n):
	val = RHa.get(i, i + n - 1)
	if val == query:
		ans.append((i, a[i] ^ b[0]))
ans.sort()
for (k, x) in ans:
	print(k, x)


from itertools import chain
N = int(input())
a = list(map(int, input().split()))
b = list(map(int, input().split()))
assert len(a) == N and len(b) == N
a_xor = [a[i] ^ a[(i + 1) % N] for i in range(N)]
b_xor = [b[i] ^ b[i + 1] for i in range(N - 1)]

def kmp_search(T, P):
	m = len(P)
	matches = []
	pi = compute_prefix_func(P)
	q = 0
	for (i, t) in enumerate(T):
		while q > 0 and P[q] != t:
			q = pi[q]
		if P[q] == t:
			q += 1
		if q == m:
			matches.append(i - (m - 1))
			q = pi[q]
	return matches

def compute_prefix_func(P):
	m = len(P)
	pi = [0] * (m + 1)
	k = 0
	for q in range(1, m):
		while k > 0 and P[k] != P[q]:
			k = pi[k]
		if P[k] == P[q]:
			k += 1
		pi[q + 1] = k
	return pi
for k in kmp_search(chain(a_xor, a_xor), b_xor):
	if k < N:
		x = b[0] ^ a[k]
		print(k, x)


N = int(input())
A = list(map(int, input().split()))
B = list(map(int, input().split()))
AX = [A[i % N] ^ A[(i - 1) % N] for i in range(N, 0, -1)]
BX = [B[i % N] ^ B[(i - 1) % N] for i in range(N, 0, -1)]
BX2 = BX + BX
shift = [0] * (N + 1)
k = 1
l = 0
while k < N:
	if AX[k] == AX[l]:
		k += 1
		l += 1
		shift[k] = l
	elif l > 0:
		l = shift[l]
	else:
		k += 1
		shift[k] = 0
ans = []
ai = bi = 0
Z = 0
while bi < N:
	if BX2[bi + ai] == AX[ai]:
		ai += 1
		if ai == N - 1:
			print(bi, A[bi] ^ B[0])
			ans.append((bi + 1) % N)
			bi += ai - shift[ai]
			ai = shift[ai]
	else:
		bi += 1 if ai == 0 else ai - shift[ai]
		ai = shift[ai]


import sys

def I():
	return int(sys.stdin.readline().rstrip())

def LI():
	return list(map(int, sys.stdin.readline().rstrip().split()))
N = I()
a = LI()
b = LI()
if N == 1:
	print(0, a[0] ^ b[0])
	exit()
A = [a[i] ^ a[i + 1] for i in range(N - 1)]
A = A + [a[N - 1] ^ a[0]] + A
B = [b[i] ^ b[i + 1] for i in range(N - 1)]

def f(mod, base):
	x = pow(base, N - 1, mod)
	d = 0
	for i in range(N - 1):
		d *= base
		d += B[i]
		d %= mod
	c = 0
	for i in range(N - 1):
		c *= base
		c += A[i]
		c %= mod
	for i in range(N):
		if c == d:
			print(i, a[i] ^ b[0])
		c *= base
		c -= A[i] * x
		c += A[i + N - 1]
		c %= mod
f(10 ** 9 + 7, 1234)


import sys
input = sys.stdin.readline
N = int(input())
A = list(map(int, input().split()))
B = list(map(int, input().split()))
h = 10 ** 11 + 7
b = 10 ** 7 + 7
H = [1]
for _ in range(N):
	H.append(H[-1] * b % h)
allSum = 0
for i in range(N):
	allSum = (allSum + H[i]) % h
ok = [True] * N
ans = [0] * N
L = 30
for l in range(L):
	HashA = 0
	for (i, a) in enumerate(A):
		if 1 << l & a:
			HashA = (HashA + H[i]) % h
	HashB = 0
	for (i, a) in enumerate(B):
		if 1 << l & a:
			HashB = (HashB + H[i]) % h
	for k in range(N):
		if (HashA + HashB) % h == allSum:
			ans[k] += 1 << l
		elif HashA != HashB:
			ok[k] = False
		HashB = HashB * b % h
		if 1 << l & B[-k - 1]:
			HashB = (HashB + h - H[N] + 1) % h
for k in range(N):
	if ok[k]:
		print(k, ans[k])


import sys
(BASE, MOD) = (80408696819889532, (1 << 61) - 1)

class RollingHash:

	def __init__(self, s, base, mod):
		self.mod = mod
		self.pw = pw = [1] * (len(s) + 1)
		l = len(s)
		self.h = h = [0] * (l + 1)
		v = 0
		for i in range(l):
			h[i + 1] = v = (v * base + s[i]) % mod
		v = 1
		for i in range(l):
			pw[i + 1] = v = v * base % mod

	def get(self, l, r):
		return (self.h[r] - self.h[l] * self.pw[r - l]) % self.mod

	def concatenate(self, l1, r1, l2, r2):
		return (self.get(l1, r1) * self.pw[r2 - l2] + self.get(l2, r2)) % self.mod
n = int(input())
a = list(map(int, input().split()))
b = list(map(int, input().split()))
if n == 1:
	print(0, a[0] ^ b[0])
	sys.exit()
x = [a[n - 1] ^ a[0]]
y = [b[n - 1] ^ b[0]]
for i in range(n - 1):
	x.append(a[i] ^ a[i + 1])
	y.append(b[i] ^ b[i + 1])
(rh_x, rh_y) = (RollingHash(x, BASE, MOD), RollingHash(y, BASE, MOD))
for k in range(n):
	if rh_y.concatenate(n - k, n, 0, n - k) == rh_x.get(0, n):
		print(k, a[0] ^ b[(n - k) % n])


import os
import sys
if os.getenv('LOCAL'):
	sys.stdin = open('_in.txt', 'r')
sys.setrecursionlimit(10 ** 9)
INF = float('inf')
IINF = 10 ** 18
MOD = 10 ** 9 + 7

class KMP:

	def __init__(self, needle):
		self._needle = needle
		kmp = [0] * (len(needle) + 2)
		kmp[0] = -1
		kmp[1] = 0
		i = 2
		j = 0
		while i < len(needle):
			if needle[i - 1] == needle[j]:
				kmp[i] = j + 1
				i += 1
				j += 1
			elif j > 0:
				j = kmp[j]
			else:
				kmp[i] = 0
				i += 1
		self._kmp = kmp

	def index_of(self, haystack, m=0, i=0):
		while m + i < len(haystack):
			if self._needle[i] == haystack[m + i]:
				i += 1
				if i == len(self._needle):
					return m
			else:
				m += i - self._kmp[i]
				if i > 0:
					i = self._kmp[i]
		return -1

	def search(self, haystack):
		ret = [False] * len(haystack)
		m = 0
		i = 0
		while m + i < len(haystack):
			m = self.index_of(haystack, m=m, i=i)
			if m < 0:
				break
			ret[m] = True
			m += len(self._needle) - self._kmp[len(self._needle) - 1] - 1
			i = max(0, self._kmp[len(self._needle) - 1])
		return ret
N = int(sys.stdin.buffer.readline())
A = list(map(int, sys.stdin.buffer.readline().split()))
B = list(map(int, sys.stdin.buffer.readline().split()))

def test():
	ans = []
	for k in range(N):
		b = np.roll(B, k)
		x = A[0] ^ b[0]
		a = A ^ x
		if np.all(a == b):
			ans.append((k, x))
	for r in ans:
		print(*r)
xa = []
xb = []
for (a1, a2) in zip(A, A[1:] + [A[0]]):
	xa.append(a1 ^ a2)
for (b1, b2) in zip(B, B[1:] + [B[0]]):
	xb.append(b1 ^ b2)
kmp = KMP(xb)
k_ok = kmp.search(xa + xa)
for k in range(N):
	if k_ok[k]:
		x = A[k] ^ B[0]
		print(k, x)


def main():
	N = int(input())
	a = [int(x) for x in input().split()]
	b = [int(x) for x in input().split()]
	xor_a = [a[i] ^ a[(i + 1) % N] for i in range(len(a))]
	xor_b = [b[i] ^ b[(i + 1) % N] for i in range(len(b))]
	kmp = KmpSearch(xor_a + xor_a, xor_b)
	ans = kmp.full_search()
	for k in ans:
		if k == len(a):
			break
		print(str(k) + ' ' + str(a[0 + k] ^ b[0]))

class KmpSearch:

	def __init__(self, target, pattern):
		self.target = target
		self.pattern = pattern
		self.__table = self.__create_kmp_table()

	def full_search(self):
		if len(self.pattern) > len(self.target):
			return -1
		res = []
		i = 0
		p = 0
		while i < len(self.target):
			if self.pattern[p] == self.target[i]:
				i += 1
				p += 1
				if p == len(self.pattern):
					res.append(i - p)
					i -= 1
					p = self.__table[p - 1]
			elif p == 0:
				i += 1
			else:
				p = self.__table[p]
		return res

	def __create_kmp_table(self):
		table = [0 for x in range(len(self.pattern))]
		j = 0
		for i in range(1, len(self.pattern)):
			table[i] = j
			if self.pattern[j] == self.pattern[i]:
				j += 1
			else:
				j = 0
		return table
main()


N = int(input())
AS = list(map(int, input().split()))
BS = list(map(int, input().split()))
AXOR = [AS[i] ^ AS[(i + 1) % N] for i in range(N)]
BXOR = [BS[i] ^ BS[(i + 1) % N] for i in range(N)]

def getZarr(string, z):
	n = len(string)
	(l, r, k) = (0, 0, 0)
	for i in range(1, n):
		if i > r:
			(l, r) = (i, i)
			while r < n and string[r - l] == string[r]:
				r += 1
			z[i] = r - l
			r -= 1
		else:
			k = i - l
			if z[k] < r - i + 1:
				z[i] = z[k]
			else:
				l = i
				while r < n and string[r - l] == string[r]:
					r += 1
				z[i] = r - l
				r -= 1
string = list(BXOR) + [-1] + list(AXOR) + list(AXOR)[:-1]
Z = [0 for i in range(len(string))]
getZarr(string, Z)
res = []
for i in range(N, len(string)):
	if Z[i] >= N:
		res.append((i - N - 1, AS[i - N - 1] ^ BS[0]))
res.sort()
for (a, b) in res:
	print(a, b)


N = int(input())
A = list(map(int, input().split()))
B = list(map(int, input().split()))
X = []
for (a, b) in zip(A, A[1:]):
	X.append(a ^ b)
X.append(A[-1] ^ A[0])
Y = []
for (a, b) in zip(B, B[1:]):
	Y.append(a ^ b)
Y.append(B[-1] ^ B[0])

def z_algorithm(s):
	N = len(s)
	ret = [0] * N
	ret[0] = N
	(i, j) = (1, 0)
	while i < N:
		while i + j < N and s[j] == s[i + j]:
			j += 1
		ret[i] = j
		if j == 0:
			i += 1
			continue
		k = 1
		while i + k < N and k + ret[k] < j:
			ret[i + k] = ret[k]
			k += 1
		i += k
		j -= k
	return ret
za = z_algorithm(X + [-1] + Y + Y)
for i in range(N):
	if za[-N - i] == N:
		print(i, A[i] ^ B[0])


def z_algo(s):
	res = [0] * len(s)
	res[0] = len(s)
	(i, j) = (1, 0)
	while i < len(s):
		while i + j < len(s) and s[j] == s[i + j]:
			j += 1
		res[i] = j
		if j == 0:
			i += 1
			continue
		k = 1
		while i + k < len(s) and k + res[k] < j:
			res[i + k] = res[k]
			k += 1
		(i, j) = (i + k, j - k)
	return res
n = int(input())
a = list(map(int, input().split()))
b = list(map(int, input().split()))
diff_a = []
diff_b = []
for i in range(n):
	diff_a.append(a[(i + 1) % n] ^ a[i % n])
	diff_b.append(b[(i + 1) % n] ^ b[i % n])
diff_a2b = diff_b + diff_a + diff_a
t = z_algo(diff_a2b)
for i in range(n, 2 * n):
	if t[i] >= n:
		print(i - n, a[i - n] ^ b[0])


import sys

def bit_most(v):
	if v == 0:
		return 0
	else:
		return len(bin(v)) - 2

def z_algorithm(S):
	N = len(S)
	Z = [0] * N
	c = 0
	for i in range(1, N):
		if i + Z[i - c] < c + Z[c]:
			Z[i] = Z[i - c]
		else:
			j = max(0, c + Z[c] - i)
			while i + j < N and S[j] == S[i + j]:
				j += 1
			Z[i] = j
			c = i
	Z[0] = N
	return Z

def solve(N: int, a: 'List[int]', b: 'List[int]'):
	a1 = [0] * (2 * N)
	b1 = [0] * N
	b2 = [0] * N
	k_cand = [True] * N
	for keta in range(bit_most(max(max(a), max(b))) + 1):
		for (i, aa) in enumerate(a):
			a1[i] = a1[i + N] = aa >> keta & 1
		for (i, bb) in enumerate(b):
			b1[i] = v = bb >> keta & 1
			b2[i] = 1 - v
		Z1 = z_algorithm(b1 + [-1] + a1)
		Z2 = z_algorithm(b2 + [-1] + a1)
		for i in range(N):
			if k_cand[i]:
				k_cand[i] = Z2[i + N + 1] == N or Z1[i + N + 1] == N
	for i in range(N):
		if k_cand[i]:
			print(i, b[0] ^ a[i])
	return

def main():

	def iterate_tokens():
		for line in sys.stdin:
			for word in line.split():
				yield word
	tokens = iterate_tokens()
	N = int(next(tokens))
	a = [int(next(tokens)) for _ in range(N - 1 - 0 + 1)]
	b = [int(next(tokens)) for _ in range(N - 1 - 0 + 1)]
	solve(N, a, b)
main()


import sys
import math
from bisect import bisect_right as br
from bisect import bisect_left as bl
sys.setrecursionlimit(2147483647)
from heapq import heappush, heappop, heappushpop
from collections import defaultdict
from itertools import accumulate
from collections import Counter
from collections import deque
from operator import itemgetter
from itertools import permutations
mod = 10 ** 9 + 7
inf = float('inf')

def I():
	return int(sys.stdin.readline())

def LI():
	return list(map(int, sys.stdin.readline().split()))

def Z_algorithm(s):
	n = len(s)
	Z = [0] * n
	Z[0] = n
	(i, j) = (1, 0)
	while i < n:
		while i + j < n and s[j] == s[i + j]:
			j += 1
		Z[i] = j
		if j == 0:
			i += 1
			continue
		k = 1
		while i + k < n and k + Z[k] < j:
			Z[i + k] = Z[k]
			k += 1
		i += k
		j -= k
	return Z
n = I()
a = LI()
b = LI()
x = [a[i % n] ^ a[(i + 1) % n] for i in range(2 * n)]
y = [b[i % n] ^ b[(i + 1) % n] for i in range(n)]
z = Z_algorithm(y + x)
for i in range(n, 2 * n):
	if z[i] >= n:
		k = i - n
		x = a[k] ^ b[0]
		print(k, x)


maxN = int(600000.0 + 100)
a = [0] * maxN
b = [0] * maxN
ans = [0] * maxN

def solve():
	L = R = 0
	for i in range(2, 3 * n + 1):
		if i > R:
			L = R = i
			while R + 1 <= 3 * n and a[i] ^ a[1] == a[R + 1] ^ a[R - L + 2]:
				R += 1
			ans[i] = R - L + 1
		else:
			k = i - L + 1
			if ans[k] < R - i + 1:
				ans[i] = ans[k]
			else:
				L = i
				while R + 1 <= 3 * n and a[i] ^ a[1] == a[R + 1] ^ a[R - L + 2]:
					R += 1
				ans[i] = R - L + 1
n = int(input())
inp = input().split()
for i in range(n + 1, 2 * n + 1):
	a[i] = int(inp[i - n - 1])
for i in range(2 * n + 1, 3 * n + 1):
	a[i] = a[i - n]
inp = input().split()
for i in range(1, n + 1):
	a[i] = int(inp[i - 1])
solve()
for i in range(n + 1, 2 * n + 1):
	if ans[i] >= n:
		print(i - n - 1, a[i] ^ a[1])


n = int(input())
a = list(map(int, input().split()))
b = list(map(int, input().split()))
c = [0] * n
d = [0] * (2 * n - 1)
for i in range(n - 1):
	c[i] = b[i] ^ b[i + 1]
	d[i] = a[i] ^ a[i + 1]
c[n - 1] = b[0] ^ b[-1]
d[n - 1] = a[0] ^ a[-1]
for i in range(n - 1):
	d[n + i] = d[i]
t = [0] * (n + 1)
t[0] = -1
j = -1
for i in range(n):
	while j >= 0 and c[i] != c[j]:
		j = t[j]
	j += 1
	t[i + 1] = j
m = 0
i = 0
ans = []
while m < n:
	if c[i] == d[m + i]:
		i += 1
		if i == n:
			ans.append(m)
			m += i - t[i]
			i = t[i]
	else:
		m += i - t[i]
		if i > 0:
			i = t[i]
for k in ans:
	print(k, a[k] ^ b[0])


import sys
input = sys.stdin.readline
import math
from fractions import gcd
from functools import lru_cache
MOD = 10 ** 9 + 7
INF = float('inf')

def inputI():
	return int(input().strip())

def inputS():
	return input().strip()

def inputIL():
	return list(map(int, input().split()))

def inputSL():
	return list(map(str, input().split()))

def inputILs(n):
	return list((int(input()) for _ in range(n)))

def inputSLs(n):
	return list((input().strip() for _ in range(n)))

def inputILL(n):
	return [list(map(int, input().split())) for _ in range(n)]

def inputSLL(n):
	return [list(map(str, input().split())) for _ in range(n)]

def inv(n):
	return pow(n, MOD - 2, MOD)
kaijo_memo = []

def kaijo(n):
	if len(kaijo_memo) > n:
		return kaijo_memo[n]
	if len(kaijo_memo) == 0:
		kaijo_memo.append(1)
	while len(kaijo_memo) <= n:
		kaijo_memo.append(kaijo_memo[-1] * len(kaijo_memo) % MOD)
	return kaijo_memo[n]
gyaku_kaijo_memo = []

def gyaku_kaijo(n):
	if len(gyaku_kaijo_memo) > n:
		return gyaku_kaijo_memo[n]
	if len(gyaku_kaijo_memo) == 0:
		gyaku_kaijo_memo.append(1)
	while len(gyaku_kaijo_memo) <= n:
		gyaku_kaijo_memo.append(gyaku_kaijo_memo[-1] * pow(len(gyaku_kaijo_memo), MOD - 2, MOD) % MOD)
	return gyaku_kaijo_memo[n]

def nCr(n, r):
	if n == r:
		return 1
	if n < r or r < 0:
		return 0
	ret = 1
	ret = ret * kaijo(n) % MOD
	ret = ret * gyaku_kaijo(r) % MOD
	ret = ret * gyaku_kaijo(n - r) % MOD
	return ret

def factorization(n):
	arr = []
	temp = n
	for i in range(2, int(-(-n ** 0.5 // 1)) + 1):
		if temp % i == 0:
			cnt = 0
			while temp % i == 0:
				cnt += 1
				temp //= i
			arr.append([i, cnt])
	if temp != 1:
		arr.append([temp, 1])
	if arr == []:
		arr.append([n, 1])
	return arr

def lcm(a, b):
	return a * b // gcd(a, b)
N = inputI()
a = inputIL()
b = inputIL()
difa = [0] * N
difb = [0] * N
for i in range(N - 1):
	difa[i] = a[i] ^ a[i + 1]
	difb[i] = b[i] ^ b[i + 1]
difa[N - 1] = a[0] ^ a[N - 1]
difb[N - 1] = b[0] ^ b[N - 1]
if set(difa) != set(difb):
	exit()
memo = []
for i in range(N):
	j = 0
	while difa[(i + j) % N] == difb[j % N]:
		j += 1
		if j == N:
			print(i, a[i] ^ b[0])
			memo.append(i)
			break
	if len(memo) == 2:
		break
if len(memo) == 2:
	d = memo[1] - memo[0]
	k = memo[1] + d
	while k < N:
		print(k, a[k] ^ b[0])
		k += d


from collections import defaultdict
N = int(input())
a = list(map(int, input().split()))
b = list(map(int, input().split()))
A = []
B = []
ans = []
for i in range(N):
	A.append(a[i] ^ a[(i + 1) % N])
	B.append(b[i] ^ b[(i + 1) % N])
if A == B == [A[0]] * N:
	for i in range(N):
		ans.append((i, a[i] ^ b[0]))
else:
	A += A
	d = defaultdict(list)
	for i in range(N):
		d[B[i]].append(i)
	i = 0
	ans = []
	while i < N:
		ok = True
		for j in range(N):
			if B[N - j - 1] != A[N - j - 1 + i]:
				if d[A[N - j - 1]] == []:
					i += N
					ok = False
					break
				else:
					i += N - d[A[N - j - 1 + i]][-1] - 1
					ok = False
					break
		if ok:
			ans.append((i, a[i] ^ b[0]))
			if len(d[A[N - 1 + i]]) == 1:
				i += N
			else:
				i += N - d[A[N - 1 + i]][-2] - 1
for x in ans:
	print(*x)


import sys
input = lambda : sys.stdin.readline().rstrip()
sys.setrecursionlimit(max(1000, 10 ** 9))
write = lambda x: sys.stdout.write(x + '\n')
n = int(input())
A = list(map(int, input().split()))
B = list(map(int, input().split()))
da = []
db = []
for i in range(n - 1):
	da.append(A[i + 1] ^ A[i])
	db.append(B[i + 1] ^ B[i])
da.append(A[-1] ^ A[0])
db.append(B[-1] ^ B[0])
import random
M = 10 ** 9 + 7
b = random.choice(range(M))

def rhash(s):
	import random
	ans = 0
	v = 1
	for item in s:
		ans += item * v
		v *= b
		ans %= M
		v %= M
	return ans
h = rhash(db)
g = rhash(da)
t = pow(b, n, M)
ans = []
for i in range(n):
	if h == g:
		ans.append((i, A[i] ^ B[0]))
	h *= b
	h = h - t * db[n - 1 - i] + db[n - 1 - i]
	h %= M
write('\n'.join((' '.join(map(str, item)) for item in ans)))


import sys
input = sys.stdin.readline
N = int(input())
A = list(map(int, input().split()))
B = list(map(int, input().split()))
h = 10 ** 11 + 7
b = 10 ** 7 + 7
H = [1]
for _ in range(N):
	H.append(H[-1] * b % h)
C = []
D = []
for i in range(N):
	C.append(A[i - 1] ^ A[i])
	D.append(B[i - 1] ^ B[i])
HashA = 0
for (i, a) in enumerate(C):
	HashA = (HashA + a * H[i] % h) % h
HashB = 0
for (i, a) in enumerate(D):
	HashB = (HashB + a * H[i] % h) % h
ans = []
for k in range(N):
	if HashA == HashB:
		ans.append(k)
	HashB = HashB * b % h
	HashB = (HashB + (1 - H[N]) * D[-k - 1] % h) % h
for k in ans:
	print(k, A[k] ^ B[0])


def main():

	def z_algo(S):
		(n, i, j) = (len(S), 1, 0)
		a = [0] * n
		a[0] = n
		while i < n:
			while i + j < n and S[i + j] == S[j]:
				j += 1
			if not j:
				i += 1
				continue
			(a[i], k) = (j, 1)
			while a[k] < j - k and i + k < n:
				a[i + k] = a[k]
				k += 1
			i += k
			j -= k
		return a
	n = int(input())
	(a, b) = (list(map(int, input().split())), list(map(int, input().split())))
	a1 = [a[i - 1] ^ a[i] for i in range(n)]
	z = z_algo([b[i - 1] ^ b[i] for i in range(n)] + a1 + a1)
	memo = []
	for i in range(n):
		if z[n + i] >= n:
			memo.append(i)
	b0 = b[0]
	for i in memo:
		print(i, b0 ^ a[i])
main()


n = int(input())
a = list(map(int, input().split()))
b = list(map(int, input().split()))
f = [0] * n
g = [0] * n
for i in range(n):
	f[i] = a[i] ^ a[(i + 1) % n]
	g[i] = b[i] ^ b[(i + 1) % n]

def KMP(S, W):
	(ls, lw) = (len(S), len(W))
	(m, i) = (0, 0)
	T = _KMP_table(W)
	res = list()
	while m + i < ls:
		if W[i] == S[m + i]:
			i += 1
			if i == lw:
				res.append(m)
				m += i - T[i]
				if i > 0:
					i = T[i]
		else:
			m += i - T[i]
			if i > 0:
				i = T[i]
	return res

def _KMP_table(W):
	W += ['$']
	lw = len(W)
	T = [0] * lw
	T[0] = -1
	(i, j) = (2, 0)
	while i < lw:
		if W[i - 1] == W[j]:
			T[i] = j + 1
			i += 1
			j += 1
		elif j > 0:
			j = T[j]
		else:
			T[i] = 0
			i += 1
	return T
res = KMP(f * 2, g)
for x in res:
	if x < n:
		print(x, a[x] ^ b[0])


n = int(input())
a = list(map(int, input().split()))
b = list(map(int, input().split()))
axor = [0] * n
bxor = [0] * n
for i in range(n - 1):
	axor[i] = a[i] ^ a[i + 1]
	bxor[i] = b[i] ^ b[i + 1]
axor[-1] = a[0] ^ a[-1]
bxor[-1] = b[0] ^ b[-1]

def MP(it):
	n = len(it)
	res = [0] * (n + 1)
	res[0] = -1
	j = -1
	for i in range(n):
		while j >= 0 and it[i] != it[j]:
			j = res[j]
		j += 1
		res[i + 1] = j
	return res
mp = MP(bxor)
shift = [1] * (n + 1)
for i in range(n):
	shift[i + 1] = i + 1 - mp[i + 1]
txt = axor + axor
head = 0
ans = list()
start = 0
while head < n:
	for i in range(start, n):
		if bxor[i] != txt[head + i]:
			start = max(0, i - shift[i])
			head += shift[i]
			break
	else:
		x = b[0] ^ a[head]
		ans.append([head, x])
		start = i + 1 - shift[i + 1]
		head += shift[i + 1]
for (k, x) in ans:
	print(k, x)


import sys
INF = float('inf')
B = 10 ** 7 + 7
MOD = 10 ** 9 + 7

class RollingHash:

	def __init__(self, s, base, mod):
		self.mod = mod
		self.pw = pw = [1] * (len(s) + 1)
		l = len(s)
		self.h = h = [0] * (l + 1)
		v = 0
		for i in range(l):
			h[i + 1] = v = (v * base + s[i]) % mod
		v = 1
		for i in range(l):
			pw[i + 1] = v = v * base % mod

	def get(self, l, r):
		return (self.h[r] - self.h[l] * self.pw[r - l]) % self.mod

def z_algorithm(S):
	N = len(S)
	Z = [0] * N
	c = 0
	for i in range(1, N):
		if i + Z[i - c] < c + Z[c]:
			Z[i] = Z[i - c]
		else:
			j = max(0, c + Z[c] - i)
			while i + j < N and S[j] == S[i + j]:
				j += 1
			Z[i] = j
			c = i
	Z[0] = len(S)
	return Z

def zfindall(text, pattern, separator='$'):
	N = len(pattern)
	conc = pattern + separator + text
	Z = z_algorithm(conc)
	return {i - N - 1 for i in range(len(conc)) if Z[i] == N}

def solve(N: int, a: 'List[int]', b: 'List[int]'):
	c = [a[i] ^ a[(i + 1) % N] for i in range(N)]
	d = [b[i] ^ b[(i + 1) % N] for i in range(N)] * 2
	i = -1
	a1 = [0] * N
	a2 = [0] * N
	b1 = [0] * (2 * N)
	k_cand = [True] * N
	for keta in range(30):
		mask = 1 << keta
		for (i, aa) in enumerate(a):
			a1[i] = (aa & mask) >> keta
			a2[i] = (~aa & mask) >> keta
		for (i, bb) in enumerate(b):
			b1[i] = (bb & mask) >> keta
			b1[i + N] = (bb & mask) >> keta
		P = RollingHash(a1, 97, MOD)
		Q = RollingHash(a2, 97, MOD)
		R = RollingHash(b1, 97, MOD)
		for i in range(N):
			if k_cand[i]:
				if not (P.get(0, N) == R.get(i, i + N) or Q.get(0, N) == R.get(i, i + N)):
					k_cand[i] = False
	ans = []
	if len(k_cand) == 0:
		return
	if k_cand[0] == True:
		print(0, b[0] ^ a[0])
		for (i, k) in enumerate(k_cand[:0:-1], start=1):
			if k:
				print(i, b[0] ^ a[i])
	else:
		for (i, k) in enumerate(k_cand[::-1], start=1):
			if k:
				print(i, b[0] ^ a[i])
	return

def main():

	def iterate_tokens():
		for line in sys.stdin:
			for word in line.split():
				yield word
	tokens = iterate_tokens()
	N = int(next(tokens))
	a = [int(next(tokens)) for _ in range(N - 1 - 0 + 1)]
	b = [int(next(tokens)) for _ in range(N - 1 - 0 + 1)]
	solve(N, a, b)
main()


N = int(input())
A = list(map(int, input().split()))
B = list(map(int, input().split()))
AX = [A[i] ^ A[i - 1] for i in range(N)]
AX += AX
BX = [B[i] ^ B[i - 1] for i in range(N)]
m = 0
for i in range(1, N):
	if BX[m] == BX[i]:
		m += 1
	else:
		m = 0
(i, j, k) = (0, 0, 0)
while k < N:
	while True:
		if AX[i] == BX[j]:
			if j == N - 1:
				print(k, A[k] ^ B[0])
				i += 1
				j = m
				break
			i += 1
			j += 1
		elif j != 0:
			j -= 1
		else:
			i += 1
			break
	k = i - j


import sys
input = sys.stdin.readline
N = int(input())
a = list(map(int, input().split()))
b = list(map(int, input().split()))
ta = [[0] * N for _ in range(30)]
tb = [[0] * N for _ in range(30)]
mxl = max(max(a), max(b)).bit_length()
for i in range(mxl):
	x = 1 << i
	for j in range(N):
		ta[i][j] = int(a[j] & x > 0)
		tb[i][j] = int(b[j] & x > 0)

class KmpSearch:

	def __init__(self, word):
		self.word = word
		self.table = [0] * (len(word) + 1)
		self.table[0] = -1
		(i, j) = (0, 1)
		while j < len(self.word):
			matched = self.word[i] == self.word[j]
			if not matched and i > 0:
				i = self.table[i]
			else:
				if matched:
					i += 1
				j += 1
				self.table[j] = i

	def search(self, text):
		table = self.table
		word = self.word
		(i, p) = (0, 0)
		res = []
		while i < len(text):
			if text[i] == word[p]:
				i += 1
				p += 1
			elif p == 0:
				i += 1
			else:
				p = table[p]
			if p == len(word):
				res.append(i - p)
				p = table[p]
		return res
res = [0] * N
vis = [1 for _ in range(N)]
for i in range(mxl):
	kmp = KmpSearch(ta[i])
	s = [0] * (2 * N - 1)
	for j in range(2 * N - 1):
		s[j] = tb[i][j % N] ^ 1
	xs = set(kmp.search(s))
	tvis = [0] * N
	for j in range(N):
		tvis[j] |= j in xs
		res[j] += (j in xs) << i
	xs = set(kmp.search(tb[i] + tb[i][:-1]))
	for j in range(N):
		tvis[j] |= j in xs
	for j in range(N):
		vis[j] &= tvis[j]
rres = []
for i in range(N):
	if vis[i]:
		rres.append(((N - i) % N, res[i]))
rres.sort(key=lambda x: (x[0], x[1]))
for r in rres:
	print(*r)


class RollingHash:

	def __init__(self, s: list, base: int=1007, mod: int=10 ** 9 + 7):
		self.s = s
		self.n = len(s)
		self.base = base
		self.mod = mod
		self.h_cum = [0] * (self.n + 1)
		self.b_pow = [1] * (self.n + 1)
		for i in range(self.n):
			self.h_cum[i + 1] = (self.h_cum[i] * base + s[i]) % mod
			self.b_pow[i + 1] = self.b_pow[i] * base % mod

	def get_hash(self, l: int, r: int) -> int:
		hash_val = self.h_cum[r] - self.h_cum[l] * self.b_pow[r - l] % self.mod
		if hash_val < 0:
			hash_val += self.mod
		return hash_val

class RollingHashMulti:

	def __init__(self, s: list, base_list: list=[1007, 2009], mod_list: list=[10 ** 9 + 7, 10 ** 9 + 9]):
		self.n = len(base_list)
		self.base_list = base_list
		self.mod_list = mod_list
		self.rh_list = [RollingHash(s, base_list[i], mod_list[i]) for i in range(self.n)]

	def get_hash(self, l: int, r: int) -> tuple:
		return tuple((self.rh_list[i].get_hash(l, r) for i in range(self.n)))
n = int(input())
a = list(map(int, input().split()))
b = list(map(int, input().split()))
a_xor = [a[i % n] ^ a[(i + 1) % n] for i in range(n * 2)]
b_xor = [b[i % n] ^ b[(i + 1) % n] for i in range(n * 2)]
a_xor_rh = RollingHashMulti(a_xor)
b_xor_rh = RollingHashMulti(b_xor)
for k in range(n):
	if a_xor_rh.get_hash(k, k + n) == b_xor_rh.get_hash(0, n):
		x = a[k] ^ b[0]
		print(k, x)


n = int(input())
b = list(map(int, input().split()))
a = list(map(int, input().split()))
a2 = [a[i] ^ a[i - 1] for i in range(n)]
b2 = [b[i] ^ b[i - 1] for i in range(n)]
b2 = b2 + b2
base = 37
mod = 10 ** 9 + 9
pw = None

def rolling_hash(s):
	l = len(s)
	h = [0] * (l + 1)
	v = 0
	for i in range(l):
		h[i + 1] = v = (v * base + s[i]) % mod
	return h

def setup_pw(l):
	global pw
	pw = [1] * (l + 1)
	v = 1
	for i in range(l):
		pw[i + 1] = v = v * base % mod

def get(h, l, r):
	return (h[r] - h[l] * pw[r - l]) % mod
setup_pw(n * 2)
bh = rolling_hash(b2)
ah = rolling_hash(a2)
ans = []
get_a = get(ah, 0, n)
for k in range(n):
	if get(bh, k, k + n) == get_a:
		ans.append(k)
for k in ans:
	x = b[k] ^ a[0]
	print(k, x)


import re
N = int(input())
A = list(map(lambda x: bin(int(x))[2:], input().split()))
B = list(map(lambda x: bin(int(x))[2:], input().split()))
keta = max(max(map(len, A)), max(map(len, B)))

def xor(a, b):
	while keta > len(b):
		b = '0' + b
	while keta > len(a):
		a = '0' + a
	ret = ''
	for (a_, b_) in zip(a, b):
		ret += '0' if a_ == b_ else '1'
	return ret

def create_table(pattern):
	table = [0 for _ in range(len(pattern) + 1)]
	j = 0
	for i in range(1, len(pattern)):
		if pattern[i] == pattern[j]:
			j += 1
			table[i] = j
		else:
			table[i] = j
			j = 0
	table[i + 1] = j
	return table

def kmp_search(string, pattern):
	ret = []
	table = create_table(pattern)
	i = j = 0
	while i < len(string):
		if string[i] == pattern[j]:
			i += 1
			j += 1
		elif j == 0:
			i += 1
		else:
			j = table[j]
		if j == len(pattern):
			ret.append(i - j)
			j = table[j]
	else:
		return ret

def bm_search(string, pattern):
	ret = []
	pat_len = len(pattern)
	skip = [pat_len for _ in range(256)]
	for i in range(pat_len):
		skip[ord(pattern[i])] = pat_len - i - 1
	i = pat_len - 1
	while i < len(string):
		j = pat_len - 1
		while string[i] == pattern[j]:
			if j == 0:
				ret.append(i)
			i -= 1
			j -= 1
		i = i + max(skip[ord(string[i])], pat_len - j)
	return ret
(C, D) = ([], [])
for i in range(N - 1):
	C.append(xor(A[i], A[i + 1]))
	D.append(xor(B[i], B[i + 1]))
C.append(xor(A[-1], A[0]))
D.append(xor(B[-1], B[0]))
for k in kmp_search(D + D, C)[::-1]:
	if k == 0:
		continue
	print(N - k, int(xor(A[N - k], B[0]), 2))


def check(ccc, ddd, e, ans):
	m = 2147483647
	g = 1000000007
	for l in range(e):
		cl = ccc[l]
		if any((c != cl for c in ccc[l::e])):
			return
		dl = ddd[l]
		if any((d != dl for d in ddd[l::e])):
			return
	s = 0
	for c in ccc[:e]:
		s = (s * g + c) % m
	t = 0
	for d in ddd[:e]:
		t = (t * g + d) % m
	u = pow(g, e, m)
	for h in range(e):
		if s == t:
			bh = bbb[h]
			ans.update((((i - h) % n, aaa[i] ^ bh) for i in range(0, n, e)))
			return
		t = (t * g + ddd[(e + h) % n] - ddd[h] * u) % m

def solve(n, aaa, bbb):
	ccc = [a1 ^ a2 for (a1, a2) in zip(aaa, aaa[1:])] + [aaa[-1] ^ aaa[0]]
	ddd = [b1 ^ b2 for (b1, b2) in zip(bbb, bbb[1:])] + [bbb[-1] ^ bbb[0]]
	ans = set()
	e = 1
	while e * e <= n:
		if n % e != 0:
			e += 1
			continue
		check(ccc, ddd, e, ans)
		check(ccc, ddd, n // e, ans)
		e += 1
	return ans
n = int(input())
aaa = list(map(int, input().split()))
bbb = list(map(int, input().split()))
ans = solve(n, aaa, bbb)
print(''.join(('{} {}\n'.format(*answer) for answer in sorted(ans))))


def xor_next(values):
	result = [0] * len(values)
	for i in range(len(values)):
		result[i] = values[i] ^ values[(i + 1) % len(values)]
	return result

def make_mp_table(values):
	result = [-1] * (len(values) + 1)
	j = -1
	for i in range(len(values)):
		while j != -1 and values[j] != values[i]:
			j = result[j]
		j += 1
		result[i + 1] = j
	return result

def mp_find(target, pattern, table):
	result = []
	j = 0
	for i in range(len(target)):
		while j != -1 and pattern[j] != target[i]:
			j = table[j]
		j += 1
		if j == len(pattern):
			result.append(i - (j - 1))
			j = table[j]
	return result

def main():
	n = int(input())
	a = list(map(int, input().split()))
	b = list(map(int, input().split()))
	xa = xor_next(a)
	xb = xor_next(b)
	mp_t = make_mp_table(xa)
	xb += xb
	res = mp_find(xb, xa, mp_t)
	res.sort(reverse=True)
	for i in range(len(res)):
		k = n - res[i]
		if k >= n:
			continue
		x = a[k] ^ b[0]
		print(str(k) + ' ' + str(x))
main()


n = int(input())
a = list(map(int, input().split()))
b = list(map(int, input().split()))
a = a + a[:-1]
da = [a[i] ^ a[i + 1] for i in range(len(a) - 1)]
db = [b[i] ^ b[i + 1] for i in range(len(b) - 1)]
fail = [0 for i in range(len(da))]
fail[0] = -1
p = 0
for q in range(2, len(da)):
	while p >= 0 and da[q - 1] != da[p]:
		p = fail[p]
	p += 1
	fail[q] = p
p = 0
q = 0
while p + q < len(da):
	if db[q] == da[p + q]:
		if q == len(db) - 1:
			print(p, a[p] ^ b[0])
			p += q - fail[q]
			q = fail[q]
		else:
			q += 1
	else:
		p += q - fail[q]
		if q > 0:
			q = fail[q]


def Z_algorithm(s):
	n = len(s)
	A = [n] + [0] * (n - 1)
	(i, j) = (1, 0)
	while i < n:
		while i + j < n and s[j] == s[i + j]:
			j += 1
		A[i] = j
		if j == 0:
			i += 1
			continue
		k = 1
		while i + k < n and k + A[k] < j:
			A[i + k] = A[k]
			k += 1
		i += k
		j -= k
	return A
N = int(input())
A = [int(a) for a in input().split()]
B = [int(a) for a in input().split()]
AA = [A[i] ^ A[i - 1] for i in range(N)]
BB = [B[i] ^ B[i - 1] for i in range(N)]
T = Z_algorithm(AA + BB + BB)
for i in range(N, 0, -1):
	if T[N + i] >= N:
		print(N - i, A[-i % N] ^ B[0])


N = int(input())
A = list(map(int, input().split()))
B = list(map(int, input().split()))
C = [0] * (2 * N - 1)
D = [0] * N
for i in range(2 * N - 1):
	C[i] = A[i % N] ^ A[(i + 1) % N]
	D[i % N] = B[i % N] ^ B[(i + 1) % N]

class KMP:

	def __init__(self, W):
		self.W = W
		self.L = len(W)
		self.T = self._build(W)

	def _build(self, W):
		T = [0] * self.L
		T[0] = -1
		T[1] = 0
		i = 2
		j = 0
		while i < self.L:
			if W[i - 1] == W[j]:
				T[i] = j + 1
				i += 1
				j += 1
			elif j > 0:
				j = T[j]
			else:
				T[i] = 0
				i += 1
		return T

	def search(self, S):
		m = 0
		i = 0
		L = len(S)
		while m + i < L:
			if self.W[i] == S[m + i]:
				i += 1
				if i == self.L:
					i -= 1
					ret = m
					m = m + i - self.T[i]
					i = self.T[i]
					yield ret
			else:
				m = m + i - self.T[i]
				if i > 0:
					i = self.T[i]
kmp = KMP(D)
for x in kmp.search(C):
	xor = A[x] ^ B[0]
	print(x, xor)


def get_next_int():
	return int(input().rstrip('\n'))

def get_next_ints(delim=' '):
	return tuple([int(x) for x in input().rstrip('\n').split(delim)])

def main():
	n = get_next_int()
	a = get_next_ints()
	b = get_next_ints()
	a_offsets = []
	b_offsets = []
	for i in range(n):
		a_offsets.append(str(a[i] ^ a[i - 1]))
		b_offsets.append(str(b[i] ^ b[i - 1]))
	a_text = ' '.join(a_offsets)
	b_text = ' '.join(b_offsets)
	target_text = a_text + ' ' + a_text
	start_pos = 0
	if target_text.find(b_text, start_pos) >= 0:
		fisrt_pos = target_text.find(b_text, start_pos)
		fisrt_pos_diff = target_text[:fisrt_pos].count(' ')
		fisrt_xor_diff = b[0] ^ a[fisrt_pos_diff]
		print(fisrt_pos_diff, fisrt_xor_diff)
		if target_text.find(b_text, fisrt_pos + 1) >= 0:
			second_pos = target_text.find(b_text, fisrt_pos + 1)
			second_pos_diff = target_text[:second_pos].count(' ')
			if second_pos_diff < len(a):
				second_xor_diff = b[0] ^ a[second_pos_diff]
				print(second_pos_diff, second_xor_diff)
				interval = second_pos_diff - fisrt_pos_diff
				remain = (n - second_pos_diff - 1) // (second_pos_diff - fisrt_pos_diff)
				for i in range(remain):
					print(second_pos_diff + interval * (i + 1), [fisrt_xor_diff, second_xor_diff][i % 2])
main()


N = int(input())
A = list(map(int, input().split()))
B = list(map(int, input().split()))
A.append(A[0])
B.append(B[0])
AX = []
BX = []
for i in range(N):
	AX.append(A[i] ^ A[i + 1])
	BX.append(B[i] ^ B[i + 1])
AX += AX + [AX[0]]
p = 1 << 30
mod = (1 << 62) + 1
A_TABLE = [0]
B_TABLE = [0]
for i in range(len(AX)):
	A_TABLE.append((p * A_TABLE[-1] % mod + AX[i]) % mod)
for i in range(len(BX)):
	B_TABLE.append((p * B_TABLE[-1] % mod + BX[i]) % mod)

def hash(i, j):
	return (A_TABLE[j] - A_TABLE[i] * pow(p, j - i, mod)) % mod
BH = B_TABLE[-1]
ANS = []
for i in range(N):
	if hash(i, i + N) == BH:
		ANS.append((i, A[i] ^ B[0]))
for a in ANS:
	print(*a)


import sys
from operator import xor
from functools import reduce
readline = sys.stdin.readline
mod = 10 ** 18 + 3
base = 10 ** 9 + 9

def rollinghash(S):
	N = len(S)
	has = [0] * (N + 1)
	power = [1] * (N + 1)
	for i in range(N):
		s = S[i]
		has[i + 1] = (has[i] * base + s) % mod
		power[i + 1] = power[i] * base % mod
	return (has, power)

def rh(i, j):
	return (has[j] - has[i] * power[j - i]) % mod

def rotate(k):
	pass
N = int(readline())
A = list(map(int, readline().split()))
B = list(map(int, readline().split()))
CA = [a1 ^ a2 for (a1, a2) in zip(A, A[1:])]
CA.append(A[0] ^ A[-1])
CB = [a1 ^ a2 for (a1, a2) in zip(B, B[1:])]
CB.append(B[0] ^ B[-1])
rA = [1 + ca for ca in CA]
(has, power) = rollinghash(rA)
R = rh(0, N)
HA = [None] * N
suf = pow(base, N - 1, mod)
for i in range(N):
	HA[i] = R
	R = ((R - suf * rA[i]) * base + rA[i]) % mod
rB = [1 + cb for cb in CB]
(has, power) = rollinghash(rB)
R = rh(0, N)
Ans = []
for i in range(N):
	if HA[i] == R:
		Ans.append((i, A[i] ^ B[0]))
if Ans:
	print('\n'.join((' '.join(map(str, a)) for a in Ans)))


import sys
input = sys.stdin.readline

def main():

	def I():
		return int(input())

	def MI():
		return map(int, input().split())

	def LI():
		return list(map(int, input().split()))
	mod = 10 ** 9 + 7

	def Z(s):
		n = len(s)
		lcp = [0] * n
		lcp[0] = n
		(L, R) = (0, 0)
		for i in range(1, n):
			if i >= R:
				L = i
				R = i
				while R < n and s[R - L] == s[R]:
					R += 1
				lcp[i] = R - L
			elif lcp[i - L] < R - i:
				lcp[i] = lcp[i - L]
			else:
				L = i
				while R < n and s[R - L] == s[R]:
					R += 1
				lcp[i] = R - L
		return lcp
	N = I()
	a = LI()
	b = LI()
	a += [a[0]]
	b += [b[0]]
	a2 = [0] * N
	b2 = [0] * N
	for i in range(N):
		a2[i] = a[i + 1] ^ a[i]
		b2[i] = b[i + 1] ^ b[i]
	K = []
	abb = a2 + b2 + b2
	L = Z(abb)
	for i in range(N, 2 * N, 1):
		if L[i] >= N:
			K.append((2 * N - i) % N)
	X = []
	for k in K:
		x = b[0] ^ a[k]
		X.append(x)
	if K != []:
		(K, X) = zip(*sorted(zip(K, X)))
	else:
		exit()
	for i in range(len(K)):
		print(K[i], X[i])
main()