#include <algorithm>
#include <iostream>
#include <fstream>
#include <vector>
#include <bitset>
#include <list>
#define Nmax 100099
#define Mmax 400099
#define pb push_back
#define mp make_pair
#define ld long double
#define ll long long
#define ull unsigned long long
using namespace std;
//#define f cin
//#define g cout
#define Block -1
ifstream f("gigel.in");
ofstream g("gigel.out");

int N,M;
vector < pair < int ,int > > edge;
list < int > graph[Nmax];

int Sol(int a,int b)
{
     for(int i=a;i<=b;++i)
          for(list<int>::iterator it=graph[i].begin();it!=graph[i].end();++it)
               if(*it<a || *it>b)return 0;
     return 1;
}

main()
{
     //freopen("gigel.in","r",stdin);
     //freopen("gigel.out","w",stdout);
     scanf("%d %d\n",&N,&M);
     for(int i=1;i<=M;++i)
     {
          int op;
          scanf("%d ",&op);
          if(op==1)
          {
               int a,b;
               scanf("%d %d",&a,&b);
               graph[a].pb(b);
               graph[b].pb(a);
               edge.pb(mp(a,b));
          }
          else
          if(op==2)
          {
               int a,b;
               scanf("%d ",&a);
               --a;
               int x=edge[a].first,y=edge[a].second;
               list<int>::iterator it2;
               for(list<int>::iterator it=graph[x].begin();it!=graph[x].end();++it)
                    if(*it==y)
                    {
                         it2=it;
                         --it;
                         graph[x].erase(it2);
                    }
               for(list<int>::iterator it=graph[y].begin();it!=graph[y].end();++it)
                    if(*it==x)
                    {
                         it2=it;
                         --it;
                         graph[y].erase(it2);
                    }
          }
          else
          {
               int a,b;
               scanf("%d %d",&a,&b);
               if(Sol(a,b))printf("YES\n");
                    else printf("NO\n");

          }
     }

     return 0;
}