#include <cstdio>
#include <algorithm>
#include <vector>

using namespace std;

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

struct op
{
    int x,y;
} A[NMAX];

struct query
{
    int x,y;
} B[NMAX];

vector <int> v[NMAX];

int t,n,m,x,y,nr,num,GR[NMAX];
int k,st[NMAX],sol[NMAX];

int grupa(int k)
{
    if (GR[k]==k) return k;
    GR[k]=grupa(GR[k]);
    return GR[k];
}
void unifica(int k1, int k2)
{
    int r1=grupa(k1), r2=grupa(k2);
    GR[r2]=r1;
}
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;
}

int main()
{
    int i,j;

//    freopen("date.in","r",stdin);
//    freopen("date.out","w",stdout);

    n = getInt(), m = getInt();

    for (i=1;i<=m;++i)
    {
        t = getInt(), x = getInt();
        if (t==1)
        {
            y = getInt();
            A[++nr].x = x, A[nr].y = y;
            st[++k]=nr;
        }
        else
        {
            if (t==2)
            {
                for (j=0;j<x && k>0;++j)
                    --k;
            }
            else
            {
                y = getInt();
                B[++num].x = x, B[num].y = y;
                v[st[k]].push_back(num);
            }
        }
    }
    for (i=1;i<=n;++i)
        GR[i]=i;
    for (j=0;j<v[0].size();++j)
    {
        t=v[0][j];
        if (grupa(B[t].x)==grupa(B[t].y))
            sol[t]=1;
        else
            sol[t]=0;
    }
    for (i=1;i<=nr;++i)
    {
        unifica(A[i].x,A[i].y);
        for (j=0;j<v[i].size();++j)
        {
            t=v[i][j];
            if (grupa(B[t].x)==grupa(B[t].y))
                sol[t]=1;
            else
                sol[t]=0;
        }
    }
    for (i=1;i<=num;++i)
        printf("%d\n",sol[i]);
    return 0;
}