/* PE APROAPE */ #include #include #include #include #include #include #include #include #include #define in cin #define out cout #define abs(x) ((x>0)?(x):(-(x))) #define max(a,b) ((a)>(b)?(a):(b)) #define min(a,b) ((a)<(b)?(a):(b)) #define FOR(i, a, b) for(int i = a; i <= b; ++i) #define DOWNFOR(i, a, b) for(int i = a; i >= b; --i) #define FOREACH(i, t) for (typeof(t.begin()) i = t.begin(); i != t.end(); ++i) using namespace std; typedef long long ll; const int Nmax = 100001; struct nod{ nod *st,*dr; int x; nod(){ st=dr=NULL; x=0; } }; nod* root[Nmax]; int N,M; nod* build(int st,int dr){ nod* n=new nod(); if(st>=dr){ n->x=st; } else{ int mij=(st+dr)/2; n->st = build(st,mij); n->dr = build(mij+1,dr); } return n; } nod* upd(nod *t,int st,int dr,int w,int val){ nod* n=new nod(); if(st>=dr){ n->x=val; } else{ int mij=(st+dr)/2; if(w<=mij){ n->st = upd(t->st,st,mij,w,val); n->dr = t->dr; } else{ n->st = t->st; n->dr = upd(t->dr,mij+1,dr,w,val); } } return n; } int query(nod* n,int st,int dr,int w){ if(st>=dr){ return n->x; } else{ int mij=(st+dr)/2; if(w<=mij){ return query(n->st,st,mij,w); } else{ return query(n->dr,mij+1,dr,w); } } } int main(){ #ifndef ONLINE_JUDGE ifstream in("test.in"); ofstream out("test.out"); #endif in>>N>>M; root[0]=build(1,N); int w=0,t,x,y; FOR(i,1,M){ in>>t; if(t==1){ in>>x>>y; int a=query(root[w],1,N,x); int b=query(root[w],1,N,y); if(a!=b){ root[++w] = upd(root[w-1],1,N,a,b); } } if(t==2){ in>>x; w-=x; } if(t==3){ in>>x>>y; int a=query(root[w],1,N,x); int b=query(root[w],1,N,y); out<<(a==b)<<'\n'; } } return 0; }