#include <bits/stdc++.h>
using namespace std;
const long long inf = 1000000007;
int kol_vo, q, pok = 0, timer = 0;
vector<int> tin, tout, dsu, used, tops;
vector<vector<int> > v;
void init() {
  v.resize(kol_vo);
  tin.resize(kol_vo);
  tout.resize(kol_vo);
  dsu.resize(kol_vo);
  used.resize(kol_vo);
}
void top_sort(int ver) {
  used[ver] = true;
  for (auto to : v[ver])
    if (!used[to]) top_sort(to);
  tops.push_back(ver);
}
void dfs(int ver) {
  used[ver] = true;
  tin[ver] = timer++;
  for (auto to : v[ver])
    if (!used[to]) dfs(to);
  tout[ver] = timer++;
}
int get(int ver) {
  if (dsu[ver] == ver)
    return ver;
  else
    return dsu[ver] = get(dsu[ver]);
}
void unite(int a, int b) {
  a = get(a);
  b = get(b);
  if (a == b) return;
  if (rand() & 1) swap(a, b);
  dsu[a] = b;
}
bool check(int a, int b) {
  a = get(a);
  b = get(b);
  if (a == b)
    return true;
  else
    return false;
}
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  cout.tie(0);
  cin >> kol_vo >> q;
  init();
  vector<vector<int> > ask;
  vector<vector<int> > dop;
  vector<int> help(3);
  for (int c = 0; c < q; c++) {
    int t;
    cin >> t;
    if (t == 1) {
      int from, to;
      cin >> to >> from;
      from--, to--;
      v[from].push_back(to);
      help[0] = 1;
      help[1] = from;
      help[2] = to;
      dop.push_back(help);
    }
    if (t == 2) {
      int x;
      cin >> x;
      x--;
      help[0] = 2;
      help[1] = x;
      dop.push_back(help);
    }
    if (t == 3) {
      int x, i;
      cin >> x >> i;
      x--;
      help[0] = 3;
      help[1] = x;
      help[2] = i;
      dop.push_back(help);
      help[0] = i;
      help[1] = x;
      help[2] = pok++;
      ask.push_back(help);
    }
  }
  for (int c = 0; c < kol_vo; c++) {
    if (!used[c]) top_sort(c);
  }
  reverse(tops.begin(), tops.end());
  memset(&used[0], 0, used.size() * sizeof(used[0]));
  for (int c = 0; c < kol_vo; c++) {
    if (!used[tops[c]]) dfs(tops[c]);
  }
  pok = 0;
  int now = 1;
  for (int c = 0; c < kol_vo; c++) dsu[c] = c;
  vector<int> take;
  sort(ask.begin(), ask.end());
  vector<int> answ(ask.size());
  for (int c = 0; c < dop.size(); c++) {
    if (dop[c][0] == 1) {
      unite(dop[c][1], dop[c][2]);
    }
    if (dop[c][0] == 2) {
      take.push_back(dop[c][1]);
      while (pok < ask.size() && ask[pok][0] == now) {
        if (tin[ask[pok][1]] <= tin[dop[c][1]] &&
            tout[ask[pok][1]] >= tout[dop[c][1]] &&
            check(ask[pok][1], dop[c][1]))
          answ[ask[pok][2]] = 1;
        else
          answ[ask[pok][2]] = 0;
        pok++;
      }
      now++;
    }
  }
  for (auto i : answ) {
    if (i)
      cout << "YES" << endl;
    else
      cout << "NO" << endl;
  }
  return 0;
}
