#include using namespace std; typedef long long int ll; typedef double ld; typedef vector vi; typedef vector Graph; // push_back insert lower_bound upper_bound erase #define SQRT_MULT (1.0) //unionfind struct Uf{ vector p, r; // p=element's parent, r=rank unordered_map fake_p; void clear_fake(){ fake_p.clear(); } Uf(ll n):p(n),r(n){ iota(p.begin(), p.end(), 0); } // finds representant of a's set ll find(ll a){ return p[a]==a ? a : p[a]=find(p[a]); } ll fake_find(ll a){ a = find(a); return fake_p.count(a) ? fake_find(fake_p[a]) : a; } // unifies sets of a and b void fake_uni(ll a, ll b){ a = fake_find(a); b = fake_find(b); if(a==b)return; /* if(r[a]> edges; vi v, inv; void check(ll cur_b, ll prev_b, ll bound){ ll cur_e = v[prev_b]; /* cerr<<"v: ";for(ll n:v)cerr<prev_b; --j){ auto &pp=edges[j]; ll aa=pp.first; ll bb=pp.second; if(uf.same(aa,bb)){ /* cerr<<"KILL because: " << uf.same(aa,bb) << " for " << aa << ' ' << bb <> N >> M; g = Graph(N); for(ll i=0; i> a >> b; --a; --b; edges.push_back({a,b}); g[a].push_back(b); g[b].push_back(a); } edges.push_back({0,0}); ll Q; cin >> Q; vector> q(Q); for(auto &p:q) cin >> p.first >> p.second; for(auto &p:q) --p.first, --p.second; inv = v = vi(M, 0); ll bound = max(3,((int)ceil(SQRT_MULT * sqrt(M)))); /* ll bound=1; */ ll idx=0, last=0; while(idx