#include #include using namespace std; const int N=100005; multiset G[N]; multiset ::iterator it; int aint[3*N], aint1[3*N], mc1[4*N], mc2[4*N]; int X, Y, maxs, mins; void update(int nod, int l, int r) { if(l==r) { if(G[l].empty()) { aint[nod]=-1; aint1[nod]=N; } else { aint1[nod]=*G[l].begin(); it=G[l].end(); aint[nod]=*(--it); } return; } int mij=(l+r)/2; if(X<=mij) update(2*nod, l, mij); else update(2*nod+1, mij+1, r); aint[nod]=max(aint[2*nod], aint[2*nod+1]); aint1[nod]=min(aint1[2*nod], aint1[2*nod+1]); } void query(int nod, int l, int r) { if(X<=l&&r<=Y) { mins=min(mins, aint1[nod]); maxs=max(maxs, aint[nod]); return; } int mij=(l+r)/2; if(X<=mij) query(2*nod, l, mij); if(Y>mij) query(2*nod+1, mij+1, r); } int main() { //freopen("input", "r", stdin); //freopen("output", "w", stdout); int n, m, i, op, x, y, k=0; scanf("%d%d", &n, &m); for(i=1;i<=3*n;i++) { aint[i]=-1; aint1[i]=N; } while(m--) { scanf("%d%d", &op, &x); if(op==1) { scanf("%d", &y); G[x].insert(y); G[y].insert(x); X=x; update(1, 1, n); X=y; update(1, 1, n); mc1[++k]=x; mc2[++k]=y; } else if(op==2) { G[mc1[x]].erase(G[mc1[x]].find(mc2[x])); G[mc2[x]].erase(G[mc2[x]].find(mc1[x])); X=mc1[x]; update(1, 1, n); X=mc2[x]; update(1, 1, n); } else { scanf("%d", &y); X=x; Y=y; maxs=-1; mins=N; query(1, 1, n); if((maxs==-1||maxs<=y)&&(mins==N||mins>=x)) printf("YES\n"); else printf("NO\n"); } } }