#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cctype>
#define _for(i,a,b) for(int i=(a);i<(b);++i)
#define _rep(i,a,b) for(int i=(a);i<=(b);++i)
using namespace std;
typedef long long LL;
inline int read_int(){
int t=0;bool sign=false;char c=getchar();
while(!isdigit(c)){sign|=c=='-';c=getchar();}
while(isdigit(c)){t=(t<<1)+(t<<3)+(c&15);c=getchar();}
return sign?-t:t;
}
inline void write(LL x){
register char c[21],len=0;
if(!x)return putchar('0'),void();
if(x<0)x=-x,putchar('-');
while(x)c[++len]=x%10,x/=10;
while(len)putchar(c[len--]+48);
}
inline void space(LL x){write(x),putchar(' ');}
inline void enter(LL x){write(x),putchar('\n');}
const int MAXN=1e5+5;
struct Node{
int lef,rig,fa,d;
};
Node node[MAXN*20];
int cnt,root[MAXN<<1],n,q;
inline int nodecopy(int k){
node[++cnt]=node[k];
return cnt;
}
void build(int &k,int lef,int rig){
k=++cnt;
int mid=lef+rig>>1;
if(lef==rig)
return node[k].fa=mid,void();
build(node[k].lef,lef,mid);
build(node[k].rig,mid+1,rig);
}
void update_fa(int &k,int p,int lef,int rig,int pos,int F){
k=nodecopy(p);
if(lef==rig){
node[k].fa=F;
return;
}
int mid=lef+rig>>1;
if(mid<pos)
update_fa(node[k].rig,node[p].rig,mid+1,rig,pos,F);
else
update_fa(node[k].lef,node[p].lef,lef,mid,pos,F);
}
void update_dep(int k,int lef,int rig,int pos){
if(lef==rig){
node[k].d++;
return;
}
int mid=lef+rig>>1;
if(mid<pos)
update_dep(node[k].rig,mid+1,rig,pos);
else
update_dep(node[k].lef,lef,mid,pos);
}
int query_id(int k,int lef,int rig,int pos){
int mid=lef+rig>>1;
if(lef==rig)
return k;
if(mid<pos)
return query_id(node[k].rig,mid+1,rig,pos);
else
return query_id(node[k].lef,lef,mid,pos);
}
int Find(int rt,int pos){
int id=query_id(rt,1,n,pos);
return node[id].fa==pos?id:Find(rt,node[id].fa);
}
void Union(int &rt,int p,int a,int b){
int x=Find(p,a),y=Find(p,b);
if(node[x].fa==node[y].fa)
return rt=p,void();
if(node[x].d>node[y].d)
swap(x,y);
update_fa(rt,p,1,n,node[x].fa,node[y].fa);
if(node[x].d==node[y].d)
update_dep(rt,1,n,node[y].fa);
}
int main()
{
n=read_int(),q=read_int();
build(root[0],1,n);
int opt,a,b;
_rep(i,1,q){
opt=read_int();
if(opt==1){
a=read_int(),b=read_int();
Union(root[i],root[i-1],a,b);
}
else if(opt==2)
root[i]=root[read_int()];
else{
root[i]=root[i-1];
a=read_int(),b=read_int();
int x=Find(root[i],a),y=Find(root[i],b);
if(node[x].fa==node[y].fa)
puts("1");
else
puts("0");
}
}
return 0;
}