#include <bits/stdc++.h>
using namespace std;
const int M = 2000043;
const int N = 200043;
const int B = 30;
const int IDX = 200002;
int* where[M];
int val[M];
int st = 0;
inline void rollback(int new_st) {
  while (st != new_st) {
    st--;
    (*where[st]) = val[st];
  }
}
inline void change(int& address, int new_val) {
  where[st] = &address;
  val[st] = address;
  st++;
  address = new_val;
}
vector<pair<pair<int, int>, int> > T[4 * N];
vector<pair<pair<int, int>, int> > Q[4 * N];
int ans[N];
void add_edge(int v, int l, int r, int L, int R, pair<pair<int, int>, int> e) {
  if (L >= R) return;
  if (l == L && r == R) {
    T[v].push_back(e);
    return;
  }
  int mid = (l + r) >> 1;
  add_edge(v * 2 + 1, l, mid, L, min(mid, R), e);
  add_edge(v * 2 + 2, mid, r, max(L, mid), R, e);
}
int base[B];
inline void try_gauss(int v) {
  for (int i = 29; i >= 0; i--)
    if (base[i] != -1 && (v & (1 << i))) v ^= base[i];
  if (v != 0)
    for (int i = 29; i >= 0; i--)
      if (v & (1 << i)) return change(base[i], v);
}
int rnk[N];
int dsu[N];
int dist[N];
inline int get_p(int first) {
  while (dsu[first] != first) first = dsu[first];
  return first;
}
inline int get_dist(int first) {
  int res = 0;
  while (dsu[first] != first) {
    res ^= dist[first];
    first = dsu[first];
  }
  return res;
}
inline bool merge(int first, int second, int d) {
  int dist_x = get_dist(first);
  int dist_y = get_dist(second);
  first = get_p(first);
  second = get_p(second);
  if (first == second) return false;
  d ^= (dist_x ^ dist_y);
  if (rnk[first] < rnk[second]) swap(first, second);
  change(dsu[second], first);
  change(rnk[first], rnk[first] + rnk[second]);
  change(dist[second], d);
  return true;
}
inline void process(int v) {
  for (auto first : T[v])
    if (!merge(first.first.first, first.first.second, first.second)) {
      int cycle_len = first.second ^ get_dist(first.first.first) ^
                      get_dist(first.first.second);
      try_gauss(cycle_len);
    }
}
inline int answer(int first, int second) {
  int d = get_dist(first) ^ get_dist(second);
  for (int i = 29; i >= 0; i--)
    if (base[i] != -1 && (d & (1 << i))) d ^= base[i];
  return d;
}
void dfs(int v, int l, int r) {
  int rollback_to = st;
  process(v);
  if (l == r - 1) {
    for (auto first : Q[v])
      ans[first.second] = answer(first.first.first, first.first.second);
  } else {
    int mid = (l + r) >> 1;
    dfs(v * 2 + 1, l, mid);
    dfs(v * 2 + 2, mid, r);
  }
  rollback(rollback_to);
}
void add_query(int v, int l, int r, int pos, pair<pair<int, int>, int> e) {
  if (l == r - 1)
    Q[v].push_back(e);
  else {
    int mid = (l + r) >> 1;
    if (pos < mid)
      add_query(v * 2 + 1, l, mid, pos, e);
    else
      add_query(v * 2 + 2, mid, r, pos, e);
  }
}
int main() {
  int n, m;
  scanf("%d %d", &n, &m);
  for (int i = 0; i < n; i++) {
    dsu[i] = i;
    dist[i] = 0;
    rnk[i] = 1;
  }
  int cur = 0;
  map<pair<int, int>, pair<int, int> > z;
  for (int i = 0; i < m; i++) {
    int first, second, d;
    scanf("%d %d %d", &first, &second, &d);
    --first;
    --second;
    z[make_pair(first, second)] = make_pair(0, d);
  }
  int cnt_q = 0;
  int q;
  scanf("%d", &q);
  for (int i = 0; i < q; i++) {
    int t;
    scanf("%d", &t);
    if (t == 1) {
      int first, second, d;
      scanf("%d %d %d", &first, &second, &d);
      cur++;
      --first;
      --second;
      z[make_pair(first, second)] = make_pair(cur, d);
    }
    if (t == 2) {
      int first, second;
      scanf("%d %d", &first, &second);
      --first;
      --second;
      cur++;
      add_edge(0, 0, IDX, z[make_pair(first, second)].first, cur,
               make_pair(make_pair(first, second),
                         z[make_pair(first, second)].second));
      z.erase(make_pair(first, second));
    }
    if (t == 3) {
      int first, second;
      scanf("%d %d", &first, &second);
      --first;
      --second;
      add_query(0, 0, IDX, cur, make_pair(make_pair(first, second), cnt_q));
      cnt_q++;
    }
  }
  cur++;
  for (auto first : z)
    add_edge(0, 0, IDX, first.second.first, cur,
             make_pair(first.first, first.second.second));
  dfs(0, 0, IDX);
  for (int i = 0; i < cnt_q; i++) printf("%d\n", ans[i]);
  return 0;
}
