#include <bits/stdc++.h>
using namespace std;
using cd = complex<double>;
const int mod = 1e9 + 7;
const double Pi = acos(-1);
void Fastio() {
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  cout.tie(0);
}
int n, m, tim = 0;
int dsu[100005], par[100005], type[100005], x[100005], y[100005];
int Ans[100005], tin[100005], tout[100005];
vector<int> Adj[100005];
vector<pair<int, int> > Query[100005];
int Root(int node) { return dsu[node] == node ? node : Root(dsu[node]); }
void DFS(int node) {
  tin[node] = ++tim;
  for (auto xx : Adj[node]) {
    DFS(xx);
  }
  tout[node] = tim;
}
bool Isparent(int u, int v) { return (tin[u] <= tin[v] && tout[u] >= tout[v]); }
signed main() {
  Fastio();
  cin >> n >> m;
  int cnt = 0;
  for (int i = 1; i <= n; i++) {
    dsu[i] = i;
    par[i] = -1;
  }
  for (int i = 1; i <= m; i++) {
    cin >> type[i];
    if (type[i] == 2) {
      cin >> x[i];
    } else {
      cin >> x[i] >> y[i];
      if (type[i] == 1) {
        par[x[i]] = y[i];
        Adj[y[i]].emplace_back(x[i]);
      } else {
        Query[y[i]].emplace_back(x[i], ++cnt);
      }
    }
  }
  for (int i = 1; i <= n; i++) {
    if (par[i] == -1) {
      DFS(i);
    }
  }
  int o = cnt;
  cnt = 0;
  for (int i = 1; i <= m; i++) {
    if (type[i] == 1) {
      if (Root(x[i]) != Root(y[i])) {
        dsu[Root(x[i])] = Root(y[i]);
      }
    } else if (type[i] == 2) {
      for (auto xx : Query[++cnt]) {
        if (Root(x[i]) == Root(xx.first) && Isparent(xx.first, x[i])) {
          Ans[xx.second] = 1;
        } else {
          Ans[xx.second] = 0;
        }
      }
    }
  }
  for (int i = 1; i <= o; i++) {
    if (Ans[i]) {
      cout << "YES\n";
    } else {
      cout << "NO\n";
    }
  }
}
