#include <bits/stdc++.h>
using namespace std;
class DSU {
public:
    DSU(int _n) {
      init(_n);
    }
    /* 
    查找该数的根节点,实现方式为 先查找该数的父节点,如果父节点
    等于节点本身,那么该数就为根节点。
    路径压缩: 由于每次查找父节点时会遍历整个路径长度,时间复杂度为o(q * n);
            所以我们可以通过将每个数的父节点直接连到根节点的方法(压缩路径)降低复杂度。
    */
    int find(int x) {
      // if(fa[x] == x) return x;
      // else return fa[x] = find(fa[x])          ;
      return fa[x] == x ? x : fa[x] = find(fa[x]);
    }
    /*
      merge 合并两个不在同一集合的数,即将一个数的根节点放在另一个数的根节点下。
      同时要更新size,只需更新根节点大小,其余不需要管,因为不会再访问到了。
    */
    void merge(int x,int y) {
        int fx = find(x),fy = find(y);
        if(fx == fy) return;
        //fa[fx] = fy;
        if(sz[fx] <= sz[fy]) {
           fa[fx] = fy;
           sz[fy] += sz[fx];
        } else {
          fa[fy] = fx; 
          sz[fx] += sz[fy];
        }
    }
    bool isSame(int x,int y) {
        return find(x) == find(y);
    }
    int sze(int x) {
        return sz[find(x)];
    }
private: 
    vector<int> fa,sz;
    //初始化方式
    /*
      方法一:  
        resize
        函数原型:
        void std::vector<T>::resize(size_t x) 接受一个size_t参数(即无符号整数,跟随系统)
        即将容器大小设置为 x
        用法:
        resize -> fa.resize(_n + 1);(重置数组大小,数值默认为0)
        assign
        函数原型:
        void std::vector<T>::assign(size_t x, T y)接收两个size_t,T y参数,将容器大小设置为 x,值设置为 y。
        用法: sz.assign(_n + 1,1);
        iota
        函数原型:
        void std::iota(std::vector<T>::iterator_begin, std::vector<T>::iterator_end, T x) 
        从begin到end的前一个位置初始化为从x开始递增的排列。
      方法二:
        for(int i = 0;i < _n;i++) {
          fa[i] = i;
          sz[i] = 1;
        }
    */
   // std::size_t n;for (int i = 0; i < (int)a.size(); i++)
    void init(int _n) {
        fa.resize(_n + 5);
        iota(fa.begin(),fa.end(),0);
        sz.assign(_n + 5,1);
    }
};
void solve() {
    int n,q;cin >> n >> q;
    DSU dsu(n);
    while(q--) {
        int op;cin >> op;
        if(op == 1) {
            int a,b;cin >> a >> b;
            dsu.merge(a,b);
        }
        if(op == 2) {
            int a,b;cin >> a >> b;
            if(dsu.isSame(a,b)) {
                cout << "YES\n";
            }
            else cout << "NO\n";
        }
        if(op == 3) {
            int x;cin >> x;
            cout << dsu.sze(x) << "\n";
        }
    }
}
int main() {
  cin.tie(0) -> sync_with_stdio(0);
  solve();
  return 0;
}