import java.util.Random; import java.util.Scanner; public class prog { public static void baga ( int x , int y , Object[] tr , MinAint arb1 , MaxAint arb2 , int[] now1 , int [] now2 ){ AvlTreet = (AvlTree)tr[x]; t.insert(y,y); int minim = t.getMinKey(); int maxim = t.getMaxKey(); 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 , Object[] tr , MinAint arb1 , MaxAint arb2 , int[] now1 , int [] now2 ){ AvlTreet = (AvlTree)tr[x]; t.delete(y); int minim = t.getMinKey(); int maxim = t.getMaxKey(); 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); } Object[] t = new Object[n+1]; for ( int i = 1 ; i <= n ; ++i ){ t[i] = new AvlTree(); } 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 AvlNode,K> { T key; int height; private K value; AvlNode lson,rson; public AvlNode () { key = null; value = null; height = 0; lson = rson = null; } public AvlNode ( T key , K value , AvlNode lson , AvlNode rson ){ this.key = key; this.value = value; this.lson = lson; this.rson = rson; updateHeight(); } private void updateHeight () { int h1 = lson != null ? lson.height : 0; int h2 = rson != null ? rson.height : 0; this.height = 1 + (h1 >= h2 ? h1 : h2); } private static int getHeight ( AvlNode node ){ if ( node == null ) return 0; return node.height; } public void setLson ( AvlNode lson ){ this.lson = lson; updateHeight(); } public void setRson ( AvlNode rson ){ this.rson = rson; updateHeight(); } public AvlNode rotateLeft () { if ( lson == null ) return this; AvlNodeaux = lson; setLson(lson.rson); aux.setRson(this); return aux; } public AvlNode rotateRight () { if ( rson == null ) return this; AvlNodeaux = rson; setRson(rson.lson); aux.setLson(this); return aux; } public AvlNode rotateLeftRight () { setLson(lson.rotateLeft()); return rotateRight(); } public AvlNode rotateRightLeft () { setRson(rson.rotateRight()); return rotateLeft(); } public AvlNode rebalance () { int hl = getHeight(lson),hr = getHeight(rson); if ( hl <= hr-2 ){ int hrl = getHeight(rson.lson),hrr = getHeight(rson.rson); if ( hrl > hrr ) return rotateRightLeft(); else return rotateRight(); } else{ if ( hl >= hr+2 ){ int hll = getHeight(lson.lson),hlr = getHeight(lson.rson); if ( hll < hlr ) return rotateLeftRight(); else return rotateLeft(); } } return this; } } static class AvlTree,K> { AvlNode root; public void insert ( T key , K value ){ root = insertAVL(root,key,value); } public T getMinKey (){ return getMinAVL(root); } public T getMaxKey () { return getMaxAVL(root); } public void delete ( T key ){ root = deleteAVL(root,key); } private AvlNode insertAVL ( AvlNodenode , T key , K value ){ if ( node == null ){ return new AvlNode(key,value,null,null); } if ( key.compareTo(node.key) <= 0 ){ node.setLson(insertAVL(node.lson,key,value)); } else{ node.setRson(insertAVL(node.rson,key,value)); } return node.rebalance(); } private AvlNode deleteAVL ( AvlNodenode , T key ){ if ( node == null ) return null; if ( key.compareTo(node.key) == 0 ){ return deleteAVLNode(node); } if ( key.compareTo(node.key) < 0 ){ node.setLson(deleteAVL(node.lson,key)); } else{ node.setRson(deleteAVL(node.rson,key)); } return node.rebalance(); } private AvlNode deleteAVLNode ( AvlNode node ){ if ( node.lson == null ) return node.rson; if ( node.rson == null ) return node.lson; AvlNode replacementNode = findLeftMost(node.rson); AvlNode newRight = deleteLeftMost(node.rson); replacementNode.setLson(node.lson); replacementNode.setRson(newRight); return replacementNode.rebalance(); } private AvlNode findLeftMost ( AvlNode node ){ if ( node.lson == null ) return node; return findLeftMost(node.lson); } private AvlNode deleteLeftMost ( AvlNode node ){ if ( node.lson == null ) return node.rson; return deleteLeftMost(node.lson).rebalance(); } private T getMinAVL ( AvlNodenode ){ if ( node.lson == null ) return node.key; return getMinAVL(node.lson); } private T getMaxAVL ( AvlNodenode ){ if ( node.rson == null ) return node.key; return getMaxAVL(node.rson); } } }