#include <bits/stdc++.h>
#pragma GCC optimize("Ofast")
#pragma GCC optimize("unroll-loops")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
using namespace std;
inline void base() {
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  cout.tie(0);
  cout << fixed << setprecision(2);
}
int dsu[200005];
set<int> ls;
int find(int x) {
  if (dsu[x] != x) dsu[x] = find(dsu[x]);
  return dsu[x];
}
void merge(int a, int b) {
  int ra = find(a);
  int rb = find(b);
  if (ra == rb) return;
  if (ra < rb)
    dsu[ra] = rb;
  else
    dsu[rb] = ra;
}
int getInt() {
  int res = 0;
  char x = getchar();
  while (!isdigit(x)) x = getchar();
  for (; '0' <= x && x <= '9'; x = getchar()) {
    res *= 10;
    res += x - '0';
  }
  return res;
}
int main() {
  int n, q;
  n = getInt();
  q = getInt();
  for (int i = 1; i <= n; ++i) {
    dsu[i] = i;
    ls.insert(i);
  }
  while (q--) {
    int ty, a, b;
    ty = getInt();
    a = getInt();
    b = getInt();
    if (ty == 3) {
      if (find(a) == find(b))
        puts("YES");
      else
        puts("NO");
    } else if (ty == 1) {
      if (a > b) swap(a, b);
      merge(a, b);
    } else {
      set<int>::iterator it = ls.lower_bound(a);
      while (*it < b) {
        merge(*it, b);
        ls.erase(*it);
        it = ls.lower_bound(a);
      }
    }
  }
  return 0;
}
