#include <bits/stdc++.h>
using namespace std;
const int maxn = 8e5 + 5;
int Q;
int sz = 4e5 + 1;
struct node {
  int par[maxn];
  int size[maxn];
  void init() {
    for (int i = 0; i <= 2 * sz; i++) par[i] = i, size[i] = 1;
  }
  int fd(int x) { return x == par[x] ? x : par[x] = fd(par[x]); }
  void unite(int x, int y) {
    x = fd(x);
    y = fd(y);
    if (x == y) return;
    if (size[x] > size[y]) swap(x, y);
    par[x] = y;
    size[y] += size[x];
  }
  int ask(int x, int y) {
    if (fd(x) == fd(y) || fd(x + sz) == fd(y + sz)) return 0;
    if (fd(x) == fd(y + sz) || fd(x + sz) == fd(y)) return 1;
    return -1;
  }
} a[32];
map<int, int> mp;
int z;
int ask(int l, int r) {
  if (!mp.count(r) || !mp.count(l - 1)) {
    return -1;
  }
  int u = mp[l - 1];
  int v = mp[r];
  int x = 0;
  for (int i = 30; i >= 0; i--) {
    x <<= 1;
    int t = a[i].ask(u, v);
    if (t == -1) return -1;
    x += t;
  }
  return x;
}
int main() {
  for (int i = 0; i <= 29; i++) a[i].init();
  scanf("%d", &Q);
  int l, r, x;
  int last = 0;
  int tot = 0;
  while (Q--) {
    scanf("%d", &z);
    if (z == 1) {
      scanf("%d%d%d", &l, &r, &x);
      l ^= last;
      r ^= last;
      x ^= last;
      if (l > r) swap(l, r);
      if (!mp.count(r)) mp[r] = ++tot;
      if (!mp.count(l - 1)) mp[l - 1] = ++tot;
      int t = ask(l, r);
      if (t == -1) {
        int u = mp[l - 1];
        int v = mp[r];
        for (int i = 0; i <= 29; i++, x >>= 1) {
          if (x & 1)
            a[i].unite(u, v + sz), a[i].unite(v, u + sz);
          else
            a[i].unite(u, v), a[i].unite(u + sz, v + sz);
        }
      }
    } else {
      scanf("%d%d", &l, &r);
      l ^= last;
      r ^= last;
      if (l > r) swap(l, r);
      int t = ask(l, r);
      last = t;
      printf("%d\n", t);
      if (t == -1) last = 1;
    }
  }
  return 0;
}
