#include <iostream>
#include <streambuf>
#include <fstream>
#include <cstring>
#include <algorithm>
namespace AKA
{
#if __cplusplus >= 201103L
using uint = unsigned int;
using ll = long long;
using ull = unsigned long long;
using llrg = __int128_t;
using ullrg = __uint128_t;
using dbl = double;
using ldbl = long double;
#else
typedef unsigned int uint;
typedef long long ll;
typedef unsigned long long ull;
typedef __int128_t llrg;
typedef __uint128_t ullrg;
typedef double dbl;
typedef long double ldbl;
#endif
}
namespace IO
{
using namespace AKA;
std::streambuf* inbuf, *outbuf;
char ibuf[1 << 23 | 1], *i1 = ibuf, *i2 = ibuf;
char outstk[105];
int top = 0;
inline char gc() { return (i1 == i2 && (i2 = (i1 = ibuf) + inbuf->sgetn(ibuf, 1 << 23), i1 == i2) ? EOF : *i1++); }
inline void pc(char x) { outbuf->sputc(x); }
inline int iget() { int x = 0; bool f = false; char c = gc(); while (c < '0' || c > '9') { f |= c == '-'; c = gc(); } while (c >= '0' && c <= '9') { x = (x << 3) + (x << 1) + (c ^ 48); c = gc(); } return f ? -x : x; }
inline void ipr(int x) { if (x == 0) { pc('0'); return ; } if (x < 0) { pc('-'); x = -x; } top = 0; while (x) { outstk[top++] = x % 10 + 48; x /= 10; } while (top--) { pc(outstk[top]); } }
inline void iwsp(int x) { ipr(x); pc(' '); }
inline void iwln(int x) { ipr(x); pc('\n'); }
inline ll llget() { ll x = 0; bool f = false; char c = gc(); while (c < '0' || c > '9') { f |= c == '-'; c = gc(); } while (c >= '0' && c <= '9') { x = (x << 3) + (x << 1) + (c ^ 48); c = gc(); } return f ? -x : x; }
inline void llpr(ll x) { if (x == 0) { pc('0'); return ; } if (x < 0) { pc('-'); x = -x; } top = 0; while (x) { outstk[top++] = x % 10 + 48; x /= 10; } while (top--) { pc(outstk[top]); } }
inline void llwsp(ll x) { llpr(x); pc(' '); }
inline void llwln(ll x) { llpr(x); pc('\n'); }
inline ull ullget() { ll x = 0; bool f = false; char c = gc(); while (c < '0' || c > '9') { f |= c == '-'; c = gc(); } while (c >= '0' && c <= '9') { x = (x << 3) + (x << 1) + (c ^ 48); c = gc(); } return f ? -x : x; }
inline void ullpr(ull x) { if (x == 0) { pc('0'); return ; } if (x < 0) { pc('-'); x = -x; } top = 0; while (x) { outstk[top++] = x % 10 + 48; x /= 10; } while (top--) { pc(outstk[top]); } }
inline void ullwsp(ull x) { ullpr(x); pc(' '); }
inline void ullwln(ull x) { ullpr(x); pc('\n'); }
inline void spr(const char* s) { char* t = const_cast<char*>(s); while (*t && (pc(*t++), true)) {} }
inline void swsp(const char* s) { spr(s); pc(' '); }
inline void swln(const char* s) { spr(s); pc('\n'); }
template<typename _Tp> inline void iget(_Tp& x) { x = 0; bool f = false; char c = gc(); while (c < '0' || c > '9') { f |= c == '-'; c = gc(); } while (c >= '0' && c <= '9') { x = (x << 3) + (x << 1) + (c ^ 48); c = gc(); } f && (x = -x); }
template<typename _Tp, typename ... Args> inline void iget(_Tp& x, Args& ... args) { iget(x), iget(args ...); }
template<typename _Tp> inline void pr(_Tp x) { if (x == 0) { pc('0'); return ; } if (x < 0) { pc('-'); x = -x; } top = 0; while (x) { outstk[top++] = x % 10 + 48; x /= 10; } while (top--) { pc(outstk[top]); } }
template<typename _Tp, typename ... Args> inline void pr(_Tp x, Args ... args) { pr(x), pr(args ...); }
template<typename _Tp> inline void wsp(_Tp x) { pr(x), pc(' '); }
template<typename _Tp, typename ... Args> inline void wsp(_Tp x, Args ... args) { wsp(x), wsp(args ...); }
}
namespace Solution
{
#ifndef ONLINE_JUDGE
std::ifstream cin;
std::ofstream cout;
#else
using std::cin;
using std::cout;
#endif
using namespace AKA;
using IO::gc; using IO::pc;
using IO::iget; using IO::ipr; using IO::iwsp; using IO::iwln;
using IO::llget; using IO::llpr; using IO::llwsp; using IO::llwln;
using IO::ullget; using IO::ullwsp; using IO::ullwln;
using IO::spr; using IO::swsp; using IO::swln;
using IO::pr; using IO::wsp;
#define flp(name, lpst, lped) for (int name = lpst, name##end = lped; name <= name##end; ++name)
#define plf(name, lpst, lped) for (int name = lpst, name##end = lped; name >= name##end; --name)
constexpr int maxn = 2e5 + 5;
template<int maxn>
struct DSU
{
struct Node
{
int ls, rs, l, r, ff, d;
} tr[maxn * 30 + 5];
int rt[maxn];
inline int& ls(int i) { return tr[i].ls; }
inline int& rs(int i) { return tr[i].rs; }
inline int& ff(int i) { return tr[i].ff; }
inline int& d(int i) { return tr[i].d; }
int ncnt = 0;
void build(int l, int r, int& rt)
{
rt = ++ncnt;
tr[rt].l = l, tr[rt].r = r;
if (l == r)
{
ff(rt) = l;
return ;
}
int mid = l + ((r - l) >> 1);
build(l, mid, ls(rt)), build(mid + 1, r, rs(rt));
}
void upd(int pos, int rt)
{
if (tr[rt].l == tr[rt].r)
{
++d(rt);
return ;
}
if (pos <= tr[ls(rt)].r)
{
upd(pos, ls(rt));
}
else
{
upd(pos, rs(rt));
}
}
void mrg(int pos, int fa, int pre, int& rt)
{
rt = ++ncnt;
tr[rt] = tr[pre];
d(rt) = 0;
if (tr[rt].l == tr[rt].r)
{
ff(rt) = fa;
d(rt) = d(pre);
return ;
}
if (pos <= tr[ls(rt)].r)
{
mrg(pos, fa, ls(pre), ls(rt));
}
else
{
mrg(pos, fa, rs(pre), rs(fa));
}
}
int qry(int pos, int rt)
{
if (tr[rt].l == tr[rt].r)
{
return rt;
}
if (pos <= tr[ls(rt)].r)
{
return qry(pos, ls(rt));
}
else
{
return qry(pos, rs(rt));
}
}
int getf(int pos, int rt)
{
int x = qry(pos, rt);
if (ff(x) == pos)
{
return x;
}
return getf(ff(x), rt);
}
};
DSU<maxn> dsu;
void main(void)
{
std::ios::sync_with_stdio(false);
#ifndef ONLINE_JUDGE
cin.open("main.in"), cout.open("main.out");
IO::inbuf = cin.rdbuf(); IO::outbuf = cout.rdbuf();
#else
#if __cplusplus >= 201103L
cin.tie(nullptr); cout.tie(nullptr);
#else
cin.tie(NULL); cout.tie(NULL);
#endif
IO::inbuf = cin.rdbuf(); IO::outbuf = cout.rdbuf();
#endif
std::ofstream ferr("main.err.out");
#define iwln(x) (ferr << (x) << std::endl)
int n = iget(), General_Q = iget();
dsu.build(1, n, dsu.rt[0]);
flp (i, 1, General_Q)
{
std::cerr << i << "\n";
int op = iget(), x = iget();
if (op == 1)
{
int y = iget();
dsu.rt[i] = dsu.rt[i - 1];
int fx = dsu.getf(x, dsu.rt[i]), fy = dsu.getf(y, dsu.rt[i]);
if (dsu.ff(fx) != dsu.ff(fy))
{
if (dsu.d(fx) > dsu.d(fy))
{
std::swap(fx, fy);
}
dsu.mrg(dsu.ff(fx), dsu.ff(fy), dsu.rt[i - 1], dsu.rt[i]);
if (dsu.d(fx) == dsu.d(fy))
{
dsu.upd(dsu.ff(fy), dsu.rt[i]);
}
}
}
else if (op == 2)
{
dsu.rt[i] = dsu.rt[x];
}
else if (op == 3)
{
int y = iget();
dsu.rt[i] = dsu.rt[i - 1];
int fx = dsu.getf(x, dsu.rt[i]), fy = dsu.getf(y, dsu.rt[i]);
iwln(dsu.ff(fx) == ff(fy));
}
}
#ifndef ONLINE_JUDGE
cin.close(); cout.close();
#endif
}
}
int main(void)
{
Solution::main();
return 0;
}