#include <bits/stdc++.h>
using namespace std;
template <typename T, typename U>
bool ckmin(T &a, U b) {
  return b < a ? a = b, true : false;
}
template <typename T, typename U>
bool ckmax(T &a, U b) {
  return b > a ? a = b, true : false;
}
struct DSU {
  int SZ;
  vector<int> p, r, second;
  DSU(int sz) : SZ(sz) {
    p.assign(SZ, 0);
    iota(p.begin(), p.end(), 0);
    r.assign(SZ, 0);
    second.assign(SZ, 1);
  }
  pair<int, int> find(int u) {
    if (p[u] == u) return {u, 0};
    pair<int, int> cur = find(p[u]);
    r[u] ^= cur.second;
    p[u] = cur.first;
    return {p[u], r[u]};
  }
  void merge(int u, int v, int x) {
    pair<int, int> up = find(u), vp = find(v);
    if (up.first == vp.first) return;
    if (second[up.first] < second[vp.first]) swap(up, vp);
    second[up.first] += second[vp.first], p[vp.first] = up.first;
    r[vp.first] = x ^ up.second ^ vp.second;
  }
};
int q, prv = 0, cnt = 0;
map<int, int> m;
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(NULL);
  cin >> q;
  DSU st(2 * q + 5);
  while (q--) {
    int v, l, r;
    cin >> v >> l >> r;
    l ^= prv, r ^= prv;
    l--, r--, v--;
    if (l > r) swap(l, r);
    r++;
    if (m.find(l) == m.end()) m[l] = cnt++;
    if (m.find(r) == m.end()) m[r] = cnt++;
    l = m[l], r = m[r];
    if (v) {
      pair<int, int> a = st.find(l), b = st.find(r);
      if (a.first != b.first)
        cout << "-1\n", prv = 1;
      else
        cout << (a.second ^ b.second) << "\n", prv = a.second ^ b.second;
    } else {
      int x;
      cin >> x;
      x ^= prv;
      st.merge(l, r, x);
    }
  }
  return 0;
}
