#include <bits/stdc++.h>
#include <ext/rope>
using namespace __gnu_cxx;
using namespace std;
#define endl '\n'
int read() {
int x = 0, y = 1;
char c = getchar();
while (c < '0' || c > '9') {
if (c == '-')
y = -1;
c = getchar();
}
while (c >= '0' && c <= '9')
x = x * 10 + c - '0', c = getchar();
return x * y;
}
void write_base(int x) {
if (x > 9)
write_base(x / 10);
putchar('0' + x % 10);
}
void write(int x) {
if (x < 0)
putchar('-'), x *= -1;
write_base(x);
putchar('\n');
}
const int N=2e5+10;
inline int find(rope<int>&fa,int i){
int f=fa[i];
return f==i?i:find(fa,f);
}
inline void merge(rope<int>&fa,rope<int>&deep,int a,int b){
a=find(fa,a),b=find(fa,b);
if(a!=b){
int deepA=deep[a],deepB=deep[b];
if(deepA<deepB){
fa.replace(a,b);
}else{
fa.replace(b,a);
if(deepA==deepB){
deep.replace(a,deepB+1);
}
}
}
}
signed main() {
int n=read(),m=read();
rope<int>fa[m+1],deep[m+1];
int arr[n+1];
fill(arr,arr+1+n,1);
deep[0]=rope<int>(arr);
for(int i=2;i<=n;i++)
arr[i]=i;
fa[0]=rope<int>(arr);
for(int i=1;i<=m;i++){
int opt=read(),a,b;
switch(opt){
case 1:
fa[i]=fa[i-1];
deep[i]=deep[i-1];
a=read(),b=read();
merge(fa[i],deep[i],a,b);
break;
case 2:
a=read();
fa[i]=fa[a];
deep[i]=deep[a];
break;
default:
fa[i]=fa[i-1];
deep[i]=deep[i-1];
a=read(),b=read();
cout<<(find(fa[i],a)==find(fa[i],b)?1:0)<<endl;
}
}
}