#include <bits/stdc++.h>
using namespace std;
class DSU {
 private:
  int n;
  int rank[200009], par[200009];

 public:
  DSU(int n) {
    this->n = n;
    for (int i = 0; i < n; i++) rank[i] = 0, par[i] = i;
  }
  int get_set(int v) { return par[v] == v ? v : (par[v] = get_set(par[v])); }
  bool same_set(int i, int j) { return get_set(i) == get_set(j); }
  void _union(int i, int j) {
    int k1 = get_set(i);
    int k2 = get_set(j);
    if (k1 == k2) return;
    if (rank[k1] > rank[k2])
      par[k2] = k1;
    else {
      par[k1] = k2;
      if (rank[k1] == rank[k2]) ++rank[k2];
    }
  }
};
set<int> s;
int main() {
  int n, q;
  scanf("%d%d", &n, &q);
  DSU dsu1(n);
  for (int i = 0; i < n; i++) s.insert(i);
  int t, x, y;
  for (int i = 0; i < q; i++) {
    scanf("%d%d%d", &t, &x, &y);
    if (t == 1)
      dsu1._union(x, y);
    else if (t == 3) {
      if (dsu1.same_set(x, y))
        printf("YES\n");
      else
        printf("NO\n");
    } else {
      vector<int> v;
      set<int>::iterator itr = s.lower_bound(x);
      while (itr != s.end()) {
        if ((*itr) >= y) break;
        v.push_back(*itr);
        itr++;
      }
      int i;
      for (i = 0; i < v.size(); i++) s.erase(v[i]);
      for (i = 0; i < v.size(); i++) dsu1._union(v[i], v[i] + 1);
    }
  }
}
