#include <algorithm>
#include <fstream>
#include <iostream>
#include <vector>
#include <set>
using namespace std;

#define DEBUG 0

const int inf = 0x3f3f3f3f, kMaxN = 100005;

pair<int, int> aint[4 * kMaxN], edge[kMaxN * 4];
int nr_e;
multiset<int> s[kMaxN];

void get_min(int &a, int b) {
	if (a > b)
		a = b;
}

void get_max(int &a, int b) {
	if (a < b)
		a = b;
}

void aint_update(int nod, int st, int dr, int poz, pair<int, int> el) {
   
	if (st == dr) {
		aint[nod] = el;
		return ;
	}
	int m = (st + dr) / 2;
	if (poz <= m)
		aint_update(2 * nod, st, m, poz, el);
	else
		aint_update(2 * nod + 1, m + 1, dr, poz, el);

	aint[nod].first = min(aint[2 * nod].first, aint[2 * nod + 1].first);
	aint[nod].second = max(aint[2 * nod].second, aint[2 * nod + 1].second);
    	
	return;
}

pair<int, int> aint_query(int nod, int st, int dr, int c1, int c2) {
 	if (dr < c1 or c2 < st)
		return make_pair(inf, -inf);
//  	if (DEBUG) 
//		cerr << nod << "\t" << st << '\t' << dr << '\t' << aint[nod].first << '\t' << aint[nod].second << '\n';
	if (c1 <= st and dr <= c2)
		return aint[nod];
	
	pair<int, int> rez1, rez2;
	int m = (st + dr) / 2;
	rez1 = aint_query(2 * nod, st, m, c1, c2);
	rez2 = aint_query(2 * nod + 1, m + 1, dr, c1, c2);
	get_min(rez1.first, rez2.first);
	get_max(rez1.second, rez2.second);
	return rez1;
}

void aint_make(int nod, int st, int dr) {
 	aint[nod] = make_pair(st, dr);
	if (st == dr)
		return;
	int m = (st + dr) / 2;
	aint_make(2 * nod, st, m);
	aint_make(2 * nod + 1, m + 1, dr);
	return ;
}

int main() {
	int n, m;
	cin >> n >> m;
	for (int i = 1; i <= n; ++i)
		s[i].insert(i);
	aint_make(1, 1, n);
	for (int i = 1; i <= m; ++i) {
		int t;
		cin >> t;
		if (t == 1) {
			int a, b;
			++nr_e;
			cin >> a >> b;
			edge[nr_e] = make_pair(a, b);
 			s[a].insert(b);
			s[b].insert(a);
			aint_update(1, 1, n, a, make_pair(*s[a].begin(), *s[a].rbegin()));
			aint_update(1, 1, n, b, make_pair(*s[b].begin(), *s[b].rbegin()));
		}
		if (t == 2) {
			int x;
			cin >> x;
			int a = edge[x].first;
			int b = edge[x].second;
			s[a].erase(s[a].find(b));
			s[b].erase(s[b].find(a));
 			aint_update(1, 1, n, a, make_pair(*s[a].begin(), *s[a].rbegin()));
			aint_update(1, 1, n, b, make_pair(*s[b].begin(), *s[b].rbegin()));
		}
		if (t == 3) {
			int a, b;
			cin >> a >> b;
			if (a > b)
				swap(a, b);
			pair<int, int> rez;

			rez = aint_query(1, 1, n, a, b);
			if (rez.first == a and rez.second == b)
				cout << "YES\n";
			else
				cout << "NO\n";
			if (DEBUG)
				cerr << rez.first << '\t' << rez.second << '\n';
		}
	}
	return 0;
}