#include <cstdio>
#include <vector>
#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 undo_graph(int x,int y)
{
    mul[x]=ant[x][ant[x].size() - 1];
    mul[y]=ant[y][ant[y].size() - 1];
    ant[x].erase(ant[x].end()-1);
    ant[y].erase(ant[y].end()-1);
}

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

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

int main()
{

  //  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(x,y);
        }
        if (type==3)
        {
           // x = getInt();
          //  y = getInt();
          cin>>x>>y;
            if (gr(x)==gr(y)) cout <<"1\n";
                else cout<<"0\n";
        }
        if (type==2)
        {
          //  x = getInt();
          cin>>x;
            for(int i = k; x > 0; --x,--k)
            undo_graph(v[i].x,v[i].y);

        }
    }
    return 0;

}