#include <bits/stdc++.h>
using namespace std;
const int maxn = 1 << 18;
int dsu[maxn];
int siz[maxn];
int pro[2 * maxn - 1];
void push(int v) {
  if (2 * v + 1 >= 2 * maxn - 1 || pro[v] == -1) return;
  pro[2 * v + 1] = pro[2 * v + 2] = pro[v];
  pro[v] = -1;
}
int get(int x) {
  int v = 0, vl = 0, vr = maxn;
  while (vr - vl > 1) {
    int m = (vl + vr) / 2;
    push(v);
    if (x < m) {
      vr = m;
      v = 2 * v + 1;
    } else {
      vl = m;
      v = 2 * v + 2;
    }
  }
  return pro[v];
}
void set_(int l, int r, int x, int v, int vl, int vr) {
  push(v);
  if (vl >= r || vr <= l) {
    return;
  } else if (vl >= l && vr <= r) {
    pro[v] = x;
  } else {
    int m = (vl + vr) / 2;
    set_(l, r, x, 2 * v + 1, vl, m);
    set_(l, r, x, 2 * v + 2, m, vr);
  }
}
int root(int x) { return dsu[x] == x ? x : dsu[x] = root(dsu[x]); }
int unite(int a, int b) {
  a = root(a);
  b = root(b);
  if (a == b) return a;
  if (siz[a] < siz[b]) swap(a, b);
  siz[a] += siz[b];
  return dsu[b] = a;
}
void unite_seq(int l, int r) {
  int nr = root(l);
  int nx;
  int i;
  for (i = get(l); i < r; i = nx) {
    nx = get(i);
    nr = unite(nr, i);
  }
  set_(l, i, i, 0, 0, maxn);
}
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(nullptr);
  int n, q;
  cin >> n >> q;
  for (int i = 0; i < maxn; ++i) {
    dsu[i] = i;
    siz[i] = 1;
    pro[maxn - 1 + i] = i + 1;
  }
  for (int i = maxn - 2; i >= 0; --i) pro[i] = -1;
  for (int i = 0; i < q; ++i) {
    int t, x, y;
    cin >> t >> x >> y;
    if (t == 1)
      unite(x, y);
    else if (t == 2)
      unite_seq(x, y + 1);
    else
      std::cout << (root(x) == root(y) ? "YES" : "NO") << '\n';
  }
}
