#include<bits/stdc++.h>
using namespace std;
int n,m;
struct zz{
int l,r;
};
int fa[20000005];
int dep[20000005];
int root[2000005];
struct HJT_Tree{
int cnt=0;
zz t[40000005];
void Build_Tree(int &p,int l,int r){
p=++cnt;
if(l==r) return (void)(fa[p]=l);
int mid=(l+r)>>1;
Build_Tree(t[p].l,l,mid),Build_Tree(t[p].r,mid+1,r);
}
void Change_Tree(int x,int &y,int l,int r,int pos,int f){
y=++cnt,t[y]=t[x];
if(t[y].l==t[y].r) return (void)(fa[y]=f,dep[y]=dep[x]);
int mid=(l+r)>>1;
if(pos<=mid) Change_Tree(t[x].l,t[y].l,l,mid,pos,f);
else Change_Tree(t[x].r,t[y].r,mid+1,r,pos,f);
}
void XSH_Tree(int p,int l,int r,int pos){
if(l==r) return (void)(dep[p]++);
int mid=(l+r)>>1;
if(pos<=mid) XSH_Tree(t[p].l,l,mid,pos);
else XSH_Tree(t[p].r,mid+1,r,pos);
}
int Find_Tree(int p,int l,int r,int pos){
if(l==r) return p;
int mid=(l+r)>>1;
if(pos<=mid) return Find_Tree(t[p].l,l,mid,pos);
else return Find_Tree(t[p].r,mid+1,r,pos);
}
int Find_Fa(int p,int x){
int now=Find_Tree(p,1,n,x);
if(fa[now]==x)return now;
return Find_Fa(p,fa[now]);
}
}T;
int ans=0;
int main(){
cin>>n>>m;
T.Build_Tree(root[0],1,n);
for(int i=1,op,x,y;i<=m;i++){
scanf("%d%d",&op,&x);
if(!(op&1)){ root[i]=root[x];continue;}
scanf("%d",&y),root[i]=root[i-1];
if(!(op-1)){
x=T.Find_Fa(root[i],x),y=T.Find_Fa(root[i],y);
if(fa[x]!=fa[y]){
if(dep[x]>dep[y]) swap(x,y);
T.Change_Tree(root[i-1],root[i],1,n,fa[x],fa[y]);
if(dep[x]==dep[y]) T.XSH_Tree(root[i],1,n,fa[y]);
}
}
else {
x=T.Find_Fa(root[i],x),y=T.Find_Fa(root[i],y);
printf("%d\n",ans=fa[x]==fa[y]);
}
}
return 0;
}