#include <iostream>
#include <algorithm>
#include <set>
#include <vector>

using namespace std;

const int INF = 0x3f3f3f3f;

int N, M;
vector<pair<int, int> > V;

multiset<int> S[2][100002];
int ARB[2][4 * 100002], A1, A2, Ap, Ar, Aw;

void setn(int nod, int i1, int i2)
{
	if (i1 == i2)
	{
		ARB[0][nod] = INF;
		ARB[1][nod] = -INF;
		
		return;
	}
	
	int mid = (i1 + i2) / 2;
	setn(nod * 2, i1, mid);
	setn(nod * 2 + 1, mid + 1, i2);
	
	ARB[0][nod] = min(ARB[0][nod * 2], ARB[0][nod * 2 + 1]);
	ARB[1][nod] = max(ARB[1][nod * 2], ARB[1][nod * 2 + 1]);
}
void update(int nod, int i1, int i2)
{
	if (i1 == i2)
	{
		if (S[Aw][i1].empty())
		{
			if (Aw == 0) ARB[Aw][nod] = INF;
			else         ARB[Aw][nod] = -INF;
		}
		else
		{
			if (Aw == 0) ARB[Aw][nod] = *S[Aw][i1].begin();
			else
			{
				multiset<int>::iterator it = S[Aw][i1].end();
				--it;
				
				ARB[Aw][nod] = *it;
			}
		}
		return;
	}
	
	int mid = (i1 + i2) / 2;
	if (Ap <= mid) update(nod * 2, i1, mid);
	else           update(nod * 2 + 1, mid + 1, i2);
	
	if (Aw == 0) ARB[Aw][nod] = min(ARB[Aw][nod * 2], ARB[Aw][nod * 2 + 1]);
	if (Aw == 1) ARB[Aw][nod] = max(ARB[Aw][nod * 2], ARB[Aw][nod * 2 + 1]);
}
void query(int nod, int i1, int i2)
{
	if (A1 <= i1 && i2 <= A2)
	{
		if (Aw == 0) Ar = min(Ar, ARB[Aw][nod]);
		else         Ar = max(Ar, ARB[Aw][nod]);
		
		return;
	}
	
	int mid = (i1 + i2) / 2;
	if (A1 <= mid) query(nod * 2, i1, mid);
	if (A2 > mid)  query(nod * 2 + 1, mid + 1, i2);
}

int main()
{
	cin.sync_with_stdio(false);
	
	cin >> N >> M;
	setn(1, 1, N);
	
	for (int i = 1, type; i <= M; ++i)
	{
		cin >> type;
		if (type == 1)
		{
			int nod1, nod2;
			cin >> nod1 >> nod2;
			
			if (nod1 > nod2) swap(nod1, nod2);
			V.push_back(make_pair(nod1, nod2));
			
			S[1][nod1].insert(nod2);
			S[0][nod2].insert(nod1);
			
			Aw = 1, Ap = nod1;
			update(1, 1, N);
			
			Aw = 0, Ap = nod2;
			update(1, 1, N);
		}
		else if (type == 2)
		{
			int wh;
			cin >> wh;
			
			S[1][V[wh - 1].first].erase(S[1][V[wh - 1].first].find(V[wh - 1].second));
			S[0][V[wh - 1].second].erase(S[0][V[wh - 1].first].find(V[wh - 1].first));
			
			Aw = 1, Ap = V[wh - 1].first;
			update(1, 1, N);
			
			Aw = 0, Ap = V[wh - 1].second;
			update(1, 1, N);
		}
		else if (type == 3)
		{
			int nod1, nod2;
			cin >> nod1 >> nod2;
			
			if (nod1 > nod2) swap(nod1, nod2);
			
			bool ok = true;
			
			A1 = nod1, A2 = nod2, Aw = 0, Ar = INF;
			query(1, 1, N);
		
			if (Ar < nod1) ok = false;

			A1 = nod1, A2 = nod2, Aw = 1, Ar = -INF;
			query(1, 1, N);
		
			if (Ar > nod2) ok = false;

			if (ok) cout << "YES\n";
			else    cout << "NO\n";
		}
	}
}