#include <bits/stdc++.h>
using namespace std;
struct Val {
  int fa;
  int val;
};
map<int, Val> mp;
int find(int x) {
  if (mp[x].fa == x) return x;
  int k = find(mp[x].fa);
  mp[x].val ^= mp[mp[x].fa].val;
  mp[x].fa = k;
  return k;
}
void merge(int l, int r, int c) {
  l--;
  if (!mp.count(l)) mp[l] = (Val){l, 0};
  if (!mp.count(r)) mp[r] = (Val){r, 0};
  int f1 = find(l), f2 = find(r);
  if (f1 == f2) return;
  int x = mp[l].val;
  int y = mp[r].val;
  if (!mp.count(f1)) mp[f1] = (Val){f1, 0};
  if (!mp.count(f2)) mp[f2] = (Val){f2, 0};
  if (f1 > f2) swap(f1, f2);
  mp[f2].fa = f1;
  mp[f2].val = x ^ y ^ c;
  return;
}
int query(int l, int r) {
  l--;
  if (!mp.count(l) || !mp.count(r)) return -1;
  int f1 = find(l);
  int f2 = find(r);
  if (f1 != f2) return -1;
  return mp[r].val ^ mp[l].val;
}
int main() {
  int q;
  scanf("%d", &q);
  int last = 0;
  while (q--) {
    int t;
    scanf("%d", &t);
    if (t == 1) {
      int l, r, x;
      scanf("%d %d %d", &l, &r, &x);
      l ^= last;
      r ^= last;
      x ^= last;
      if (l > r) swap(l, r);
      merge(l, r, x);
    } else {
      int l, r;
      scanf("%d %d", &l, &r);
      l ^= last;
      r ^= last;
      if (l > r) swap(l, r);
      last = query(l, r);
      printf("%d\n", last);
      if (last == -1) last = 1;
    }
  }
  return 0;
}
