//#undef _DEBUG
//#pragma GCC optimize("Ofast")
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace std;
using namespace std::chrono;
#define int long long //todo 消したら動かない intの代わりにsignedを使う
#define ll long long
auto start_time = system_clock::now();
auto past_time = system_clock::now();

#define debugName(VariableName) # VariableName
//最大引数がN
#define over2(o1, o2, name, ...) name
#define over3(o1, o2, o3, name, ...) name
#define over4(o1, o2, o3, o4, name, ...) name
#define over5(o1, o2, o3, o4, o5, name, ...) name
#define over6(o1, o2, o3, o4, o5, o6, name, ...) name
#define over7(o1, o2, o3, o4, o5, o6, o7, name, ...) name
#define over8(o1, o2, o3, o4, o5, o6, o7, o8, name, ...) name
#define over9(o1, o2, o3, o4, o5, o6, o7, o8, o9, name, ...) name
#define over10(o1, o2, o3, o4, o5, o6, o7, o8, o9, o10, name, ...) name

#define rand xor128_
/*@formatter:on*/
unsigned long xor128_(void) {
    static unsigned long x = 123456789, y = 362436069, z = 521288629, w = 88675123;
    unsigned long t;
    t = (x ^ (x << 11));
    x = y;
    y = z;
    z = w;
    return (w = (w ^ (w >> 19)) ^ (t ^ (t >> 8)));
}
/*@formatter:on*/
ll rand(ll min, ll max) {
    assert(min <= max);
    if (min >= 0 && max >= 0) { return rand() % (max + 1 - min) + min; } else if (max < 0) { return -rand(-max, -min); } else { if (rand() % 2) { return rand(0, max); } else { return -rand(0, -min); }}
}
#define sz(a) ((int)a.size())
const int inf = (int) 1e9 + 100;

/*@formatter:off*/
//@起動時
struct initon {
    initon() {
        cin.tie(0);
        ios::sync_with_stdio(false);
        cout.setf(ios::fixed);
        cout.precision(16);
        srand((unsigned) clock() + (unsigned) time(NULL));
    };
} initonv;
#define pre prev
#define nex next


//hashを共有したくない場合、中に書く
const uint64_t base = rand((uint64_t) 868491463, ((uint64_t) 1 << 61) - 1 - 1);

//安全で爆速なrollinghash
class roll {
    /*@formatter:on*/
    static constexpr uint64_t mask30 = ((uint64_t) 1 << 30) - 1;
    static constexpr uint64_t mask31 = ((uint64_t) 1 << 31) - 1;
    static constexpr uint64_t mask61 = ((uint64_t) 1 << 61) - 1;
    static constexpr uint64_t offset = mask61 * 7;
    static constexpr uint64_t mod(const uint64_t x) {
        const uint64_t y = (x >> 61) + (x & mask61);
        return y >= mask61 ? y - mask61 : y;
    }
    static constexpr uint64_t mul(const uint64_t x, const uint64_t y) {
        const uint64_t xh = x >> 31, xl = x & mask31;
        const uint64_t yh = y >> 31, yl = y & mask31;
        const uint64_t z = xl * yh + xh * yl;
        const uint64_t zh = z >> 30, zl = z & mask30;
        return xh * yh * 2 + zh + (zl << 31) + xl * yl;
    }
    const std::size_t siz;
    vector<uint64_t> pow, h;
public:
    template<typename T> roll(T &A) : siz(sz(A)), pow(siz + 1, 1), h(siz + 1, 0) { for (std::size_t i = 1; i <= siz; i++) { pow[i] = mod(mul(pow[i - 1], base)), h[i] = mod(mul(h[i - 1], base) + A[i - 1]); }}
    uint64_t operator()(const std::size_t l, const std::size_t r) { return mod(h[r] + offset - mul(h[l], pow[r - l])); }
    uint64_t operator()(int r = inf) { return operator()(0, min((int)siz, r)); }
    // get lcp of S[a:] and T[b:]
    //接頭語がどれだけ一致するか
    //範囲の重複を含む
    int lcp_dup(int a, int b) {
        int len = min((int) siz - a, (int) siz - b);
        int low = 0, high = len;
        while (high - low > 1) {
            int mid = (low + high) >> 1;
            if (operator()(a, a + mid) != operator()(b, b + mid)) high = mid; else low = mid;
        }
        return low;
    }
    //重複を認めない
    int lcp_not(int a, int b) { return min(lcp_dup(a, b), b - a); }//@formatter:on
};
//動かない場合roll2
//roll ro(list);
using vi = vector<int>;
int N;
#define rep(i,a,b) for (int i = a; i < b; i++)

void solve() {
    cin >> N;
    vi A(N), B(N), A2(N), B2(N);
    rep(i, 0, N)cin >> A[i];
    rep(i, 0, N)cin >> B[i];

    rep(i, 0, N)A2[i] = A[i] ^ A[(i + 1) % N];
    rep(i, 0, N)B2[i] = B[i] ^ B[(i + 1) % N];

    vector<signed> v;
    rep(i, 0, N)v.push_back(A2[i]);
    rep(i, 0, N)v.push_back(A2[i]);
    rep(i, 0, N)v.push_back(B2[i]);

    roll rh(v);

    rep(k, 0, N)
    if (rh(k, k + N) == rh(N * 2, N * 2 + N)) {
        int x = A[k] ^B[0];
        cout<<k<<" "<<x<<endl;
    }
}


auto my(ll n, vi &a) {
    return 0;
}

auto sister(ll n, vi &a) {
    ll ret = 0;
    return ret;
}

signed main() {
    solve();
    return 0;
};


Measured memory_bytes: 22892