#include <bits/stdc++.h>
using namespace std;
struct Dsu {
  vector<int> pa, rk;
  Dsu(int n) {
    pa.resize(n);
    iota(pa.begin(), pa.end(), 0);
    rk.assign(n, 0);
  }
  int anc(int x) { return pa[x] == x ? x : pa[x] = anc(pa[x]); }
  bool unite(int x, int y) {
    int a = anc(x), b = anc(y);
    if (a == b) return false;
    if (rk[a] < rk[b]) swap(a, b);
    pa[b] = a;
    rk[a] += rk[a] == rk[b];
    return true;
  }
};
int ans[1 << 17], pa[1 << 17];
struct Package {
  vector<pair<int, int>> Es;
  vector<pair<int, int>> Qs;
  int dec;
  Package(vector<pair<int, int>> Es, int dec) : Es(Es), dec(dec) {}
};
int main() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  int n, m;
  cin >> n >> m;
  vector<pair<int, int>> curE;
  iota(pa, pa + n, 0);
  vector<Package> Ps;
  vector<vector<int>> g(n);
  vector<int> in(n), out(n);
  static int ord = 0;
  for (int i = 0; i < m; ++i) {
    int t;
    cin >> t;
    if (t == 1) {
      int x, y;
      cin >> x >> y;
      --x, --y, pa[x] = y;
      curE.emplace_back(x, y);
      g[y].push_back(x);
    } else if (t == 2) {
      int x;
      cin >> x, --x;
      Ps.emplace_back(curE, x);
      curE.clear();
    } else {
      int x, i;
      cin >> x >> i;
      --x, --i;
      Ps[i].Qs.emplace_back(x, ord++);
    }
  }
  function<void(int)> dfs = [&](int u) {
    static int cur = 0;
    in[u] = cur++;
    for (int v : g[u]) dfs(v);
    out[u] = cur;
  };
  for (int u = 0; u < n; ++u)
    if (pa[u] == u) dfs(u);
  auto anc = [&](int a, int p) { return in[p] <= in[a] and out[a] <= out[p]; };
  Dsu djs(n);
  for (auto P : Ps) {
    for (auto [u, v] : P.Es) {
      djs.unite(u, v);
    }
    for (auto [x, id] : P.Qs) {
      ans[id] = djs.anc(x) == djs.anc(P.dec) and anc(P.dec, x);
    }
  }
  for (int i = 0; i < ord; ++i) cout << (ans[i] ? "YES" : "NO") << '\n';
}
