#include <iostream>
#include <cstdio>

#define NMAX 100005
using namespace std;

struct log {
    int h;
    int x, y;
} logs[NMAX];

int pos;

int father[NMAX];
int h[NMAX];

int f (int x) {
    if (x == father[x])
        return x;
    return f(father[x]);
}

inline void unite (int x, int y) {
    x = f(x);
    y = f(y);

    ++ pos;
    if (x == y)
        return ;

    if (h[x] < h[y]) {
        logs[pos].x =x;
        logs[pos].y = father[x];
        father[x] = y;
    }
    else {
        if (h[x] == h[y]) {
            logs[pos].h = x;
            h[x] ++;
        }

        logs[pos].x = y;
        logs[pos].y = father[y];
        father[y] = x;
    }
}

bool united (int x, int y) {
    return (f(x) == f(y));
}

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

//getInt() reads and returns one integer at a time
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;
}

inline void undo (int x) {
    while (x--) {
        h[logs[pos].h] --;
        father[logs[pos].x] = logs[pos].y;

        pos --;
    }
}

int main()
{
    int n, m;
    n = getInt();
    m = getInt();

    for (int i = 1; i <= n; i++) {
        h[i] = 1;
        father[i] = i;
    }

    int tip;
    int a, b;
    while (m--) {
        //cin >> tip;
        tip = getInt();

        if (tip == 3) {
            //cin >> a >> b;
            a = getInt();
            b = getInt();

            cout << united(a, b) << '\n';
        }
        else if (tip == 2) {
            //cin >> a;
            a = getInt();

            undo(a);
        }
        else {
            //cin >> a >> b;
            a = getInt();
            b = getInt();

            unite(a, b);
        }
    }

    return 0;
}