#include <cstdio>
#include <iostream>
#include <fstream>
#include <vector>
#include <list>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <bitset>
#include <algorithm>
#include <sstream>
#include <iomanip>
#include <cmath>
#include <cstdlib>
#include <cctype>
#include <cstring>
#include <string>
#include <ctime>
#include <cassert>
#include <utility>

using namespace std;

#define MAXN 100005
#define MAXM 400005
#define INF 1000000000

int N, M, t;
int Amin[4 * MAXN], Amax[4 * MAXN];
int e1[MAXM], e2[MAXM];
int crtE, a, b;
multiset<int> eMin[MAXN];
multiset<int, greater<int> > eMax[MAXN];

void init(int k, int st, int dr) {
    if(st == dr) {
        Amin[k] = st;
        Amax[k] = st;
        return;
    }
    
    int m = (st + dr) / 2;
    init(2 * k, st, m);
    init(2 * k + 1, m + 1, dr);
    
    Amin[k] = min(Amin[2 * k], Amin[2 * k + 1]);
    Amax[k] = max(Amax[2 * k], Amax[2 * k + 1]);
}

void updateAdd(int k, int st, int dr, int from, int to) {
    if(st == dr) {
        eMin[st].insert(to);
        eMax[st].insert(to);
        Amin[k] = min(Amin[k], *eMin[st].begin());
        Amax[k] = max(Amax[k], *eMax[st].begin());
        return;
    }
    
    int m = (st + dr) / 2;
    if(from <= m)
        updateAdd(2 * k, st, m, from, to);
    else
        updateAdd(2 * k + 1, m + 1, dr, from, to);
    
    Amin[k] = min(Amin[2 * k], Amin[2 * k + 1]);
    Amax[k] = max(Amax[2 * k], Amax[2 * k + 1]);
}

void updateDelete(int k, int st, int dr, int from, int to) {
    if(st == dr) {
        eMin[st].erase(to);
        eMax[st].erase(to);
        Amin[k] = min(Amin[k], *eMin[st].begin());
        Amax[k] = max(Amax[k], *eMax[st].begin());
        return;
    }
    
    int m = (st + dr) / 2;
    if(from <= m)
        updateDelete(2 * k, st, m, from, to);
    else
        updateDelete(2 * k + 1, m + 1, dr, from, to);
    
    Amin[k] = min(Amin[2 * k], Amin[2 * k + 1]);
    Amax[k] = max(Amax[2 * k], Amax[2 * k + 1]);
}

pair<int, int> query(int k, int st, int dr, int L, int R) {
    if(L <= st && dr <= R)
        return make_pair(Amin[k], Amax[k]);
    
    pair<int, int> ret = make_pair(INF, -INF);
    int m = (st + dr) / 2;
    if(L <= m) {
        pair<int, int> crt = query(2 * k, st, m, L, R);
        ret.first = min(ret.first, crt.first);
        ret.second = max(ret.second, crt.second);
    }
    if(R > m) {
        pair<int, int> crt = query(2 * k + 1, m + 1, dr, L, R);
        ret.first = min(ret.first, crt.first);
        ret.second = max(ret.second, crt.second);
    }
    
    return ret;
}

int main() {
//	freopen("date.in", "r", stdin);
//	freopen("date.out","w", stdout);
	
	scanf("%d %d", &N, &M);
	
	init(1, 1, N);
	crtE = 1;
	for(int i = 0; i < M; i++) {
        scanf("%d", &t);
        
        if(t == 1) {
            scanf("%d %d", &a, &b);
            e1[crtE] = a;
            e2[crtE] = b;
            crtE++;
            updateAdd(1, 1, N, a, b);
            updateAdd(1, 1, N, b, a);
        }
        else if(t == 2) {
            scanf("%d", &a);
            updateDelete(1, 1, N, e1[a], e2[a]);
            updateDelete(1, 1, N, e2[a], e1[a]);
        }
        else {
            scanf("%d %d", &a, &b);
            pair<int, int> q = query(1, 1, N, a, b);
            if(a <= q.first && q.second <= b)
                printf("YES\n");
            else            
                printf("NO\n");
        }
	}
	
	return 0;
}