#include<cstdio>
#include<fstream>
#include<iostream>
#include<iomanip>
#include<algorithm>
#include<vector>
#include<bitset>
#include<deque>
#include<queue>
#include<set>
#include<map>
#include<cmath>
#include<cstring>
#include<ctime>
#include<cstdlib>
#include<unordered_map>

#define ll long long
#define pb push_back
#define mp make_pair
#define pii pair<int,int>
#define pll pair<ll,ll>
#define all(x) (x).begin(), (x).end()
#define fi first
#define se second

using namespace std;

const int DIM = 10005;
const int nmax = 100005;

int x, n, m, y, op, i, j, cnt, fx, fy, f[nmax];

vector<int> v[nmax];
vector<pii> st;

char buff[DIM];
int poz;

void read(int &x)
{
    x = 0;

    while(buff[poz] < '0' || buff[poz] > '9')
        if(++poz == DIM) fread(buff, 1, DIM, stdin), poz = 0;

    while(buff[poz] >= '0' && buff[poz] <= '9')
    {
        x = x * 10 + buff[poz] - '0';
        if(++poz == DIM) fread(buff, 1, DIM, stdin), poz = 0;
    }
}

int find(int x)
{
    int mlc;
    for(mlc = x; mlc != f[mlc]; mlc = f[mlc]);
    return mlc;
}

int main()
{
    //    freopen("test.in", "r", stdin);
//    freopen("test.out", "w", stdout);

    read(n);
    read(m);

    for(i = 1; i <= n; i++)
    {
        f[i] = i;
        v[i].pb(i);
    }

    for(; m; m--)
    {
        read(op);

        if(op == 1)
        {
            read(x);
            read(y);
            f[x] = y;
            v[x].pb(y);
            st.pb(mp(x, y));
        }
        else if(op == 2)
        {
            read(cnt);
            for(j = 1; j <= cnt; j++)
            {
                x = st.back().fi;
                y = st.back().se;
                v[x].pop_back();
                f[x] = v[x].back();
                st.pop_back();
            }
        }
        else
        {
            read(x);
            read(y);
            fx = find(x);
            fy = find(y);

            printf("%d\n", (fx == fy));
        }
    }

    return 0;
}