#include <bits/stdc++.h>
using namespace std;
class DSU {
 private:
  int *r, *t;

 public:
  DSU(int n) {
    r = new int[n + 5]();
    t = new int[n + 5]();
    for (int i = 1; i <= n; ++i) {
      r[i] = 1;
      t[i] = i;
    }
  }
  int _find(int first) {
    int rez, second;
    rez = first;
    while (rez != t[rez]) rez = t[rez];
    while (first != t[first]) {
      second = t[first];
      t[first] = rez;
      first = second;
    }
    return rez;
  }
  void _unite(int first, int second) {
    first = _find(first);
    second = _find(second);
    if (first == second) return;
    if (r[first] < r[second])
      t[first] = second;
    else
      t[second] = first;
    if (r[first] == r[second]) r[second]++;
  }
};
int main() {
  ios_base ::sync_with_stdio(false);
  cin.tie(nullptr);
  mt19937 rng(chrono::steady_clock ::now().time_since_epoch().count());
  uniform_int_distribution<int> _random(1, INT_MAX);
  int n, q;
  cin >> n >> q;
  vector<int> v;
  DSU T(n);
  set<int> s;
  for (int i = 1; i <= n; ++i) s.insert(i);
  s.insert(INT_MAX);
  while (q--) {
    int op, first, second;
    cin >> op >> first >> second;
    if (op == 1) T._unite(first, second);
    if (op == 2) {
      v.clear();
      for (set<int>::iterator it = s.lower_bound(first);
           it != s.end() and *it < second; ++it)
        v.push_back(*it);
      for (auto &it : v) {
        s.erase(it);
        T._unite(it, it + 1);
      }
    }
    if (op == 3) {
      if (T._find(first) == T._find(second))
        cout << "YES\n";
      else
        cout << "NO\n";
    }
  }
  return 0;
}
