#include <bits/stdc++.h>
using namespace std;
const int maxn = 2e5 + 7;
int fa[maxn], val[maxn], sz[maxn], b[40], top, cx[maxn], cy[maxn];
int typ[maxn];
struct node {
  int a, b, c, d;
  node(int a = 0, int b = 0, int c = 0, int d = 0) {
    this->a = a, this->b = b, this->c = c, this->d = d;
  }
  inline friend bool operator<(const node &x, const node &y) {
    return x.a == y.a ? x.b < y.b : x.a < y.a;
  }
  inline void update() { fa[a] = b, val[a] = c, sz[a] = d; }
} sta[maxn << 2];
map<node, int> mp;
vector<node> cs[maxn << 2];
inline void ins(int x) {
  for (int i = 29; ~i; --i)
    if ((x >> i) & 1) {
      if (!b[i]) {
        b[i] = x;
        return;
      } else
        x ^= b[i];
    }
}
inline int que(int x) {
  for (int i = 29; ~i; --i)
    if ((x ^ b[i]) < x) x ^= b[i];
  return x;
}
int find(int x) { return fa[x] == x ? x : find(fa[x]); }
int getval(int x) { return fa[x] == x ? 0 : (val[x] ^ getval(fa[x])); }
void merge(int x, int y, int z) {
  int fx = find(x), fy = find(y);
  if (sz[fx] < sz[fy]) swap(x, y), swap(fx, fy);
  if (fx == fy)
    ins(getval(x) ^ getval(y) ^ z);
  else
    sta[++top] = node(fy, fa[fy], val[fy], sz[fy]),
    sta[++top] = node(fx, fa[fx], val[fx], sz[fx]),
    val[fy] = getval(x) ^ getval(y) ^ z, fa[fy] = fx, sz[fx] += sz[fy];
}
void solve(int k, int l, int r) {
  int tmp = top, t[40];
  for (int i = 0; i < 30; ++i) t[i] = b[i];
  for (node x : cs[k]) merge(x.a, x.b, x.c);
  if (l == r) {
    if (typ[l] == 3) printf("%d\n", que(getval(cx[l]) ^ getval(cy[l])));
  } else {
    int mid = l + r >> 1;
    solve(k << 1, l, mid), solve(k << 1 | 1, mid + 1, r);
  }
  while (top > tmp) sta[top--].update();
  for (int i = 0; i < 30; ++i) b[i] = t[i];
}
void insert(int k, int l, int r, int gl, int gr, node x) {
  if (gl > gr) return;
  if (l >= gl && r <= gr) return cs[k].push_back(x), void();
  int mid = l + r >> 1;
  if (gl <= mid) insert(k << 1, l, mid, gl, gr, x);
  if (gr > mid) insert(k << 1 | 1, mid + 1, r, gl, gr, x);
}
int main() {
  int n, m;
  cin >> n >> m;
  for (int i = 1; i <= n; ++i) fa[i] = i, sz[i] = 1;
  for (int i = 1; i <= m; ++i) {
    int a, b, c;
    scanf("%d%d%d", &a, &b, &c);
    if (a > b) swap(a, b);
    mp[node(a, b, c)] = 0;
  }
  int q;
  cin >> q;
  for (int i = 1; i <= q; ++i) {
    int a, b, c;
    scanf("%d%d%d", &typ[i], &a, &b);
    if (a > b) swap(a, b);
    if (typ[i] == 1)
      scanf("%d", &c), mp[node(a, b, c)] = i;
    else if (typ[i] == 2)
      insert(1, 1, q, mp[node(a, b)] + 1, i, mp.find(node(a, b))->first),
          mp[node(a, b)] = -1;
    else
      cx[i] = a, cy[i] = b;
  }
  for (auto it = mp.begin(); it != mp.end(); ++it)
    if (~it->second) insert(1, 1, q, it->second + 1, q, it->first);
  solve(1, 1, q);
  return 0;
}
