#include #include #include #include using namespace std; #pragma GCC optimize("O3") int N,Q; struct str{ int ix; int type; int x,y; int end; int lvl; }; const int MAXN = 1e6; int tab[MAXN]; int Rank[MAXN]; int k; vector queries; vector queries_cleared; int result[MAXN]; map, int > M; vector type2 [MAXN]; void clear_queries() { for(auto const& x : queries) if(x.type == 0) queries_cleared.push_back(x); } int FIND(int k, vector > &v) { if(tab[k] == k) return k; v.push_back({k, tab[k]}); tab[k] = FIND(tab[k], v); return tab[k]; } void unio(int a, int b, vector > & v) { //cerr << a << " "<< b << endl; a = FIND(a, v); b = FIND(b, v); if(Rank[a] > Rank[b]) swap(a, b); v.push_back({ a, tab[a]}); tab[a] = b; Rank[b] += 1; v.push_back({-1, b}); } void g(int l, int r, vector const& v) { vector > to_rev; if(v.size() == 0) { for(int i=l; i=0; i--) { auto const& x = to_rev[i]; if(x.first == -1) Rank[x.second]--; else tab[x.first] = x.second; } return; } //cerr << l<< " " << r << " " << v.size() << endl; vector vl, vr; int m = (l+r)/2; for(auto const& x : v) { if(x.ix >= r || x.end <= l) continue; if(x.ix <= l && x.end >= r) { unio(x.x, x.y, to_rev); continue; } if(x.ix < m) vl.push_back(x); if(x.end >= m) vr.push_back(x); } if(l+1 != r) { g(l, m, vl); g(m, r, vr); } if(l+1 == r) { for(auto const& x : type2[l]) { if(FIND(x.x, to_rev) == FIND(x.y, to_rev)) result[x.ix] = k; } } for(int i=to_rev.size()-1; i>=0; i--) { auto const& x = to_rev[i]; if(x.first == -1) Rank[x.second]--; else tab[x.first] = x.second; } } void f() { for(int i=0; i<=N; i++) { tab[i] = i; Rank[i] = 1; } vector v; for(auto const& x : queries_cleared) if(x.type == 0 && x.lvl <= k) v.push_back(x); g(0, Q, v); } int32_t main(){ ios_base::sync_with_stdio(0); cin.tie(0); cin >> N >> Q; for(int i=0; i> s.type; s.ix = i; if(s.type == 2) { cin >> s.x >> s.y; queries.push_back(s); type2[i].push_back(s); continue; } if(s.type == 0) { cin >> s.x >> s.y >> s.lvl; M[{s.x,s.y}] = i; queries.push_back(s); continue; } if(s.type == 1) { cin >> s.x >> s.y; queries[M[{s.x,s.y}]].end = i + 1; queries.push_back(s); } } assert(queries.size() == Q); k = 9; clear_queries(); while(k >= 0) { f(); k--; } for(int i=0; i