#include <bits/stdc++.h>
using namespace std;
struct edge {
  int u, v, w, x, y;
} e[400050];
vector<edge> g[800050];
map<pair<int, int>, int> mp;
int val[200050], fa[200050], sz[200050];
int stk[400050], top;
void Update(int rt, int l, int r, edge a) {
  if (a.x > a.y) return;
  if (l > r || l > a.y || r < a.x) return;
  if (a.x <= l && r <= a.y) {
    g[rt].push_back(a);
    return;
  }
  if (l == r) return;
  int mid = (l + r) >> 1;
  Update(rt << 1, l, mid, a);
  Update(rt << 1 | 1, mid + 1, r, a);
}
int find_fa(int rt) { return fa[rt] == rt ? rt : find_fa(fa[rt]); }
int find_val(int rt) { return fa[rt] == rt ? 0 : val[rt] ^ find_val(fa[rt]); }
int base[75][35];
void ins(int k, int dep) {
  for (int i = 0; i < g[k].size(); ++i) {
    edge e = g[k][i];
    int u = e.u, v = e.v, w = e.w, x = u, y = v;
    u = find_fa(u);
    v = find_fa(v);
    if (u != v) {
      if (sz[u] > sz[v]) swap(u, v), swap(x, y);
      fa[u] = v;
      sz[v] += sz[u];
      val[u] = 0;
      val[u] = find_val(x) ^ find_val(y) ^ w;
      stk[++top] = u;
    } else {
      w = find_val(x) ^ find_val(y) ^ e.w;
      for (int j = 30; j >= 0; --j)
        if (w & (1 << j))
          if (base[dep][j] == 0) {
            base[dep][j] = w;
            for (int k = 30; k > j; --k)
              if (base[dep][k] & (1 << j)) base[dep][k] ^= w;
            break;
          } else
            w ^= base[dep][j];
    }
  }
}
void reset(int to) {
  while (top > to) {
    int u = stk[top--];
    sz[fa[u]] -= sz[u];
    val[u] = 0;
    fa[u] = u;
  }
}
struct qqq {
  int u, v;
} qst[200050];
void solv(int k, int l, int r, int dep) {
  if (l > r) return;
  int tmp = top;
  ins(k, dep);
  if (l == r) {
    int x = qst[l].u, y = qst[l].v;
    int ans = find_val(x) ^ find_val(y);
    for (int i = 30; i >= 0; --i)
      if (base[dep][i]) ans = min(ans, ans ^ base[dep][i]);
    printf("%d\n", ans);
    reset(tmp);
    return;
  }
  int mid = (l + r) >> 1;
  for (int i = 0; i <= 30; ++i) base[dep + 1][i] = base[dep][i];
  solv(k << 1, l, mid, dep + 1);
  for (int i = 0; i <= 30; ++i) base[dep + 1][i] = base[dep][i];
  solv(k << 1 | 1, mid + 1, r, dep + 1);
  reset(tmp);
}
int n, m, q;
int main() {
  scanf("%d%d", &n, &m);
  int totq = 0, ecnt = 0;
  for (int i = 1; i <= m; ++i) {
    ecnt++;
    int u, v, w;
    scanf("%d%d%d", &u, &v, &w);
    e[ecnt] = (edge){u, v, w, 1, -1};
    mp[make_pair(u, v)] = ecnt;
  }
  scanf("%d", &q);
  for (int i = 1; i <= q; ++i) {
    int op, x, y, d;
    scanf("%d", &op);
    if (op == 1) {
      scanf("%d%d%d", &x, &y, &d);
      e[++ecnt] = (edge){x, y, d, totq + 1, -1};
      mp[make_pair(x, y)] = ecnt;
    } else {
      scanf("%d%d", &x, &y);
      if (op == 2) {
        e[mp[make_pair(x, y)]].y = totq;
        mp[make_pair(x, y)] = 0;
      } else {
        qst[++totq] = (qqq){x, y};
      }
    }
  }
  for (int i = 1; i <= ecnt; ++i)
    if (e[i].y == -1) e[i].y = totq;
  for (int i = 1; i <= ecnt; ++i) Update(1, 1, totq, e[i]);
  for (int i = 1; i <= n; ++i) fa[i] = i, sz[i] = 1;
  solv(1, 1, totq, 0);
}
