#include <bits/stdc++.h>
using namespace std;
int n, m;
char c;
vector<int> g[100001];
int parent[100001], time_in[100001], time_out[100001], timer;
void dfs(int v) {
  time_in[v] = timer++;
  for (int i(0); i < g[v].size(); ++i) dfs(g[v][i]);
  time_out[v] = timer++;
}
int p[100001], h[100001];
int find_set(int v) {
  if (v != p[v]) p[v] = find_set(p[v]);
  return p[v];
}
void union_set(int u, int v) {
  u = find_set(u);
  v = find_set(v);
  if (h[u] < h[v]) swap(u, v);
  p[v] = u;
  if (h[u] == p[u]) h[u]++;
}
struct event {
  int type, x, y, i;
};
struct ask_type {
  int y, time;
};
int ask_cnt, doc_cnt;
vector<event> hist;
vector<ask_type> doc[100001];
bool ask[100001];
int main() {
  n = 0;
  for (c = getchar(); isdigit(c); c = getchar()) n = n * 10 + c - '0';
  m = 0;
  for (c = getchar(); isdigit(c); c = getchar()) m = m * 10 + c - '0';
  for (int i(1); i <= n; ++i) p[i] = i;
  event e;
  ask_type a;
  for (int i(0); i < m; ++i) {
    e.type = 0;
    for (c = getchar(); isdigit(c); c = getchar())
      e.type = e.type * 10 + c - '0';
    if (e.type == 1) {
      e.x = 0;
      for (c = getchar(); isdigit(c); c = getchar()) e.x = e.x * 10 + c - '0';
      e.y = 0;
      for (c = getchar(); isdigit(c); c = getchar()) e.y = e.y * 10 + c - '0';
      parent[e.x] = e.y;
      g[e.y].push_back(e.x);
      hist.push_back(e);
    }
    if (e.type == 2) {
      e.x = 0;
      for (c = getchar(); isdigit(c); c = getchar()) e.x = e.x * 10 + c - '0';
      e.i = doc_cnt++;
      hist.push_back(e);
    }
    if (e.type == 3) {
      a.y = 0;
      for (c = getchar(); isdigit(c); c = getchar()) a.y = a.y * 10 + c - '0';
      e.i = 0;
      for (c = getchar(); isdigit(c); c = getchar()) e.i = e.i * 10 + c - '0';
      e.i--;
      a.time = ask_cnt++;
      doc[e.i].push_back(a);
    }
  }
  for (int i(1); i <= n; ++i)
    if (!parent[i]) dfs(i);
  for (int i(0); i < hist.size(); ++i)
    if (hist[i].type == 1)
      union_set(hist[i].x, hist[i].y);
    else
      for (int j(0); j < doc[hist[i].i].size(); ++j)
        ask[doc[hist[i].i][j].time] =
            (find_set(hist[i].x) == find_set(doc[hist[i].i][j].y)) &&
            (time_in[hist[i].x] >= time_in[doc[hist[i].i][j].y] &&
             time_out[hist[i].x] <= time_out[doc[hist[i].i][j].y]);
  for (int i(0); i < ask_cnt; ++i)
    if (ask[i])
      puts("YES");
    else
      puts("NO");
}
