#include <bits/stdc++.h>
using namespace std;
int n, m, q;
map<pair<int, int>, int> mp, tim;
pair<int, int> qry[200004];
vector<pair<pair<int, int>, int> > g[524300];
void updqry(int l, int r, int id, int a, int b, pair<pair<int, int>, int> x) {
  if (r < a || b < l) return;
  if (a <= l && r <= b) {
    g[id].push_back(x);
    return;
  }
  int mid = (l + r) >> 1;
  updqry(l, mid, id << 1, a, b, x), updqry(mid + 1, r, id << 1 | 1, a, b, x);
}
int bas[30];
void ins(int x) {
  for (int i = 29; ~i; i--)
    if ((1 << i) & x) {
      if (!bas[i]) {
        bas[i] = x;
        break;
      }
      x ^= bas[i];
    }
}
int f[200004], xorsum[200004], dep[200004];
stack<pair<pair<int, int>, int> > st;
pair<int, int> F(int x) {
  int res = 0;
  while (f[x] != x) res ^= xorsum[x], x = f[x];
  return make_pair(x, res);
}
void merge(int x, int y, int d) {
  if (dep[x] > dep[y]) swap(x, y);
  st.push(make_pair(make_pair(x, y), dep[y]));
  dep[y] = max(dep[y], dep[x] + 1);
  xorsum[x] = d, f[x] = y;
}
void solsegtree(int l, int r, int id) {
  int bas1[30];
  for (int i = 0; i < 30; i++) bas1[i] = bas[i];
  int cur = st.size();
  for (auto x : g[id]) {
    int u = x.first.first, v = x.first.second, d = x.second;
    pair<int, int> uu = F(u), vv = F(v);
    if (uu.first != vv.first)
      merge(uu.first, vv.first, d ^ uu.second ^ vv.second);
    else
      ins(uu.second ^ vv.second ^ d);
  }
  if (l != r) {
    int mid = (l + r) >> 1;
    solsegtree(l, mid, id << 1), solsegtree(mid + 1, r, id << 1 | 1);
  } else if (qry[l].first != 0) {
    int u = qry[l].first, v = qry[l].second;
    pair<int, int> uu = F(u), vv = F(v);
    int ans = uu.second ^ vv.second;
    for (int i = 29; ~i; i--)
      if (ans > (ans ^ bas[i])) ans ^= bas[i];
    printf("%d\n", ans);
  }
  for (int i = 0; i < 30; i++) bas[i] = bas1[i];
  while (st.size() > cur) {
    pair<pair<int, int>, int> x = st.top();
    st.pop();
    xorsum[x.first.first] = 0, f[x.first.first] = x.first.first;
    dep[x.first.second] = x.second;
  }
}
int main() {
  scanf("%d%d", &n, &m);
  for (int i = 1; i <= m; i++) {
    int u, v, d;
    scanf("%d%d%d", &u, &v, &d);
    if (u > v) swap(u, v);
    mp[make_pair(u, v)] = d;
    tim[make_pair(u, v)] = 1;
  }
  scanf("%d", &q);
  for (int i = 1; i <= q; i++) {
    int op, x, y, d;
    scanf("%d%d%d", &op, &x, &y);
    if (x > y) swap(x, y);
    if (op == 1) {
      scanf("%d", &d);
      mp[make_pair(x, y)] = d, tim[make_pair(x, y)] = i;
    }
    if (op == 2) {
      int times = tim[make_pair(x, y)], len = mp[make_pair(x, y)];
      updqry(1, q, 1, times, i - 1, make_pair(make_pair(x, y), len));
      tim[make_pair(x, y)] = 0;
    }
    if (op == 3) qry[i] = make_pair(x, y);
  }
  for (int i = 1; i <= n; i++) f[i] = i;
  for (auto it = tim.begin(); it != tim.end(); it++)
    if ((it->second) != 0)
      updqry(1, q, 1, it->second, q, make_pair(it->first, mp[(it->first)]));
  solsegtree(1, q, 1);
}
