#include <bits/stdc++.h>
using namespace std;
struct basis {
  int vis[29 + 1];
  void ins(int x) {
    for (int i = 29; i >= 0; i--)
      if ((1 << i) & x) {
        if (vis[i])
          x ^= vis[i];
        else {
          vis[i] = x;
          break;
        }
      }
  }
  int minimize(int x) {
    for (int i = 29; i >= 0; i--) {
      if ((x ^ vis[i]) < x) x ^= vis[i];
    }
    return x;
  }
};
void merge(basis &a, basis b) {
  for (int i = 0; i <= 29; i++) a.ins(b.vis[i]);
}
namespace violet {
int pa[65536 * 4];
int size[65536 * 4];
basis bas[65536 * 4];
int topa[65536 * 4];
vector<int> dex, desize, depa, detopa;
vector<basis> debas;
void init() {
  for (int i = 0; i < 65536 * 4; i++) pa[i] = i, size[i] = 1;
}
int findpa(int x) {
  if (pa[x] == x) return x;
  return findpa(pa[x]);
}
int findtopa(int x) {
  if (pa[x] == x) return 0;
  return topa[x] ^ findtopa(pa[x]);
}
void save(int x) {
  dex.push_back(x), desize.push_back(size[x]);
  depa.push_back(pa[x]);
  detopa.push_back(topa[x]);
  debas.push_back(bas[x]);
}
void link(int x, int y, int w) {
  int rx = findpa(x);
  int ry = findpa(y);
  if (size[rx] > size[ry]) swap(x, y), swap(rx, ry);
  save(rx);
  save(ry);
  if (rx == ry) {
    bas[rx].ins(w ^ findtopa(x) ^ findtopa(y));
  } else {
    size[ry] += size[rx];
    merge(bas[ry], bas[rx]);
    pa[rx] = ry;
    topa[rx] = w ^ findtopa(x) ^ findtopa(y);
  }
}
void deop() {
  int x = dex[dex.size() - 1];
  size[x] = desize[desize.size() - 1];
  pa[x] = depa[depa.size() - 1];
  topa[x] = detopa[detopa.size() - 1];
  bas[x] = debas[debas.size() - 1];
  dex.pop_back();
  desize.pop_back();
  depa.pop_back();
  detopa.pop_back();
  debas.pop_back();
}
int ask(int x, int y) {
  return bas[findpa(x)].minimize(findtopa(x) ^ findtopa(y));
}
};  // namespace violet
int n, m, q;
int output[65536 * 4];
int askx[65536 * 4], asky[65536 * 4];
vector<int> ow[65536 * 4 * 2], ox[65536 * 4 * 2], oy[65536 * 4 * 2];
void modi(int a, int b, int l, int r, int id, int &x, int &y, int &w) {
  if (l >= a and r <= b) {
    ox[id].push_back(x);
    oy[id].push_back(y);
    ow[id].push_back(w);
    return;
  }
  int mid = (l + r) / 2;
  if (a <= mid) modi(a, b, l, mid, id << 1, x, y, w);
  if (b > mid) modi(a, b, mid + 1, r, id << 1 | 1, x, y, w);
}
vector<int> newid, oldid;
void ask(int x, int l, int r, int id) {
  newid.push_back(id);
  if (l == r) return;
  int mid = (l + r) / 2;
  if (x <= mid)
    ask(x, l, mid, id << 1);
  else
    ask(x, mid + 1, r, id << 1 | 1);
}
map<pair<int, int>, int> edge, ew;
void redo(int id) {
  for (int i = 0; i < ox[id].size(); i++) violet::deop(), violet::deop();
}
void doit(int id) {
  for (int i = 0; i < ox[id].size(); i++)
    violet::link(ox[id][i], oy[id][i], ow[id][i]);
}
int main() {
  scanf("%d%d", &n, &m);
  violet::init();
  while (m--) {
    int x, y, z;
    scanf("%d%d%d", &x, &y, &z);
    if (x > y) swap(x, y);
    edge[make_pair(x, y)] = 1, ew[make_pair(x, y)] = z;
  }
  scanf("%d", &q);
  for (int i = 1; i <= q; i++) {
    int op;
    scanf("%d", &op);
    if (op == 1) {
      int x, y, w;
      scanf("%d%d%d", &x, &y, &w);
      if (x > y) swap(x, y);
      edge[make_pair(x, y)] = i;
      ew[make_pair(x, y)] = w;
    } else if (op == 2) {
      int x, y;
      scanf("%d%d", &x, &y);
      if (x > y) swap(x, y);
      modi(edge[make_pair(x, y)], i, 1, 65536 * 4, 1, x, y,
           ew[make_pair(x, y)]);
      edge[make_pair(x, y)] = 0;
    } else {
      output[i] = 1;
      scanf("%d%d", &askx[i], &asky[i]);
    }
  }
  for (map<pair<int, int>, int>::iterator it = edge.begin(); it != edge.end();
       it++) {
    if (it->second) {
      pair<int, int> p = it->first;
      modi(it->second, q, 1, 65536 * 4, 1, p.first, p.second, ew[p]);
    }
  }
  for (int i = 1; i <= q; ++i)
    if (output[i]) {
      newid.clear();
      ask(i, 1, 65536 * 4, 1);
      int st = 0;
      for (int j = 0; j < oldid.size() and j < newid.size(); j++)
        if (oldid[j] == newid[j])
          st = j + 1;
        else
          break;
      while (oldid.size() > st) redo(oldid[oldid.size() - 1]), oldid.pop_back();
      for (int i = st; i < newid.size(); i++) {
        doit(newid[i]);
        oldid.push_back(newid[i]);
      }
      printf("%d\n", violet::ask(askx[i], asky[i]));
    }
  return 0;
}
