#include <bits/stdc++.h>
using namespace std;
map<int, int> mp;
int tot = 1;
const int MAXN = 5e5 + 5;
int pa[MAXN];
int v[MAXN];
int getId(int x) {
  int tmp = mp[x];
  if (tmp) {
    return tmp;
  }
  mp[x] = tot;
  pa[tot] = tot;
  return tot++;
}
int findRoot(int x) {
  if (pa[x] == x) {
    return x;
  }
  if (pa[pa[x]] == pa[x]) {
    return pa[x];
  }
  int tmp = findRoot(pa[x]);
  v[x] = v[x] ^ v[pa[x]];
  pa[x] = pa[pa[x]];
  return tmp;
}
void unite(int a, int b, int val) {
  int ra = findRoot(a), rb = findRoot(b);
  v[rb] = val ^ v[b];
  pa[rb] = a;
}
int main() {
  int q;
  scanf("%d", &q);
  int lastans = 0;
  while (q--) {
    int cmd;
    scanf("%d", &cmd);
    if (cmd == 1) {
      int l, r, va;
      scanf("%d%d%d", &l, &r, &va);
      l ^= lastans;
      r ^= lastans;
      va ^= lastans;
      if (l > r) {
        swap(l, r);
      }
      r++;
      int id1 = mp[l], id2 = mp[r];
      if (id1 == 0 || id2 == 0 || findRoot(id1) != findRoot(id2)) {
        l = getId(l), r = getId(r);
        unite(l, r, va);
      }
    } else {
      int l, r;
      scanf("%d%d", &l, &r);
      l ^= lastans;
      r ^= lastans;
      if (l > r) {
        swap(l, r);
      }
      r++;
      int id1 = mp[l], id2 = mp[r];
      if (id1 == 0 || id2 == 0 || findRoot(id1) != findRoot(id2)) {
        puts("-1");
        lastans = 1;
      } else {
        printf("%d\n", v[id2] ^ v[id1]);
        lastans = v[id2] ^ v[id1];
      }
    }
  }
  return 0;
}
