#include using namespace std; class Persistent_UnionFind { public: Persistent_UnionFind() : parent(), sizeComp(), stiva(), nrComp(0), N(0) { } Persistent_UnionFind(const int n) : parent(vector(n + 1)), sizeComp(vector(n + 1)), stiva(vector>(8)), nrComp(n), N(n) { this->reset(); } void reset() { for (int i = 1; i <= N; ++i) MakeSet(i); } int Find(int x) const { assert(1 <= x && x <= N); if (parent[x] != x) return Find(parent[x]); else return parent[x]; } void Union(int x, int y) { assert(1 <= x && x <= N); assert(1 <= y && y <= N); x = Find(x); y = Find(y); pair op{-1, -1}; if (x != y) { if (sizeComp[x] < sizeComp[y]) swap(x, y); /// append y to x sizeComp[x] += sizeComp[y]; parent[y] = x; this->nrComp--; assert(this->nrComp >= 1); op = {x, y}; ///x-root, y-son } stiva.push_back(op); } void rollback() { assert(stiva.size() > 0); pair op = stiva.back(); stiva.pop_back(); if (op.first != -1) disconnect(op.first, op.second); } bool connected(int x, int y) const { return Find(x) == Find(y); } unsigned int sizeComponent(int x) const { return sizeComp[Find(x)]; } unsigned int numberOfComponents() const { return this->nrComp; } private: vector parent; vector sizeComp; vector> stiva; unsigned int nrComp; int N; void MakeSet(const int x) { assert(1 <= x && x <= N); parent[x] = x; sizeComp[x] = 1; } void disconnect(int x, int y) /// disconned y from x { assert(1 <= x && x <= N); assert(1 <= y && y <= N); if (parent[y] == x) { parent[y] = y; sizeComp[x] -= sizeComp[y]; this->nrComp++; assert(this->nrComp <= static_cast(N)); } } }; const int buffer=1<<13; char buff[buffer]; int cnt=0; //getInt() reads and returns one integer at a time int getInt() { int number = 0; while(buff[cnt] < '0' || '9' < buff[cnt]) if(++cnt >= buffer) fread(buff, buffer, 1, stdin), cnt = 0; while('0' <= buff[cnt] && buff[cnt] <= '9') { number = number * 10 + buff[cnt] - '0'; if(++cnt >= buffer) fread(buff, buffer, 1, stdin), cnt = 0; } return number; } int main() { ///freopen("dfs.in", "r", stdin); int N = getInt(); int M = getInt(); Persistent_UnionFind dsu(N); while (M--) { int t = getInt(); if (t == 1) { int x = getInt(); int y = getInt(); dsu.Union(x, y); } else if (t == 2) { int x = getInt(); while (x--) dsu.rollback(); } else { int x = getInt(); int y = getInt(); printf("%d\n", (int)dsu.connected(x, y)); } } return 0; }