#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;   }   