#include <cstdio>
#include <vector>
#include <fstream>
//#include <iostream>
#define nmax 100005

using namespace std;

struct qu
{
    int x,y;
}v[nmax];

int n, m, type, k, x, y;
int mul[nmax];
vector<int>ant[nmax];

const int buffer=1<<13;
char buff[buffer];
int cnt=0;

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;
}
void undogr(int x)
{
    if (mul[x]==x) return;
    undogr(mul[x]);
    mul[x]=ant[x][ant[x].size() - 1];
    ant[x].erase(ant[x].end()-1);
}

void undo(int x,int y)
{
    undogr(x);
    undogr(y);
}

int gr(int i)
{
    ant[i].push_back(mul[i]);
    if (mul[i]==i) return i;
    mul[i]=gr(mul[i]);
    return mul[i];
}

int quer(int i)
{
    if (mul[i]==i) return i;
   x=quer(mul[i]);
    return x;
}

void unite(int i,int j)
{
    int l1=gr(i);
    int l2=gr(j);
    mul[l1]=l2;
}

int main()
{
    ifstream cin("test.in");
    ofstream cout("test.out");
  //  n = getInt();
   // m = getInt();
    cin>>n>>m;
    for(int i=1; i<=n; ++i)
    {
        mul[i]=i;
        ant[i].push_back(i);
    }

    for(int i=1; i<=m; ++i)
    {
       // type = getInt();
       cin>>type;
        if (type==1)
        {
            ++k;
            //v[k].x = getInt();
           // v[k].y = getInt();
           cin>>v[k].x>>v[k].y;
            unite(v[k].x, v[k].y);
        }
        if (type==3)
        {
           // x = getInt();
          //  y = getInt();
          cin>>x>>y;
            if (quer(x)==quer(y)) cout <<"1\n";
                else cout<<"0\n";
        }
        if (type==2)
        {
          //  x = getInt();
          cin>>x;
            for(int i = k; x > 0; --x,--k)
            undo(v[i].x,v[i].y);

        }
    }
    return 0;

}