package graphWars; import java.util.Random; import java.util.Scanner; public class Gw { public static void baga ( int x , int y , Treap[] t , MinAint arb1 , MaxAint arb2 , int[] now1 , int [] now2 ){ t[x].insert(y); int minim = t[x].getMin(); int maxim = t[x].getMax(); if ( minim != now1[x] ){ now1[x] = minim; arb1.update(x, minim); } if ( maxim != now2[x] ){ now2[x] = maxim; arb2.update(x, maxim); } } public static void scoate ( int x , int y , Treap[] t , MinAint arb1 , MaxAint arb2 , int[] now1 , int [] now2 ){ t[x].delete(y); int minim = t[x].getMin(); int maxim = t[x].getMax(); if ( minim != now1[x] ){ now1[x] = minim; arb1.update(x, minim); } if ( maxim != now2[x] ){ now2[x] = maxim; arb2.update(x, maxim); } } public static void main (String[] args){ Scanner sc = new Scanner(System.in); int n = sc.nextInt(),m = sc.nextInt(); int now1[] = new int[n+1],now2[] = new int[n+1]; int insertedx[] = new int[m+1],insertedy[] = new int[m+1],inserted = 0; MinAint aintmin = new MinAint(n); MaxAint aintmax = new MaxAint(n); for ( int i = 1 ; i <= n ; ++i ){ now1[i] = Integer.MAX_VALUE; aintmin.update(i, Integer.MAX_VALUE); } Treap[] t = new Treap[n+1]; for ( int i = 1 ; i <= n ; ++i ){ t[i] = new Treap(); } for ( int step = 1 ; step <= m ; ++step ){ int type = sc.nextInt(),x,y; if ( type == 1 ){ x = sc.nextInt(); y = sc.nextInt(); baga(x,y,t,aintmin,aintmax,now1,now2); baga(y,x,t,aintmin,aintmax,now1,now2); ++inserted; insertedx[inserted] = x; insertedy[inserted] = y; } if ( type == 2 ){ int ind = sc.nextInt(); x = insertedx[ind]; y = insertedy[ind]; scoate(x,y,t,aintmin,aintmax,now1,now2); scoate(y,x,t,aintmin,aintmax,now1,now2); } if ( type == 3 ){ x = sc.nextInt(); y = sc.nextInt(); int minim = aintmin.query(x, y); int maxim = aintmax.query(x, y); if ( minim >= x && maxim <= y ){ System.out.println("YES"); } else{ System.out.println("NO"); } } } sc.close(); } static class MinAint{ private int n; private int arb[]; MinAint ( int n ){ this.n = n; arb = new int[4*n+1]; for ( int i = 1 ; i <= 4*n ; ++i ){ arb[i] = Integer.MAX_VALUE; } } public void update ( int poz , int value ){ update(1,1,n,poz,value); } public int query ( int left , int right ){ return query(1,1,n,left,right); } private void update ( int nod , int st , int dr , int poz , int value ){ if ( st == dr ){ arb[nod] = value; return ; } int mij = (st+dr)>>1; int nodst = nod<<1; int noddr = nodst | 1; if ( poz <= mij ){ update(nodst,st,mij,poz,value); } else{ update(noddr,mij+1,dr,poz,value); } arb[nod] = Math.min(arb[nodst],arb[noddr]); } int query ( int nod , int st , int dr , int left , int right ){ if ( left <= st && dr <= right ){ return arb[nod]; } int mij = (st+dr)>>1; int nodst = nod<<1; int noddr = nodst | 1; int r = Integer.MAX_VALUE; if ( left <= mij ){ r = Math.min(r,query(nodst,st,mij,left,right)); } if ( right > mij ){ r = Math.min(r,query(noddr,mij+1,dr,left,right)); } return r; } } static class MaxAint{ private int n; private int arb[]; MaxAint ( int n ){ this.n = n; arb = new int[4*n+1]; } public void update ( int poz , int value ){ update(1,1,n,poz,value); } public int query ( int left , int right ){ return query(1,1,n,left,right); } private void update ( int nod , int st , int dr , int poz , int value ){ if ( st == dr ){ arb[nod] = value; return ; } int mij = (st+dr)>>1; int nodst = nod<<1; int noddr = nodst | 1; if ( poz <= mij ){ update(nodst,st,mij,poz,value); } else{ update(noddr,mij+1,dr,poz,value); } arb[nod] = Math.max(arb[nodst],arb[noddr]); } int query ( int nod , int st , int dr , int left , int right ){ if ( left <= st && dr <= right ){ return arb[nod]; } int mij = (st+dr)>>1; int nodst = nod<<1; int noddr = nodst | 1; int r = 0; if ( left <= mij ){ r = Math.max(r,query(nodst,st,mij,left,right)); } if ( right > mij ){ r = Math.max(r,query(noddr,mij+1,dr,left,right)); } return r; } } static class Treap { private final TreapNode nul; private TreapNode rNode; Random random; Treap () { nul = new TreapNode(); rNode = nul; random = new Random(); } public int getMin () { return rNode.getMin(); } public int getMax () { return rNode.getMax(); } public void insert ( int value ){ rNode = rNode.insert(value,random.nextInt(Integer.MAX_VALUE)); } public void delete ( int value ){ rNode = rNode.delete(value); } public void printt () { rNode.printt(); } public class TreapNode { private int priority,key; TreapNode ls,rs; TreapNode () { priority = key = 0; ls = rs = nul; } TreapNode ( int priority , int key , TreapNode ls , TreapNode rs ){ this.priority = priority; this.key = key; this.ls = ls; this.rs = rs; } @Override public TreapNode clone () { return new TreapNode(priority, key, ls, rs); } private TreapNode rotateLS () { TreapNode nextrsNode = new TreapNode(this.priority,this.key, this.ls.rs, this.rs); return new TreapNode(this.ls.priority,this.ls.key,this.ls.ls,nextrsNode); } private TreapNode rotateRS () { TreapNode nextlsNode = new TreapNode(this.priority, this.key, this.ls, this.rs.ls); return new TreapNode(this.rs.priority, this.rs.key, nextlsNode, this.rs.rs); } private TreapNode balance () { if ( ls.priority > this.priority ){ return this.rotateLS(); } else{ if ( rs.priority > this.priority ){ return this.rotateRS(); } } return this; } private void printt () { if ( this.ls != nul ){ this.ls.printt(); } System.out.printf("%d ",this.key); if ( this.rs!= nul ){ this.rs.printt(); } } private int getMin () { //assert(this != nul):"empty tree in getmin"; if ( this == nul ){ return Integer.MAX_VALUE; } if ( this.ls == nul ){ return this.key; } return this.ls.getMin(); } private int getMax () { //assert(this != nul):"empty tree in getmin"; if ( this == nul ){ return 0; } if ( this.rs == nul ){ return this.key; } return this.rs.getMax(); } TreapNode insert ( int key , int priority ){ if ( this == nul ){ return new TreapNode(priority, key, nul, nul); } if ( this.key >= key ){ return (new TreapNode(this.priority, this.key, ls.insert(key, priority) , rs)).balance(); } else{ return (new TreapNode(this.priority, this.key, ls , rs.insert(key, priority))).balance(); } } TreapNode delete ( int key ){ if ( this == nul ) return this; if ( key < this.key ){ return new TreapNode(this.priority, this.key, this.ls.delete(key) , rs); } if ( key > this.key ){ return new TreapNode(this.priority, this.key, ls, this.rs.delete(key)); } //key == this.key if ( this.ls == nul && this.rs == nul ){ return nul; } if ( this.ls.priority > this.rs.priority ){ TreapNode rotated = this.rotateLS(); return new TreapNode(rotated.priority, rotated.key, rotated.ls, rotated.rs.delete(key)); } else{ TreapNode rotated = this.rotateRS(); return new TreapNode(rotated.priority, rotated.key, rotated.ls.delete(key), rotated.rs); } } } } }