#include <bits/stdc++.h>
using namespace std;
int indeg[100005];
vector<int> g[100005];
int timer = 0;
int start[100005];
int stop[100005];
int parent[100005];
int rnk[100005];
int given[100005];
vector<int> ques[100005];
unordered_map<int, bool> anss[100005];
void dfs(int u) {
  start[u] = ++timer;
  for (int v : g[u]) {
    dfs(v);
  }
  stop[u] = ++timer;
}
int find_set(int v) {
  if (v == parent[v]) return v;
  return parent[v] = find_set(parent[v]);
}
void make_set(int v) {
  parent[v] = v;
  rnk[v] = 0;
}
void union_sets(int a, int b) {
  a = find_set(a);
  b = find_set(b);
  if (a != b) {
    if (rnk[a] < rnk[b]) swap(a, b);
    parent[b] = a;
    if (rnk[a] == rnk[b]) rnk[a]++;
  }
}
int main() {
  int n, m;
  cin >> n >> m;
  for (int i = 0; i < n; i++) {
    make_set(i);
  }
  vector<pair<int, pair<int, int> > > inp;
  int total_pac = 1;
  for (int i = 0; i < m; i++) {
    int t, x, y;
    cin >> t >> x;
    if (t != 2) cin >> y;
    x--;
    if (t != 3) y--;
    inp.push_back({t, {x, y}});
    if (t == 1) {
      indeg[x]++;
      g[y].push_back(x);
    } else if (t == 3) {
      ques[y].push_back(x);
    }
  }
  for (int i = 0; i < n; i++) {
    if (indeg[i] == 0) dfs(i);
  }
  total_pac = 1;
  for (pair<int, pair<int, int> > i : inp) {
    int t = i.first;
    int x = i.second.first;
    int y = i.second.second;
    if (t == 1) {
      union_sets(x, y);
    } else if (t == 2) {
      for (int j : ques[total_pac]) {
        int ans = 0;
        if (find_set(x) == find_set(j) && stop[j] >= start[x] &&
            start[j] <= start[x])
          ans = 1;
        anss[total_pac][j] = ans;
      }
      total_pac++;
    } else {
      cout << (anss[y][x] ? "YES\n" : "NO\n");
    }
  }
}
