#include <bits/stdc++.h>
using namespace std;
int n, m, Q, cnt, top, head[400100], vis[8 * 400100], que[400100 * 2],
    lst[400100 * 8], sta[400100 * 8];
struct point {
  int x, y, z, l, r, p;
} q[400100 * 2];
struct edge {
  int x, y, z;
};
struct bcj {
  int fa, dis, sz;
} b[400100], ys[400100 * 8];
struct xxj {
  int d[32];
  void insert(int x) {
    for (int i = 30; i >= 0; i--)
      if (x & (1 << i)) {
        if (!d[i]) d[i] = x;
        x ^= d[i];
      }
  }
  int get_min(int x) {
    for (int i = 30; i >= 0; i--)
      if (x & (1 << i)) x ^= d[i];
    return x;
  }
} D[25];
vector<edge> v[400100 * 8];
map<pair<int, int>, int> mp;
int get_dis(int x, int &ret) {
  while (x != b[x].fa) ret ^= b[x].dis, x = b[x].fa;
  return x;
}
void modify(int x, int l, int r, int L, int R, edge p) {
  if (l >= L && r <= R) return v[x].push_back(p), void();
  int mid = (l + r) >> 1;
  if (L <= mid) modify(x << 1, l, mid, L, R, p);
  if (R > mid) modify(x << 1 | 1, mid + 1, r, L, R, p);
}
void add(int x, int l, int r, int pos) {
  vis[x] = 1;
  int mid = (l + r) >> 1;
  if (l == r) return;
  if (pos <= mid)
    add(x << 1, l, mid, pos);
  else
    add(x << 1 | 1, mid + 1, r, pos);
}
void solve(int x, int l, int r, int d) {
  lst[x] = top;
  D[d] = D[d - 1];
  for (int i = 0; i < v[x].size(); i++) {
    edge now = v[x][i];
    int fx, fy, dis1 = 0, dis2 = 0;
    fx = get_dis(now.x, dis1), fy = get_dis(now.y, dis2);
    sta[++top] = fx;
    ys[top] = b[fx];
    sta[++top] = fy;
    ys[top] = b[fy];
    if (fx == fy)
      D[d].insert(dis1 ^ dis2 ^ now.z);
    else {
      if (b[fx].sz < b[fy].sz) swap(fx, fy);
      b[fy].fa = fx;
      b[fy].dis = dis1 ^ dis2 ^ now.z;
      b[fx].sz += b[fy].sz;
    }
  }
  if (l == r) {
    int L = q[que[l]].x, R = q[que[l]].y, w = 0;
    get_dis(L, w);
    get_dis(R, w);
    printf("%d\n", D[d].get_min(w));
    return;
  }
  int mid = (l + r) >> 1;
  if (vis[x << 1]) solve(x << 1, l, mid, d + 1);
  if (vis[x << 1 | 1]) solve(x << 1 | 1, mid + 1, r, d + 1);
  while (top > lst[x]) b[sta[top]] = ys[top--];
}
int main() {
  scanf("%d%d", &n, &m);
  for (int i = 1, x, y, z; i <= m; i++) {
    scanf("%d%d%d", &x, &y, &z);
    mp[make_pair(x, y)] = ++cnt;
    q[cnt].x = x;
    q[cnt].y = y;
    q[cnt].z = z;
    q[cnt].l = 1;
  }
  scanf("%d", &Q);
  for (int i = 1, opt, x, y, z; i <= Q; i++) {
    scanf("%d%d%d", &opt, &x, &y);
    if (opt == 1) {
      scanf("%d", &z);
      mp[make_pair(x, y)] = ++cnt;
      q[cnt].x = x;
      q[cnt].y = y;
      q[cnt].z = z;
      q[cnt].l = i;
    } else if (opt == 2)
      q[mp[make_pair(x, y)]].r = i;
    else
      q[++cnt].x = x, q[cnt].y = y, q[cnt].p = i;
  }
  for (int i = 1; i <= cnt; i++)
    if (!q[i].p && !q[i].r) q[i].r = Q;
  for (int i = 1; i <= cnt; i++)
    if (!q[i].p)
      modify(1, 1, Q, q[i].l, q[i].r, (edge){q[i].x, q[i].y, q[i].z});
    else
      add(1, 1, Q, q[i].p), que[q[i].p] = i;
  for (int i = 1; i <= n; i++) b[i].fa = i, b[i].sz = 1;
  solve(1, 1, Q, 1);
}
