#include <bits/stdc++.h>
using namespace std;
clock_t __stt;
inline void TStart() { __stt = clock(); }
inline void TReport() {
  printf("\nTaken Time : %.3lf sec\n",
         (double)(clock() - __stt) / CLOCKS_PER_SEC);
}
template <typename T>
T MIN(T a, T b) {
  return a < b ? a : b;
}
template <typename T>
T MAX(T a, T b) {
  return a > b ? a : b;
}
template <typename T>
T ABS(T a) {
  return a > 0 ? a : (-a);
}
template <typename T>
void UMIN(T &a, T b) {
  if (b < a) a = b;
}
template <typename T>
void UMAX(T &a, T b) {
  if (b > a) a = b;
}
int n, m, fa[500005], rk[500005];
int anscestor(int x) {
  if (fa[x] != x) fa[x] = anscestor(fa[x]);
  return fa[x];
}
inline void Union(int x, int y) {
  x = anscestor(x);
  y = anscestor(y);
  if (x != y) {
    if (rk[x] < rk[y])
      fa[x] = y;
    else {
      fa[y] = x;
      if (rk[x] == rk[y]) ++rk[x];
    }
  }
}
class segT {
 public:
  int l[1000005], r[1000005];
  bool e[1000005];
  void Init(int p, int L, int R) {
    l[p] = L;
    r[p] = R;
    e[p] = 0;
    if (L < R) {
      int M = ((L + R) >> 1);
      Init((p << 1), L, M);
      Init(((p << 1) | 1), M + 1, R);
    }
  }
  void Modify(int p, int L, int R, int bas) {
    if (l[p] >= L && r[p] <= R) {
      if (!e[p]) {
        R = r[p];
        L = l[p];
        while (R > L) Union(R--, L);
        e[p] = 1;
      }
      Union(l[p], bas);
    } else {
      int M = ((l[p] + r[p]) >> 1);
      if (L <= M) Modify((p << 1), L, R, bas);
      if (R > M) Modify(((p << 1) | 1), L, R, bas);
    }
  }
} segt;
int main() {
  int xb, x2, t, x, y;
  scanf("%d%d", &n, &m);
  for (xb = 0; xb < 500005; ++xb) fa[xb] = xb;
  segt.Init(1, 0, n - 1);
  for (xb = 0; xb < m; ++xb) {
    scanf("%d%d%d", &t, &x, &y);
    --x;
    --y;
    if (t == 1) {
      Union(x, y);
    } else if (t == 2) {
      segt.Modify(1, x, y, x);
    } else {
      if (anscestor(x) == anscestor(y))
        puts("YES");
      else
        puts("NO");
    }
  }
  return 0;
}
