#include "bits/stdc++.h" using namespace std; #define LL long long //#define int LL #define PB push_back #define VI vector #define FOR(i,a,b) for(int i = (a); i <= (b); i++) #define REP(i,n) FOR(i, 0, (int)n - 1) #define PII pair #define ALL(x) (x).begin(), (x).end() #define SZ(x) ((int)(x).size()) #define st first #define nd second template void mini(C & a4, C b4){a4 = min(a4, b4);} template void maxi(C & a4, C b4){a4 = max(a4, b4);} template void _dbg(const char * sdbg, TH h){ cerr< void _dbg(const char * sdbg, TH h, TA... a){ while(*sdbg!=',') cerr<<*sdbg++; cerr<<'='< ostream & operator<<(ostream & os, vector V){ os<<"[";for(auto vv: V) os < ostream & operator<<(ostream & os , pair P){ return os << "(" << P.st <<","< > V[N][D]; int find(int w, int d) { return rep[w][d] = (rep[w][d] == w ? w : find(rep[w][d], d)); } void Union(int a, int b, int d) { //size[find(b, d)][d] += size[find(a, d)][d]; rep[find(a, d)][d] = find(b, d); } void remove(int a, int d, pair p) { int x = p.first; int y = p.second; for (int i = 0; i < V[a][d].size(); i++) { if (V[a][d][i] == make_pair(x, y)) { swap(V[a][d][i], V[a][d].back()); V[a][d].pop_back(); i--; continue; } } } void insert(int x, int y, int d) { int a = find(x, d); int b = find(y, d); V[a][d].push_back({x, y}); V[b][d].push_back({x, y}); } vector visited; bool DFS(int w, int goal, int d) { if (w == goal) return true; vis[w] = true; visited.push_back(w); for (int i = 0; i < V[w][d].size(); i++) { int u = find(V[w][d][i].second, d); if (!vis[u] && DFS(u, goal, d)) { return true; } } return false; } bool isPath(int x, int y, int d) { int a = find(x, d); int b = find(y, d); if (a == b) return true; bool ret = DFS(a, b, d); for (int w : visited) { vis[w] = false; } visited.clear(); return ret; } set, int> > currentEdges; vector > interestingEdges; vector reps; void preprocess(int fromD) { // debug("preprocess", fromD); for (int w : reps) { for (int d = 0; d < 10; d++) { V[w][d].clear(); } } reps.clear(); for (int i = 0; i < n; i++) { deg[i] = 0; for (int d = 0; d < 10; d++) { rep[i][d] = i; //size[i][d] = 1; } } interestingEdges.clear(); for (int i = fromD; i <= min(q, fromD + S - 1); i++) { if (type[i] == 1 || type[i] == 0) { interestingEdges.push_back({from[i], to[i]}); deg[from[i]]++; deg[to[i]]++; } if (type[i] == 1) { auto x = currentEdges.lower_bound({{from[i], to[i]}, 0}); if (x->first.first != from[i] || x->first.second != to[i]) { continue; } int d = x->second; currentEdges.erase(x); // break; } else if (type[i] == 0) { currentEdges.insert({{from[i], to[i]}, digit[i]}); } } sort(interestingEdges.begin(), interestingEdges.end()); int ptr = 0; for (auto e : currentEdges) { auto p = e.first; while (ptr < interestingEdges.size() && interestingEdges[ptr] < p) { ptr++; } if (ptr < interestingEdges.size() && interestingEdges[ptr] == p) { continue; } for (int d = e.second; d < 10; d++) { Union(e.first.first, e.first.second, d); } } for (int i = 0; i < n; i++) { for (int d = 0; d < 10; d++) { if (find(i, d) == i && deg[i] > 0) { // debug(i, d); reps.push_back(i); } } } } int32_t main(){ ios_base::sync_with_stdio(0); cin.tie(0); cin >> n >> q; for (int i = 1; i <= q; i++) { int x, y, v; cin >> type[i]; if (type[i] == 0) { cin >> x >> y >> v; from[i] = x; to[i] = y; if (to[i] < from[i]) swap(from[i], to[i]); digit[i] = v; } else if (type[i] == 1) { cin >> x >> y; from[i] = x; to[i] = y; if (to[i] < from[i]) swap(from[i], to[i]); } else { cin >> x >> y; from[i] = x; to[i] = y; if (to[i] < from[i]) swap(from[i], to[i]); } } for (int i = 1; i <= q; i++) { int x, y, v; if (i % S == 1) { preprocess(i); } if (type[i] == 0) { x = from[i]; y = to[i]; v = digit[i]; for (int d = v; d < 10; d++) { insert(x, y, d); insert(y, x, d); } } else if (type[i] == 1) { x = from[i]; y = to[i]; for (int d = 0; d < 10; d++) { int a = find(x, d); int b = find(y, d); remove(a, d, {x, y}); remove(b, d, {y, x}); } } else { x = from[i]; y = to[i]; bool found = false; for (int d = 0; d < 10; d++) { if (isPath(x, y, d)) { cout << d << endl; found = true; break; } } if (!found) { cout << -1 << endl; continue; } } } return 0; }