#include <bits/stdc++.h>
using namespace std;
const int MOD = 1e9 + 7;
const int N = 3e5 + 10;
class DSU {
 public:
  vector<int> parent, siz, next;
  DSU(int n) {
    parent.resize(n + 1);
    siz.resize(n + 1);
    next.resize(n + 4);
    make_set(n);
  }
  void make_set(int n) {
    for (int i = 0; i <= n; i++) {
      parent[i] = i;
      siz[i] = 1;
      next[i] = i + 1;
    }
  }
  inline int find_set(int v) {
    if (v == parent[v]) return v;
    return parent[v] = find_set(parent[v]);
  }
  inline bool same_set(int a, int b) { return find_set(a) == find_set(b); }
  inline bool union_sets(int a, int b) {
    a = find_set(a);
    b = find_set(b);
    if (a != b) {
      parent[a] = parent[b] = min(a, b);
      return false;
    }
    return true;
  }
  inline void Query3(int l, int r) {
    for (int i = l + 1; i <= r;) {
      union_sets(i - 1, i);
      int k = next[i];
      next[i] = max(next[i], r);
      i = k;
    }
  }
};
int32_t main() {
  ios_base::sync_with_stdio(false);
  cin.tie(NULL);
  int n, q;
  cin >> n >> q;
  DSU ds(n);
  while (q--) {
    int type, x, y;
    cin >> type >> x >> y;
    if (type == 3) {
      if (ds.same_set(x, y)) {
        cout << "YES\n";
      } else {
        cout << "NO\n";
      }
    } else if (type == 1) {
      ds.union_sets(x, y);
    } else {
      ds.Query3(x, y);
    }
  }
  return 0;
}
