#include using namespace std; #define TRACE(x) cerr << #x << ' ' << x << endl #define FOR(i, a, b) for (int i = (a); i < int(b); i++) #define REP(i, n) FOR(i, 0, n) #define _ << ' ' << typedef long long llint; typedef long long ll; typedef pair pii; #define fi first #define sec second #define pb push_back const int MAXN = 100100; struct UN { int par[MAXN], sz[MAXN]; stack s, s1; UN() { REP(i, MAXN) par[i] = i; } int find(int x) { if (par[x] == x) return x; return find(par[x]); } int pitaj(int a, int b) { return (find(a) == find(b)); } void join(int a, int b) { a = find(a); b = find(b); if (a == b) return; if (sz[a] < sz[b]) { s.push({a, par[a]}); par[a] = b; } else if (sz[b] < sz[a]) { s.push({b, par[b]}); par[b] = a; } else { s.push({a, par[a]}); s1.push({b, sz[b]}); sz[b]++; par[a] = b; } } void remove(int n, int m) { while (s.size() > n) { int x = s.top().fi; int y = s.top().sec; par[x] = y; s.pop(); } while (s1.size() > m) { int x = s1.top().fi; int y = s1.top().sec; sz[x] = y; s1.pop(); } } }; UN U[11]; const int offset = (1 << 18); vector > v[offset * 2]; void ubaci(int cvor, int l, int r, int a, int b, pair t) { if (l > b || r < a) return; if (l >= a && r <= b) { v[cvor].push_back(t); return; } int mid = (l + r)/2; ubaci(cvor * 2, l, mid, a, b, t); ubaci(cvor * 2 + 1, mid + 1, r, a, b, t); } int n, q, kve[MAXN]; int ans[MAXN]; int A[MAXN], B[MAXN]; map last; void dfs(int cvor) { int staro[11]; int staro1[11]; REP(i, 11) staro[i] = U[i].s.size(); REP(i, 11) staro1[i] = U[i].s1.size(); for (auto &x : v[cvor]) { FOR(i, x.sec, 11) U[i].join(x.fi.fi, x.fi.sec); } if (cvor >= offset) { if (kve[cvor - offset]) { REP(i, 11) { if (U[i].pitaj(A[cvor - offset], B[cvor - offset])) { ans[cvor - offset] = i; break; } } } } if (cvor < offset) { dfs(cvor * 2); dfs(cvor * 2 + 1); } REP(i, 11) U[i].remove(staro[i], staro1[i]); } int main() { scanf("%d %d",&n,&q); FOR(i, 1, q + 1) { int t; int a, b, c; scanf("%d",&t); scanf("%d %d",&a,&b); if (a > b) swap(a, b); if (!t) { scanf("%d", &c); last[{a, b}] = {i, c}; continue; } if (t == 1) { ubaci(1, 0, offset - 1, last[{a, b}].fi, i, {{a, b}, last[{a, b}].sec}); last.erase({a, b}); continue; } if (t == 2) { kve[i] = 1; A[i] = a; B[i] = b; } } for (auto &it : last) { int a = it.fi.fi; int b = it.fi.sec; int c = it.sec.sec; ubaci(1, 0, offset - 1, it.sec.fi, q + 1, {{a, b}, c}); } memset(ans, -1, sizeof ans); dfs(1); FOR(i, 1, q + 1) if (kve[i]) printf("%d\n",ans[i]); return 0; }