#include #include #include #include #include #include using namespace std; typedef long long llint; typedef pair pii; const int MAXV = 10; const int MAXN = 1 << 17; int dad[MAXV][MAXN]; int n, q; struct event{ int l, r; pii b; event(int l, int r, pii b) : l(l), r(r), b(b) {} }; struct query { int t; pii b; query(int t, pii b) : t(t), b(b) {} }; map built; map value; struct update { pii pos; int v; update(pii pos, int v) : pos(pos), v(v) {} }; stack> S; void new_updates() { S.push(stack()); } void revert_update(update u) { dad[u.pos.first][u.pos.second] = u.v; } void pop_updates() { stack &tmp = S.top(); while (tmp.size()) { revert_update(tmp.top()); tmp.pop(); } S.pop(); } int update_value(int v, int x, int new_value) { S.top().push(update(pii(v, x), dad[v][x])); dad[v][x] = new_value; return new_value; } int find(int v, int x) { if (dad[v][x] == -1) return x; return update_value(v, x, find(v, dad[v][x])); } void merge(int v, int x1, int x2) { x1 = find(v, x1); x2 = find(v, x2); if (x1 == x2) return; update_value(v, x1, x2); } vector apply_events(int l, int r, vector &E) { vector left_e; for (auto e: E) { if (e.l <= l && e.r >= r) { for (int v = value[e.b]; v < 10; ++v) { merge(v, e.b.first, e.b.second); } } else if (e.r < l || e.l > r) { //if no intersection do nothing } else { left_e.push_back(e); } } return left_e; } int ans[MAXN]; void solve(int l, int r, vector E, vector Q) { // printf("%d %d\n", l, r); new_updates(); E = apply_events(l, r, E); if (E.empty() || Q.empty()) { for (auto q: Q) { for (int v = 0; v < 10; ++v) { if (find(v, q.b.first) == find(v, q.b.second)) { ans[q.t] = v; break; } } } pop_updates(); return; } int mid = (l+r) / 2; vector EL, ER; vector QL, QR; for (auto e : E) { if (e.l <= mid) EL.push_back(e); if (e.r >= mid+1) ER.push_back(e); } for (auto q: Q) { if (q.t <= mid) QL.push_back(q); else QR.push_back(q); } solve(l, mid, EL, QL); solve(mid+1, r, ER, QR); pop_updates(); } int main(void) { memset(dad, -1, sizeof dad); memset(ans, -1, sizeof ans); scanf("%d%d", &n, &q); vector E; vector Q; for (int i = 0; i < q; ++i) { int t, x, y, v; scanf("%d%d%d", &t, &x, &y); if (x > y) swap(x, y); if (t == 0) { scanf("%d", &v); built[pii(x, y)] = i; value[pii(x, y)] = v; } if (t == 1) { E.push_back(event(built[pii(x, y)], i, pii(x, y))); built[pii(x, y)] = -1; } if (t == 2) { Q.push_back(query(i, pii(x, y))); } } for (auto b: built) { if (b.second != -1) { E.push_back(event(b.second, q-1, b.first)); } } solve(0, q-1, E, Q); for (auto q: Q) printf("%d\n", ans[q.t]); return 0; }