#include <bits/stdc++.h>
using namespace std;
const int N = 100 * 1000 + 10;
vector<int> u[N], v[N], v2[N];
vector<pair<int, int> > q[N];
int t, st[N], fi[N], di[N], g[N], par[N];
int root(int u) { return (par[u] == u) ? u : par[u] = root(par[u]); }
void merge1(int x, int y) {
  int dx = root(x), dy = root(y);
  if (dx == dy) return;
  par[dy] = dx;
}
bool mark[N], ans[N];
void dfs(int u) {
  mark[u] = true;
  st[u] = t++;
  for (int i = 0; i < v[u].size(); i++) {
    if (!mark[v[u][i]]) dfs(v[u][i]);
  }
  fi[u] = t++;
}
int main() {
  int n, m, p = 1, j = 1;
  cin >> n >> m;
  for (int i = 0; i < m; i++) {
    int a, b, c;
    cin >> a;
    u[i].push_back(a);
    if (a == 1) {
      cin >> b >> c;
      u[i].push_back(b);
      u[i].push_back(c);
      v[c].push_back(b);
      di[b]++;
    }
    if (a == 2) {
      cin >> b;
      u[i].push_back(b);
      u[i].push_back(p);
      p++;
    }
    if (a == 3) {
      cin >> b >> c;
      u[i].push_back(b);
      u[i].push_back(c);
      q[c].push_back({b, j++});
    }
  }
  for (int i = 1; i <= n; i++) par[i] = i;
  for (int i = 1; i <= n; i++) {
    if (di[i] == 0) dfs(i);
  }
  for (int i = 1; i <= n; i++) {
  }
  for (int i = 0; i < m; i++) {
    int a = u[i][0], b = u[i][1], c = u[i][2];
    if (u[i][0] == 1) merge1(b, c);
    if (u[i][0] == 2) {
      for (int i = 0; i < q[c].size(); i++) {
        int qu = q[c][i].first, kj = q[c][i].second;
        if (st[qu] <= st[b] && fi[qu] >= fi[b] && root(qu) == root(b))
          ans[kj] = true;
        else
          ans[kj] = false;
      }
    }
  }
  for (int i = 1; i < j; i++) {
    if (ans[i])
      cout << "YES" << endl;
    else
      cout << "NO" << endl;
  }
}
