#include <bits/stdc++.h>
using namespace std;
const double eps = 1.0e-11;
const double pi = acos(-1.0);
const int N = 100100;
int n, m, timer;
int t[N], x[N], y[N], tin[N], tout[N], p[N];
vector<vector<int> > g;
void dfs(int v) {
  tin[v] = timer++;
  for (long long i = 0; i < (int)(g[v]).size(); i++) {
    dfs(g[v][i]);
  }
  tout[v] = timer++;
}
bool Check(int a, int b) { return (tin[a] <= tin[b] && tout[b] <= tout[a]); }
class DSU {
  vector<int> p;

 public:
  DSU(int n) {
    for (long long i = 0; i < n; i++) p.push_back(i);
  }
  int Get(int x) {
    if (p[x] == x) return x;
    return p[x] = Get(p[x]);
  }
  void Join(int a, int b) {
    if (rand() & 1) swap(a, b);
    a = Get(a);
    b = Get(b);
    if (a == b) return;
    p[a] = b;
  }
};
int main() {
  ios_base::sync_with_stdio(0);
  cin >> n >> m;
  g.resize(n);
  vector<vector<pair<int, int> > > q;
  for (long long i = 0; i < n; i++) p[i] = -1;
  for (long long i = 0; i < m; i++) {
    cin >> t[i];
    if (t[i] != 2) {
      cin >> x[i] >> y[i];
      --x[i], --y[i];
      if (t[i] == 1) {
        g[y[i]].push_back(x[i]);
        p[x[i]] = y[i];
      }
    } else
      cin >> x[i], --x[i], q.push_back(vector<pair<int, int> >());
  }
  int time = 0;
  for (long long i = 0; i < m; i++) {
    if (t[i] == 3) {
      q[y[i]].push_back(make_pair(x[i], time++));
    }
  }
  for (long long i = 0; i < n; i++)
    if (p[i] == -1) dfs(i);
  DSU dsu(n);
  vector<int> packs;
  vector<bool> resp(time);
  time = 0;
  for (long long i = 0; i < m; i++) {
    if (t[i] == 1) dsu.Join(x[i], y[i]);
    if (t[i] == 2) {
      for (long long j = 0; j < (int)(q[time]).size(); j++) {
        int xx = q[time][j].first;
        int yy = x[i];
        int pos = q[time][j].second;
        if (dsu.Get(xx) == dsu.Get(yy) && Check(xx, yy)) resp[pos] = true;
      }
      ++time;
    }
  }
  for (long long i = 0; i < (int)(resp).size(); i++)
    cout << (resp[i] ? "YES\n" : "NO\n");
  return 0;
}
