#define PROB Problema4

#include <iostream>
#include <fstream>
#include<vector>
#include<queue>
#include<stack>

using namespace std;
typedef int var;
#define fin cin
#define fout cout

//ifstream fin("date.in");
//ofstream fout("date.out");

#define MAXN 100005


#include <cstdio>

const int buffer=1<<13;
char buff[buffer]; int cnt=0;
/*
int getInt() {
    int a;
    fin>>a;
    return a;
}*/

//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;
}




bool TRUE[MAXN];

var TREE[MAXN];

const var zeros(var val) {
    return val & (-val);
}

void update(var ind, var val) {
    for(;ind<MAXN; ind += zeros(ind)) {
        TREE[ind] += val;
    }
}

bool query(var ind) {
    var s = 0;
    for(;ind;ind -= zeros(ind)) {
        s += TREE[ind];
    }
    return s;
}

void update_int(var b, var e, var delta) {
    update(b, delta);
    update(e+1, -delta);
}



var PARENT[MAXN], RANK[MAXN], T[MAXN];
var INIT[MAXN];
var TIMES[MAXN];

var Find(var a) {
    if(PARENT[a] == 0 || query(T[a]) <= 0) {
        return a;
    }
    return Find(PARENT[a]);
}

var Union(var r1, var r2, var t) {
    if(RANK[r1] < RANK[r2]) {
        PARENT[r1] = r2;
        T[r1] = t;
    } else {
        PARENT[r2] = r1;
        T[r2] = t;
        if(RANK[r1] == RANK[r2]) {
            RANK[r1] ++;
        }
    }
}

int main()
{
    var n, m, a, timp = 0, time_index = 0, b, type;
    n = getInt();
    m = getInt();
    while(m--) {
        type = getInt();
        if(type == 1) {
            a = getInt();
            b = getInt();

            timp++;
            update_int(timp, timp, 1);
            ++time_index;
            TIMES[time_index] = timp;

            if(query(INIT[a]) == 0) {
                INIT[a] = timp;
            }
            if(query(INIT[b]) == 0) {
                INIT[b] = timp;
            }

            var r1 = Find(a), r2 = Find(b);
            if(r1 != r2) {
                Union(r1, r2, timp);
            }
        } else if(type == 2) {
            a = getInt();
            var it = 0;
            time_index -= a;
            update_int(TIMES[time_index]+1, timp, -1);
        } else {
            a = getInt();
            b = getInt();
            if(a == b) {
                if(query(INIT[a]) <= 0) {
                    fout<<"0\n";
                } else {
                    fout<<"1\n";
                }
            } else {
                fout<<(Find(a) == Find(b))<<'\n';
            }
        }
    }
}