#include <cstdio>
#include <algorithm>
#include <iostream>
#include <stack>
#include <unordered_set>

using namespace std;

int main()
{
    int n, m;
    cin >> n >> m;
    vector<vector<int> > updatedNodes;
    vector<stack<int> > nodeComp(n+1);
    vector<unordered_set<int> > comp(n+1);
    for(int i = 1; i <= n; ++i)
    {
        nodeComp[i].push(i);
        comp[i].insert(i);
    }
    int type, x, y;
    while(m--)
    {
        cin >> type >> x;
        if(type != 2)
            cin >> y;

        if(type == 1)
        {
            int father = nodeComp[x].top(), child = nodeComp[y].top();
            if(father == child)
                continue;
            if(comp[child].size() > comp[father].size())
                swap(father, child);
            int nod;
            vector<int> upd;
            while(comp[child].empty() == false)
            {
                nod = *comp[child].begin();
                comp[father].insert(nod);
                comp[child].erase(comp[child].begin());
                nodeComp[nod].push(father);
                upd.push_back(nod);

            }
            updatedNodes.push_back(upd);
        }
        else if(type == 2)
        {
            int oldComp;
            while(x--)
            {
                for(auto nod:updatedNodes.back())
                {
                    oldComp = nodeComp[nod].top();
                    nodeComp[nod].pop();
                    comp[oldComp].erase(nod);
                    comp[nodeComp[nod].top()].insert(nod);
                }
                updatedNodes.pop_back();
            }
        }
        else
            cout << (nodeComp[x].top() == nodeComp[y].top()) << "\n";
    }
}