Real Cosmic Communications is the largest telecommunication company on a far far away planet, located at the very edge of the universe. RCC launches communication satellites.The planet is at the very edge of the universe, so its form is half of a circle. Its radius is r, the ends of its diameter are points A and B. The line AB is the edge of the universe, so one of the half-planes contains nothing, neither the planet, nor RCC satellites, nor anything else. Let us introduce coordinates in the following way: the origin is at the center of AB segment, OX axis coincides with line AB, the planet is completely in y > 0 half-plane.The satellite can be in any point of the universe, except the planet points. Satellites are never located beyond the edge of the universe, nor on the edge itself — that is, they have coordinate y > 0. Satellite antennas are directed in such way that they cover the angle with the vertex in the satellite, and edges directed to points A and B. Let us call this area the satellite coverage area. The picture below shows coordinate system and coverage area of a satellite.  When RCC was founded there were no satellites around the planet. Since then there have been several events of one of the following types:   1 x y — launch the new satellite and put it to the point (x, y). Satellites never move and stay at the point they were launched. Let us assign the number i to the i-th satellite in order of launching, starting from one.  2 i — remove satellite number i.  3 i j — make an attempt to create a communication channel between satellites i and j. To create a communication channel a repeater is required. It must not be located inside the planet, but can be located at its half-circle border, or above it. Repeater must be in coverage area of both satellites i and j. To avoid signal interference, it must not be located in coverage area of any other satellite. Of course, the repeater must be within the universe, it must have a coordinate y > 0. For each attempt to create a communication channel you must find out whether it is possible.Sample test has the following satellites locations:

The first line of input data contains integers r and n — radius of the planet and the number of events (1 ≤ r ≤ 109, 1 ≤ n ≤ 5·105). Each of the following n lines describe events in the specified format. Satellite coordinates are integer, the satisfy the following constraints |x| ≤ 109, 0 < y ≤ 109. No two satellites that simultaneously exist can occupy the same point. Distance from each satellite to the center of the planet is strictly greater than r. It is guaranteed that events of types 2 and 3 only refer to satellites that exist at the moment. For all events of type 3 the inequality i ≠ j is satisfied.

For each event of type 3 print «YES» on a separate line, if it is possible to create a communication channel, or «NO» if it is impossible.

#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <string>
#include <cstring>
#include <cmath>
#include <set>
#include <map>
#include <cstdio>
#include <stdlib.h>
#include <stack>
#include <numeric>
#include <bitset>
#include <cctype>
#include <list>
#include <assert.h>
#include <random>
#include <unordered_map>
#include <ctime>
typedef  long long ll;
using namespace std;
#define INF 2147483647
#define infL (1LL<<60)
#define inf (1<<30)
#define inf9 (1000000000)
#define MOD 1000000007
#define EPS 1e-9
#define Gr 9.8
#define PI acos(-1)
#define REP(i,n) for(int (i)=0;(i)<(int)(n);(i)++)
#define REQ(i,n) for(int (i)=1;(i)<=(int)(n);(i)++)
#define lch (rt<<1)
#define rch (rt<<1|1)
#define readmp(n) for(int i=0,u,v;i<n;i++) {scanf("%d%d",&u,&v); mp[u].push_back(v); mp[v].push_back(u);}
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef long double ld;
typedef unsigned int uint;
#define MAX 500105
bool debug = 0;
int n,m,k;
int dx[4] = {0,1,0,-1}, dy[4] = {1,0,-1,0};
string direc="RDLU";
ll ln, lk, lm;
void etp(bool f = 0) {
    puts(f ?"YES" : "NO");
    exit(0);
}
void addmod(int &x, int y, int mod = MOD) {
    assert(y>=0);
    x+=y; if (x>=mod) x-=mod;
    assert(x>=0 && x<mod);
}
void et() {
    puts("-1"); exit(0);
}
ll fastPow(ll x, ll y, int mod=MOD) {
    ll ans = 1;
    while(y>0) {
        if(y&1) ans = (x * ans)%mod;
        x = x*x%mod;
        y>>=1;
    }
    return ans;
}

struct Frac {
    ll x, y;
    int z;
    Frac() { }
    Frac(ll x, ll y, int z) : x(x), y(y) ,z(z){}
    bool operator<(const Frac& o) const {
        return z || (o.z==0 && (x*o.y < y*o.x));
    }
    friend bool operator == (const Frac &r1,const Frac &r2) {return r1.x*r2.y == r1.y*r2.x;}
};
int R;
Frac lt[MAX],rt[MAX];
int sateCnt;
struct mb {
    int t,x,y, id;
    void rd() {
        scanf("%d", &t);
        if (t==2) scanf("%d", &id);
        else scanf("%d%d", &x,&y);
    }
}q[MAX];
map<Frac, int> mp;
int li[MAX],cnt;

const int MN=(1<<21)+5;
struct mbt {
    int M; Frac T[MN];
    void init(int sz) {
        for(M=1;sz+2>M;M<<=1);
        REP(i,MN) T[i]={0,0,1};
    }
    void uptSingleMax(int l, Frac val) {
        l+=M; T[l]=val;
        while(l>1) {
            T[l>>1] = max(T[l],T[l^1]); l>>=1;
        }
    }
    Frac qyRangeMax(int l, int r) {
        Frac ans = {0,0,1};
        for(l=l+M-1,r=r+M+1;l^r^1;l>>=1,r>>=1){
            if(~l&1) ans = max(ans, T[l^1]);
            if(r&1) ans = max(ans, T[r^1]);
        }
        return ans;
    }
}T;
bool del[MAX];
priority_queue<pair<Frac,int>> Q[MAX];
void add(int staId) {
    del[staId] = 0;
    int k = li[staId];
    Q[k].push({rt[staId], staId});
    T.uptSingleMax(k,Q[k].top().first);
}
void rmv(int staId) {
    del[staId] = 1;
    int k = li[staId];
    while(del[Q[k].top().second]) {
        Q[k].pop();
    }
    T.uptSingleMax(k, Q[k].top().first);
}
void fmain(int tid) {
    scanf("%d%d", &R, &n);
    REQ(i,n) {
        q[i].rd();
        if (q[i].t == 1) {
            int x=q[i].x,y=q[i].y;
            sateCnt++;
            lt[sateCnt] = Frac(x+R,y,0);
            rt[sateCnt] = Frac(y,R-x,0);
            q[i].id = sateCnt;
        }
    }
    REQ(i,sateCnt) {
        mp[lt[i]];
    }
    for(auto &p : mp) {
        p.second = ++cnt;
    }
    REQ(i,sateCnt) {
        li[i] = mp[lt[i]];
    }
    T.init(cnt);
    REQ(i, cnt) Q[i].push({Frac(0, 0, 1), 0});
    REQ(i,n) {
        if (q[i].t==1) {
            add(q[i].id);
        } else if (q[i].t==2) {
            rmv(q[i].id);
        } else {
            int x=q[i].x,y=q[i].y;
            if(lt[y] < lt[x]) swap(x,y);
            bool ok = 0;
            if (rt[x] < lt[y]) {
                puts("NO"); continue;
            }

                int idx = li[y];
                rmv(x); rmv(y);
                ok = T.qyRangeMax(1, idx) < min(rt[x],rt[y]);
                add(x); add(y);

            puts(ok ? "YES" : "NO");
        }
    }
}
int main() {
    int t=1;
//    scanf("%d", &t);
    REQ(i,t) {
        fmain(i);
    }
    return 0;
}

#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <string>
#include <cstring>
#include <cmath>
#include <set>
#include <map>
#include <cstdio>
#include <stdlib.h>
#include <stack>
#include <numeric>
#include <bitset>
#include <cctype>
#include <list>
#include <assert.h>
#include <random>
#include <unordered_map>
#include <ctime>
typedef  long long ll;
using namespace std;
#define INF 2147483647
#define infL (1LL<<60)
#define inf (1<<30)
#define inf9 (1000000000)
#define MOD 1000000007
#define EPS 1e-9
#define Gr 9.8
#define PI acos(-1)
#define REP(i,n) for(int (i)=0;(i)<(int)(n);(i)++)
#define REQ(i,n) for(int (i)=1;(i)<=(int)(n);(i)++)
#define lch (rt<<1)
#define rch (rt<<1|1)
#define readmp(n) for(int i=0,u,v;i<n;i++) {scanf("%d%d",&u,&v); mp[u].push_back(v); mp[v].push_back(u);}
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef long double ld;
typedef unsigned int uint;
#define MAX 500105
bool debug = 0;
int n,m,k;
int dx[4] = {0,1,0,-1}, dy[4] = {1,0,-1,0};
string direc="RDLU";
ll ln, lk, lm;
void etp(bool f = 0) {
    puts(f ?"YES" : "NO");
    exit(0);
}
void addmod(int &x, int y, int mod = MOD) {
    assert(y>=0);
    x+=y; if (x>=mod) x-=mod;
    assert(x>=0 && x<mod);
}
void et() {
    puts("-1"); exit(0);
}
ll fastPow(ll x, ll y, int mod=MOD) {
    ll ans = 1;
    while(y>0) {
        if(y&1) ans = (x * ans)%mod;
        x = x*x%mod;
        y>>=1;
    }
    return ans;
}

struct Frac {
    ll x, y;
    int z;
    Frac() { }
    Frac(ll x, ll y, int z) : x(x), y(y) ,z(z){}
    bool operator<(const Frac& o) const {
        return z || (o.z==0 && (x*o.y < y*o.x));
    }
    friend bool operator == (const Frac &r1,const Frac &r2) {return r1.x*r2.y == r1.y*r2.x;}
};
int R;
Frac lt[MAX],rt[MAX],mp[MAX];
int sateCnt;
struct mb {
    int t,x,y, id;
    void rd() {
        scanf("%d", &t);
        if (t==2) scanf("%d", &id);
        else scanf("%d%d", &x,&y);
    }
}q[MAX];
int li[MAX],cnt;

const int MN=(1<<21)+5;
struct mbt {
    int M; Frac T[MN];
    void init(int sz) {
        for(M=1;sz+2>M;M<<=1);
        REP(i,MN) T[i]={0,0,1};
    }
    void uptSingleMax(int l, Frac val) {
        l+=M; T[l]=val;
        while(l>1) {
            T[l>>1] = max(T[l],T[l^1]); l>>=1;
        }
    }
    Frac qyRangeMax(int l, int r) {
        Frac ans = {0,0,1};
        for(l=l+M-1,r=r+M+1;l^r^1;l>>=1,r>>=1){
            if(~l&1) ans = max(ans, T[l^1]);
            if(r&1) ans = max(ans, T[r^1]);
        }
        return ans;
    }
}T;
bool del[MAX];
priority_queue<pair<Frac,int>> Q[MAX];
void add(int staId) {
    del[staId] = 0;
    int k = li[staId];
    Q[k].push({rt[staId], staId});
    T.uptSingleMax(k, Q[k].top().first);
}
void rmv(int staId) {
    del[staId] = 1;
    int k = li[staId];
    while(del[Q[k].top().second]) {
        Q[k].pop();
    }
    T.uptSingleMax(k, Q[k].top().first);
}
void fmain(int tid) {
    scanf("%d%d", &R, &n);
    REQ(i,n) {
        q[i].rd();
        if (q[i].t == 1) {
            int x=q[i].x,y=q[i].y;
            sateCnt++;
            lt[sateCnt] = Frac(x+R,y,0);
            rt[sateCnt] = Frac(y,R-x,0);
            q[i].id = sateCnt;
        }
    }
    REQ(i,sateCnt) {
        mp[i]=(lt[i]);
    }
    sort(mp+1,mp+1+sateCnt);
    cnt = unique(mp+1,mp+1+sateCnt) - mp-1;

    REQ(i,sateCnt) {
        li[i] = lower_bound(mp+1,mp+cnt+1,lt[i])-mp;
    }
    T.init(cnt);
    REQ(i, cnt) Q[i].push({Frac(0, 0, 1), 0});
    REQ(i,n) {
        if (q[i].t==1) {
            add(q[i].id);
        } else if (q[i].t==2) {
            rmv(q[i].id);
        } else {
            int x=q[i].x,y=q[i].y;
            if(lt[y] < lt[x]) swap(x,y);
            bool ok = 0;
            if (rt[x] < lt[y]) {
                puts("NO"); continue;
            }

                int idx = li[y];
                rmv(x); rmv(y);
                ok = T.qyRangeMax(1, idx) < min(rt[x],rt[y]);
                add(x); add(y);

            puts(ok ? "YES" : "NO");
        }
    }
}
int main() {
    int t=1;
//    scanf("%d", &t);
    REQ(i,t) {
        fmain(i);
    }
    return 0;
}

#include<bits/stdc++.h>
using namespace std;
#define beta Beta
typedef long long ll;
class vec
{
	public:
		int x,y;
		vec()
		{
			x=y=0;
		}
		vec(int tx,int ty)
		{
			x=tx,y=ty;
		}
		vec operator -(const vec &t)const
		{
			return vec(x-t.x,y-t.y);
		}
		vec operator +(const vec &t)const
		{
			return vec(x+t.x,y+t.y);
		}
		ll operator *(const vec &t)const
		{
			return (ll)x*t.y-(ll)y*t.x;
		}
		ll operator ^(const vec &t)const
		{
			return (ll)x*t.x+(ll)y*t.y;
		}
		bool operator <(const vec &t)const
		{
			return (*this)*t>0;
		}
		bool operator ==(const vec &t)const
		{
			return (*this)*t==0;
		}
}v[500010];
vector<vec> lsa,lsb;
int idcnt,Q,opt[500010],x[500010],y[500010],R,alpha[500010],beta[500010];
class delheap
{
	public:
		priority_queue<int> A,B;
		void insert(int v)
		{
			A.push(v);
		}
		void erase(int v)
		{
			B.push(v);
		}
		int top()
		{
			while(!A.empty()&&!B.empty()&&A.top()==B.top())A.pop(),B.pop();
			if(A.empty())return -1e9;
			return A.top();
		}
};
#define lc (p<<1)
#define rc ((p<<1)|1)
class sgt
{
	public:
		delheap q[500010];
		int mx[2000010];
		void build(int p,int l,int r)
		{
			mx[p]=-1e9;
			if(l==r)return;
			int mid=(l+r)>>1;
			build(lc,l,mid);
			build(rc,mid+1,r);
		}
		void modify(int p,int l,int r,int pos,int v,bool opt)
		{
			if(l==r)
			{
				if(opt)q[l].insert(v);
				else q[l].erase(v);
				mx[p]=q[l].top();
				return;
			}
			int mid=(l+r)>>1;
			if(pos<=mid)modify(lc,l,mid,pos,v,opt);
			else modify(rc,mid+1,r,pos,v,opt);
			mx[p]=max(mx[lc],mx[rc]);
		}
		int query(int p,int l,int r,int ql,int qr)
		{
			if(ql<=l&&r<=qr)return mx[p];
			int mid=(l+r)>>1,ret=-1e9;
			if(ql<=mid)ret=query(lc,l,mid,ql,qr);
			if(qr>mid)ret=max(ret,query(rc,mid+1,r,ql,qr));
			return ret;
		}
}T;
int main()
{
	scanf("%d%d",&R,&Q);
	for(int i=1;i<=Q;i++)
	{
		scanf("%d%d",&opt[i],&x[i]);
		if(opt[i]==1)
		{
			scanf("%d",&y[i]);
			v[++idcnt]=vec(x[i],y[i]);
			x[i]=idcnt;
		}
		else if(opt[i]==3)scanf("%d",&y[i]);
	}
	vec lft(-R,0),rgt(R,0);
	for(int i=1;i<=idcnt;i++)
	{
		lsa.push_back(v[i]-lft);
		lsb.push_back(v[i]-rgt);
	}
	sort(lsa.begin(),lsa.end());
	sort(lsb.begin(),lsb.end());
	lsa.erase(unique(lsa.begin(),lsa.end()),lsa.end());
	lsb.erase(unique(lsb.begin(),lsb.end()),lsb.end());
	T.build(1,0,lsb.size()-1);
	for(int i=1;i<=idcnt;i++)
	{
		alpha[i]=lower_bound(lsa.begin(),lsa.end(),v[i]-lft)-lsa.begin();
		beta[i]=lower_bound(lsb.begin(),lsb.end(),v[i]-rgt)-lsb.begin();
	}
	for(int i=1;i<=Q;i++)
	{
		if(opt[i]==1)
		{
			T.modify(1,0,lsb.size()-1,beta[x[i]],alpha[x[i]],1);
		}
		else if(opt[i]==2)
		{
			T.modify(1,0,lsb.size()-1,beta[x[i]],alpha[x[i]],0);
		}
		else
		{
			int ta=min(alpha[x[i]],alpha[y[i]]),tb=max(beta[x[i]],beta[y[i]]);
			if((lsa[ta]^lsb[tb])<0)puts("NO");
			else
			{
				T.modify(1,0,lsb.size()-1,beta[x[i]],alpha[x[i]],0);
				T.modify(1,0,lsb.size()-1,beta[y[i]],alpha[y[i]],0);
				if(T.query(1,0,lsb.size()-1,0,tb)>=ta)puts("NO");
				else puts("YES");
				T.modify(1,0,lsb.size()-1,beta[x[i]],alpha[x[i]],1);
				T.modify(1,0,lsb.size()-1,beta[y[i]],alpha[y[i]],1);
			}
		}
	}
	return 0;
}

#include<bits/stdc++.h>
using namespace std;

typedef long long ll;
const int N=500100;

struct C{
	int x,y;
	C(int x=0,int y=0):x(x),y(y){}
	ll operator * (const C&a)const{return (ll)x*a.x+(ll)y*a.y;}
	ll operator / (const C&a)const{return (ll)x*a.y-(ll)y*a.x;}
	C conj()const{return C(x,-y);}
	bool operator + (const C&a)const{
		ll u=*this*a.conj(),v=*this/a.conj();
		return !u||!v||((u>0)^(v>0));
	}
	bool operator < (const C&a)const{return *this/a<0;}
	bool operator != (const C&a)const{return *this<a||a<*this;}
	bool operator == (const C&a)const{return !(*this!=a);}
};

int mx[N*4],q1,q2,q3;

void mdf(int o,int l,int r){
	if(l==r){mx[o]=q2;return;}
	int mid=(l+r)/2;
	if(q1<=mid)mdf(o*2,l,mid);
	else mdf(o*2+1,mid+1,r);
	mx[o]=max(mx[o*2],mx[o*2+1]);
}

void qry(int o,int l,int r){
	if(q1<=l&&r<=q2){q3=max(q3,mx[o]);return;}
	int mid=(l+r)/2;
	if(q1<=mid)qry(o*2,l,mid);
	if(q2>mid)qry(o*2+1,mid+1,r);
}
int R,q,opt[N],u[N],v[N],w[N],cnt,id[N],fi[N];
pair<C,C>a[N];
C f[N],g[N];
pair<pair<int,int>,int>b[N];
int main(){
	ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
	cin>>R>>q;
	for(int i=1;i<=q;++i){
		cin>>opt[i]>>u[i];
		if(opt[i]!=2)cin>>v[i];
		if(opt[i]==1){w[i]=++cnt;a[cnt]=make_pair(f[cnt]=C(-u[i]-R,v[i]),g[cnt]=C(u[i]-R,v[i]));}
	}
	sort(f+1,f+cnt+1);sort(g+1,g+cnt+1);
	int cntl=unique(f+1,f+cnt+1)-f-1,cntr=unique(g+1,g+cnt+1)-g-1;
	for(int i=1;i<=cnt;++i)
		b[i]=make_pair(make_pair(lower_bound(f+1,f+cntl+1,a[i].first)-f,lower_bound(g+1,g+cntr+1,a[i].second)-g),i);
	sort(b+1,b+cnt+1);
	for(int i=cnt;i;--i)
		id[b[i].second]=i,fi[b[i].first.first]=i;
	for(int i=1;i<=q;++i)
		if(opt[i]==1){
			q1=id[w[i]];q2=b[q1].first.second;mdf(1,1,cnt);
		}else if(opt[i]==2){
			q1=id[u[i]];q2=0;mdf(1,1,cnt);
		}else{
			int x=id[u[i]],y=id[v[i]],l=min(b[x].first.first,b[y].first.first),r=min(b[x].first.second,b[y].first.second);
			if(x>y)swap(x,y);
			if(f[l]+g[r]){
				int ql=fi[l],qr=cnt;q3=0;
				q1=ql;q2=x-1;if(q1<=q2)qry(1,1,cnt);
				q1=x+1;q2=y-1;if(q1<=q2)qry(1,1,cnt);
				q1=y+1;q2=qr;if(q1<=q2)qry(1,1,cnt);
				if(q3<r)cout<<"YES\n";
				else cout<<"NO\n";
			}else cout<<"NO\n";
		}
	return 0;
}

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;

int r, n, num = 0;
struct pnt
{
    long long x, y;
    int id;
} in[500010], a[500010], b[500010];
bool cmp1(pnt x, pnt y)
{
    long long hh = (x.x + r) * y.y - (y.x + r) * x.y;
    return hh == 0 ? (x.x + r) * (x.x + r) + x.y * x.y < (y.x + r) * (y.x + r) + y.y * y.y : hh > 0;
}
bool cmp2(pnt x, pnt y)
{
    long long hh = (x.x - r) * y.y - (y.x - r) * x.y;
    return hh == 0 ? (x.x - r) * (x.x - r) + x.y * x.y < (y.x - r) * (y.x - r) + y.y * y.y : hh < 0;
}
bool cm1(int x, int y)
{
    return cmp1(b[x], b[y]);
}
bool cm2(int x, int y)
{
    return cmp2(b[x], b[y]);
}
bool eq1(pnt x, pnt y)
{
    return (x.x + r) * y.y - (y.x + r) * x.y == 0;
}
bool eq2(pnt x, pnt y)
{
    return (x.x - r) * y.y - (y.x - r) * x.y == 0;
}
int order[500010], rk[500010], l[500010];
struct tree
{
    int l, r, c;
    tree *lc, *rc;
    tree(int l, int r) : l(l), r(r), c(l), lc(NULL), rc(NULL) {}
} *root;

tree *bt(int l, int r)
{
    tree *i = new tree(l, r);
    if (l < r)
    {
        int md = l + r >> 1;
        i->lc = bt(l, md);
        i->rc = bt(md + 1, r);
        i->c = max(i->lc->c, i->rc->c, cm2);
    }
    else i->c = order[l];
    return i;
}
void chg(tree *i, int p)
{
    if (i->l == i->r)
    {
        if (!b[i->c].y) b[i->c] = in[b[i->c].id];
        else b[i->c].x = b[i->c].y = 0;
        return;
    }
    int md = i->l + i->r >> 1;
    if (p <= md) chg(i->lc, p);
    else chg(i->rc, p);
    i->c = max(i->lc->c, i->rc->c, cm2);
}
int get(tree *i, int l, int r)
{
    if (i->l == l && i->r == r) return i->c;
    int md = i->l + i->r >> 1;
    if (r <= md) return get(i->lc, l, r);
    else if (l > md) return get(i->rc, l, r);
    else return max(get(i->lc, l, md), get(i->rc, md + 1, r), cm2);
}
int main()
{
    scanf("%d%d", &r, &n);
    for (int i = 1; i <= n; i++)
    {
        int op;
        scanf("%d", &op);
        if (op == 1)
        {
            scanf("%lld%lld", &a[i].x, &a[i].y);
            a[i].id = ++num;
            b[num] = in[num] = a[i];
        }
        else if (op == 2)
        {
            scanf("%d", &a[i].id);
            a[i].x = a[i].y = -1;
        }
        else
        {
            scanf("%lld%lld", &a[i].x, &a[i].y);
            a[i].id = -1;
        }
    }
    // for (int i = 1; i <= num; i++)
    //     printf("%lld %lld\n", b[i].x, b[i].y);
    for (int i = 1; i <= num; i++) order[i] = i;
    sort(order + 1, order + 1 + num, cm1);
    // for (int i = 1; i <= num; i++) printf("%d ", order[i]);
    // puts("");
    for (int i = 1; i <= num; i++) rk[order[i]] = i;
    l[1] = 1;
    for (int i = 2; i <= num; i++)
    {
        if (eq1(b[order[i - 1]], b[order[i]])) l[i] = l[i - 1];
        else l[i] = i;
    }
    for (int i = 1; i <= num; i++) b[i].x = b[i].y = 0;
    root = bt(1, num);
    for (int i = 1; i <= n; i++)
    {
        if (a[i].id == -1)
        {
            int x = min(a[i].x, a[i].y, cm1), y = min(a[i].x, a[i].y, cm2);
            // printf("%lld %lld %lld %lld\n", b[x].x, b[x].y, b[y].x, b[y].y);
            // printf("%d %d\n", x, y);
            if ((b[x].x + r) * (b[y].x - r) + b[x].y * b[y].y < 0)
            {
                puts("NO");
                continue;
            }
            chg(root, rk[a[i].x]);
            chg(root, rk[a[i].y]);
            int hh = get(root, l[rk[x]], num);
            // printf("%lld %lld\n", b[hh].x, b[hh].y);
            if (!b[hh].y)
            {
                puts("YES");
                chg(root, rk[a[i].x]);
                chg(root, rk[a[i].y]);
                continue;
            }
            chg(root, rk[a[i].x]);
            chg(root, rk[a[i].y]);
            if ((!eq2(b[hh], b[y]) && cm2(hh, y)) || (eq2(b[hh], b[y]) && cm1(hh, x))) puts("YES");
            else puts("NO");
        }
        else
        {
            chg(root, rk[a[i].id]);
        }
    }
}

#pragma comment(linker, "/stack:200000000")
#pragma GCC optimize("Ofast")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")

#include <bits/stdc++.h>

#define F0R(i, a) for (int i = 0; i < (a); i++)
#define FOR(i, a, b) for (int i = (a); i < (b); i++)
#define R0F(i, a) for (int i = (a) - 1; i >= 0; i--)
#define ROF(i, a, b) for (int i = (b) - 1; i >= (a); i--)

#define ran() (rand() & 0x7FFF)
#define rand31() ((ran() << 16) | (ran() << 1) | (ran() & 1))
#define rand32() ((ran() << 17) | (ran() << 2) | (ran() & 3))
#define rand63() (((ll)ran() << 48) | ((ll)ran() << 33) | ((ll)ran() << 18) | ((ll)ran() << 3) | ((ll)ran() & 7))
#define rand64() (((ll)ran() << 49) | ((ll)ran() << 34) | ((ll)ran() << 19) | ((ll)ran() << 4) | ((ll)ran() & 15))

#define F first
#define S second
#define PB push_back
#define MP make_pair
#define MT make_tuple
#define UB upper_bound
#define LB lower_bound
#define X real()
#define Y imag()

#define INF 1e18
#define PI acos(-1)

#define sz(x) ((int)(x).size())
#define all(x) (x).begin(), (x).end()
#define SQ(x) ((x) * (x))

using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef vector<int> vi;
typedef vector<pii> vpii;
typedef vector<ll> vll;
typedef vector<ull> vul;

#define MAXN 500000

struct angle {

ll y, x;

bool operator<(const angle& a2) const {
    return x * a2.y - y * a2.x > 0;
}

bool operator==(const angle& a2) const {
    return x * a2.y == y * a2.x;
}

bool operator<=(const angle& a2) const { return *this < a2 || *this == a2; }

bool operator>=(const angle& a2) const { return !(*this < a2); }

angle operator+(const angle& a2) const {
    return {y * a2.x + a2.y * x, x * a2.x - y * a2.y};
}

};

struct SegTree{

int sz;
angle *tree;

SegTree(int _sz) {
    sz = 1 << (32 - __builtin_clz(_sz - 1));
    tree = new angle[2 * sz];
    F0R(i, 2 * sz) tree[i] = angle({0, 1});
}

void upd(int idx, angle v) {
    idx += sz;
    tree[idx] = v;
    for (idx /= 2; idx > 0; idx /= 2) tree[idx] = max(tree[2 * idx], tree[2 * idx + 1]);
}

angle query(int lo, int hi) {
    lo += sz, hi += sz;
    angle res = angle({0, 1});
    while(lo <= hi) {
        if ((lo % 2) == 1) res = max(res, tree[lo++]);
        if ((hi % 2) == 0) res = max(res, tree[hi--]);
        lo /= 2;
        hi /= 2;
    }
    return res;
}

};

ll r;
angle alpha[MAXN], beta123[MAXN];
int n, q, posof[MAXN];
vector<pair<angle, int>> order;
vpii updates;
vector<pair<int, pii>> queries;

SegTree st(2);

void toggle(int idx) {
    int pos = posof[idx];
    if (st.query(pos, pos) == angle({0, 1})) st.upd(pos, beta123[idx]);
    else st.upd(pos, {0, 1});
}

int main() {
    ios::sync_with_stdio(0);
    cin.tie(0);
    cin >> r >> q;
    F0R(i, q) {
        int t;
        cin >> t;
        switch(t) {
            case 1:
                ll x, y;
                cin >> x >> y;
                alpha[n] = {y, r - x};
                beta123[n] = {y, x + r};
                updates.PB(MP(i, n++));
                break;
            case 2:
                int idx;
                cin >> idx;
                idx--;
                updates.PB(MP(i, idx));
                break;
            case 3:
                int a, b;
                cin >> a >> b;
                a--, b--;
                queries.PB(MP(i, MP(a, b)));
                break;
        }
    }
    F0R(i, n) order.PB(MP(alpha[i], i));
    sort(all(order));
    F0R(i, n) posof[order[i].S] = i;
    reverse(all(updates));
    reverse(all(queries));
    st = SegTree(n);
    while (!updates.empty() || !queries.empty()) {
        if (queries.empty() || (!updates.empty() && updates.back().F < queries.back().F)) {
            int idx = updates.back().S;
            updates.pop_back();
            toggle(idx);
        } else {
            int a = queries.back().S.F;
            int b = queries.back().S.S;
            queries.pop_back();
            angle _alpha = min(alpha[a], alpha[b]);
            angle _beta123 = min(beta123[a], beta123[b]);
            if(_alpha + _beta123 < angle({1, 0})) {
                cout << "NO\n";
            } else {
                toggle(a);
                toggle(b);

                int lo = LB(all(order), MP(_alpha, 0)) - order.begin();
                assert(lo == 0 || order[lo - 1].F < _alpha);
                if (st.query(lo, n - 1) >= _beta123) cout << "NO\n";
                else cout << "YES\n";

                toggle(a);
                toggle(b);
            }
        }
    }
}

#include <bits/stdc++.h>

const int MAXN = 1000010;
typedef long long LL;
typedef long double db;
typedef LL VT;
struct vec {
	VT x, y;
	vec() { x = y = 0; }
	vec(VT a, VT b) { x = a, y = b; }
	VT operator ^ (vec b) const { return x * b.y - y * b.x; }
	VT operator * (vec b) const { return x * b.x + y * b.y; }
	VT norm2() const { return x * x + y * y; }
	db norm() const { return sqrt(x * x + y * y); }
	vec operator - (vec b) const { return vec(x - b.x, y - b.y); }
	vec operator + (vec b) const { return vec(x + b.x, y + b.y); }
	vec operator * (db k) const { return vec(x * k, y * k); }
	friend bool operator < (const vec & a, const vec & b) {
		return (a ^ b) > 0;
	}
	friend std::istream & operator >> (std::istream & in, vec & x) {
		in >> x.x >> x.y;
		return in;
	}
	friend std::ostream & operator << (std::ostream & out, vec x) {
		out << '(' << x.x << ',' << x.y << ')';
		return out;
	}
} ;
typedef std::pair<vec, int> pi;
int bel[MAXN], lll[MAXN], rrr[MAXN];
int discr(std::vector<pi> v, int * tar) {
	const int L = v.size();
	std::sort(v.begin(), v.end());
	int rnk = 0;
	for (int i = 0; i != L; ++i) {
		if (i != 0 && !(v[i].first < v[i - 1].first || v[i - 1].first < v[i].first)) ;
		else ++rnk;
		bel[tar[v[i].second] = i + 1] = rnk;
		if (!lll[rnk]) lll[rnk] = i + 1;
		rrr[rnk] = i + 1;
	}
	return L;
}
vec ps[MAXN];
int opt[MAXN], xs[MAXN], ys[MAXN];
const int NINF = 0xcfcfcfcf;
int tree[MAXN << 2];
void add(int u, int l, int r, int tar, int v) {
	if (l == r) return (void) (tree[u] = v);
	int mid = l + r >> 1;
	if (tar <= mid) add(u << 1, l, mid, tar, v);
	else add(u << 1 | 1, mid + 1, r, tar, v);
	tree[u] = std::max(tree[u << 1], tree[u << 1 | 1]);
}
int qry(int u, int l, int r, int L, int R) {
	if (L <= l && r <= R) return tree[u];
	int mid = l + r >> 1, res = NINF;
	if (L <= mid) res = qry(u << 1, l, mid, L, R);
	if (mid < R) res = std::max(res, qry(u << 1 | 1, mid + 1, r, L, R));
	return res;
}
int n;
inline int tr(int x, int y) { return x == 1 ? y : NINF; }
int nl;
void add(int i, int v) {
	add(1, 1, nl, ys[i], tr(v, xs[i]));
}
LL R;
bool incir(vec x, vec y) {
	return (x * y) < 0 || (x ^ y) <= 0;
}
int trans[MAXN];
int main() {
	memset(tree, 0xcf, sizeof tree);
	std::ios_base::sync_with_stdio(false), std::cin.tie(0);
	std::cin >> R >> n;
	vec pol(-R, 0), por(R, 0);
	std::vector<pi> ll;
	for (int i = 1, bak = 0; i <= n; ++i) {
		std::cin >> opt[i] >> xs[i];
		if (opt[i] != 2) std::cin >> ys[i];
		if (opt[i] == 1) {
			ps[i] = vec(xs[i], ys[i]);
			ll.emplace_back(ps[i] - pol , i);
			ll.emplace_back(ps[i] - por, i + n);
			trans[++bak] = i;
		} else xs[i] = trans[xs[i]], ys[i] = trans[ys[i]];
	}
	static int ls[MAXN << 1], app[MAXN];
	nl = discr(ll, ls);
	for (int i = 1; i <= n; ++i) if (opt[i] == 1)
		xs[i] = ls[i], ys[i] = ls[i + n];
//	for (int i = 1; i <= n; ++i)
//		std::cout << xs[i] << ' ' << ys[i] << std::endl;
	for (int T = 1; T <= n; ++T) {
		if (opt[T] == 1) add(T, 1), app[T] = true;
		else if (opt[T] == 2) add(xs[T], -1), app[xs[T]] = false;
		else {
			bool can = true;
			int A = xs[T], B = ys[T];
			if (!incir( std::min(ps[A] - pol, ps[B] - pol),
						std::max(ps[A] - por, ps[B] - por) )) {
				int l = lll[bel[std::min(xs[A], xs[B])]];
				int r = rrr[bel[std::max(ys[A], ys[B])]];
				if (app[A]) add(A, -1);
				if (app[B]) add(B, -1);
				can = qry(1, 1, nl, 1, r) >= l;
				if (app[A]) add(A, 1);
				if (app[B]) add(B, 1);
			}
			std::cout << (can ? "NO" : "YES") << '\n';
		}
	}

	return 0;
}

#include <bits/stdc++.h>
//#include <ext/pb_ds/tree_policy.hpp>
//#include <ext/pb_ds/assoc_container.hpp>
using namespace std;
//using namespace __gnu_pbds;
//template<typename key, typename val>
//using ordered_tree =
//  tree<key, val, greater<>, rb_tree_tag, tree_order_statistics_node_update>;
typedef long long int64;
typedef complex<double> comp;
const double pi = 3.14159265358979323846;
const int inf = (int)1e+9 + 2;
const int64 inf64 = (int64)1e+18 + 2;
const double dinf = 1e+20;
const int mod = /*1'000'000'007;*/998244353;
const int base = 2187;
const double eps = 1e-8;
const int N = 500'000;
const int LOGN = 19;

int n, m, k, R;
vector<pair<int, int>> a;
int t[4 * N];

int64 vec(int64 x1, int64 y1, int64 x2, int64 y2)
{
  return x1 * y2 - x2 * y1;
}

struct cmp
{
  cmp(int d) : d(d) {}

  bool operator()(int i, int j)
  {
    return vec(a[i].first - d, a[i].second, a[j].first - d, a[j].second) < 0;
  }

  int d;
};

void add(int v, int l, int r, int p, int val)
{
  if (r - l == 1) {
    t[v] = val;
    return;
  }
  int mid = (l + r) / 2;
  if (p < mid)
    add(v * 2 + 1, l, mid, p, val);
  else
    add(v * 2 + 2, mid, r, p, val);
  t[v] = max(t[v * 2 + 1], t[v * 2 + 2]);
}

int get(int v, int l, int r, int ql, int qr)
{
  if (l == ql && r == qr) {
    return t[v];
  }
  int mid = (l + r) / 2;
  if (qr <= mid)
    return get(v * 2 + 1, l, mid, ql, qr);
  if (ql >= mid)
    return get(v * 2 + 2, mid, r, ql, qr);
  return max(get(v * 2 + 1, l, mid, ql, mid),
             get(v * 2 + 2, mid, r, mid, qr));
}

int64 scalar(int64 x1, int64 y1, int64 x2, int64 y2, int64 x3, int64 y3, int64 x4, int64 y4)
{
  return (x2 - x1) * (x4 - x3) + (y2 - y1) * (y4 - y3);
}

void solve(int test)
{
  cin >> R >> n;
  vector<pair<int, int>> q;
  vector<int> ao, bo;
  ao.reserve(n / 2);
  bo.reserve(n / 2);
  int id = 0;
  for (int i = 0; i < n; ++i) {
    int type, x, y;
    cin >> type;
    if (type == 1) {
      cin >> x >> y;
      ao.push_back(id);
      bo.push_back(id);
      a.emplace_back(x, y);
      q.emplace_back(id++, -1);
    }
    else if (type == 2) {
      cin >> x;
      q.emplace_back(x - 1, -2);
    }
    else {
      cin >> x >> y;
      q.emplace_back(x - 1, y - 1);
    }
  }
  sort(ao.begin(), ao.end(), cmp(-R));
  sort(bo.begin(), bo.end(), cmp(R));
  n = (int)ao.size();
  vector<int> ra(n), rb(n);
  for (int i = 0; i < n; ++i) {
    ra[ao[i]] = i;
    rb[bo[i]] = lower_bound(begin(bo), end(bo), bo[i], cmp(R)) - begin(bo);
  }
  memset(t, -1, sizeof(t));
  for (auto& pr : q) {
    if (pr.second == -1) {
      add(0, 0, n, ra[pr.first], rb[pr.first]);
    }
    else if (pr.second == -2) {
      add(0, 0, n, ra[pr.first], -1);
    }
    else {
      auto&[x, y] = pr;
      if (ra[x] > ra[y])
        swap(x, y);
      add(0, 0, n, ra[x], -1);
      add(0, 0, n, ra[y], -1);
      size_t off = upper_bound(begin(ao) + ra[y], end(ao), ao[ra[y]], cmp(-R)) - begin(ao);
      int b_max = get(0, 0, n, 0, off);
      int xb = rb[x] < rb[y] ? x : y;
      add(0, 0, n, ra[x], rb[x]);
      add(0, 0, n, ra[y], rb[y]);
      if (b_max < rb[xb] && scalar(-R, 0, a[y].first, a[y].second,
                                   R, 0, a[xb].first, a[xb].second) >= 0)
        cout << "YES\n";
      else
        cout << "NO\n";
    }
  }
}

void precalc()
{
}

int main()
{
  ios::sync_with_stdio(0);
  cin.tie(0), cout.tie(0);
  precalc();
  int test = 1;
  //cin >> test;
  //auto start = chrono::high_resolution_clock::now();
  for (int i = 1; i <= test; ++i)
    solve(i);
  //cerr << chrono::duration_cast<chrono::milliseconds>(chrono::high_resolution_clock::now() - start).count() << '\n';
  return 0;
}

#include<iostream>
#include<cstdlib>
#include<stdio.h>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<vector>
#include<set>
#include<map>
using namespace std;
long long r;
const int inf=1e9+9;
int n,cnt,list[501000],cnt_list,mf[1010000];
struct segment_tree
{
	int l,r,max_vl;
};
segment_tree tree[1<<21];
map<int,int>hs[1<<21];
map<int,int>::iterator it;
struct point
{
	long long x,y;
	int z;
	bool operator <(const point &temp)const
	{
		  return y*temp.x<x*temp.y;
	}
};
point pt[1000001];
struct query
{
	int u,v,flag,id;
	long long x,y;
	point l,r;
};
query qy[501000];
void build(int left,int right,int id)
{
	int l=2*id+1,r=2*id+2,mid=(left+right)>>1;
	tree[id].max_vl=-inf;
	tree[id].l=left;
	tree[id].r=right;
	if(left==right)
	    return;
    build(left,mid,l);
    build(mid+1,right,r);
}
void update(int pos,int vl,int flag,int id)
{
	int l=2*id+1,r=2*id+2;
	 if(tree[id].l==tree[id].r)
     {
     	if(flag<0)
     	{
	     	hs[id][vl]--;
	        if(hs[id][vl]==0)
	           hs[id].erase(vl);
            if(hs[id].size()>0)
            {
			    it=hs[id].end();
			    it--;
                tree[id].max_vl=it->first;
			}
			else
			    tree[id].max_vl=-inf;
		}
  	    else
  	    {
    	  	hs[id][vl]++;
    	  	tree[id].max_vl=max(tree[id].max_vl,vl);
      }
 	     return;
  	 }
  	 if(tree[l].r<pos)
	     update(pos,vl,flag,r);
	 else
	     update(pos,vl,flag,l);
	 tree[id].max_vl=max(tree[l].max_vl,tree[r].max_vl);
}
int qw(int left,int right,int id)
{
	int l=2*id+1,r=2*id+2;
	if(tree[id].l>right||tree[id].r<left)
	    return -inf;
    if(tree[id].l>=left&&tree[id].r<=right)
    	return tree[id].max_vl;
	return max(qw(left,right,l),qw(left,right,r));
}
int binary(int left,int right,point now)
{
	int mid;
	while(left<=right)
	{
		mid=(left+right)>>1;
		if(pt[mid]<now)
			left=mid+1;
		else if(now<pt[mid])
		    right=mid-1;
        else
            return mid;
	}
}
int main()
{
	scanf("%lld%d",&r,&n);
	int i,j,s,p,q,l_id,r_id;
	cnt=0;
	cnt_list=0;
	for(i=0;i<n;i++)
	{
		scanf("%d",&qy[i].flag);
		if(qy[i].flag==1)
		{
			list[cnt_list++]=i;
            scanf("%lld%lld",&qy[i].x,&qy[i].y);
		   	pt[cnt].x=qy[i].y;
            pt[cnt++].y=r-qy[i].x;
			qy[i].l=pt[cnt-1];
		   	pt[cnt].x=qy[i].x+r;
            pt[cnt++].y=qy[i].y;
			qy[i].id=cnt_list-1;
		    qy[i].r=pt[cnt-1];
		    if(qy[i].r<qy[i].l)
		        swap(qy[i].l,qy[i].r);
		}
		else if(qy[i].flag==2)
        {
           scanf("%d",&qy[i].u);
           qy[i].u--;
        }
        else
        {
        	scanf("%d%d",&qy[i].u,&qy[i].v);
        	qy[i].u--;
        	qy[i].v--;
        }
	}
	sort(pt,pt+cnt);
	int nn=0;
	for(i=0;i<cnt;i++)
	{
		if(nn==0||(pt[i].x!=pt[nn-1].x||pt[i].y!=pt[nn-1].y))
		    pt[nn++]=pt[i];
	}
	cnt=nn;
	build(0,cnt-1,0);
	point ll,rr;
	for(i=0;i<n;i++)
	{
		int flag;
		if(qy[i].flag==1)
		{
		   flag=1;
		   ll=qy[i].l;
		   rr=qy[i].r;
		}
		else if(qy[i].flag==2)
		{
			flag=-1;
			ll=qy[list[qy[i].u]].l;
			rr=qy[list[qy[i].u]].r;
		}
		if(qy[i].flag==1||qy[i].flag==2)
		{
    		l_id=binary(0,cnt-1,ll);
    	     r_id=binary(0,cnt-1,rr);
    		update(l_id,r_id,flag,0);
		}
		else
		{
			int id1,id2;
			id1=qy[i].u;
			id2=qy[i].v;
            int l1,r1,l2,r2;
			l1=binary(0,cnt-1,qy[list[id1]].l);
			r1=binary(0,cnt-1,qy[list[id1]].r);
			l2=binary(0,cnt-1,qy[list[id2]].l);
			r2=binary(0,cnt-1,qy[list[id2]].r);
			bool ans;
            l_id=max(l1,l2);
            r_id=min(r1,r2);
            if(l_id>r_id)
                ans=0;
            else
            {
            	update(l1,r1,-1,0);
            	update(l2,r2,-1,0);
            	if(qw(0,l_id,0)<r_id)
            	   ans=1;
         	    else
         	       ans=0;
      	        update(l1,r1,1,0);
      	        update(l2,r2,1,0);
            }
            if(ans)
               puts("YES");
            else
               puts("NO");
		}
	}
	return 0;
}
/*

100000000 5
1 -106382777 300000523
1 -75340202 300000165
1 -148918484 300000552
1 96360393 300000458
3 3 2
*/

#include<bits/stdc++.h>
//#pragma GCC optimize ("O3")
//#pragma GCC target ("sse4")
using namespace std;
typedef long long LL;
#define FI(x) read(x)

const int SIZE = 1<<12;
char buf[SIZE], str[60];

int bi = SIZE, bn = SIZE;
int read(char *s) {
	while (bn) {
		for (; bi < bn && buf[bi] <= ' '; bi++);
		if (bi < bn) break;
		bn = fread(buf, 1, SIZE, stdin);
		bi = 0;
	}
	int sn = 0;
	while (bn) {
		for (; bi < bn && buf[bi] > ' '; bi++) s[sn++] = buf[bi];
		if (bi < bn) break;
		bn = fread(buf, 1, SIZE, stdin);
		bi = 0;
	}
	s[sn] = 0;
	return sn;
}

bool read(int& x) {
	int n = read(str), bf = 0;
	if (!n) return 0;
	int i = 0; if (str[i] == '-') bf = 1, i++; else if (str[i] == '+') i++;
	for (x = 0; i < n; i++) x = x * 10 + str[i] - '0';
	if (bf) x = -x;
	return 1;
}

struct FR {
	int a, b;

	FR() {}
	FR(int x, int y) {
		int g = __gcd(x, y);
		x /= g, y /= g;
		if (y < 0) x = -x, y = -y;
		a = x, b = y;
	}
};

bool operator<(const FR& f1, const FR& f2) {
	return 1LL * f1.a * f2.b < 1LL * f2.a * f1.b;
}

bool operator==(const FR& f1, const FR& f2) {
	return f1.a == f2.a && f1.b == f2.b;
}

const int N = 500000+10;
int r, x[N], y[N];
FR ha[N], hb[N], ang1[N], ang2[N];
int t[N], a[N], b[N], ida[N], idb[N];

vector<int> VEC[N], vec[N];

void Add(int x, int y) {
	for (++x; x < N; x += x & -x) VEC[x].push_back(y);
}

void add(int x, int y, int val) {
	for (++x; x < N; x += x & -x) {
		int p = lower_bound(VEC[x].begin(), VEC[x].end(), y) - VEC[x].begin() + 1;
		for (; p < vec[x].size(); p += p & -p) {
			vec[x][p] += val;
		}
	}
}

int get(int x, int y) {
	int ret = 0;
	for (++x; x; x -= x & -x) {
		int p = upper_bound(VEC[x].begin(), VEC[x].end(), y) - VEC[x].begin();
		for (; p; p -= p & -p) {
			ret += vec[x][p];
		}
	}
	return ret;
}

int main() {
	int n; FI(r), FI(n);
	int now = 1;
	for (int i = 0; i < n; i ++) {
		FI(t[i]);
		if (t[i] == 1) {
			FI(x[now]), FI(y[now]);
			++now;
		}
		if (t[i] == 2) {
			FI(a[i]);
		}
		if (t[i] == 3) {
			FI(a[i]), FI(b[i]);
		}
	}
	int han = 0, hbn = 0;
	for (int i = 1; i < now; i ++) {
		ang1[i] = FR(x[i] + r, y[i]);
		ang2[i] = FR(x[i] - r, y[i]);
		ha[han++] = ang1[i];
		hb[hbn++] = ang2[i];
	}

	sort(ha, ha + han);
	han = unique(ha, ha + han) - ha;

	sort(hb, hb + hbn);
	hbn = unique(hb, hb + hbn) - hb;

	for (int i = 1; i < now; i ++) {
		ida[i] = han - 1 - (lower_bound(ha, ha + han, ang1[i]) - ha);
		idb[i] = hbn - 1 - (lower_bound(hb, hb + hbn, ang2[i]) - hb);
	}

	for (int i = 1; i < now; i ++) Add(ida[i], idb[i]);
	for (int i = 0; i < N; i ++) {
		sort(VEC[i].begin(), VEC[i].end());
		vec[i].resize(VEC[i].size() + 1);
	}

	now = 1;
	for (int i = 0; i < n; i ++) {
		if (t[i] == 1) {
			add(ida[now], idb[now], 1);
			++now;
		}
		if (t[i] == 2) {
			add(ida[a[i]], idb[a[i]], -1);
		}
		if (t[i] == 3) {
			int xmin, ymin, xmax, ymax;
			xmin = ida[a[i]], xmax = ida[b[i]];
			ymin = idb[a[i]], ymax = idb[b[i]];

			if (xmin > xmax) swap(xmin, xmax);
			if (ymin > ymax) swap(ymin, ymax);

			int xid = han - 1 - xmin, yid = hbn - 1 - ymax;

			if (FR(0, 1) < ha[xid] && hb[yid] < FR(0, 1)) {
				FR tem1 = ha[xid], tem2 = FR(hb[yid].b, -hb[yid].a);
				if (tem2 < tem1) {
					puts("NO");
					continue;
				}
			}

			int ret = get(N - 2, ymax) - get(xmin - 1, ymax);
			if (ret > 2) puts("NO");
			else puts("YES");
		}
	}
	return 0;
}

#define ONLINE_JUDGE
#include <bits/stdc++.h>

#define inf 0x3f3f3f3f

#define MOD 1000000007

#define pb push_back

#define sq(x) ((x)*(x))

#define x first

#define y second

#define eps 1e-8

#define bpt(x) (__builtin_popcount(x))

#define bptl(x) (__builtin_popcountll(x))

#define bit(x, y) (((x)>>(y))&1)

#define bclz(x) (__builtin_clz(x))

#define bclzl(x) (__builtin_clzll(x))

#define bctz(x) (__builtin_ctz(x))

#define bctzl(x) (__builtin_ctzll(x))

#define PQ priority_queue<pii, vector<pii>, greater<pii> >

using namespace std;

typedef long long INT;

typedef vector<int> VI;

typedef pair<int, int> pii;

typedef pair<pii, int> pi3;

typedef double DO;

template<typename T, typename U> inline void smin(T &a, U b) {if (a>b) a=b;}

template<typename T, typename U> inline void smax(T &a, U b) {if (a<b) a=b;}

template<class T>inline void gn(T &x) {char c, sg=0; while (c=getchar(), (c>'9' || c<'0') && c!='-');for((c=='-'?sg=1, c=getchar():0), x=0; c>='0' && c<='9'; c=getchar()) x=(x<<1)+(x<<3)+c-'0';if (sg) x=-x;}

template<class T, class T1>inline void gn(T &x, T1 &y) {gn(x); gn(y);}

template<class T, class T1, class T2>inline void gn(T &x, T1 &y, T2 &z) {gn(x); gn(y); gn(z);}

template<class T>inline void print(T x) {if (x<0) {putchar('-');return print(-x);}if (x<10) {putchar('0'+x);return;} print(x/10);putchar(x%10+'0');}

int power(int a, int b, int m, int ans=1) {

	for (; b; b>>=1, a=1LL*a*a%m) if (b&1) ans=1LL*ans*a%m;

	return ans;

}

#ifndef ONLINE_JUDGE

void debug() {cout << endl;}

template<typename T, typename... Args>void debug(T&& head, Args&&... tail) {cout << head << ' ';debug(tail...);}

#endif

#define NN 500010

struct Node {

	int ax, ay, bx, by;

	int st, en;

	int flag;

};

Node mem[4*NN];

int x[NN], y[NN];

int I[NN];

INT ans;

void select(int k, int st, int en, int *val) {

	int le, ri, ll, ho, a, i, j;

	le=st; ri=en-1;

	while (1) {

		if (ri<=le+1) {

			if (ri==le+1 && val[I[le]]>val[I[ri]]) swap(I[le], I[ri]);

			return;

		}

		ll=le+1;

		ho=le+rand()%(ri-le+1);

		swap(I[ho], I[ll]);

		if (val[I[ri]]<val[I[le]]) swap(I[ri], I[le]);

		if (val[I[ll]]>val[I[ri]]) swap(I[ri], I[ll]);

		if (val[I[le]]>val[I[ll]]) swap(I[le], I[ll]);

		a=val[I[ll]];

		i=ll; j=ri;

		while (1) {

			do i++; while (val[I[i]]<a);

			do j--; while (val[I[j]]>a);

			if (i>j) break;

			swap(I[i], I[j]);

		}

		swap(I[ll], I[j]);

		if (k<=j) ri=j;

		else if (k>=i) le=i;

		else break;

	}

}

#define MIN(x, y)((x)<(y)?(x):(y))

#define MAX(x, y)((x)>(y)?(x):(y))

void make_tree(int u, int st, int en, int dp) {

	int mid, le, ri;

	mem[u].st=st; mem[u].en=en;

	mem[u].flag=0;

	if (en==st+1) {

		mem[u].ax=mem[u].bx=x[I[st]];

		mem[u].ay=mem[u].by=y[I[st]];

		return;

	}

	mid=(st+en)/2; le=2*u; ri=2*u+1;

	if (dp&1) select(mid, st, en, x);

	else select(mid, st, en, y);

	make_tree(le, st, mid, 1-dp);

	make_tree(ri, mid, en, 1-dp);

	mem[u].ax=MIN(mem[le].ax, mem[ri].ax);

	mem[u].ay=MIN(mem[le].ay, mem[ri].ay);

	mem[u].bx=MAX(mem[le].bx, mem[ri].bx);

	mem[u].by=MAX(mem[le].by, mem[ri].by);

	return;

}

#define ls (u<<1)

#define rs (ls|1)

int find(int u, int idx) {

	if (x[idx]<mem[u].ax) return 0;

	if (x[idx]>mem[u].bx) return 0;

	if (y[idx]<mem[u].ay) return 0;

	if (y[idx]>mem[u].by) return 0;

	if (mem[u].en==mem[u].st+1) {

		mem[u].flag^=1;

		return 1;

	}

	find(ls, idx);

	find(rs, idx);

	mem[u].flag=mem[ls].flag|mem[rs].flag;

}

int calc(int u, int tx, int ty) {

	if (mem[u].bx<tx) return 0;

	if (mem[u].ay>ty) return 0;

	if (!mem[u].flag) return 0;

	if (mem[u].st+1==mem[u].en) return 1;

	if (calc(ls, tx, ty)) return 1;

	return calc(rs, tx, ty);

}

int t[NN], II[NN];

pii X[NN], XX[NN], Y[NN], YY[NN];

const long double pi2=acosl(-1.0)/2;

void print_tree(int u=1) {

	if (mem[u].st+1==mem[u].en) {

		printf("%d %d %d\n", mem[u].bx, mem[u].by, mem[u].flag);

		return ;

	}

	print_tree(ls);

	print_tree(rs);

}

INT operator * (pii a, pii b) {

	return (INT)a.x*b.x+(INT)a.y*b.y;

}

int can(int uu, int vv) {

	int u=II[uu], v=II[vv];

	if (x[u]>x[v]) swap(u, v);

	if (x[u]==x[v] && y[u]>y[v]) swap(u, v);

	int tx=min(x[u], x[v]);

	int ty=max(y[u], y[v]);

	find(1, u); find(1, v);

	int ok=(X[tx]*Y[ty]<0) || calc(1, tx, ty);

	find(1, u); find(1, v);

	return !ok;

}

int cmp(pii a, pii b) {

	return (INT)a.x*b.y>(INT)a.y*b.x;

}

int cmp1(pii a, pii b) {

	return (INT)a.x*b.y==(INT)a.y*b.x;

}

int main() {

#ifndef ONLINE_JUDGE

	freopen("in.in", "r", stdin);

	freopen("out.out", "w", stdout);

#endif

	int r, n, u, v;

	gn(r); gn(n);

	int nn=0, nx=0, ny=0;

	VI a, b;

	for (int i=0; i<n; i++) {

		gn(t[i]);

		if (t[i]==1) {

			gn(u, v);

			X[nx++]=XX[nn]=pii(u+r, v);

			Y[ny++]=YY[nn]=pii(u-r, v);

			nn++;

		}

		if (t[i]==2) {

			gn(u);

			a.pb(u);

		}

		if (t[i]==3) {

			gn(u, v);

			b.pb(u); b.pb(v);

		}

	}

	sort(X, X+nx, cmp); nx=unique(X, X+nx, cmp1)-X;

	sort(Y, Y+ny, cmp); ny=unique(Y, Y+ny, cmp1)-Y;

	map<pii, int> mp;

	int E=0;

	for (int i=0; i<nn; i++) {

		pii aa=pii(lower_bound(X, X+nx, XX[i], cmp)-X, lower_bound(Y, Y+ny, YY[i], cmp)-Y);

		if (mp.count(aa)) II[i]=mp[aa];

		else {

			x[E]=aa.x;

			y[E]=aa.y;

			I[E]=E;

			II[i]=mp[aa]=E;

			E++;

		}

	}

	make_tree(1, 0, E, 0);

	int id=0, id1=0, id2=0;

	for (int i=0; i<n; i++) {

		if (t[i]==1) find(1, II[id]), id++;

		if (t[i]==2) find(1, II[a[id1]-1]), id1++;

		if (t[i]==3) {

			u=b[id2++]-1, v=b[id2++]-1;

			puts(can(u, v)?"YES":"NO");

		}

	}

	return 0;

}

/*
 * test.cpp
 *
 *
 *      Author: Fireworks
 */

#include<iostream>
#include<cstdio>
#include<vector>
#include<algorithm>
#include<queue>
#include<string>
#include<map>
#include<cmath>
#include<bitset>
#include<set>
#include<iomanip>
#include<fstream>
#include<bitset>
#include<cstring>
#include<cstdlib>
#include<complex>
#include<list>
#include<sstream>

using namespace std;

typedef pair<int,int> ii;
typedef pair<int,long long> il;
typedef pair<long long,long long> ll;
typedef pair<ll,int> lli;
typedef pair<long long,int> li;
typedef pair<double,double> dd;
typedef pair<ii,int> iii;
typedef pair<double,int> di;
long long mod = 1000000007LL;
long long base = 10000007;
long long large = 1000000000000000000LL;

struct Vector{
	long long x,y;
	Vector(long long x=0,long long y=0):x(x),y(y) {};
	void init(long long _x,long long _y){
		x=_x;
		y=_y;
	}
	void print(){
		cout<<x<<" "<<y<<endl;
	}
};
Vector operator + (Vector A,Vector B){
	return Vector(A.x+B.x,A.y+B.y);
}
Vector operator - (Vector A,Vector B){
	return Vector(A.x-B.x,A.y-B.y);
}
long long cross(Vector &a,Vector &b){
	return a.x*b.y-a.y*b.x;
}

long long dot(Vector &a,Vector &b){
	return a.x*b.x+a.y*b.y;
}

bool operator < (Vector a, Vector b){
	return cross(a,b)>0LL;
}

typedef pair<int,ii> iii2;

typedef pair<Vector,int> Vi;

vector<Vector> mini;
int up;
Vector val;
void update(int o,int l,int r){
	if(l==r){
		mini[o] = val;
	}else{
		int m = (l+r)/2;
		if(up<=m) update(o*2,l,m);
		if(up>m) update(o*2+1,m+1,r);
		mini[o] = min(mini[o*2],mini[o*2+1]);
	}
}

int ql,qr;
Vector re;
void query(int o,int l,int r){
	if(ql<=l&&qr>=r){
		re = min(re,mini[o]);
	}else{
		int m = (l+r)/2;
		if(ql<=m) query(o*2,l,m);
		if(qr>m) query(o*2+1,m+1,r);
	}
}

int main(){

	int n;
	long long r;
	cin>>r>>n;
	Vector left = Vector(-r,0);
	Vector right = Vector(r,0);
	vector<Vector> lp(n,Vector());
	vector<Vector> rp = lp;
	int sz = 0;
	vector<iii2> q;
	for(int i=0;i<n;i++){
		int t;
		scanf("%d",&t);
		if(t==1){
			long long x,y;
			scanf("%I64d%I64d",&x,&y);
			Vector p(x,y);
			lp[sz] = p - left;
			rp[sz] = p - right;
			q.push_back(iii2(t,ii(sz,-1)));
			sz++;
		}
		if(t==2){
			int x;
			scanf("%d",&x);
			x--;
			q.push_back(iii2(t,ii(x,-1)));
		}
		if(t==3){
			int x,y;
			scanf("%d%d",&x,&y);
			x--;y--;
			q.push_back(iii2(t,ii(x,y)));
		}
	}
	n = sz;
	vector<Vi> e;
	for(int i=0;i<n;i++){
		e.push_back(Vi(lp[i],i));
	}
	sort(e.begin(),e.end());
	vector<Vector> b;
	for(int i=0;i<n;i++){
		b.push_back(e[i].first);
	}
	vector<int> pos(n,-1);
	for(int i=0;i<n;i++){
		pos[e[i].second] = i;
	}

	mini.assign(4*n+10,left);

	for(int i=0;i<(int)q.size();i++){
		//cout<<i<<"-----------"<<endl;
		int t= q[i].first;
		if(t==1){
			int x = q[i].second.first;
			val = rp[x];
			up = pos[x];
			update(1,0,n-1);
		}
		if(t==2){
			int x = q[i].second.first;
			val = left;
			up = pos[x];
			update(1,0,n-1);
		}
		if(t==3){
			int x = q[i].second.first;
			int y = q[i].second.second;
			Vector lp0 = min(lp[x],lp[y]);
			Vector rp0 = max(rp[x],rp[y]);

			if(dot(lp0,rp0)<0){
				printf("NO\n");
				continue;
			}
			int low = 0;
			int high = n-1;
			int mid ;
			int ans;
			while(low<=high){
				mid = (low+high)/2;
				if(b[mid]<lp0){
					low = mid+1;
				}else{
					ans=mid;
					high = mid-1;
				}
			}

			val = left;
			up = pos[x];
			update(1,0,n-1);

			val = left;
			up = pos[y];
			update(1,0,n-1);

			re = left;
			ql = ans;
			qr = n-1;
			query(1,0,n-1);
			if(rp0<re){
				printf("YES\n");
			}else{
				printf("NO\n");
			}

			val = rp[x];
			up = pos[x];
			update(1,0,n-1);

			val = rp[y];
			up = pos[y];
			update(1,0,n-1);
		}
	}

/*
	int totalcase;
	int testcase=0;
	cin>>totalcase;
	ofstream out;
	out.open("result.txt");

	while(totalcase--){
		testcase++;
		out<<"Case #"<<testcase<<": ";
		cout<<testcase<<": "<<endl;

		//GOGOGO

		//END
	}
	out.close();
*/

	return 0;
}

#include <cstdio>
#include <algorithm>
#include <cstring>
#include <queue>
#define ll long long
#define l(a) (a<<1)
#define r(a) (a<<1|1)
#define MN 500005
#define MM 1000005
#define MD 4200005
using namespace std;
struct vec
{
	int x,y;
	friend ll operator/(const vec& a,const vec& b) {return 1LL*a.x*b.y-1LL*a.y*b.x;}
	friend ll operator*(const vec& a,const vec& b) {return 1LL*a.x*b.x+1LL*a.y*b.y;}
};
struct meg{int g,x,y;}a[MN];
struct met{vec v;int pos;}b0[MM],b1[MM];
struct its{int x,y;}s[MN];
struct itv{vec x,y;}d[MN];
struct Que
{
	priority_queue <int> A,B;
	void push(int x) {A.push(x);}
	void dele(int x) {B.push(x);}
	int top()
	{
		while (!B.empty()&&A.top()==B.top()) A.pop(),B.pop();
		if (!A.empty()) return A.top(); else return 0;
	}
}q[MM];
int m,MQ,tin,b0in,b1in,ra;
int t[MD];

inline int read()
{
	int n=0,f=1; char c=getchar();
	while (c<'0' || c>'9') {if(c=='-')f=-1; c=getchar();}
	while (c>='0' && c<='9') {n=n*10+c-'0'; c=getchar();}
	return n*f;
}

inline void getcg(int x,int z) {for (t[x+=MQ]=z,x>>=1;x;x>>=1) t[x]=max(t[l(x)],t[r(x)]);}
inline int getmax(int L,int R)
{
	int sum=0;
	for (L+=MQ,R+=MQ;L<=R;L>>=1,R>>=1)
	{
		if ( L&1) sum=max(sum,t[L++]);
		if (~R&1) sum=max(sum,t[R--]);
	}
	return sum;
}

void cghp(int x,int y,int g)
{
	int lt=q[x].top();
	if (g==1) q[x].push(y); else q[x].dele(y);
	if (lt!=q[x].top()) getcg(x,q[x].top());
}

bool check(int x,int y)
{
	int cs1,cs2;
	if (s[x].x>s[y].x) cs1=x; else cs1=y;
	if (s[x].y<s[y].y) cs2=x; else cs2=y;
//	printf("1=%d 2=%d\n",cs1,cs2);
//	printf("%.14lf,%.14lf\n",atan2(d[cs2].y[0],-d[cs2].y[1]),atan2(d[cs1].x[1],d[cs1].x[0]));
	if (d[cs2].y*d[cs1].x<0) return true; else return false;
}

bool cmp(const met& a,const met& b) {return a.v/b.v>0;}

int main()
{
//	freopen("2.in","r",stdin);
	register int i,x,y;
	ra=read(); m=read();
	for (i=1;i<=m;++i)
	{
		a[i].g=read();
		if (a[i].g==1)
		{
			x=read(); y=read(); a[i].x=++tin;
			d[tin].x.x=x-ra; d[tin].x.y=y;
			d[tin].y.x=x+ra; d[tin].y.y=y;
			b0[++b0in]=(met){d[tin].x,tin};
			b1[++b1in]=(met){d[tin].y,tin};
		}
		else if (a[i].g==2) a[i].x=read();
		else if (a[i].g==3) a[i].x=read(),a[i].y=read();
	}
	sort(b0+1,b0+b0in+1,cmp); sort(b1+1,b1+b1in+1,cmp);
	b0[0].pos=b1[0].pos=s[0].x=s[0].y=0;
	for (i=1;i<=b0in;++i)
		if (i>1&&b0[i-1].v/b0[i].v==0) s[b0[i].pos].x=s[b0[i-1].pos].x;
		else s[b0[i].pos].x=s[b0[i-1].pos].x+1;
	for (i=1;i<=b1in;++i)
		if (i>1&&b1[i-1].v/b1[i].v==0) s[b1[i].pos].y=s[b1[i-1].pos].y;
		else s[b1[i].pos].y=s[b1[i-1].pos].y+1;
	b0in=s[b0[b0in].pos].x;
	for (MQ=1;MQ<b0in;MQ<<=1); --MQ;
	for (i=1;i<=m;++i)
	{
		if (a[i].g<3) cghp(s[a[i].x].x,s[a[i].x].y,a[i].g);
		else if (a[i].g==3)
		{
			if (check(a[i].x,a[i].y)) {puts("NO"); continue;}
			x=max(s[a[i].x].x,s[a[i].y].x); y=min(s[a[i].x].y,s[a[i].y].y);
			cghp(s[a[i].x].x,s[a[i].x].y,2);
			cghp(s[a[i].y].x,s[a[i].y].y,2);
			if (getmax(1,x)>=y) puts("NO"); else puts("YES");
			cghp(s[a[i].x].x,s[a[i].x].y,1);
			cghp(s[a[i].y].x,s[a[i].y].y,1);
		}
	}
}

#include <cstdio>
#include <algorithm>
#include <cstring>
#include <queue>
#define ll long long
#define l(a) (a<<1)
#define r(a) (a<<1|1)
#define MN 500005
#define MD 1100005
using namespace std;
struct vec
{
	int x,y;
	friend ll operator/(const vec& a,const vec& b) {return 1LL*a.x*b.y-1LL*a.y*b.x;}
	friend ll operator*(const vec& a,const vec& b) {return 1LL*a.x*b.x+1LL*a.y*b.y;}
};
struct meg{int g,x,y;}a[MN];
struct met{vec v;int pos;}b0[MN],b1[MN];
struct its{int x,y;}s[MN];
struct itv{vec x,y;}d[MN];
struct Que
{
	priority_queue <int> A,B;
	void push(int x) {A.push(x);}
	void dele(int x) {B.push(x);}
	int top()
	{
		while (!B.empty()&&A.top()==B.top()) A.pop(),B.pop();
		if (!A.empty()) return A.top(); else return 0;
	}
}q[MN];
int m,MQ,tin,b0in,b1in,ra;
int t[MD];

inline int read()
{
	int n=0,f=1; char c=getchar();
	while (c<'0' || c>'9') {if(c=='-')f=-1; c=getchar();}
	while (c>='0' && c<='9') {n=n*10+c-'0'; c=getchar();}
	return n*f;
}

inline void getcg(int x,int z) {for (t[x+=MQ]=z,x>>=1;x;x>>=1) t[x]=max(t[l(x)],t[r(x)]);}
inline int getmax(int L,int R)
{
	int sum=0;
	for (L+=MQ,R+=MQ;L<=R;L>>=1,R>>=1)
	{
		if ( L&1) sum=max(sum,t[L++]);
		if (~R&1) sum=max(sum,t[R--]);
	}
	return sum;
}

void cghp(int x,int y,int g)
{
	int lt=q[x].top();
	if (g==1) q[x].push(y); else q[x].dele(y);
	if (lt!=q[x].top()) getcg(x,q[x].top());
}

bool check(int x,int y)
{
	int cs1,cs2;
	if (s[x].x>s[y].x) cs1=x; else cs1=y;
	if (s[x].y<s[y].y) cs2=x; else cs2=y;
	if (d[cs2].y*d[cs1].x<0) return true; else return false;
}

bool cmp(const met& a,const met& b) {return a.v/b.v>0;}

int main()
{
	register int i,x,y;
	ra=read(); m=read();
	for (i=1;i<=m;++i)
	{
		a[i].g=read();
		if (a[i].g==1)
		{
			x=read(); y=read(); a[i].x=++tin;
			d[tin].x.x=x-ra; d[tin].x.y=y;
			d[tin].y.x=x+ra; d[tin].y.y=y;
			b0[++b0in]=(met){d[tin].x,tin};
			b1[++b1in]=(met){d[tin].y,tin};
		}
		else if (a[i].g==2) a[i].x=read();
		else if (a[i].g==3) a[i].x=read(),a[i].y=read();
	}
	sort(b0+1,b0+b0in+1,cmp); sort(b1+1,b1+b1in+1,cmp);
	b0[0].pos=b1[0].pos=s[0].x=s[0].y=0;
	for (i=1;i<=b0in;++i)
		if (i>1&&b0[i-1].v/b0[i].v==0) s[b0[i].pos].x=s[b0[i-1].pos].x;
		else s[b0[i].pos].x=s[b0[i-1].pos].x+1;
	for (i=1;i<=b1in;++i)
		if (i>1&&b1[i-1].v/b1[i].v==0) s[b1[i].pos].y=s[b1[i-1].pos].y;
		else s[b1[i].pos].y=s[b1[i-1].pos].y+1;
	b0in=s[b0[b0in].pos].x;
	for (MQ=1;MQ<b0in;MQ<<=1); --MQ;
	for (i=1;i<=m;++i)
	{
		if (a[i].g<3) cghp(s[a[i].x].x,s[a[i].x].y,a[i].g);
		else if (a[i].g==3)
		{
			if (check(a[i].x,a[i].y)) {puts("NO"); continue;}
			x=max(s[a[i].x].x,s[a[i].y].x); y=min(s[a[i].x].y,s[a[i].y].y);
			cghp(s[a[i].x].x,s[a[i].x].y,2);
			cghp(s[a[i].y].x,s[a[i].y].y,2);
			if (getmax(1,x)>=y) puts("NO"); else puts("YES");
			cghp(s[a[i].x].x,s[a[i].x].y,1);
			cghp(s[a[i].y].x,s[a[i].y].y,1);
		}
	}
}

//https://codeforces.com/contest/856/problem/E

#include<bits/stdc++.h>
const int N = 5e5 + 5;
using namespace std;

struct point{
    int id, x, y;

    point(int id, int x, int y) : id(id), x(x), y(y) {}

    point() {}

    bool operator < (const point&a) const{
        return 1LL * x * a.y < 1LL * y * a.x;
    }

    bool operator == (const point&a) const{
        return 1LL * x * a.y == 1LL * y * a.x;
    }
} p[N];

vector <point> mv[2];

multiset <int> ms[N];
int r, n, type[N], a[N], b[N], cnt, m;
int f[N][2], it[N << 2];

void update(int i, int l, int r, int pos, int val, int v){
    if (l > pos || pos > r) return;
    if (l == r){
        if (v) ms[l].insert(val);
        else ms[l].erase(ms[l].lower_bound(val));
        it[i] = ((ms[l].size()) ? *ms[l].begin() : N);
        return;
    }
    int mid = (l + r) >> 1;
    update(i << 1, l, mid, pos, val, v); update(i << 1 | 1, mid+1, r, pos, val, v);
    it[i] = min(it[i << 1], it[i << 1 | 1]);
}

int get(int i, int l, int r, int L, int R){
    if (L > r || l > R) return N;
    if (L <= l && r <= R) return it[i];
    int mid = (l + r) >> 1;
    return min(get(i << 1, l, mid, L, R), get(i << 1 | 1, mid+1, r, L, R));
}

void ins(int a, int b){
    update(1, 1, m, b, a, 1);
}

void del(int a, int b){
    update(1, 1, m, b, a, 0);
}

bool cross(point a, point b){
    a.x -= r; b.x += r;
    return 1LL * a.x * b.x + 1LL * a.y * b.y >= 0;
}

bool ck(int a, int b){
    bool res = true;
    int x = max(f[a][0], f[b][0]), y = min(f[a][1], f[b][1]);
    del(f[a][0], f[a][1]); del(f[b][0], f[b][1]);
    if (get(1, 1, m, y, m) <= x) res = false;
    ins(f[a][0], f[a][1]); ins(f[b][0], f[b][1]);

    if (f[a][0] > f[b][0]) swap(a, b);
    if (f[a][0] < f[b][0] && f[a][1] < f[b][1]){
        if (!cross(p[a], p[b])) res = false;
    }

    return res;
}

int main(){
    ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);
    for (int i = 0; i < (N << 2); i++) it[i] = N;
    cin >> r >> n;
    for (int i = 1; i <= n; i++) {
        cin >> type[i] >> a[i];
        if (type[i] != 2) cin >> b[i];
        if (type[i] == 1) cnt++, mv[0].push_back(point(cnt, a[i]+r, b[i])), mv[1].push_back(point(cnt, a[i]-r, b[i])), p[cnt] = point(0, a[i], b[i]);
    }
    sort(mv[0].begin(), mv[0].end()); sort(mv[1].begin(), mv[1].end());
    for (int i = 0; i < (int)mv[0].size(); i++){
        if (i == 0 || !(mv[0][i] == mv[0][i-1])) m++;
        f[mv[0][i].id][0] = m;
    }
    m = 0;
    for (int i = 0; i < (int)mv[1].size(); i++){
        if (i == 0 || !(mv[1][i] == mv[1][i-1])) m++;
        f[mv[1][i].id][1] = m;
    }
    cnt = 0;
    for (int i = 1; i <= n; i++){
        if (type[i] == 1) cnt++, ins(f[cnt][0], f[cnt][1]);
        if (type[i] == 2) del(f[a[i]][0], f[a[i]][1]);
        if (type[i] == 3) cout << (ck(a[i], b[i]) ? "YES" : "NO") << "\n";
    }
}

#include <bits/stdc++.h>

#define FOR(i,b,e) for(int i=(b); i <= (e); ++i)
#define FORD(i,b,e) for(int i=(b); i >= (e); --i)
#define REP(i,n) for(int i=0; i < (n); ++i)
#define SIZE(c) (int) (c).size()
#define ALL(c) (c).begin(), (c).end()
#define PB push_back
#define MP make_pair
#define ST first
#define ND second
#define FWD(i,a,b) for (int i=(a); i<(b); ++i)
#define BCK(i,a,b) for (int i=(a); i>(b); --i)
#define PI 3.14159265358979311600
#define pb push_back
#define mp make_pair
#define st first
#define nd second

using namespace std;

typedef long long ll;
typedef pair <int, int> pii;
typedef pair <ll, ll> pll;

typedef vector < int > VI;
typedef vector<ll> VL;

typedef long double K;

struct pt {
	int x, y, id;

	friend pt operator + (const pt& a, const pt& b) {
		return {a.x + b.x, a.y + b.y};
	}

	friend pt operator - (const pt& a, const pt& b) {
		return {a.x - b.x, a.y - b.y};
	}

	friend ll operator * (const pt& a, const pt& b) {
		return 1LL*a.x*b.y - 1LL*a.y*b.x;
	}

	friend ll operator % (const pt& a, const pt& b) {
		return 1LL*a.x*b.x + 1LL*a.y*b.y;
	}
};

struct SegTree {
	int n;

	SegTree() {}
};

const int N = 500005;

int r, n, t[N], x[N], y[N], sz;
pt a[N];
int ps[N];

pt tree[4*N], lf, rt;

pt up(const pt& a, const pt& b) {
	return (a - rt) * (b - rt) > 0 ? a : b;
}

void build(int v, int tl, int tr) {
	if (tl == tr) {
		tree[v] = lf;
		return;
	}
	int tm = (tl + tr) / 2;
	build(2*v, tl, tm);
	build(2*v+1, tm+1, tr);
	tree[v] = up(tree[2*v], tree[2*v+1]);
}

pt go(int v, int tl, int tr, int l, int r) {
	if (l > r || l > tr || r < tl) return lf;
	if (l <= tl && r >= tr) return tree[v];
	int tm = (tl + tr) / 2;
	return up(go(2*v, tl, tm, l, r), go(2*v+1, tm+1, tr, l, r));
}

void update(int v, int tl, int tr, int pos, pt val) {
	if (tl == tr) {
		tree[v] = val;
		return;
	}
	int tm = (tl + tr) / 2;
	if (pos <= tm) {
		update(2*v, tl, tm, pos, val);
	} else {
		update(2*v+1, tm+1, tr, pos, val);
	}
	tree[v] = up(tree[2*v], tree[2*v+1]);
}

void add(int id) {
	// cout << "ADD: " << id << endl;
	update(1, 0, sz - 1, ps[id], a[ps[id]]);
}

void remove(int id) {
	// cout << "DELETE: " << id << endl;
	update(1, 0, sz - 1, ps[id], lf);
}

bool go(int x, int y) {
	pt f = a[ps[x]];
	pt s = a[ps[y]];
	pt lf = {-r, 0};
	pt rt = {+r, 0};
	pt first = (f - lf) * (s - lf) > 0 ? (f - lf) : (s - lf);
	pt second = (f - rt) * (s - rt) < 0 ? (f - rt) : (s - rt);

	if (first % second < 0) return false;
	// cout << "HELLO" << endl;
	// cout << first.x << ' ' << first.y << endl;
	// cout << second.x << ' ' << second.y << endl;
	int l = -1, r = sz;
	while (r - l > 1) {
		int m = (l + r) / 2;
		if (first * (a[m] - lf) < 0) l = m; else r = m;
	}
	// REP(i, sz) cout << first * (a[i] - lf) << ' '; cout << endl;
	// cout << r << ' ' << sz << endl;
	remove(x);
	remove(y);
	auto here = go(1, 0, sz - 1, r, sz - 1);
	// cout << here.x << ' ' << here.y << ' ' << here.id << endl;
	here = here - rt;
	add(x);
	add(y);
	if (here * second >= 0) return false;
	return true;
}

void solve() {
	cin >> r >> n;

	REP(i, n) {
		cin >> t[i] >> x[i];
		if (t[i] != 2) cin >> y[i];
		if (t[i] == 1) {
			a[sz] = {x[i], y[i], sz};
			++sz;
			x[i] = sz;
		}
		--x[i]; --y[i];
	}
	lf = {-r, 0};
	rt = {+r, 0};
	sort(a, a + sz, [](const pt& a, const pt& b) {
		return (a - lf) * (b - lf) > 0;
	});
	REP(i, sz) ps[a[i].id] = i;
	// REP(i, sz) cout << i << " : " << a[i].id << endl;
	build(1, 0, sz - 1);
	REP(i, n) {
		if (t[i] == 1) {
			add(x[i]);
		}
		if (t[i] == 2) {
			remove(x[i]);
		}
		if (t[i] == 3) {
			cout << (go(x[i], y[i]) ? "YES" : "NO") << '\n';
		}
	}
}

int main() {
	ios_base::sync_with_stdio(false);
	cin.tie(0);

	int t = 1;
	REP(i, t) solve();

	return 0;
}

#include<bits/stdc++.h>
using namespace std;
typedef long long lint;
typedef long double llf;
const int mod = 998244353;
const int MAXN = 500005;
typedef pair<int, int> pi;

struct seg{
	multiset<int> tree[1050000];
	int val[1050000];
	int lim;
	void init(int n){
		for(lim = 1; lim <= n; lim <<= 1);
	}
	void insert(int x, int y){
		x += lim;
		tree[x].insert(y);
		val[x] = *--tree[x].end();
		while(x > 1){
			x >>= 1;
			val[x] = max(val[2*x], val[2*x+1]);
		}
	}
	void erase(int x, int y){
		x += lim;
		tree[x].erase(tree[x].find(y));
		if(tree[x].empty()) val[x] = 0;
		else val[x] = *--tree[x].end();
		while(x > 1){
			x >>= 1;
			val[x] = max(val[2*x], val[2*x+1]);
		}
	}
	int query(int s, int e){
		s += lim;
		e += lim;
		int ret = 0;
		while(s < e){
			if(s%2 == 1) ret = max(ret, val[s++]);
			if(e%2 == 0) ret = max(ret, val[e--]);
			s >>= 1;
			e >>= 1;
		}
		if(s == e) ret = max(ret, val[s]);
		return ret;
	}
}seg;

int r, n;
int qt[MAXN], qi[MAXN], qj[MAXN];
int vx[MAXN], vy[MAXN];
pi a[MAXN];

lint ccw(pi a, pi b, pi c){
	int dx1 = b.first - a.first;
	int dy1 = b.second - a.second;
	int dx2 = c.first - a.first;
	int dy2 = c.second - a.second;
	return 1ll * dx1 * dy2 - 1ll * dy1 * dx2;
}

lint dot(pi a, pi b){
	return 1ll * a.first * b.first + 1ll * a.second * b.second;
}

bool cross(pi a, pi b){
	a.first += r;
	b.first -= r;
	return dot(a, b) < 0;
}

void solve(){
	int cnt = 0;
	for(int i=0; i<n; i++){
		if(qt[i] == 1){
			cnt++;
			seg.insert(vx[cnt], vy[cnt]);
		}
		if(qt[i] == 2){
			int p = qi[i];
			seg.erase(vx[p], vy[p]);
		}
		if(qt[i] == 3){
			int x = qi[i], y = qj[i];
			if(vx[x] > vx[y]) swap(x, y);
			if(cross(a[x], a[y])) puts("NO");
			else{
				int px = min(vx[x], vx[y]);
				int py = min(vy[x], vy[y]);
				bool ok = 1;
				seg.erase(vx[x], vy[x]);
				seg.erase(vx[y], vy[y]);
				if(seg.query(px, MAXN - 1) >= py) puts("NO");
				else puts("YES");
				seg.insert(vx[x], vy[x]);
				seg.insert(vx[y], vy[y]);
			}
		}
	}
}

struct point{ pi x; int idx; };
vector<point> v;

int main(){
	scanf("%d %d",&r,&n);
	int cnt = 0;
	for(int i=0; i<n; i++){
		scanf("%d",&qt[i]);
		if(qt[i] != 2) scanf("%d %d",&qi[i],&qj[i]);
		else scanf("%d",&qi[i]);
		if(qt[i] == 1){
			a[++cnt] = pi(qi[i], qj[i]);
		}
	}
	for(int i=1; i<=cnt; i++) v.push_back({a[i], i});
	sort(v.begin(), v.end(), [&](const point &a, const point &b){
		return ccw(pi(-r, 0), a.x, b.x) > 0;
	});
	for(int i=0; i<v.size(); ){
		int e = i;
		while(e < v.size() && ccw(pi(-r, 0), v[i].x, v[e].x) == 0) e++;
		for(int j=i; j<e; j++) vx[v[j].idx] = i+1;
		i = e;
	}
	sort(v.begin(), v.end(), [&](const point &a, const point &b){
		return ccw(pi(r, 0), a.x, b.x) < 0;
	});
	for(int i=0; i<v.size(); ){
		int e = i;
		while(e < v.size() && ccw(pi(r, 0), v[i].x, v[e].x) == 0) e++;
		for(int j=i; j<e; j++) vy[v[j].idx] = i+1;
		i = e;
	}
	seg.init(MAXN);
	solve();
}

#include <bits/stdc++.h>
using namespace std;
const int N = 5e5 + 7;
int cnt;
struct frac {
	int x, y;
};
frac X[N], Y[N];
bool operator < (const frac &a, const frac &b) {
	return 1LL * a.x * b.y > 1LL * a.y * b.x;
	/*if (a.x == 0) return b.x > 0;
	if (b.x == 0) return a.x < 0;
	if (a.x < 0 && b.x > 0) return 1 < 0;
	if (a.x > 0 && b.x < 0) return 0 < 1;
	if (a.x >= 0) {
		return 1LL * a.y * b.x < 1LL * a.x * b.y;
	}
	return 1LL * a.y * b.x > 1LL * a.x * b.y;*/
}
bool operator == (const frac &a, const frac &b) {
	return !(a < b || b < a);
}
struct event {
	bool is_modify;
	int id; frac x, y;
};
bool operator < (const event &a, const event &b) {
	if (!(a.y == b.y)) return b.y < a.y;
	return a.is_modify > b.is_modify;
}
vector<event> all;
int ans[N], Tree[N], tick[N], xxx, n;
int &tree(int x) {
	if (tick[x] < xxx) {
		tick[x] = xxx;
		Tree[x] = 0;
	}
	return Tree[x];
}
void add(int x, int c) {
	while (x <= n) {
		tree(x) += c;
		x += x & -x;
	}
}
int query(int x) {
	int res = 0;
	while (x) {
		res += tree(x);
		x -= x & -x;
	}
	return res;
}
void divide_time(int l, int r) {
	if (l >= r) return;
	int mid = (l + r) / 2;
	divide_time(l, mid);
	divide_time(mid + 1, r);
	vector<event> bll;
	vector<frac> ax;
	for (int i = l; i <= mid; ++ i) {
		if (all[i].is_modify) {
			bll.push_back(all[i]);
			ax.push_back(all[i].x);
		}
	}
	for (int i = mid + 1; i <= r; ++ i) {
		if (!all[i].is_modify) {
			bll.push_back(all[i]);
			ax.push_back(all[i].x);
		}
	}
	sort(bll.begin(), bll.end());
	sort(ax.begin(), ax.end());
	ax.erase(unique(ax.begin(), ax.end()), ax.end());
	xxx ++;
	::n = ax.size();
	for (auto e : bll) {
		int x = lower_bound(ax.begin(), ax.end(), e.x) - ax.begin() + 1;
		if (e.is_modify) {
			int c = (e.id > 0 ? 1 : -1);
			add(n - x + 1, c);
		}
		else {
			ans[e.id] += query(n - x + 1);
		}
	}
}
bool debug = 0;
bool inside(frac a, frac b) {
	return 1LL * a.x * b.x + 1LL * a.y * b.y < 0;
}
int main() {
	int R, m, n = 0;
	if (debug) R = 1000, m = 50000; else
	scanf("%d%d", &R, &m);
	for (int r = 0; r < m; ++ r) {
		int type;
		if (debug) type = (cnt == 0 ? 1 : rand() % 2 * 2 + 1); else
		scanf("%d", &type);
		if (type == 1) {
			++ cnt;
			int x, y;
			if (debug) {
				x = rand() % 20000 - 10000;
				y = rand() % 10000;
				while (1LL * x * x + 1LL * y * y <= 1LL * R * R) {
					x = rand() % 20000 - 10000;
					y = rand() % 10000;
				}
			} else
			scanf("%d%d", &x, &y);
			X[cnt] = (frac) {x + R, y};
			Y[cnt] = (frac) {R - x, y};
			all.push_back((event) {1, cnt, X[cnt], Y[cnt]});
		}
		else if (type == 2) {
			int x;
			scanf("%d", &x);
			all.push_back((event) {1, -x, X[x], Y[x]});
		}
		else {
			int x, y;
			if (debug) {
				x = rand() % cnt + 1;
				y = rand() % cnt + 1;
			} else
			scanf("%d%d", &x, &y);
			all.push_back((event) {0, n ++, min(X[x], X[y]), min(Y[x], Y[y])});
			auto tmp = all.back().y; tmp.x = -tmp.x;
			if (inside(all.back().x, tmp)) ans[n - 1] = 3;
		}
	}
	divide_time(0, (int) all.size() - 1);
	for (int i = 0; i < n; ++ i) puts(ans[i] <= 2 ? "YES" : "NO");
}

#include<cstdio>
#include<algorithm>
#include<vector>
#define N_ 510000
#define SZ (1<<19)
using namespace std;
struct point {
	long long x, y;
	int num;
	bool operator<(const point &p)const {
		return x*p.y  < p.x*y ;
	}
}A[N_], B[N_];
long long Mul(point a, point b) {
	return a.x*b.x + a.y*b.y;
}
int R, n, cnt;
struct AA{
	int b, e, num;
	bool operator<(const AA &p)const {
		return b != p.b ? b < p.b : e < p.e;
	}
}w[N_];
int ReNum[N_];
struct QQ {
	int ck, a, b;
}Q[N_];
int IT[SZ + SZ];
void Ins(int a) {
	a = ReNum[a];
	int y = w[a].e;
	a += SZ;
	IT[a] = y;
	while (a != 1) {
		a >>= 1;
		IT[a] = max(IT[a + a], IT[a + a + 1]);
	}
}
void Del(int a) {
	a = ReNum[a];
	a += SZ;
	IT[a] = 0;
	while (a != 1) {
		a >>= 1;
		IT[a] = max(IT[a + a], IT[a + a + 1]);
	}
}
int Max(int b, int e) {
	int r = 0;
	b += SZ, e += SZ;
	while (b <= e) {
		r = max(r, max(IT[b], IT[e]));
		b = (b + 1) >> 1;
		e = (e - 1) >> 1;
	}
	return r;
}
bool Valid(int a, int b) {
	point t1 = A[a], t2 = A[b];
	if (Mul(A[a], B[b]) < 0)return false;
	return true;
}
int main() {
	int i, ck, x, y;
	scanf("%d%d", &R, &n);
	for (i = 1; i <= n; i++) {
		scanf("%d", &ck);
		if (ck == 1) {
			scanf("%d%d", &x, &y);
			cnt++;
			Q[i] = { 1,cnt,0 };
			A[cnt] = { x + R,y,cnt };
			B[cnt] = { x - R,y,cnt };
		}
		else if (ck == 2) {
			scanf("%d", &x);
			Q[i] = { 2,x,0 };
		}
		else {
			scanf("%d%d", &x, &y);
			Q[i] = { 3,x,y };
		}
	}
	sort(A + 1, A + cnt + 1);
	sort(B + 1, B + cnt + 1);
	int pv1 = 1, pv2 = 1;
	for (i = 1; i <= cnt; i++) {
		if (A[pv1] < A[i])pv1 = i;
		if (B[pv2] < B[i])pv2 = i;
		w[A[i].num].b = pv1;
		w[B[i].num].e = pv2;
		w[i].num = i;
	}
	sort(w + 1, w + cnt + 1);
	for (i = 1; i <= cnt; i++)ReNum[w[i].num] = i;
	for (i = 1; i <= n; i++) {
		if (Q[i].ck == 1) {
			Ins(Q[i].a);
		}
		if (Q[i].ck == 2) {
			Del(Q[i].a);
		}
		if (Q[i].ck == 3) {
			Del(Q[i].a), Del(Q[i].b);
			int a = ReNum[Q[i].a], b = ReNum[Q[i].b];
			int aa = max(w[a].b, w[b].b), bb = min(w[a].e, w[b].e);
			if (!Valid(aa, bb)) {
				printf("NO\n");
			}
			else {
				AA tp = { aa + 1,0,0 };
				int t = lower_bound(w + 1, w + cnt + 1, tp) - w - 1;
				if (Max(1, t) >= bb) {
					printf("NO\n");
				}
				else printf("YES\n");
			}

			Ins(Q[i].a), Ins(Q[i].b);
		}
	}
}

#pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")
#pragma GCC optimize("no-stack-protector")
#pragma GCC target("sse,sse2,ssse3,sse3,sse4,popcnt,avx,mmx,abm,tune=native")
#include <bits/stdc++.h>
#define DEBUG 1
using namespace std;

namespace output{
    void __(short x){cout<<x;}
    void __(unsigned x){cout<<x;}
    void __(int x){cout<<x;}
    void __(long long x){cout<<x;}
    void __(unsigned long long x){cout<<x;}
    void __(double x){cout<<x;}
    void __(long double x){cout<<x;}
    void __(char x){cout<<x;}
    void __(const char*x){cout<<x;}
    void __(const string&x){cout<<x;}
    void __(bool x){cout<<(x?"true":"false");}
    template<class S,class T>
    void __(const pair<S,T>&x){__(DEBUG?"(":""),__(x.first),__(DEBUG?", ":" "),__(x.second),__(DEBUG?")":"");}
    template<class T>
    void __(const vector<T>&x){__(DEBUG?"{":"");bool _=0;for(const auto&v:x)__(_?DEBUG?", ":" ":""),__(v),_=1;__(DEBUG?"}":"");}
    template<class T>
    void __(const set<T>&x){__(DEBUG?"{":"");bool _=0;for(const auto&v:x)__(_?DEBUG?", ":" ":""),__(v),_=1;__(DEBUG?"}":"");}
    template<class T>
    void __(const multiset<T>&x){__(DEBUG?"{":"");bool _=0;for(const auto&v:x)__(_?DEBUG?", ":" ":""),__(v),_=1;__(DEBUG?"}":"");}
    template<class S,class T>
    void __(const map<S,T>&x){__(DEBUG?"{":"");bool _=0;for(const auto&v:x)__(_?DEBUG?", ":" ":""),__(v),_=1;__(DEBUG?"}":"");}
    void pr(){cout<<"\n";}
    template<class S,class... T>
    void pr(const S&a,const T&...b){__(a);if(sizeof...(b))__(' ');pr(b...);}
}

using namespace output;

typedef long long ll;
typedef long double ld;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
typedef pair<int,char> pic;
typedef pair<double,double> pdd;
typedef pair<ld,ld> pld;
typedef vector<int> vi;
typedef vector<ll> vl;

#define pb push_back
#define fox(i,x,y) for(int i=(x);i<=(y);i++)
#define foxr(i,x,y) for(int i=(y);i>=(x);i--)
#define F first
#define S second

const int MN = 5e5+5;
const ld PI = (ld)4*atan((ld)1), eps = (ld)5e-19;
int N, R, i, j, x, y, cnt, nxt; ld st[3*MN];
map<ld,int> mp; set<ld> pnt[MN];
ld aa[MN], bb[MN]; pii pos[MN];
struct qur{int t, x, y;}q[MN];

ll dot(pii i,pii j){return 1LL*i.F*j.F+1LL*i.S*j.S;}

bool ok(int i,int j){
    pii v1, v2;
    if(aa[i]<aa[j]) v1={pos[i].F+R,pos[i].S};
    else v1={pos[j].F+R,pos[j].S};
    if(bb[i]<bb[j]) v2={pos[i].F-R,pos[i].S};
    else v2={pos[j].F-R,pos[j].S};
    return dot(v1,v2)>=0;
}

void upd(int i,int s,int e,int ind,ld val,bool del=0){
    if(s!=e){
        if((s+e)/2<ind) upd(2*i+1,(s+e)/2+1,e,ind,val,del);
        else upd(2*i,s,(s+e)/2,ind,val,del);
        st[i]=max(st[2*i],st[2*i+1]);
    }
    else{
        if(del) pnt[s].erase(val);
        else pnt[s].insert(val);
        if(pnt[s].empty()) st[i]=-1;
        else{
            auto it=pnt[s].end(); it--;
            st[i]=*it;
        }
    }
}

ld qu(int i,int s,int e,int ss,int se){
    if(s>=ss&&e<=se) return st[i];
    else if((s+e)/2<ss) return qu(2*i+1,(s+e)/2+1,e,ss,se);
    else if((s+e)/2>=se) return qu(2*i,s,(s+e)/2,ss,se);
    else return max(qu(2*i,s,(s+e)/2,ss,se),qu(2*i+1,(s+e)/2+1,e,ss,se));
}

int main(){
    scanf("%d%d",&R,&N);
    for(i=1;i<=N;i++){
        scanf("%d%d",&q[i].t,&q[i].x);
        if(q[i].t==1){
            cnt ++;
            scanf("%d",&q[i].y);
            pos[cnt] = {q[i].x, q[i].y};
            aa[cnt] = (ld)atan2((ld)q[i].y,(ld)q[i].x+R);
            bb[cnt] = PI-(ld)atan2((ld)q[i].y,(ld)q[i].x-R);
            //printf(">>> %.20Lf %.20Lf\n",aa[cnt],bb[cnt]);
            mp[aa[cnt]]=0;
        }
        else if(q[i].t==3)
            scanf("%d",&q[i].y);
    }
    for(auto it=mp.begin();it!=mp.end();it++)
        it->second = ++nxt;
    cnt = 0;
    for(i=1;i<=N;i++){
        if(q[i].t==1){
            cnt ++;
            upd(1,1,nxt,mp[aa[cnt]],bb[cnt],0);
        }
        else if(q[i].t==2){
            upd(1,1,nxt,mp[aa[q[i].x]],bb[q[i].x],1);
        }
        else{
            x=q[i].x, y=q[i].y;
            if(!ok(x,y)) printf("NO\n");
            else{
                ld ix=min(aa[x],aa[y]);
                ld iy=min(bb[x],bb[y]);
                int inx = mp[ix];
                upd(1,1,nxt,mp[aa[x]],bb[x],1);
                upd(1,1,nxt,mp[aa[y]],bb[y],1);
                if(qu(1,1,nxt,inx,nxt)>=iy) printf("NO\n");
                else printf("YES\n");
                upd(1,1,nxt,mp[aa[x]],bb[x],0);
                upd(1,1,nxt,mp[aa[y]],bb[y],0);
            }
        }
    }
    return 0;
}

#include <bits/stdc++.h>
#define xx first
#define yy second
#define mp make_pair
#define pb push_back
#define mset(x, y) memset(x, y, sizeof x)
#define mcpy(x, y) memcpy(x, y, sizeof x)
using namespace std;

typedef long long LL;
typedef pair <int, int> pii;

inline int Read()
{
	int x = 0, f = 1, c = getchar();
	for (; !isdigit(c); c = getchar())
		if (c == '-')
			f = -1;
	for (;  isdigit(c); c = getchar())
		x = x * 10 + c - '0';
	return x * f;
}

const int MAXN = 500005;

struct Node
{
	int opt, x, y;
} e[MAXN];

int n, m, r, tot, x[MAXN], y[MAXN], p[MAXN], q[MAXN], mx[MAXN << 2], rnk[MAXN], pos[MAXN], rot[MAXN];
pii a[MAXN], b[MAXN];

inline bool Cmp(pii u, pii v) { return 1LL * u.xx * v.yy - 1LL * u.yy * v.xx > 0; }

inline void Modify(int x, int l, int r, int p, int v)
{
	if (l == r)
		return (void)(mx[x] = v);
	int mid = l + r >> 1;
	if (p <= mid)
		Modify(x << 1, l, mid, p, v);
	else
		Modify(x << 1 | 1, mid + 1, r, p, v);
	mx[x] = max(mx[x << 1], mx[x << 1 | 1]);
}

inline int Query(int x, int l, int r, int ql, int qr)
{
	if (l == ql && r == qr)
		return mx[x];
	int mid = l + r >> 1;
	if (qr <= mid)
		return Query(x << 1, l, mid, ql, qr);
	if (ql > mid)
		return Query(x << 1 | 1, mid + 1, r, ql, qr);
	return max(Query(x << 1, l, mid, ql, mid), Query(x << 1 | 1, mid + 1, r, mid + 1, qr));
}

int main()
{
#ifdef wxh010910
	freopen("data.in", "r", stdin);
#endif
	r = Read(), m = Read();
	for (int i = 1; i <= m; i ++)
	{
		e[i].opt = Read();
		if (e[i].opt == 1)
			n ++, x[n] = e[i].x = Read(), y[n] = e[i].y = Read();
		else if (e[i].opt == 2)
			e[i].x = Read();
		else
			e[i].x = Read(), e[i].y = Read();
	}
	for (int i = 1; i <= n; i ++)
		a[i] = mp(x[i] + r, y[i]);
	sort(a + 1, a + n + 1, Cmp);
	for (int i = 1; i <= n; i ++)
		p[i] = lower_bound(a + 1, a + n + 1, mp(x[i] + r, y[i]), Cmp) - a;
	for (int i = 1; i <= n; i ++)
		b[i] = mp(r - x[i], y[i]);
	sort(b + 1, b + n + 1, Cmp);
	for (int i = 1; i <= n; i ++)
		q[i] = lower_bound(b + 1, b + n + 1, mp(r - x[i], y[i]), Cmp) - b;
	for (int i = 1; i <= n; i ++)
		pos[i] = i;
	sort(pos + 1, pos + n + 1, [&](int x, int y) { return mp(p[x], q[x]) < mp(p[y], q[y]); });
	for (int i = 1; i <= n; i ++)
		rnk[pos[i]] = i;
	for (int i = 1, cur = 0; i <= m; i ++)
		if (e[i].opt == 1)
			cur ++, Modify(1, 1, n, rnk[cur], q[cur]);
		else if (e[i].opt == 2)
			Modify(1, 1, n, rnk[e[i].x], 0);
		else
		{
			int idx = e[i].x, idy = e[i].y;
			Modify(1, 1, n, rnk[idx], 0);
			Modify(1, 1, n, rnk[idy], 0);
			pii x, y;
			if (p[idx] < p[idy])
				x = a[p[idx]];
			else
				x = a[p[idy]];
			if (q[idx] < q[idy])
				y = b[q[idx]];
			else
				y = b[q[idy]];
			if (1LL * x.xx * y.xx - 1LL * x.yy * y.yy > 0)
				puts("NO");
			else
			{
				p[n + 1] = lower_bound(a + 1, a + n + 1, x, Cmp) - a;
				q[n + 1] = lower_bound(b + 1, b + n + 1, y, Cmp) - b;
				int t = lower_bound(pos + 1, pos + n + 1, n + 1, [&](int x, int y) { return mp(p[x], q[x]) < mp(p[y], q[y]); }) - pos;
				if (Query(1, 1, n, t, n) >= q[n + 1])
					puts("NO");
				else
					puts("YES");
			}
			Modify(1, 1, n, rnk[idx], q[idx]);
			Modify(1, 1, n, rnk[idy], q[idy]);
		}
}

#include <bits/stdc++.h>
using namespace std;

#define ms(s, n) memset(s, n, sizeof(s))
#define FOR(i, a, b) for (int i = (a); i < (b); i++)
#define FORd(i, a, b) for (int i = (a) - 1; i >= (b); i--)
#define FORall(it, a) for (__typeof((a).begin()) it = (a).begin(); it != (a).end(); it++)
#define sz(a) int((a).size())
#define present(t, x) (t.find(x) != t.end())
#define all(a) (a).begin(), (a).end()
#define uni(a) (a).erase(unique(all(a)), (a).end())
#define pb push_back
#define pf push_front
#define mp make_pair
#define fi first
#define se second
#define prec(n) fixed<<setprecision(n)
#define bit(n, i) (((n) >> (i)) & 1)
#define bitcount(n) __builtin_popcountll(n)
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef pair<int, int> pi;
typedef vector<int> vi;
typedef vector<pi> vii;
const int MOD = (int) 1e9 + 7;
const int MOD2 = 1007681537;
const int INF = (int) 1e9;
const ll LINF = (ll) 1e18;
const ld PI = acos((ld) -1);
const ld EPS = 1e-9;
inline ll gcd(ll a, ll b) {ll r; while (b) {r = a % b; a = b; b = r;} return a;}
inline ll lcm(ll a, ll b) {return a / gcd(a, b) * b;}
inline ll fpow(ll n, ll k, int p = MOD) {ll r = 1; for (; k; k >>= 1) {if (k & 1) r = r * n % p; n = n * n % p;} return r;}
template<class T> inline int chkmin(T& a, const T& val) {return val < a ? a = val, 1 : 0;}
template<class T> inline int chkmax(T& a, const T& val) {return a < val ? a = val, 1 : 0;}
inline ll isqrt(ll k) {ll r = sqrt(k) + 1; while (r * r > k) r--; return r;}
inline ll icbrt(ll k) {ll r = cbrt(k) + 1; while (r * r * r > k) r--; return r;}
inline void addmod(int& a, int val, int p = MOD) {if ((a = (a + val)) >= p) a -= p;}
inline void submod(int& a, int val, int p = MOD) {if ((a = (a - val)) < 0) a += p;}
inline int mult(int a, int b, int p = MOD) {return (ll) a * b % p;}
inline int inv(int a, int p = MOD) {return fpow(a, p - 2, p);}
inline int sign(ld x) {return x < -EPS ? -1 : x > +EPS;}
inline int sign(ld x, ld y) {return sign(x - y);}
#define db(x) cerr << #x << " = " << (x) << " ";
#define endln cerr << "\n";

const int maxn = 5e5 + 5;
int n, d, k;
int op[maxn];
int x[maxn];
int y[maxn];
int z[maxn];
int l[maxn];
int r[maxn];
int a[maxn];
int b[maxn];

long long ff1(int i, int j) {
    int x1 = x[i] + d;
    int y1 = y[i] + 0;
    int x2 = x[j] + d;
    int y2 = y[j] + 0;
    return (long long) x1 * y2 - (long long) x2 * y1;
}

long long ff2(int i, int j) {
    int x1 = x[i] - d;
    int y1 = y[i] - 0;
    int x2 = x[j] - d;
    int y2 = y[j] - 0;
    return (long long) x1 * y2 - (long long) x2 * y1;
}

int cmp1(int i, int j) {
    long long cr = ff1(i, j);
    if (cr) return cr > 0;
    return i < j;
}

int cmp2(int i, int j) {
    long long cr = ff2(i, j);
    if (cr) return cr > 0;
    return i < j;
}

set<int> heap[maxn];
int st[maxn << 1];
void upd(int p, int n, int val) {
    for (st[p += n] = val; p > 1; ) p >>= 1, st[p] = min(st[p << 1], st[p << 1 | 1]);
}
int query(int l, int r, int n) {
    int res = INF;
    for (l += n, r += n + 1; l < r; l >>= 1, r >>= 1) {
        if (l & 1) chkmin(res, st[l++]);
        if (r & 1) chkmin(res, st[--r]);
    }
    return res;
}

void upd(int u, int n) {
    int val = sz(heap[u]) ? *heap[u].begin() : INF;
    upd(u, n, val);
}

long long dot(pi a, pi b) {
    return (long long) a.fi * b.fi + (long long) a.se * b.se;
}

void solve() {
    cin >> d >> n;
    FOR(i, 0, n) {
        cin >> op[i];
        if (op[i] == 1) {
            cin >> x[k] >> y[k], k++;
        }
        else if (op[i] == 2) {
            cin >> z[i], z[i]--;
        }
        else {
            cin >> l[i] >> r[i], l[i]--, r[i]--;
        }
    }
    vi ver; FOR(i, 0, k) ver.pb(i);
    sort(all(ver), cmp1);
    int st1 = 0;
    FOR(i, 0, k) {
        if (i && ff1(ver[i - 1], ver[i])) st1++;
        a[ver[i]] = st1;
    }
    FOR(i, 0, k) a[i] = st1 - a[i];
    int st2 = 0;
    sort(all(ver), cmp2);
    FOR(i, 0, k) {
        if (i && ff2(ver[i - 1], ver[i])) st2++;
        b[ver[i]] = st2;
    }
    FOR(i, 0, k + k) st[i] = INF;
    k = 0;
    FOR(i, 0, n) {
        if (op[i] == 1) {
            heap[a[k]].insert(b[k]);
            upd(a[k], st1 + 1);
            k++;
        }
        else if (op[i] == 2) {
            int ix = z[i];
            heap[a[ix]].erase(b[ix]);
            upd(a[ix], st1 + 1);
        }
        else {
            int ix1 = l[i];
            int ix2 = r[i];
            int u = max(a[ix1], a[ix2]);
            int v = max(b[ix1], b[ix2]);
            pi p, q;
            if (a[ix1] > a[ix2]) {
                p = mp(x[ix1] + d, y[ix1]);
            }
            else {
                p = mp(x[ix2] + d, y[ix2]);
            }
            if (b[ix1] > b[ix2]) {
                q = mp(x[ix1] - d, y[ix1]);
            }
            else {
                q = mp(x[ix2] - d, y[ix2]);
            }
            heap[a[ix1]].erase(b[ix1]);
            upd(a[ix1], st1 + 1);
            heap[a[ix2]].erase(b[ix2]);
            upd(a[ix2], st1 + 1);
            if (dot(p, q) < 0 || query(0, u, st1 + 1) <= v) {
                cout << "NO\n";
            }
            else {
                cout << "YES\n";
            }
            heap[a[ix1]].insert(b[ix1]);
            upd(a[ix1], st1 + 1);
            heap[a[ix2]].insert(b[ix2]);
            upd(a[ix2], st1 + 1);
        }
    }
}

int main() {
    int JUDGE_ONLINE = 1;
    if (fopen("in.txt", "r")) {
        JUDGE_ONLINE = 0;
        assert(freopen("in.txt", "r", stdin));
        //assert(freopen("out.txt", "w", stdout));
    }
    else {
        ios_base::sync_with_stdio(0), cin.tie(0);
    }
    solve();
    if (!JUDGE_ONLINE) {
        //cout << "\nTime elapsed: " << 1000 * clock() / CLOCKS_PER_SEC << "ms\n";
    }
    return 0;
}

#include <stdio.h>
#include <algorithm>
#include <assert.h>
#include <bitset>
#include <cmath>
#include <complex>
#include <deque>
#include <functional>
#include <iostream>
#include <limits.h>
#include <map>
#include <math.h>
#include <queue>
#include <set>
#include <stdlib.h>
#include <string.h>
#include <string>
#include <time.h>
#include <unordered_map>
#include <unordered_set>
#include <vector>

#pragma warning(disable:4996)
#pragma comment(linker, "/STACK:336777216")
using namespace std;

#define mp make_pair
#define Fi first
#define Se second
#define pb(x) push_back(x)
#define szz(x) ((int)(x).size())
#define all(x) (x).begin(), (x).end()
#define ldb ldouble

typedef tuple<int, int, int> t3;
typedef long long ll;
typedef unsigned long long ull;
typedef double db;
typedef long double ldb;
typedef pair <int, int> pii;
typedef pair <ll, ll> pll;
typedef pair <ll, int> pli;
typedef pair <db, db> pdd;

int IT_MAX = 1 << 19;
const ll MOD = 998244353;
const int INF = 0x3f3f3f3f;
const ll LL_INF = 0x3f3f3f3f3f3f3f3f;
const db PI = acos(-1);
const db ERR = 1e-10;

pii operator-(const pii &l, const pii &r) {
	return pii(l.first - r.first, l.second - r.second);
}

ll operator/(const pii &l, const pii &r) {
	return (ll)l.first * r.second - (ll)l.second * r.first;
}
ll operator*(const pii &l, const pii &r) {
	return (ll)l.first * r.first + (ll)l.second * r.second;
}

const int MX = 1<<19;

int ord[MX][3], sz = 0;
pii D[MX];

auto cw = [](pii l, pii r) { return l / r < 0; };

struct Tree {
	int t[MX * 2];
	int read(int s, int e) {
		s += MX, e += MX;
		int r = 0;
		while (s <= e) {
			if (s & 1) r = max(r, t[s++]);
			if (~e & 1) r = max(r, t[e--]);
			s /= 2, e /= 2;
		}
		return r;
	}
	void update(int x, int v) {
		x += MX; t[x] = v;
		while (x > 1) {
			x /= 2; t[x] = max(t[x * 2], t[x * 2 + 1]);
		}
	}
} tree;
set<int> P[MX];

void add_point(int a, int b) {
	P[a].insert(b);
	tree.update(a, *P[a].rbegin());
}

void erase_point(int a, int b) {
	P[a].erase(b);
	tree.update(a, P[a].empty()? 0 : *P[a].rbegin());
}

bool solve(int a, int b) {
	if (tree.read(0, a) >= b) return true;
	return false;
}

int main()
{
	int N, R;
	vector<pii> X, Y;
	scanf("%d%d", &R, &N);
	pii A = pii(-R, 0), B = pii(R, 0);
	for (int i = 1; i <= N; i++) {
		for (int j = 0; j < 2; j++) scanf("%d", ord[i] + j);
		if (ord[i][0] != 2) scanf("%d", ord[i] + 2);
		if (ord[i][0] == 1) {
			D[++sz] = pii(ord[i][1], ord[i][2]);
			X.push_back(D[sz] - A);
			Y.push_back(D[sz] - B);
		}
	}
	sort(X.begin(), X.end(), cw);
	sort(Y.begin(), Y.end(), cw);
	auto V = [](vector<pii> &X, pii x) {
		return lower_bound(X.begin(), X.end(), x, cw) - X.begin() + 1;
	};

	for (int i = 1; i <= N; i++) {
		int o = ord[i][0], x = ord[i][1], y = ord[i][2];
		if (o == 1) {
			int a = V(X, pii(x, y) - A), b = V(Y, pii(x, y) - B);
			add_point(a, b);
		}
		else if(o == 2){
			int a = V(X, D[x] - A), b = V(Y, D[x] - B);
			erase_point(a, b);
		}
		else {
			int a = V(X, D[x] - A), b = V(Y, D[x] - B);
			int p = V(X, D[y] - A), q = V(Y, D[y] - B);
			int u = max(a, p), v = min(b, q);
			erase_point(a, b);
			erase_point(p, q);
			if (X[u-1] * Y[v-1] >= 0 && !solve(u, v)) printf("YES\n");
			else printf("NO\n");
			add_point(a, b);
			add_point(p, q);
		}
	}
	return 0;
}
/*
5 8
1 -5 8
1 -4 8
1 -3 8
1 3 7
3 1 3
2 2
3 1 3
3 3 4
*/

#include <bits/stdc++.h>
using namespace std;

#define ms(s, n) memset(s, n, sizeof(s))
#define FOR(i, a, b) for (int i = (a); i < (b); i++)
#define FORd(i, a, b) for (int i = (a) - 1; i >= (b); i--)
#define FORall(it, a) for (__typeof((a).begin()) it = (a).begin(); it != (a).end(); it++)
#define sz(a) int((a).size())
#define present(t, x) (t.find(x) != t.end())
#define all(a) (a).begin(), (a).end()
#define uni(a) (a).erase(unique(all(a)), (a).end())
#define pb push_back
#define pf push_front
#define mp make_pair
#define fi first
#define se second
#define prec(n) fixed<<setprecision(n)
#define bit(n, i) (((n) >> (i)) & 1)
#define bitcount(n) __builtin_popcountll(n)
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef pair<int, int> pi;
typedef vector<int> vi;
typedef vector<pi> vii;
const int MOD = (int) 1e9 + 7;
const int MOD2 = 1007681537;
const int INF = (int) 1e9;
const ll LINF = (ll) 1e18;
const ld PI = acos((ld) -1);
const ld EPS = 1e-9;
inline ll gcd(ll a, ll b) {ll r; while (b) {r = a % b; a = b; b = r;} return a;}
inline ll lcm(ll a, ll b) {return a / gcd(a, b) * b;}
inline ll fpow(ll n, ll k, int p = MOD) {ll r = 1; for (; k; k >>= 1) {if (k & 1) r = r * n % p; n = n * n % p;} return r;}
template<class T> inline int chkmin(T& a, const T& val) {return val < a ? a = val, 1 : 0;}
template<class T> inline int chkmax(T& a, const T& val) {return a < val ? a = val, 1 : 0;}
inline ll isqrt(ll k) {ll r = sqrt(k) + 1; while (r * r > k) r--; return r;}
inline ll icbrt(ll k) {ll r = cbrt(k) + 1; while (r * r * r > k) r--; return r;}
inline void addmod(int& a, int val, int p = MOD) {if ((a = (a + val)) >= p) a -= p;}
inline void submod(int& a, int val, int p = MOD) {if ((a = (a - val)) < 0) a += p;}
inline int mult(int a, int b, int p = MOD) {return (ll) a * b % p;}
inline int inv(int a, int p = MOD) {return fpow(a, p - 2, p);}
inline int sign(ld x) {return x < -EPS ? -1 : x > +EPS;}
inline int sign(ld x, ld y) {return sign(x - y);}
#define db(x) cerr << #x << " = " << (x) << " ";
#define endln cerr << "\n";

const int maxn = 5e5 + 5;
int n, d, k;
int op[maxn];
int x[maxn];
int y[maxn];
int z[maxn];
int l[maxn];
int r[maxn];
int a[maxn];
int b[maxn];

long long ff1(int i, int j) {
    int x1 = x[i] + d;
    int y1 = y[i] + 0;
    int x2 = x[j] + d;
    int y2 = y[j] + 0;
    return (long long) x1 * y2 - (long long) x2 * y1;
}

long long ff2(int i, int j) {
    int x1 = x[i] - d;
    int y1 = y[i] - 0;
    int x2 = x[j] - d;
    int y2 = y[j] - 0;
    return (long long) x1 * y2 - (long long) x2 * y1;
}

int cmp1(int i, int j) {
    long long cr = ff1(i, j);
    if (cr) return cr > 0;
    return i < j;
}

int cmp2(int i, int j) {
    long long cr = ff2(i, j);
    if (cr) return cr > 0;
    return i < j;
}

set<int> heap[maxn];
int st[maxn << 1];
void upd(int p, int n, int val) {
    for (st[p += n] = val; p > 1; ) p >>= 1, st[p] = min(st[p << 1], st[p << 1 | 1]);
}
int query(int l, int r, int n) {
    int res = INF;
    for (l += n, r += n + 1; l < r; l >>= 1, r >>= 1) {
        if (l & 1) chkmin(res, st[l++]);
        if (r & 1) chkmin(res, st[--r]);
    }
    return res;
}

void upd(int u, int n) {
    int val = sz(heap[u]) ? *heap[u].begin() : INF;
    upd(u, n, val);
}

long long dot(pi a, pi b) {
    return (long long) a.fi * b.fi + (long long) a.se * b.se;
}

void solve() {
    cin >> d >> n;
    FOR(i, 0, n) {
        cin >> op[i];
        if (op[i] == 1) {
            cin >> x[k] >> y[k], k++;
        }
        else if (op[i] == 2) {
            cin >> z[i], z[i]--;
        }
        else {
            cin >> l[i] >> r[i], l[i]--, r[i]--;
        }
    }
    vi ver; FOR(i, 0, k) ver.pb(i);
    sort(all(ver), cmp1);
    int st1 = 0;
    FOR(i, 0, k) {
        if (i && ff1(ver[i - 1], ver[i])) st1++;
        a[ver[i]] = st1;
    }
    FOR(i, 0, k) a[i] = st1 - a[i];
    int st2 = 0;
    sort(all(ver), cmp2);
    FOR(i, 0, k) {
        if (i && ff2(ver[i - 1], ver[i])) st2++;
        b[ver[i]] = st2;
    }
    FOR(i, 0, k + k) st[i] = INF;
    k = 0;
    FOR(i, 0, n) {
        if (op[i] == 1) {
            heap[a[k]].insert(b[k]);
            upd(a[k], st1 + 1);
            k++;
        }
        else if (op[i] == 2) {
            int ix = z[i];
            heap[a[ix]].erase(b[ix]);
            upd(a[ix], st1 + 1);
        }
        else {
            int ix1 = l[i];
            int ix2 = r[i];
            int u = max(a[ix1], a[ix2]);
            int v = max(b[ix1], b[ix2]);
            pi p, q;
            if (a[ix1] > a[ix2]) {
                p = mp(x[ix1] + d, y[ix1]);
            }
            else {
                p = mp(x[ix2] + d, y[ix2]);
            }
            if (b[ix1] > b[ix2]) {
                q = mp(x[ix1] - d, y[ix1]);
            }
            else {
                q = mp(x[ix2] - d, y[ix2]);
            }
            heap[a[ix1]].erase(b[ix1]);
            upd(a[ix1], st1 + 1);
            heap[a[ix2]].erase(b[ix2]);
            upd(a[ix2], st1 + 1);
            if (dot(p, q) < 0 || query(0, u, st1 + 1) <= v) {
                cout << "NO\n";
            }
            else {
                cout << "YES\n";
            }
            heap[a[ix1]].insert(b[ix1]);
            upd(a[ix1], st1 + 1);
            heap[a[ix2]].insert(b[ix2]);
            upd(a[ix2], st1 + 1);
        }
    }
}

int main() {
    ios_base::sync_with_stdio(0), cin.tie(0);
    solve();
    return 0;
}

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

const int N = 1 << 19;

struct pt {
    int x, y;

    pt() {}
    pt(int _x, int _y) : x(_x), y(_y) {}

    pt operator- (const pt &p) const {
        return pt(x - p.x, y - p.y);
    }

    ll operator* (const pt &p) const {
        return 1LL * x * p.y - 1LL * y * p.x;
    }

    ll operator% (const pt &p) const {
        return 1LL * x * p.x + 1LL * y * p.y;
    }

    bool operator< (const pt &p) const {
        if (x != p.x) return x < p.x;
        return y < p.y;
    }

    bool operator== (const pt &p) const {
        return x == p.x && y == p.y;
    }
};

void print(vector<string> a) {
    for (string s : a) {
        printf("%s\n", s.c_str());
    }
}

struct segtree {
    int N;
    vector<int> t;

    segtree(int n) {
        N = 1;
        while (N < n) N <<= 1;
        t.assign(2 * N, -1);
    }

    void upd(int x, int y) {
        x += N;
        t[x] = y;
        while (x > 1) {
            x >>= 1;
            t[x] = max(t[x * 2], t[x * 2 + 1]);
        }
    }

    int get(int l, int r) {
        int res = -1;
        l += N;
        r += N;
        while (l <= r) {
            if (l & 1) res = max(res, t[l]);
            if (!(r & 1)) res = max(res, t[r]);
            l = (l + 1) >> 1;
            r = (r - 1) >> 1;
        }
        return res;
    }
};

vector<string> solve(vector<pair<int, pair<int, int> > > a, int r) {
    vector<pt> pts;
    for (int i = 0; i < (int)a.size(); i++) {
        if (a[i].first == 1) {
            pts.push_back(pt(a[i].second.first, a[i].second.second));
        }
    }
    sort(pts.begin(), pts.end());
    pts.resize(unique(pts.begin(), pts.end()) - pts.begin());

    vector<pt> p(2);
    vector<vector<pt> > b(2);
    vector<function<bool(const pt&, const pt&)> > cmp(2), cmpe(2);
    p[0] = pt(-r, 0);
    p[1] = pt(+r, 0);

    cmp[0] = [&](const pt &x, const pt &y) {
        return ((x - p[0]) * (y - p[0])) > 0;
    };
    cmp[1] = [&](const pt &x, const pt &y) {
        return ((x - p[1]) * (y - p[1])) < 0;
    };
    for (int i = 0; i < 2; i++) {
        b[i] = pts;
        cmpe[i] = [&](const pt &x, const pt &y) {
            return ((x - p[i]) * (y - p[i])) == 0;
        };
        sort(b[i].begin(), b[i].end(), cmp[i]);
        b[i].resize(unique(b[i].begin(), b[i].end(), cmpe[i]) - b[i].begin());

    }
    int m = pts.size();
    vector<pair<int, int> > c(m);
    for (int i = 0; i < m; i++) {
        c[i].first = lower_bound(b[0].begin(), b[0].end(), pts[i], cmp[0]) - b[0].begin();
        c[i].second = lower_bound(b[1].begin(), b[1].end(), pts[i], cmp[1]) - b[1].begin();
    }

    vector<pair<pair<int, int>, int> > vv;
    for (int i = 0; i < m; i++) {
        vv.push_back({c[i], i});
    }
    sort(vv.begin(), vv.end());
    vector<int> o(m);
    for (int i = 0; i < m; i++) o[vv[i].second] = i;

    segtree t(m);
    vector<char> alive(m);
    auto toggle = [&](int id) {
        if (alive[id]) t.upd(o[id], -1);
        else t.upd(o[id], c[id].second);
        alive[id] ^= 1;
    };
    vector<int> id(1, -1);
    vector<string> ans;
    for (auto o : a) {
        if (o.first == 1) {
            pt cur = pt(o.second.first, o.second.second);
            int cid = lower_bound(pts.begin(), pts.end(), cur) - pts.begin();
            assert(pts[cid] == cur);
            id.push_back(cid);
            toggle(cid);
        }
        if (o.first == 2) {
            int q = o.second.first;
            assert(alive[id[q]]);
            toggle(id[q]);
        }
        if (o.first == 3) {
            int u = id[o.second.first];
            int v = id[o.second.second];
            assert(u != v && alive[u] && alive[v]);
            toggle(u);
            toggle(v);
            pair<int, int> qq = {min(c[u].first, c[v].first), min(c[u].second, c[v].second)};
            int fr = lower_bound(vv.begin(), vv.end(), make_pair(make_pair(qq.first, -1), -1)) - vv.begin();
            bool ok = t.get(fr, m - 1) < qq.second && ((pts[u] - p[0]) % (pts[v] - p[1])) >= 0 && ((pts[u] - p[1]) % (pts[v] - p[0])) >= 0;
            ans.push_back(ok ? "YES" : "NO");
            toggle(u);
            toggle(v);
        }
    }
    return ans;
}

int main() {
#ifdef HOME
    freopen("in", "r", stdin);
#endif
    int r, n;
    scanf("%d%d", &r, &n);
    vector<pair<int, pair<int, int> > > a(n);
    for (int i = 0; i < n; i++) {
        scanf("%d%d", &a[i].first, &a[i].second.first);
        if (a[i].first != 2) scanf("%d", &a[i].second.second);
    }
    print(solve(a, r));
}

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
#define ll long long
#define l(a) (a<<1)
#define r(a) (a<<1|1)
#define MN 500005
#define MD 1100005
using namespace std;
struct vec
{
	int x,y;
	friend ll operator/(const vec& a,const vec& b)
	{
		return 1LL*a.x*b.y-1LL*a.y*b.x;
	}
	friend ll operator*(const vec& a,const vec& b)
	{
		return 1LL*a.x*b.x+1LL*a.y*b.y;
	}
};
struct meg{
	int g,x,y;
}a[MN];
struct met{
	vec v;
	int pos;
}b0[MN],b1[MN];
struct its{
	int x,y;
}s[MN];
struct itv{
	vec x,y;
}d[MN];
struct Que{
	priority_queue <int> A,B;
	void push(int x){A.push(x);}
	void dele(int x){B.push(x);}
	int top()
	{
		while(!B.empty()&&A.top()==B.top())A.pop(),B.pop();
		if(!A.empty())return A.top(); else return 0;
	}
}q[MN];
int m,MQ,tin,b0in,b1in,ra,t[MD];
inline int read()
{
	int n=0,f=1; char c=getchar();
	while(c<'0' || c>'9')
	{
		if(c=='-')f=-1;
		c=getchar();
	}
	while(c>='0' && c<='9')
	{
		n=n*10+c-'0';
		c=getchar();
	}
	return n*f;
}
inline void getcg(int x,int z)
{
	for(t[x+=MQ]=z,x>>=1;x;x>>=1)t[x]=max(t[l(x)],t[r(x)]);
}
inline int getmax(int L,int R)
{
	int sum=0;
	for(L+=MQ,R+=MQ;L<=R;L>>=1,R>>=1)
	{
		if( L&1)sum=max(sum,t[L++]);
		if(~R&1)sum=max(sum,t[R--]);
	}
	return sum;
}
void cghp(int x,int y,int g)
{
	int lt=q[x].top();
	if(g==1)q[x].push(y);
	else q[x].dele(y);
	if(lt!=q[x].top())getcg(x,q[x].top());
}
bool check(int x,int y)
{
	int cs1,cs2;
	if(s[x].x>s[y].x)cs1=x;
	else cs1=y;
	if(s[x].y<s[y].y)cs2=x;
	else cs2=y;
	if(d[cs2].y*d[cs1].x<0)return true;
	else return false;
}
bool cmp(const met& a,const met& b)
{
	return a.v/b.v>0;
}
int main()
{
	register int i,x,y;
	ra=read();
	m=read();
	for(i=1;i<=m;++i)
	{
		a[i].g=read();
		if(a[i].g==1)
		{
			x=read();
			y=read();
			a[i].x=++tin;
			d[tin].x.x=x-ra;
			d[tin].x.y=y;
			d[tin].y.x=x+ra;
			d[tin].y.y=y;
			b0[++b0in]=(met){d[tin].x,tin};
			b1[++b1in]=(met){d[tin].y,tin};
		}
		else if(a[i].g==2)a[i].x=read();
		else if(a[i].g==3)a[i].x=read(),a[i].y=read();
	}
	sort(b0+1,b0+b0in+1,cmp); sort(b1+1,b1+b1in+1,cmp);
	b0[0].pos=b1[0].pos=s[0].x=s[0].y=0;
	for(i=1;i<=b0in;++i)
	if(i>1&&b0[i-1].v/b0[i].v==0)s[b0[i].pos].x=s[b0[i-1].pos].x;
	else s[b0[i].pos].x=s[b0[i-1].pos].x+1;
	for(i=1;i<=b1in;++i)
	if(i>1&&b1[i-1].v/b1[i].v==0)s[b1[i].pos].y=s[b1[i-1].pos].y;
	else s[b1[i].pos].y=s[b1[i-1].pos].y+1;
	b0in=s[b0[b0in].pos].x;
	for(MQ=1;MQ<b0in;MQ<<=1);
	--MQ;
	for(i=1;i<=m;++i)
	{
		if(a[i].g<3)cghp(s[a[i].x].x,s[a[i].x].y,a[i].g);
		else if(a[i].g==3)
		{
			if(check(a[i].x,a[i].y))
			{
				puts("NO");
				continue;
			}
			x=max(s[a[i].x].x,s[a[i].y].x); y=min(s[a[i].x].y,s[a[i].y].y);
			cghp(s[a[i].x].x,s[a[i].x].y,2);
			cghp(s[a[i].y].x,s[a[i].y].y,2);
			if(getmax(1,x)>=y)puts("NO");
			else puts("YES");
			cghp(s[a[i].x].x,s[a[i].x].y,1);
			cghp(s[a[i].y].x,s[a[i].y].y,1);
		}
	}
	return 0;
}

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <memory.h>
#include <math.h>
#include <assert.h>
#include <stack>
#include <queue>
#include <map>
#include <set>
#include <string>
#include <algorithm>
#include <iostream>
#include <functional>
#include <unordered_set>
#include <bitset>
#include <time.h>
#include <limits.h>

using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
#define Fi first
#define Se second
#define pb(x) push_back(x)
#define szz(x) (int)x.size()
#define rep(i,n) for(int i=0;i<n;i++)
#define all(x) x.begin(),x.end()
typedef tuple<int, int, int> t3;

int R, N;
int L;
pii q[500050];
vector <t3> P;
vector <t3> query;
pii Lx[500050];

int T[1<<20]; const int ADD = 1<<19;
set <int> Sx[500050], Sy[500050];

void Ins(int x, int y) {
	Sx[x].insert(y);
	Sy[y].insert(x);
	T[x+ADD] = *Sx[x].begin(); x = (x + ADD) >> 1;
	while(x) T[x] = min(T[x<<1], T[x<<1|1]), x >>= 1;
}
void Del(int x, int y) {
	Sx[x].erase(y);
	Sy[y].erase(x);
	int v = (szz(Sx[x]) ? *Sx[x].begin() : 1e9);
	T[x+ADD] = v; x = (x + ADD) >> 1;
	while(x) T[x] = min(T[x<<1], T[x<<1|1]), x >>= 1;
}

int read_t(int l, int r) {
	l += ADD, r += ADD;
	int res = 1e9;
	while(l <= r) {
		if(l & 1) res = min(res, T[l++]);
		if(!(r & 1)) res = min(res, T[r--]);
		l >>= 1, r >>= 1;
	}
	return res;
}

int del_x, del_y;
int Query(int x, int y) {
	int xv = max(Lx[x].Fi, Lx[y].Fi);
	int yv = max(Lx[x].Se, Lx[y].Se);
	del_x = 0, del_y = 0;
	if(Lx[x].Fi < Lx[y].Fi && Lx[x].Se < Lx[y].Se) del_x = 1;
	if(Lx[y].Fi < Lx[x].Fi && Lx[y].Se < Lx[x].Se) del_y = 1;
	if(del_x) Del(Lx[x].Fi, Lx[x].Se);
	if(del_y) Del(Lx[y].Fi, Lx[y].Se);
	if(read_t(1, xv - 1) <= yv - 1) return 0;
	int w1 = -1, w2 = -1;
	if(Lx[x].Fi == xv) w1 = Lx[x].Se;
	if(Lx[y].Fi == xv) w2 = Lx[y].Se;
	for(auto it=Sx[xv].begin();it!=Sx[xv].end();++it) {
		if(*it > yv) break;
		if(*it != w1 && *it != w2) return 0;
	}
	w1 = w2 = -1;
	if(Lx[x].Se == yv) w1 = Lx[x].Fi;
	if(Lx[y].Se == yv) w2 = Lx[y].Fi;
	for(auto it=Sy[yv].begin();it!=Sy[yv].end();++it) {
		if(*it > xv) break;
		if(*it != w1 && *it != w2) return 0;
	}

	pii v1, v2;
	if(Lx[x].Fi >= Lx[y].Fi) v1 = pii(q[x].Fi + R, q[x].Se);
	else v1 = pii(q[y].Fi + R, q[y].Se);
	if(Lx[x].Se >= Lx[y].Se) v2 = pii(q[x].Fi - R, q[x].Se);
	else v2 = pii(q[y].Fi - R, q[y].Se);
	if((ll)v1.Fi * v2.Fi + (ll)v1.Se * v2.Se >= 0) return 1;
	return 0;
}

int main() {
	scanf("%d%d", &R, &N);
	for(int i=1;i<=N;i++) {
		int cmd; scanf("%d", &cmd);
		if(cmd == 1) {
			int x, y; scanf("%d%d", &x, &y);
			P.pb(t3(x, y, ++L));
			q[L] = pii(x, y);
			query.pb(t3(1, L, -1));
		}
		else if(cmd == 2) {
			int x; scanf("%d", &x);
			query.pb(t3(2, x, -1));
		}
		else {
			int x, y; scanf("%d%d", &x, &y);
			query.pb(t3(3, x, y));
		}
	}
	int xz = 1, yz = 1;
	auto comp = [&](const t3 &a, const t3 &b) {
		return (ll)(get<0>(a)+R) * get<1>(b) - (ll)get<1>(a) * (get<0>(b)+R) < 0;
	};
	sort(all(P), comp);
	for(int i=0;i<szz(P);i++) {
		Lx[get<2>(P[i])].Fi = xz;
		if(i < szz(P)-1 && comp(P[i], P[i+1])) ++xz;
	}
	auto comp2 = [&](const t3 &a, const t3 &b) {
		return (ll)(get<0>(a)-R) * get<1>(b) - (ll)get<1>(a) * (get<0>(b)-R) > 0;
	};
	sort(all(P), comp2);
	for(int i=0;i<szz(P);i++) {
		Lx[get<2>(P[i])].Se = yz;
		if(i < szz(P)-1 && comp2(P[i], P[i+1])) ++yz;
	}

	rep(i, 1<<20) T[i] = 1e9;
//	for(int i=1;i<=L;i++) printf("%d %d\n", Lx[i].Fi, Lx[i].Se);

	for(t3 e : query) {
		int cmd, x, y;
		tie(cmd, x, y) = e;
		if(cmd == 1) {
			int xv = Lx[x].Fi, yv = Lx[x].Se;
			Ins(xv, yv);
		}
		else if(cmd == 2) {
			int xv = Lx[x].Fi, yv = Lx[x].Se;
			Del(xv, yv);
		}
		else {
			int v = Query(x, y);
			if(del_x) Ins(Lx[x].Fi, Lx[x].Se);
			if(del_y) Ins(Lx[y].Fi, Lx[y].Se);

			printf("%s\n", v ? "YES" : "NO");
		}
	}

	return 0;
}

#include<cstdio>
#include<algorithm>
#include<queue>
using namespace std;
inline int read()
{
	int x,f=1;char c;
	while((c=getchar())<'0'||c>'9')if(c=='-')f=0;
	for(x=c-'0';(c=getchar())>='0'&&c<='9';)x=x*10+c-'0';
	return f?x:-x;
}
#define MN 500000
#define N 524288
#define mp(x,y) make_pair(x,y)
struct vec
{
	int x,y,z;
	friend bool operator<(const vec&a,const vec&b)
		{return a.z||(!b.z&&1LL*a.x*b.y<1LL*a.y*b.x);}
	friend bool operator==(const vec&a,const vec&b){return 1LL*a.x*b.y==1LL*a.y*b.x;}
}l[MN+5],r[MN+5],c[MN+5],T[N*2+5];
priority_queue< pair<vec,int> > p[MN+5];
int cnt,u[MN+5],t[MN+5],x[MN+5],y[MN+5],lp[MN+5];
void change(int k,const vec&x){for(T[k+=N]=x;k>>=1;)T[k]=max(T[k<<1],T[k<<1|1]);}
vec query(int l,int r)
{
	vec res=(vec){0,0,1};
	for(l+=N-1,r+=N+1;l^r^1;l>>=1,r>>=1)
	{
		if(~l&1)res=max(res,T[l+1]);
		if( r&1)res=max(res,T[r-1]);
	}
	return res;
}
void ins(int x)
{
	int k=lp[x]?lp[x]:lp[x]=lower_bound(c+1,c+cnt+1,l[x])-c;
	u[x]=0;p[k].push(mp(r[x],x));
	if(p[k].top()==mp(r[x],x))change(k,r[x]);
}
void del(int x)
{
	int k=lp[x]?lp[x]:lp[x]=lower_bound(c+1,c+cnt+1,l[x])-c,s=0;
	for(u[x]=1;u[p[k].top().second];++s)p[k].pop();
	if(s)change(k,p[k].top().first);
}
int main()
{
	int R=read(),n=read(),i,k;
	for(i=1;i<=n;++i)
	{
		t[i]=read();x[i]=read();if(t[i]!=2)y[i]=read();
		if(t[i]==1)++cnt,c[cnt]=l[cnt]=(vec){x[i]+R,y[i]},r[cnt]=(vec){y[i],R-x[i]},x[i]=cnt;
	}
	sort(c+1,c+cnt+1);cnt=unique(c+1,c+cnt+1)-c-1;
	for(i=1;i<2*N;++i)T[i]=(vec){0,0,1};
	for(i=1;i<=cnt;++i)p[i].push(mp(T[1],0));
	for(i=1;i<=n;++i)
	{
		if(t[i]==1)ins(x[i]);
		if(t[i]==2)del(x[i]);
		if(t[i]==3)
		{
			if(l[y[i]]<l[x[i]])swap(x[i],y[i]);
			if(r[x[i]]<l[y[i]]){puts("NO");continue;}
			k=lp[y[i]]?lp[y[i]]:lp[y[i]]=lower_bound(c+1,c+cnt+1,l[y[i]])-c;
			del(x[i]);del(y[i]);
			puts(query(1,k)<(r[x[i]]<r[y[i]]?r[x[i]]:r[y[i]])?"YES":"NO");
			ins(x[i]);ins(y[i]);
		}
	}
}//hello

#include <bits/stdc++.h>
using namespace std;

typedef pair<int, int> pii;
typedef long long ll;
typedef vector<int> vi;

#define pb push_back
#define eb emplace_back
#define mp make_pair
#define fi first
#define se second
#define rep(i,n) rep2(i,0,n)
#define rep2(i,m,n) for(int i=m;i<(n);i++)
#define ALL(c) (c).begin(),(c).end()

const int SZ = 1 << 19;

struct segtree {
	vector<int> dat;

	void init() {
		dat.resize(SZ * 2);
		rep(i, SZ * 2) dat[i] = -1;
	}

	void update(int pos, int x) {
		pos += SZ - 1;
		dat[pos] = x;

		while (pos > 0) {
			pos = (pos - 1) / 2;
			dat[pos] = max(dat[pos * 2 + 1], dat[pos * 2 + 2]);
		}
	}

	int get(int a, int b, int k = 0, int l = 0, int r = SZ) {
		if (b <= l || r <= a) return INT_MIN;
		if (a <= l && r <= b) return dat[k];
		return max(get(a, b, k * 2 + 1, l, (l + r) / 2), get(a, b, k * 2 + 2, (l + r) / 2, r));
	}
} seg;

typedef pair<ll, ll> pll;

pll norm(const pll& a)
{
	ll x = a.fi, y = a.se;
	if (x == 0) y = 1;
	else {
		ll d = __gcd(abs(x), y);
		x /= d; y /= d;
	}
	return mp(x, y);
}

bool cmp(const pll& a, const pll& b)
{
	return (a.fi * b.se - b.fi * a.se) > 0LL;
}

int n, R;
pii ang[500010];
multiset<int> ps[500010];

void add(pii p)
{
	ps[p.fi].insert(p.se);
	seg.update(p.fi, *ps[p.fi].rbegin());
}

void del(pii p)
{
	ps[p.fi].erase(ps[p.fi].lower_bound(p.se));
	if (ps[p.fi].size() == 0) {
		seg.update(p.fi, -1);
	} else {
		seg.update(p.fi, *ps[p.fi].rbegin());
	}
}

int main() {
	scanf("%d %d", &R, &n);
	vector<pair<int, pii>> vec(n);
	vector<pll> vl, vr;

	rep(i, n) {
		int tp;
		scanf("%d", &tp);
		if (tp == 1) {
			int x, y;
			scanf("%d %d", &x, &y);

			vl.pb(mp(x + R, y));
			vr.pb(mp(-(x - R), y));
			vec[i] = mp(1, mp(x, y));
		} else if (tp == 2) {
			int id;
			scanf("%d", &id);
			--id;
			vec[i] = mp(2, mp(id, -1));
		} else {
			int p, q;
			scanf("%d %d", &p, &q); --p; --q;
			vec[i] = mp(3, mp(p, q));
		}
	}

	rep(i, vl.size()) vl[i] = norm(vl[i]);
	rep(i, vr.size()) vr[i] = norm(vr[i]);

	sort(ALL(vl), cmp);
	sort(ALL(vr), cmp);

	int now = 0;
	seg.init();

	for (auto tt : vec) {
		if (tt.fi == 1) {
			ll x = tt.se.fi, y = tt.se.se;

			pll ul = norm(mp(x + R, y));
			pll ur = norm(mp(-(x - R), y));

			int angl = upper_bound(ALL(vl), ul, cmp) - vl.begin() - 1;
			int angr = upper_bound(ALL(vr), ur, cmp) - vr.begin() - 1;
			//cout << angl << " " << angr << endl;
			ang[now] = mp(angl, angr);
			add(ang[now]);
			++now;
		} else if (tt.fi == 2) {
			int id = tt.se.fi;
			del(ang[id]);
		} else {
			int p = tt.se.fi, q = tt.se.se;
			int angl = min(ang[p].fi, ang[q].fi);
			int angr = min(ang[p].se, ang[q].se);
			bool in = (vl[angl].fi * vr[angr].fi - vl[angl].se * vr[angr].se > 0LL);
			if (in) {
				puts("NO");
				continue;
			}
			del(ang[p]);
			del(ang[q]);
			int mx = seg.get(angl, vl.size());
			if (mx >= angr) {
				puts("NO");
			} else {
				puts("YES");
			}
			add(ang[p]);
			add(ang[q]);
		}
	}

	return 0;
}

#include <bits/stdc++.h>
using namespace std;

typedef pair<int, int> pii;
typedef long long ll;
typedef vector<int> vi;

#define pb push_back
#define eb emplace_back
#define mp make_pair
#define fi first
#define se second
#define rep(i,n) rep2(i,0,n)
#define rep2(i,m,n) for(int i=m;i<(n);i++)
#define ALL(c) (c).begin(),(c).end()

const int SZ = 1 << 19;

struct segtree {
	vector<int> dat;

	void init() {
		dat.resize(SZ * 2);
		rep(i, SZ * 2) dat[i] = -1;
	}

	void update(int pos, int x) {
		pos += SZ - 1;
		dat[pos] = x;

		while (pos > 0) {
			pos = (pos - 1) / 2;
			dat[pos] = max(dat[pos * 2 + 1], dat[pos * 2 + 2]);
		}
	}

	int get(int a, int b, int k = 0, int l = 0, int r = SZ) {
		if (b <= l || r <= a) return INT_MIN;
		if (a <= l && r <= b) return dat[k];
		return max(get(a, b, k * 2 + 1, l, (l + r) / 2), get(a, b, k * 2 + 2, (l + r) / 2, r));
	}
} seg;

typedef pair<ll, ll> pll;

pll norm(const pll& a)
{
	ll x = a.fi, y = a.se;
	if (x == 0) y = 1;
	else {
		ll d = __gcd(abs(x), y);
		x /= d; y /= d;
	}
	return mp(x, y);
}

bool cmp(const pll& a, const pll& b)
{
	return (a.fi * b.se - b.fi * a.se) > 0LL;
}

int n, R;
pii ang[500010];
multiset<int> ps[500010];

void add(pii p)
{
	ps[p.fi].insert(p.se);
	seg.update(p.fi, *ps[p.fi].rbegin());
}

void del(pii p)
{
	ps[p.fi].erase(ps[p.fi].lower_bound(p.se));
	if (ps[p.fi].size() == 0) {
		seg.update(p.fi, -1);
	} else {
		seg.update(p.fi, *ps[p.fi].rbegin());
	}
}

int main() {
	scanf("%d %d", &R, &n);
	vector<pair<int, pii>> vec(n);
	vector<pll> vl, vr;

	rep(i, n) {
		int tp;
		scanf("%d", &tp);
		if (tp == 1) {
			int x, y;
			scanf("%d %d", &x, &y);

			vl.pb(mp(x + R, y));
			vr.pb(mp(-(x - R), y));
			vec[i] = mp(1, mp(x, y));
		} else if (tp == 2) {
			int id;
			scanf("%d", &id);
			--id;
			vec[i] = mp(2, mp(id, -1));
		} else {
			int p, q;
			scanf("%d %d", &p, &q); --p; --q;
			vec[i] = mp(3, mp(p, q));
		}
	}

	rep(i, vl.size()) vl[i] = norm(vl[i]);
	rep(i, vr.size()) vr[i] = norm(vr[i]);

	sort(ALL(vl), cmp);
	sort(ALL(vr), cmp);

	int now = 0;
	seg.init();

	for (auto tt : vec) {
		if (tt.fi == 1) {
			ll x = tt.se.fi, y = tt.se.se;

			pll ul = norm(mp(x + R, y));
			pll ur = norm(mp(-(x - R), y));

			int angl = upper_bound(ALL(vl), ul, cmp) - vl.begin() - 1;
			int angr = upper_bound(ALL(vr), ur, cmp) - vr.begin() - 1;
			//cout << angl << " " << angr << endl;
			ang[now] = mp(angl, angr);
			add(ang[now]);
			++now;
		} else if (tt.fi == 2) {
			int id = tt.se.fi;
			del(ang[id]);
		} else {
			int p = tt.se.fi, q = tt.se.se;
			int angl = min(ang[p].fi, ang[q].fi);
			int angr = min(ang[p].se, ang[q].se);
			bool in = (vl[angl].fi * vr[angr].fi - vl[angl].se * vr[angr].se > 0LL);
			if (in) {
				puts("NO");
				continue;
			}
			del(ang[p]);
			del(ang[q]);
			int mx = seg.get(angl, vl.size());
			if (mx >= angr) {
				puts("NO");
			} else {
				puts("YES");
			}
			add(ang[p]);
			add(ang[q]);
		}
	}

	return 0;
}//hello

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef long double DB;
const int maxn = 500001, INF = 0x3f3f3f3f;
int rad, n, totL, totR;
struct Query {
	int typ, x, y;
} que[maxn];
struct Fraction {
	LL x, y;
	Fraction() {}
	Fraction(LL _x, LL _y) { // _y > 0
		LL r = __gcd(abs(_x), _y);
		x = _x / r;
		y = _y / r;
	}
	bool operator == (Fraction const &t) const {
		return x == t.x && y == t.y;
	}
	bool operator < (Fraction const &t) const {
		return (DB)x * t.y < (DB)t.x * y;
	}
} pL[maxn], pR[maxn], seqL[maxn], seqR[maxn];
int cnt, idx[maxn], ord[maxn], pos[maxn], seg[maxn << 1 | 1];
inline int seg_idx(int L, int R) {
	return (L + R) | (L < R);
}
void seg_upd(int L, int R, int x, int v) {
	int rt = seg_idx(L, R);
	if(L == R) {
		seg[rt] = v;
		return;
	}
	int M = (L + R) >> 1, lch = seg_idx(L, M), rch = seg_idx(M + 1, R);
	if(x <= M)
		seg_upd(L, M, x, v);
	else
		seg_upd(M + 1, R, x, v);
	seg[rt] = min(seg[lch], seg[rch]);
}
int seg_que(int L, int R, int l, int r) {
	if(l <= L && R <= r)
		return seg[seg_idx(L, R)];
	int M = (L + R) >> 1, ret = INF;
	if(l <= M)
		ret = min(ret, seg_que(L, M, l, r));
	if(M < r)
		ret = min(ret, seg_que(M + 1, R, l, r));
	return ret;
}
inline int sgn(int x) {
	return (x > 0) - (x < 0);
}
inline LL sqr(int x) {
	return (LL)x * x;
}
bool cmp(int const &u, int const &v) {
	return que[u].x < que[v].x;
}
int main() {
	scanf("%d%d", &rad, &n);
	for(int i = 1; i <= n; ++i) {
		int &typ = que[i].typ, &x = que[i].x, &y = que[i].y;
		scanf("%d%d", &typ, &x);
		if(typ != 2)
			scanf("%d", &y);
		if(typ != 1)
			continue;
		LL A = sqr(rad + x), B = sqr(rad - x), C = sqr(y);
		seqL[++totL] = pL[i] = Fraction(sgn(rad + x) * A, A + C);
		seqR[++totR] = pR[i] = Fraction(sgn(rad - x) * B, B + C);
	}
	sort(seqL + 1, seqL + totL + 1);
	totL = unique(seqL + 1, seqL + totL + 1) - seqL - 1;
	sort(seqR + 1, seqR + totR + 1);
	totR = unique(seqR + 1, seqR + totR + 1) - seqR - 1;
	for(int i = 1; i <= n; ++i) {
		int &typ = que[i].typ, &x = que[i].x, &y = que[i].y;
		if(typ == 1) {
			int px = x, py = y;
			x = lower_bound(seqL + 1, seqL + totL + 1, pL[i]) - seqL;
			y = lower_bound(seqR + 1, seqR + totR + 1, pR[i]) - seqR;
			pL[i] = px >= -rad ? Fraction(sqr(px + rad) - sqr(py), sqr(px + rad) + sqr(py)) : Fraction(-1, 1);
			pR[i] = px <= rad ? Fraction(sqr(py) - sqr(px - rad), sqr(px - rad) + sqr(py)) : Fraction(1, 1);
			ord[++cnt] = i;
			idx[cnt] = i;
		}
	}
	sort(ord + 1, ord + cnt + 1, cmp);
	for(int i = 1; i <= cnt; ++i)
		pos[ord[i]] = i;
	static bool vis[maxn] = {};
	memset(seg + 1, 0x3f, (cnt << 1) * sizeof(int));
	for(int i = 1; i <= n; ++i) {
		int &typ = que[i].typ, &x = que[i].x, &y = que[i].y;
		if(typ == 1) {
			vis[i] = 1;
			// printf("ins %d: %d %d\n", pos[i], que[i].x, que[i].y);
			seg_upd(1, cnt, pos[i], que[i].y);
		} else if(typ == 2) {
			x = idx[x];
			assert(vis[x] == 1);
			// printf("rem %d: %d %d\n", pos[x], que[x].x, que[x].y);
			seg_upd(1, cnt, pos[x], INF);
			vis[x] = 0;
		} else {
			x = idx[x], y = idx[y];
			assert(vis[x] == 1 && vis[y] == 1);
			// printf("ask (%d, %d) (%d, %d)\n", que[x].x, que[x].y, que[y].x, que[y].y);
			if(min(pR[x], pR[y]) < max(pL[x], pL[y])) {
				puts("NO");
				continue;
			}
			int A = max(que[x].x, que[y].x), B = max(que[x].y, que[y].y);
			seg_upd(1, cnt, pos[x], INF);
			seg_upd(1, cnt, pos[y], INF);
			que[0] = (Query){0, A};
			int id = upper_bound(ord + 1, ord + cnt + 1, 0, cmp) - ord - 1;
			// printf("query [%d, %d]\n", 1, id);
			puts(seg_que(1, cnt, 1, id) > B ? "YES" : "NO");
			seg_upd(1, cnt, pos[x], que[x].y);
			seg_upd(1, cnt, pos[y], que[y].y);
		}
	}
	return 0;
}

// WRONG

#include <bits/stdc++.h>
#ifndef ONLINE_JUDGE
# include <sys/time.h>
# include <sys/resource.h>
#endif

/*** TEMPLATE CODE STARTS HERE ***/

#ifndef M_PI
#define M_PI 3.1415926535897932384626433832795028841971693993751
#endif

using namespace std;

typedef vector<string> vs;
typedef long long ll;
typedef vector<ll> vi;
typedef pair<ll, ll> pii;

#define RA(x) begin(x), end(x)
#define FE(i, x) for (auto i = begin(x); i != end(x); ++i)
#define SZ(x) ((int) (x).size())

template<class T>
void splitstr(const string &s, vector<T> &out)
{
    istringstream in(s);
    out.clear();
    copy(istream_iterator<T>(in), istream_iterator<T>(), back_inserter(out));
}

template<class T> T gcd(T a, T b) { return b ? gcd(b, a % b) : a; }

static void redirect(int argc, const char **argv)
{
#ifndef ONLINE_JUDGE
    struct rlimit rlim;
    getrlimit(RLIMIT_STACK, &rlim);
    rlim.rlim_cur = 256 * 1024 * 1024;
    setrlimit(RLIMIT_STACK, &rlim);
    getrlimit(RLIMIT_DATA, &rlim);
    rlim.rlim_cur = 256 * 1024 * 1024;
    setrlimit(RLIMIT_DATA, &rlim);
#endif

    ios::sync_with_stdio(false);
    cin.tie(NULL);
    if (argc > 1)
    {
        static filebuf f;
        f.open(argv[1], ios::in);
        cin.rdbuf(&f);
        if (!cin)
        {
            cerr << "Failed to open '" << argv[1] << "'" << endl;
            exit(1);
        }
    }

    if (argc > 2)
    {
        static filebuf f;
        f.open(argv[2], ios::out | ios::trunc);
        cout.rdbuf(&f);
        if (!cout)
        {
            cerr << "Failed to open '" << argv[2] << "'" << endl;
        }
    }
}

typedef std::complex<ll> pnt;

static inline ll dot(const pnt &a, const pnt &b)
{
    return real(conj(a) * b);
}

static inline ll cross(const pnt &a, const pnt &b)
{
    return imag(conj(a) * b);
}

static inline ll cross(const pnt &a, const pnt &b, const pnt &c)
{
    return cross(b - a, c - a);
}

class CompareAngle
{
private:
    const pnt base;

public:
    explicit CompareAngle(const pnt &base) : base(base) {}

    bool operator()(const pnt &a, const pnt &b) const
    {
        return cross(base, a, b) > 0;
    }
};

template<typename T, typename Op = std::plus<T>>
class SegTree
{
    typedef std::size_t size_type;

    T identity;
    Op op;
    std::vector<T> nodes;

public:
    explicit SegTree(std::size_t n = 0, const T &identity = T(), const Op &op = Op())
        : identity(identity), op(op), nodes(2 * n, this->identity)
    {
        for (int i = n - 1; i > 0; i--)
            nodes[i] = this->op(nodes[2 * i], nodes[2 * i + 1]);
    }

    template<typename Iterator>
    SegTree(Iterator first, Iterator last, const T &identity = T(), const Op &op = Op())
        : identity(identity), op(op)
    {
        size_type n = std::distance(first, last);
        nodes.reserve(2 * n);
        nodes.resize(n, this->identity);
        nodes.insert(nodes.end(), first, last);
        for (int i = n - 1; i > 0; i--)
            nodes[i] = this->op(nodes[2 * i], nodes[2 * i + 1]);
    }

    size_type size() const { return nodes.size() / 2;}

    void set(size_type idx, T value)
    {
        assert(0 <= idx && idx < size());
        idx += size();
        nodes[idx] = std::move(value);
        while (idx > 0)
        {
            idx /= 2;
            nodes[idx] = op(nodes[2 * idx], nodes[2 * idx + 1]);
        }
    }

    const T &operator[](size_type idx) const
    {
        assert(0 <= idx && idx < size());
        return nodes[idx + size()];
    }

    T query(size_type a, size_type b) const
    {
        assert(0 <= a && a <= size());
        assert(0 <= b && b <= size());
        a += size();
        b += size();
        T left = identity, right = identity;
        while (a < b)
        {
            if (a & 1)
                left = op(left, nodes[a++]);
            if (b & 1)
                right = op(nodes[--b], right);
            a /= 2;
            b /= 2;
        }
        return op(left, right);
    }
};

/*** TEMPLATE CODE ENDS HERE */

typedef pair<int, int> sample;

struct opmin
{
    sample operator()(const sample &a, const sample &b) const { return min(a, b); }
};

struct event
{
    int t;
    int x, y;
};

static bool cut_within(const pnt &a, const pnt &p, const pnt &b, const pnt &q)
{
    pnt dp = p - a;
    pnt dq = q - b;
    return dot(dp, dq) < 0;
}

int main(int argc, const char **argv)
{
    redirect(argc, argv);
    ll R, N;
    cin >> R >> N;
    vector<event> events;
    vector<pnt> pnts;
    for (int i = 0; i < N; i++)
    {
        int t;
        cin >> t;
        if (t == 1)
        {
            int x, y;
            cin >> x >> y;
            events.push_back(event{1, SZ(pnts), -1});
            pnts.emplace_back(x, y);
        }
        else if (t == 2)
        {
            int idx;
            cin >> idx;
            idx--;
            events.push_back(event{2, idx, -1});
        }
        else
        {
            int a, b;
            cin >> a >> b;
            events.push_back(event{3, a - 1, b - 1});
        }
    }

    pnt A(-R, 0);
    pnt B(R, 0);
    int P = SZ(pnts);
    vector<int> byA(P);
    for (int i = 0; i < P; i++)
        byA[i] = i;
    auto byB = byA;
    CompareAngle cmpA(A);
    CompareAngle cmpB(B);
    sort(RA(byA), [&](int a, int b) { return cmpA(pnts[b], pnts[a]); });
    sort(RA(byB), [&](int a, int b) { return cmpB(pnts[a], pnts[b]); });
    vector<pair<int, int>> rank(P);

    rank[byA[0]].first = 0;
    int nxt = 0;
    for (int i = 1; i < P; i++)
    {
        if (cmpA(pnts[byA[i]], pnts[byA[i - 1]]))
            nxt++;
        rank[byA[i]].first = nxt;
    }
    int NA = nxt + 1;

    rank[byB[0]].second = 0;
    nxt = 0;
    for (int i = 1; i < P; i++)
    {
        if (cmpB(pnts[byB[i - 1]], pnts[byB[i]]))
            nxt++;
        rank[byB[i]].second = nxt;
    }

    vector<set<pair<int, int>>> line(NA);
    for (int i = 0; i < NA; i++)
        line[i].emplace(INT_MAX, INT_MAX);
    auto get_sample = [&](int row) { return *line[row].begin(); };
    SegTree<sample, opmin> seg(NA, get_sample(0));

    auto add = [&](int idx)
    {
        auto r = rank[idx];
        line[r.first].emplace(r.second, idx);
        seg.set(r.first, get_sample(r.first));
    };
    auto remove = [&](int idx)
    {
        auto r = rank[idx];
        line[r.first].erase(line[r.first].find(make_pair(r.second, idx)));
        seg.set(r.first, get_sample(r.first));
    };
    for (const event &ev : events)
    {
        if (ev.t == 1)
            add(ev.x);
        else if (ev.t == 2)
            remove(ev.x);
        else
        {
            pnt p = cross(A, pnts[ev.x], pnts[ev.y]) >= 0 ? pnts[ev.x] : pnts[ev.y];
            pnt q = cross(B, pnts[ev.x], pnts[ev.y]) >= 0 ? pnts[ev.y] : pnts[ev.x];
            bool good = true;
            if (cut_within(A, p, B, q))
                good = false;
            else
            {
                int ar = max(rank[ev.x].first, rank[ev.y].first);
                int br = max(rank[ev.x].second, rank[ev.y].second);
                remove(ev.x);
                remove(ev.y);
                sample samp = seg.query(0, ar + 1);
                if (samp.first <= br)
                    good = false;
                add(ev.x);
                add(ev.y);
            }
            cout << (good ? "YES\n" : "NO\n");
        }
    }

    return 0;
}

#include<cstdio>
#include<algorithm>
#include<queue>
using namespace std;
inline int read()
{
	int x,f=1;char c;
	while((c=getchar())<'0'||c>'9')if(c=='-')f=0;
	for(x=c-'0';(c=getchar())>='0'&&c<='9';)x=x*10+c-'0';
	return f?x:-x;
}
#define MN 500000
#define N 524288
#define mp(x,y) make_pair(x,y)
struct vec
{
	int x,y,z;
	friend bool operator<(const vec&a,const vec&b)
		{return a.z||(!b.z&&1LL*a.x*b.y<1LL*a.y*b.x);}
	friend bool operator==(const vec&a,const vec&b){return 1LL*a.x*b.y==1LL*a.y*b.x;}
}l[MN+5],r[MN+5],c[MN+5],T[N*2+5];
priority_queue< pair<vec,int> > p[MN+5];
int cnt,u[MN+5],t[MN+5],x[MN+5],y[MN+5],lp[MN+5];
void change(int k,const vec&x){for(T[k+=N]=x;k>>=1;)T[k]=max(T[k<<1],T[k<<1|1]);}
vec query(int l,int r)
{
	vec res=(vec){0,0,1};
	for(l+=N-1,r+=N+1;l^r^1;l>>=1,r>>=1)
	{
		if(~l&1)res=max(res,T[l+1]);
		if( r&1)res=max(res,T[r-1]);
	}
	return res;
}
void ins(int x)
{
	int k=lp[x]?lp[x]:lp[x]=lower_bound(c+1,c+cnt+1,l[x])-c;
	u[x]=0;p[k].push(mp(r[x],x));
	if(p[k].top()==mp(r[x],x))change(k,r[x]);
}
void del(int x)
{
	int k=lp[x]?lp[x]:lp[x]=lower_bound(c+1,c+cnt+1,l[x])-c,s=0;
	for(u[x]=1;u[p[k].top().second];++s)p[k].pop();
	if(s)change(k,p[k].top().first);
}
int main()
{
	int R=read(),n=read(),i,k;
	for(i=1;i<=n;++i)
	{
		t[i]=read();x[i]=read();if(t[i]!=2)y[i]=read();
		if(t[i]==1)++cnt,c[cnt]=l[cnt]=(vec){x[i]+R,y[i]},r[cnt]=(vec){y[i],R-x[i]},x[i]=cnt;
	}
	sort(c+1,c+cnt+1);cnt=unique(c+1,c+cnt+1)-c-1;
	for(i=1;i<2*N;++i)T[i]=(vec){0,0,1};
	for(i=1;i<=cnt;++i)p[i].push(mp(T[1],0));
	for(i=1;i<=n;++i)
	{
		if(t[i]==1)ins(x[i]);
		if(t[i]==2)del(x[i]);
		if(t[i]==3)
		{
			if(l[y[i]]<l[x[i]])swap(x[i],y[i]);
			if(r[x[i]]<l[y[i]]){puts("NO");continue;}
			k=lp[y[i]]?lp[y[i]]:lp[y[i]]=lower_bound(c+1,c+cnt+1,l[y[i]])-c;
			del(x[i]);del(y[i]);
			puts(query(1,k)<(r[x[i]]<r[y[i]]?r[x[i]]:r[y[i]])?"YES":"NO");
			ins(x[i]);ins(y[i]);
		}
	}
}

#include<cstdio>
#include<algorithm>
using namespace std;
char B[1<<26],*S=B;
inline int read()
{
	int x,f=1;char c;
	while((c=*S++)<'0'||c>'9')if(c=='-')f=0;
	for(x=c-'0';(c=*S++)>='0'&&c<='9';)x=x*10+c-'0';
	return f?x:-x;
}
#define MN 500000
#define N 524288
struct vec
{
	int x,y;
	friend bool operator<(const vec&a,const vec&b){return 1LL*a.x*b.y<1LL*a.y*b.x;}
	friend bool operator==(const vec&a,const vec&b){return 1LL*a.x*b.y==1LL*a.y*b.x;}
};
vec rot(const vec&a){return (vec){a.y,-a.x};}
struct work{int t,z;vec x,y;}w[MN+5],q[MN+5];
bool cmp(const work&a,const work&b){return a.x==b.x?a.t>b.t:a.x<b.x;}
vec l[MN+5],r[MN+5],c[MN+5];
int cnt,ans[MN+5],t[N*2+5],qn,sa[MN+5],sb[MN+5];
void add(int k,int x){for(k+=N;k;k>>=1)t[k]+=x;}
int query(int l,int r)
{
	int res=0;
	for(l+=N-1,r+=N+1;l^r^1;l>>=1,r>>=1)
	{
		if(~l&1)res+=t[l+1];
		if( r&1)res+=t[r-1];
	}
	return res;
}
void solve(int l,int r)
{
	int mid=l+r>>1,i;
	if(l<r)solve(l,mid),solve(mid+1,r);
	if(sa[mid]==sa[l-1]||sb[r]==sb[mid])return;
	for(qn=0,i=l;i<=mid;++i)if(w[i].t>0)q[++qn]=w[i];
	for(;i<=r;++i)if(!w[i].t)q[++qn]=w[i];
	sort(q+1,q+qn+1,cmp);
	for(i=1;i<=qn;++i)
		if(q[i].t)add(lower_bound(c+1,c+cnt+1,q[i].y)-c,q[i].z);
		else ans[q[i].z]+=query(lower_bound(c+1,c+cnt+1,q[i].y)-c,cnt);
	for(i=1;i<=qn;++i)if(q[i].t)add(lower_bound(c+1,c+cnt+1,q[i].y)-c,-q[i].z);
}
int main()
{
	B[fread(B,1,1<<26,stdin)]=0;
	int R=read(),n=read(),i,t,x,y;
	for(i=1;i<=n;++i)
	{
		t=read();x=read();sa[i]=sa[i-1];sb[i]=sb[i-1];
		if(t==1)
		{
			l[++cnt]=(vec){x+R,y=read()};
			c[cnt]=r[cnt]=(vec){x-R,y};
			w[i]=(work){1,1,l[cnt],r[cnt]},++sa[i];
		}
		if(t==2)w[i]=(work){1,-1,l[x],r[x]},++sa[i];
		if(t==3)
		{
			if(l[y=read()]<l[x])x^=y^=x^=y;
			if(rot(r[x])<l[y])w[i]=(work){-1,0,0,0},ans[i]=3;
			else w[i]=(work){0,i,l[y],r[x]<r[y]?r[x]:r[y]},++sb[i];
		}
	}
	sort(c+1,c+cnt+1);cnt=unique(c+1,c+cnt+1)-c-1;solve(1,n);
	for(i=1;i<=n;++i)if(ans[i])puts(ans[i]>2?"NO":"YES");
}

#include <bits/stdc++.h>
#define SZ(X) ((int)(X).size())
#define ALL(X) (X).begin(), (X).end()
#define REP(I, N) for (int I = 0; I < (N); ++I)
#define REPP(I, A, B) for (int I = (A); I < (B); ++I)
#define RI(X) scanf("%d", &(X))
#define RII(X, Y) scanf("%d%d", &(X), &(Y))
#define RIII(X, Y, Z) scanf("%d%d%d", &(X), &(Y), &(Z))
#define DRI(X) int (X); scanf("%d", &X)
#define DRII(X, Y) int X, Y; scanf("%d%d", &X, &Y)
#define DRIII(X, Y, Z) int X, Y, Z; scanf("%d%d%d", &X, &Y, &Z)
#define RS(X) scanf("%s", (X))
#define CASET int ___T, case_n = 1; scanf("%d ", &___T); while (___T-- > 0)
#define MP make_pair
#define PB push_back
#define MS0(X) memset((X), 0, sizeof((X)))
#define MS1(X) memset((X), -1, sizeof((X)))
#define LEN(X) strlen(X)
#define PII pair<int,int>
#define VI vector<int>
#define VL vector<long long>
#define VPII vector<pair<int,int> >
#define PLL pair<long long,long long>
#define VPLL vector<pair<long long,long long> >
#define F first
#define S second
typedef long long LL;
using namespace std;
const int INF = 1e9+7;
const int SIZE = 1e6+10;
int R,N;
int in[SIZE][3];
PII R_R[SIZE];
VPII pp;
bool cmp(PII x,PII y){
    if((x.S>=0)!=(y.S>=0)){
        return x.S<y.S;
    }
    return (LL)x.F*y.S-(LL)x.S*y.F>0;
}
PII sat[SIZE],ll[SIZE],rr[SIZE];
int sid;
int my_gcd(int x,int y){
    x=abs(x);y=abs(y);
    if(!x||!y)return x+y;
    return __gcd(x,y);
}
PII get_left(int x,int y){
    x+=R;
    int gg=my_gcd(x,y);
    x/=gg;
    y/=gg;
    return MP(x,y);
}
PII get_right(int x,int y){
    x-=R;
    int gg=my_gcd(x,y);
    x/=gg;
    y/=gg;
    if(x<=0)return MP(y,-x);
    return MP(y,-x);
}
int mi[SIZE*4];
multiset<int>ker[SIZE*2];
void ins(int L,int R,int id,int x,int v){
    if(L==R){
        mi[id]=v;
        return;
    }
    int mm=(L+R)/2;
    if(x<=mm)ins(L,mm,id*2,x,v);
    else ins(mm+1,R,id*2+1,x,v);
    mi[id]=min(mi[id*2],mi[id*2+1]);

}
int qq(int L,int R,int id,int x,int y){
    if(L>y||R<x)return INF;
    if(L>=x&&R<=y){
        return mi[id];
    }
    int mm=(L+R)/2;
    return min(qq(L,mm,id*2,x,y),qq(mm+1,R,id*2+1,x,y));
}
int main(){
    sid=0;
    RII(R,N);
    REP(i,N){
        RII(in[i][0],in[i][1]);
        if(in[i][0]!=2)RI(in[i][2]);
        if(in[i][0]==1){
            int x=in[i][1];
            int y=in[i][2];
            sid++;
            ll[sid]=get_left(x,y),rr[sid]=get_right(x,y);
            pp.PB(ll[sid]);
            pp.PB(rr[sid]);
            in[i][1]=sid;
        }
    }
    sort(ALL(pp),cmp);
    pp.resize(unique(ALL(pp))-pp.begin());
    map<PII,int>get_id;
    REP(i,SZ(pp))get_id[pp[i]]=i+1;
    REPP(i,1,sid+1)R_R[i]=MP(get_id[rr[i]],get_id[ll[i]]);
    memset(mi,0x7f,sizeof(mi));
    REP(i,N){
        if(in[i][0]==1){
            ker[R_R[in[i][1]].S].insert(R_R[in[i][1]].F);
            ins(1,sid*2,1,R_R[in[i][1]].S,*ker[R_R[in[i][1]].S].begin());
        }
        else if(in[i][0]==2){
            ker[R_R[in[i][1]].S].erase(ker[R_R[in[i][1]].S].find(R_R[in[i][1]].F));
            int v=1e9;
            if(ker[R_R[in[i][1]].S].begin()!=ker[R_R[in[i][1]].S].end())v=*ker[R_R[in[i][1]].S].begin();
            ins(1,sid*2,1,R_R[in[i][1]].S,v);
        }
        else{
            int x=max(R_R[in[i][1]].F,R_R[in[i][2]].F);
            int y=min(R_R[in[i][1]].S,R_R[in[i][2]].S);
            if(x>y)puts("NO");
            else{

                ker[R_R[in[i][1]].S].erase(ker[R_R[in[i][1]].S].find(R_R[in[i][1]].F));
                int v=1e9;
                if(ker[R_R[in[i][1]].S].begin()!=ker[R_R[in[i][1]].S].end())v=*ker[R_R[in[i][1]].S].begin();
                ins(1,sid*2,1,R_R[in[i][1]].S,v);

                ker[R_R[in[i][2]].S].erase(ker[R_R[in[i][2]].S].find(R_R[in[i][2]].F));
                v=1e9;
                if(ker[R_R[in[i][2]].S].begin()!=ker[R_R[in[i][2]].S].end())v=*ker[R_R[in[i][2]].S].begin();
                ins(1,sid*2,1,R_R[in[i][2]].S,v);

                int res=qq(1,sid*2,1,y,sid*2);
                if(res>x)puts("YES");
                else puts("NO");
                ker[R_R[in[i][1]].S].insert(R_R[in[i][1]].F);
                ins(1,sid*2,1,R_R[in[i][1]].S,*ker[R_R[in[i][1]].S].begin());
                ker[R_R[in[i][2]].S].insert(R_R[in[i][2]].F);
                ins(1,sid*2,1,R_R[in[i][2]].S,*ker[R_R[in[i][2]].S].begin());
            }
        }
    }
    return 0;
}

#include<cstdio>
#include<algorithm>
#include<queue>
using namespace std;
inline int read()
{
	int x,f=1;char c;
	while((c=getchar())<'0'||c>'9')if(c=='-')f=0;
	for(x=c-'0';(c=getchar())>='0'&&c<='9';)x=x*10+c-'0';
	return f?x:-x;
}
#define MN 500000
#define N 524288
#define mp(x,y) make_pair(x,y)
struct vec
{
	int x,y,z;
	friend bool operator<(const vec&a,const vec&b)
		{return a.z||(!b.z&&1LL*a.x*b.y<1LL*a.y*b.x);}
	friend bool operator==(const vec&a,const vec&b){return 1LL*a.x*b.y==1LL*a.y*b.x;}
}l[MN+5],r[MN+5],c[MN+5],T[N*2+5];
priority_queue< pair<vec,int> > p[MN+5];
int cnt,u[MN+5],t[MN+5],x[MN+5],y[MN+5],lp[MN+5];
void change(int k,const vec&x){for(T[k+=N]=x;k>>=1;)T[k]=max(T[k<<1],T[k<<1|1]);}
vec query(int l,int r)
{
	vec res=(vec){0,0,1};
	for(l+=N-1,r+=N+1;l^r^1;l>>=1,r>>=1)
	{
		if(~l&1)res=max(res,T[l+1]);
		if( r&1)res=max(res,T[r-1]);
	}
	return res;
}
void ins(int x)
{
	int k=lp[x]?lp[x]:lp[x]=lower_bound(c+1,c+cnt+1,l[x])-c;
	u[x]=0;p[k].push(mp(r[x],x));
	if(p[k].top()==mp(r[x],x))change(k,r[x]);
}
void del(int x)
{
	int k=lp[x]?lp[x]:lp[x]=lower_bound(c+1,c+cnt+1,l[x])-c,s=0;
	for(u[x]=1;u[p[k].top().second];++s)p[k].pop();
	if(s)change(k,p[k].top().first);
}
int main()
{
	int R=read(),n=read(),i,k;
	for(i=1;i<=n;++i)
	{
		t[i]=read();x[i]=read();if(t[i]!=2)y[i]=read();
		if(t[i]==1)++cnt,c[cnt]=l[cnt]=(vec){x[i]+R,y[i]},r[cnt]=(vec){y[i],R-x[i]},x[i]=cnt;
	}
	sort(c+1,c+cnt+1);cnt=unique(c+1,c+cnt+1)-c-1;
	for(i=1;i<2*N;++i)T[i]=(vec){0,0,1};
	for(i=1;i<=cnt;++i)p[i].push(mp(T[1],0));
	for(i=1;i<=n;++i)
	{
		if(t[i]==1)ins(x[i]);
		if(t[i]==2)del(x[i]);
		if(t[i]==3)
		{
			if(l[y[i]]<l[x[i]])swap(x[i],y[i]);
			if(r[x[i]]<l[y[i]]){puts("NO");continue;}
			k=lp[y[i]]?lp[y[i]]:lp[y[i]]=lower_bound(c+1,c+cnt+1,l[y[i]])-c;
			del(x[i]);del(y[i]);
			puts(query(1,k)<(r[x[i]]<r[y[i]]?r[x[i]]:r[y[i]])?"YES":"NO");
			ins(x[i]);ins(y[i]);
		}
	}
}//hello//hello

#include<cstdio>
#include<algorithm>
#include<queue>
using namespace std;
inline int read()
{
int x,f=1;char c;
while((c=getchar())<'0'||c>'9')if(c=='-')f=0;
for(x=c-'0';(c=getchar())>='0'&&c<='9';)x=x*10+c-'0';
return f?x:-x;
}
#define MN 500000
#define N 524288
#define mp(x,y)make_pair(x,y)
struct vec
{
int x,y,z;
friend bool operator<(const vec&a,const vec&b)
{return a.z||(!b.z&&1LL*a.x*b.y<1LL*a.y*b.x);}
friend bool operator==(const vec&a,const vec&b){return 1LL*a.x*b.y==1LL*a.y*b.x;}
}l[MN+5],r[MN+5],c[MN+5],T[N*2+5];
priority_queue<pair<vec,int>>p[MN+5];
int cnt,u[MN+5],t[MN+5],x[MN+5],y[MN+5],lp[MN+5];
void change(int k,const vec&x){for(T[k+=N]=x;k>>=1;)T[k]=max(T[k<<1],T[k<<1|1]);}
vec query(int l,int r)
{
vec res=(vec){0,0,1};
for(l+=N-1,r+=N+1;l^r^1;l>>=1,r>>=1)
{
if(~l&1)res=max(res,T[l+1]);
if(r&1)res=max(res,T[r-1]);
}
return res;
}
void ins(int x)
{
int k=lp[x]?lp[x]:lp[x]=lower_bound(c+1,c+cnt+1,l[x])-c;
u[x]=0;p[k].push(mp(r[x],x));
if(p[k].top()==mp(r[x],x))change(k,r[x]);
}
void del(int x)
{
int k=lp[x]?lp[x]:lp[x]=lower_bound(c+1,c+cnt+1,l[x])-c,s=0;
for(u[x]=1;u[p[k].top().second];++s)p[k].pop();
if(s)change(k,p[k].top().first);
}
int main()
{
int R=read(),n=read(),i,k;
for(i=1;i<=n;++i)
{
t[i]=read();x[i]=read();if(t[i]!=2)y[i]=read();
if(t[i]==1)++cnt,c[cnt]=l[cnt]=(vec){x[i]+R,y[i]},r[cnt]=(vec){y[i],R-x[i]},x[i]=cnt;
}
sort(c+1,c+cnt+1);cnt=unique(c+1,c+cnt+1)-c-1;
for(i=1;i<2*N;++i)T[i]=(vec){0,0,1};
for(i=1;i<=cnt;++i)p[i].push(mp(T[1],0));
for(i=1;i<=n;++i)
{
if(t[i]==1)ins(x[i]);
if(t[i]==2)del(x[i]);
if(t[i]==3)
{
if(l[y[i]]<l[x[i]])swap(x[i],y[i]);
if(r[x[i]]<l[y[i]]){puts("NO");continue;}
k=lp[y[i]]?lp[y[i]]:lp[y[i]]=lower_bound(c+1,c+cnt+1,l[y[i]])-c;
del(x[i]);del(y[i]);
puts(query(1,k)<(r[x[i]]<r[y[i]]?r[x[i]]:r[y[i]])?"YES":"NO");
ins(x[i]);ins(y[i]);
}
}
}

#include <bits/stdc++.h>
#define xx first
#define yy second
#define mp make_pair
#define pb push_back
#define mset(x, y) memset(x, y, sizeof x)
#define mcpy(x, y) memcpy(x, y, sizeof x)
using namespace std;

typedef long long LL;
typedef pair <int, int> pii;

inline int Read()
{
	int x = 0, f = 1, c = getchar();
	for (; !isdigit(c); c = getchar())
		if (c == '-')
			f = -1;
	for (;  isdigit(c); c = getchar())
		x = x * 10 + c - '0';
	return x * f;
}

const int MAXN = 500005;

struct Node
{
	int opt, x, y;
} e[MAXN];

int n, m, r, tot, x[MAXN], y[MAXN], p[MAXN], q[MAXN], mx[MAXN << 2], rnk[MAXN], pos[MAXN], rot[MAXN];
pii a[MAXN], b[MAXN];

inline bool Cmp(pii u, pii v) { return 1LL * u.xx * v.yy - 1LL * u.yy * v.xx > 0; }

inline void Modify(int x, int l, int r, int p, int v)
{
	if (l == r)
		return (void)(mx[x] = v);
	int mid = l + r >> 1;
	if (p <= mid)
		Modify(x << 1, l, mid, p, v);
	else
		Modify(x << 1 | 1, mid + 1, r, p, v);
	mx[x] = max(mx[x << 1], mx[x << 1 | 1]);
}

inline int Query(int x, int l, int r, int ql, int qr)
{
	if (l == ql && r == qr)
		return mx[x];
	int mid = l + r >> 1;
	if (qr <= mid)
		return Query(x << 1, l, mid, ql, qr);
	if (ql > mid)
		return Query(x << 1 | 1, mid + 1, r, ql, qr);
	return max(Query(x << 1, l, mid, ql, mid), Query(x << 1 | 1, mid + 1, r, mid + 1, qr));
}

int main()
{
#ifdef wxh010910
	freopen("data.in", "r", stdin);
#endif
	r = Read(), m = Read();
	for (int i = 1; i <= m; i ++)
	{
		e[i].opt = Read();
		if (e[i].opt == 1)
			n ++, x[n] = e[i].x = Read(), y[n] = e[i].y = Read();
		else if (e[i].opt == 2)
			e[i].x = Read();
		else
			e[i].x = Read(), e[i].y = Read();
	}
	for (int i = 1; i <= n; i ++)
		a[i] = mp(x[i] + r, y[i]);
	sort(a + 1, a + n + 1, Cmp);
	for (int i = 1; i <= n; i ++)
		p[i] = lower_bound(a + 1, a + n + 1, mp(x[i] + r, y[i]), Cmp) - a;
	for (int i = 1; i <= n; i ++)
		b[i] = mp(r - x[i], y[i]);
	sort(b + 1, b + n + 1, Cmp);
	for (int i = 1; i <= n; i ++)
		q[i] = lower_bound(b + 1, b + n + 1, mp(r - x[i], y[i]), Cmp) - b;
	for (int i = 1; i <= n; i ++)
		pos[i] = i;
	sort(pos + 1, pos + n + 1, [&](int x, int y) { return mp(p[x], q[x]) < mp(p[y], q[y]); });
	for (int i = 1; i <= n; i ++)
		rnk[pos[i]] = i;
	for (int i = 1, cur = 0; i <= m; i ++)
		if (e[i].opt == 1)
			cur ++, Modify(1, 1, n, rnk[cur], q[cur]);
		else if (e[i].opt == 2)
			Modify(1, 1, n, rnk[e[i].x], 0);
		else
		{
			int idx = e[i].x, idy = e[i].y;
			Modify(1, 1, n, rnk[idx], 0);
			Modify(1, 1, n, rnk[idy], 0);
			pii x, y;
			if (Cmp(a[p[idx]], a[p[idy]]))
				x = a[p[idx]];
			else
				x = a[p[idy]];
			if (Cmp(b[q[idx]], b[q[idy]]))
				y = b[q[idx]];
			else
				y = b[q[idy]];
			if (1LL * x.xx * y.xx - 1LL * y.xx * y.yy > 0)
				puts("NO");
			else
			{
				p[n + 1] = lower_bound(a + 1, a + n + 1, x, Cmp) - a;
				q[n + 1] = lower_bound(b + 1, b + n + 1, y, Cmp) - b;
				int t = lower_bound(pos + 1, pos + n + 1, n + 1, [&](int x, int y) { return mp(p[x], q[x]) < mp(p[y], q[y]); }) - pos;
				if (Query(1, 1, n, t, n) >= q[n + 1])
					puts("NO");
				else
					puts("YES");
			}
			Modify(1, 1, n, rnk[idx], q[idx]);
			Modify(1, 1, n, rnk[idy], q[idy]);
		}
}

#include <cstdio>
#include <algorithm>
#include <cstring>
#include <queue>
#include <cmath>
#define ld double
#define l(a) (a<<1)
#define r(a) (a<<1|1)
#define MN 500005
#define MM 1000005
#define MD 4200005
#define eps 1e-13
using namespace std;
struct meg{int g,x,y;}a[MN];
struct itv1{ld x,y;}w[MN];
struct itv2{int x,y;}s[MN];
struct Que
{
	priority_queue <int> A,B;
	void push(int x) {A.push(x);}
	void dele(int x) {B.push(x);}
	int top()
	{
		while (!B.empty()&&A.top()==B.top()) A.pop(),B.pop();
		if (!A.empty()) return A.top(); else return 0;
	}
}q[MM];
ld b0[MM],b1[MM];
int m,MQ,tin,b0in,b1in,ra;
int t[MD];

inline int read()
{
	int n=0,f=1; char c=getchar();
	while (c<'0' || c>'9') {if(c=='-')f=-1; c=getchar();}
	while (c>='0' && c<='9') {n=n*10+c-'0'; c=getchar();}
	return n*f;
}

inline void getcg(int x,int z) {for (t[x+=MQ]=z,x>>=1;x;x>>=1) t[x]=max(t[l(x)],t[r(x)]);}
inline int getmax(int L,int R)
{
	int sum=0;
	for (L+=MQ,R+=MQ;L<=R;L>>=1,R>>=1)
	{
		if ( L&1) sum=max(sum,t[L++]);
		if (~R&1) sum=max(sum,t[R--]);
	}
	return sum;
}

void cghp(int x,int y,int g)
{
	int lt=q[x].top();
	if (g==1) q[x].push(y); else q[x].dele(y);
	if (lt!=q[x].top()) getcg(x,q[x].top());
}

int main()
{
	register int i,x,y,lt=0;
	ra=read(); m=read();
	for (i=1;i<=m;++i)
	{
		a[i].g=read();
		if (a[i].g==1)
		{
			x=read(); y=read(); a[i].x=++tin;
			w[tin].x=atan2(y,x-ra);
			w[tin].y=atan2(y,x+ra);
			b0[++b0in]=w[tin].x;
			b1[++b1in]=w[tin].y;
		}
		else if (a[i].g==2) a[i].x=read();
		else if (a[i].g==3) a[i].x=read(),a[i].y=read();
	}
	sort(b0+1,b0+b0in+1); sort(b1+1,b1+b1in+1);
	for (i=2,lt=0;i<=b0in;++i) {if (b0[i]-b0[i-1]<eps) ++lt; b0[i-lt]=b0[i];} b0in-=lt;
	for (i=2,lt=0;i<=b1in;++i) {if (b1[i]-b1[i-1]<eps) ++lt; b1[i-lt]=b1[i];} b1in-=lt;
	for (i=1;i<=tin;++i)
		s[i].x=lower_bound(b0+1,b0+b0in+1,w[i].x)-b0,
		s[i].y=lower_bound(b1+1,b1+b1in+1,w[i].y)-b1;
	for (MQ=1;MQ<b0in;MQ<<=1); --MQ;
	for (i=1;i<=m;++i)
	{
		if (a[i].g<3) cghp(s[a[i].x].x,s[a[i].x].y,a[i].g);
		else if (a[i].g==3)
		{
			if (max(w[a[i].x].x,w[a[i].y].x)-min(w[a[i].x].y,w[a[i].y].y)>acos(0)+eps) {puts("NO"); continue;}
			x=max(s[a[i].x].x,s[a[i].y].x); y=min(s[a[i].x].y,s[a[i].y].y);
			cghp(s[a[i].x].x,s[a[i].x].y,2);
			cghp(s[a[i].y].x,s[a[i].y].y,2);
			if (getmax(1,x)>=y) puts("NO"); else puts("YES");
			cghp(s[a[i].x].x,s[a[i].x].y,1);
			cghp(s[a[i].y].x,s[a[i].y].y,1);
		}
	}
}

#pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")
#pragma GCC optimize("no-stack-protector")
#pragma GCC target("sse,sse2,ssse3,sse3,sse4,popcnt,avx,mmx,abm,tune=native")
#include <bits/stdc++.h>
#define DEBUG 1
using namespace std;

namespace output{
    void __(short x){cout<<x;}
    void __(unsigned x){cout<<x;}
    void __(int x){cout<<x;}
    void __(long long x){cout<<x;}
    void __(unsigned long long x){cout<<x;}
    void __(double x){cout<<x;}
    void __(long double x){cout<<x;}
    void __(char x){cout<<x;}
    void __(const char*x){cout<<x;}
    void __(const string&x){cout<<x;}
    void __(bool x){cout<<(x?"true":"false");}
    template<class S,class T>
    void __(const pair<S,T>&x){__(DEBUG?"(":""),__(x.first),__(DEBUG?", ":" "),__(x.second),__(DEBUG?")":"");}
    template<class T>
    void __(const vector<T>&x){__(DEBUG?"{":"");bool _=0;for(const auto&v:x)__(_?DEBUG?", ":" ":""),__(v),_=1;__(DEBUG?"}":"");}
    template<class T>
    void __(const set<T>&x){__(DEBUG?"{":"");bool _=0;for(const auto&v:x)__(_?DEBUG?", ":" ":""),__(v),_=1;__(DEBUG?"}":"");}
    template<class T>
    void __(const multiset<T>&x){__(DEBUG?"{":"");bool _=0;for(const auto&v:x)__(_?DEBUG?", ":" ":""),__(v),_=1;__(DEBUG?"}":"");}
    template<class S,class T>
    void __(const map<S,T>&x){__(DEBUG?"{":"");bool _=0;for(const auto&v:x)__(_?DEBUG?", ":" ":""),__(v),_=1;__(DEBUG?"}":"");}
    void pr(){cout<<"\n";}
    template<class S,class... T>
    void pr(const S&a,const T&...b){__(a);if(sizeof...(b))__(' ');pr(b...);}
}

using namespace output;

typedef long long ll;
typedef long double ld;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
typedef pair<int,char> pic;
typedef pair<double,double> pdd;
typedef pair<ld,ld> pld;
typedef vector<int> vi;
typedef vector<ll> vl;

#define pb push_back
#define fox(i,x,y) for(int i=(x);i<=(y);i++)
#define foxr(i,x,y) for(int i=(y);i>=(x);i--)
#define F first
#define S second

const int MN = 5e5+5;
const double PI = (double)acos((double)-1);
int N, R, i, x, y, cnt;
map<double,int> A, B;
double aa[MN], bb[MN];
pii pos[MN];

bool ok(int i,int j){
    double x=max(aa[i],aa[j]);
    double y=min(bb[i],bb[j]);
    return (x+y>=PI/2);
}

int main(){
    scanf("%d%d",&R,&N);
    while(N--){
        scanf("%d",&i);
        if(i==1){
            scanf("%d%d",&x,&y);
            cnt ++;
            pos[cnt] = {x,y};
            aa[cnt] = atan2(y,x+R);
            bb[cnt] = atan2(y,x-R);
            A[aa[cnt]]++;
            B[bb[cnt]]++;
        }
        else if(i==2){
            scanf("%d",&x);
            A[aa[x]]--;
            B[bb[x]]--;
            if(!A[aa[x]]) A.erase(aa[x]);
            if(!B[bb[x]]) B.erase(bb[x]);
        }
        else{
            scanf("%d%d",&x,&y);
            if(aa[x]==aa[y]){
                if(bb[x]>bb[y]) swap(x,y);
                auto it2=B.lower_bound(bb[x]);
                if(A[aa[x]]>2||it2->second!=1) printf("NO\n");
                else{
                    it2++;
                    if(it2==B.end()||it2->second!=1||it2->first!=bb[y]) printf("NO\n");
                    else printf("%s\n",ok(x,y)?"YES":"NO");
                }
                continue;
            }
            if(aa[x]>aa[y]) swap(x,y);
            auto it=A.lower_bound(aa[x]);
            if(it->second!=1) printf("NO\n");
            else{
                it++;
                if(it==A.end()||it->second!=1||it->first!=aa[y]) printf("NO\n");
                else{
                    if(bb[x]==bb[y]){
                        if(B[bb[x]]>2) printf("NO\n");
                        else printf("%s\n",ok(x,y)?"YES":"NO");
                        continue;
                    }
                    if(bb[x]>bb[y]) swap(x,y);
                    auto it2=B.lower_bound(bb[x]);
                    if(it2->second!=1) printf("NO\n");
                    else{
                        it2++;
                        if(it2==B.end()||it2->second!=1||it2->first!=bb[y]) printf("NO\n");
                        else printf("%s\n",ok(x,y)?"YES":"NO");
                    }
                }
            }
        }
    }
}

#include <bits/stdc++.h>
//#include <ext/pb_ds/tree_policy.hpp>
//#include <ext/pb_ds/assoc_container.hpp>
using namespace std;
//using namespace __gnu_pbds;
//template<typename key, typename val>
//using ordered_tree =
//  tree<key, val, greater<>, rb_tree_tag, tree_order_statistics_node_update>;
typedef long long int64;
typedef complex<double> comp;
const double pi = 3.14159265358979323846;
const int inf = (int)1e+9 + 2;
const int64 inf64 = (int64)1e+18 + 2;
const double dinf = 1e+20;
const int mod = /*1'000'000'007;*/998244353;
const int base = 2187;
const double eps = 1e-8;
const int N = 500'000;
const int LOGN = 19;

int n, m, k, R;
vector<pair<int, int>> a;
int t[4 * N];

int64 vec(int64 x1, int64 y1, int64 x2, int64 y2)
{
  return x1 * y2 - x2 * y1;
}

struct cmp
{
  cmp(int d) : d(d) {}

  bool operator()(int i, int j)
  {
    int64 v = vec(a[i].first - d, a[i].second, a[j].first - d, a[j].second);
    if (v < 0)
      return true;
    if (v > 0)
      return false;
    return a[i].second < a[j].second;
  }

  int d;
};

void add(int v, int l, int r, int p, int val)
{
  if (r - l == 1) {
    t[v] = val;
    return;
  }
  int mid = (l + r) / 2;
  if (p < mid)
    add(v * 2 + 1, l, mid, p, val);
  else
    add(v * 2 + 2, mid, r, p, val);
  t[v] = max(t[v * 2 + 1], t[v * 2 + 2]);
}

int get(int v, int l, int r, int ql, int qr)
{
  if (l == ql && r == qr) {
    return t[v];
  }
  int mid = (l + r) / 2;
  if (qr <= mid)
    return get(v * 2 + 1, l, mid, ql, qr);
  if (ql >= mid)
    return get(v * 2 + 2, mid, r, ql, qr);
  return max(get(v * 2 + 1, l, mid, ql, mid),
             get(v * 2 + 2, mid, r, mid, qr));
}

int64 scalar(int64 x1, int64 y1, int64 x2, int64 y2, int64 x3, int64 y3, int64 x4, int64 y4)
{
  return (x2 - x1) * (x4 - x3) + (y2 - y1) * (y4 - y3);
}

void solve(int test)
{
  cin >> R >> n;
  vector<pair<int, int>> q;
  vector<int> ao, bo;
  ao.reserve(n / 2);
  bo.reserve(n / 2);
  int id = 0;
  for (int i = 0; i < n; ++i) {
    int type, x, y;
    cin >> type;
    if (type == 1) {
      cin >> x >> y;
      ao.push_back(id);
      bo.push_back(id);
      a.emplace_back(x, y);
      q.emplace_back(id++, -1);
    }
    else if (type == 2) {
      cin >> x;
      q.emplace_back(x - 1, -2);
    }
    else {
      cin >> x >> y;
      q.emplace_back(x - 1, y - 1);
    }
  }
  sort(ao.begin(), ao.end(), cmp(-R));
  sort(bo.begin(), bo.end(), cmp(R));
  n = (int)ao.size();
  vector<int> ra(n), rb(n);
  for (int i= 0; i < n; ++i) {
    ra[ao[i]] = i;
    rb[bo[i]] = i;
  }
  memset(t, -1, sizeof(t));
  for (auto& pr : q) {
    if (pr.second == -1) {
      add(0, 0, n, ra[pr.first], rb[pr.first]);
    }
    else if (pr.second == -2) {
      add(0, 0, n, ra[pr.first], -1);
    }
    else {
      auto&[x, y] = pr;
      if (ra[x] > ra[y])
        swap(x, y);
      add(0, 0, n, ra[x], -1);
      add(0, 0, n, ra[y], -1);
      size_t off = upper_bound(begin(ao) + y, end(ao), ao[ra[y]], [&] (int i, int j) {
        int64 v = vec(a[i].first + R, a[i].second, a[j].first + R, a[j].second);
        return v <= 0;
      }) - begin(ao);
      int b_max = get(0, 0, n, 0, off);
      int xb = rb[x] < rb[y] ? x : y;
      add(0, 0, n, ra[x], rb[x]);
      add(0, 0, n, ra[y], rb[y]);
      if (b_max < rb[xb] && scalar(-R, 0, a[y].first, a[y].second,
                                   R, 0, a[xb].first, a[xb].second) >= 0)
        cout << "YES\n";
      else
        cout << "NO\n";
    }
  }
}

void precalc()
{
}

int main()
{
  ios::sync_with_stdio(0);
  cin.tie(0), cout.tie(0);
  precalc();
  int test = 1;
  //cin >> test;
  //auto start = chrono::high_resolution_clock::now();
  for (int i = 1; i <= test; ++i)
    solve(i);
  //cerr << chrono::duration_cast<chrono::milliseconds>(chrono::high_resolution_clock::now() - start).count() << '\n';
  return 0;
}

#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#define ll long long
#define ld long double
#define l(a) (a<<1)
#define r(a) (a<<1|1)
#define MN 500005
#define MM 8000005
#define eps 1e-6
using namespace std;
struct meg{int g,x,y;}a[MN];
struct itv1{ld x,y;}w[MN];
struct itv2{int x,y;}s[MN];
ld b[MN<<1];
ll ra;
int m,tin,bin;
int t[MM],tg[MM];

inline int read()
{
	int n=0,f=1; char c=getchar();
	while (c<'0' || c>'9') {if(c=='-')f=-1; c=getchar();}
	while (c>='0' && c<='9') {n=n*10+c-'0'; c=getchar();}
	return n*f;
}

inline void mark(int x,int z) {tg[x]+=z; t[x]+=z;}
inline void down(int x) {if (tg[x]) mark(l(x),tg[x]),mark(r(x),tg[x]),tg[x]=0;}
inline void update(int x) {t[x]=min(t[l(x)],t[r(x)]);}

void getadd(int x,int L,int R,int ql,int qr,int ad)
{
	if (ql==L&&qr==R) {mark(x,ad); return;}
	down(x);
	int mid=L+R>>1;
	if (qr<=mid) getadd(l(x),L,mid,ql,qr,ad);
	else if (ql>mid) getadd(r(x),mid+1,R,ql,qr,ad);
	else getadd(l(x),L,mid,ql,mid,ad),getadd(r(x),mid+1,R,mid+1,qr,ad);
	update(x);
}

int getmin(int x,int L,int R,int ql,int qr)
{
	if (ql==L&&qr==R) return t[x];
	down(x);
	int mid=L+R>>1;
	if (qr<=mid) return getmin(l(x),L,mid,ql,qr);
	else if (ql>mid) return getmin(r(x),mid+1,R,ql,qr);
	else return min(getmin(l(x),L,mid,ql,mid),getmin(r(x),mid+1,R,mid+1,qr));
}

int main()
{
	register int i,x,y,lt=0;
	ll x1,y1,x0,y0;
	ld bi,ki;
	ra=read(); m=read();
	for (i=1;i<=m;++i)
	{
		a[i].g=read();
		if (a[i].g==1)
		{
			x1=read(); y1=read(); a[i].x=++tin;
			x0=ra; y0=0;
			if (x1>=x0) w[tin].x=acos(1);
			else
			{
				ki=(ld)(y1-y0)/(x1-x0);
				bi=(ld)y0-(ld)x0*(y1-y0)/(x1-x0);
				w[tin].x=acos((ld)(bi*bi-ra*ra)/(ki*ki+1)/(ra*ra));
			}
			x0=-ra; y0=0;
			if (x1<=x0) w[tin].y=acos(-1);
			else
			{
				ki=(ld)(y1-y0)/(x1-x0);
				bi=(ld)y0-(ld)x0*(y1-y0)/(x1-x0);
				w[tin].y=acos((ld)(ra*ra-bi*bi)/(ki*ki+1)/(ra*ra));
			}
			b[++bin]=w[tin].x; b[++bin]=w[tin].y;
		}
		else if (a[i].g==2) a[i].x=read();
		else if (a[i].g==3) a[i].x=read(),a[i].y=read();
	}
	sort(b+1,b+bin+1);
	for (i=2;i<=bin;++i)
	{
		if (b[i]-b[i-1]<eps) ++lt;
		b[i-lt]=b[i];
	}
	bin-=lt;
	for (i=1;i<=tin;++i)
		s[i].x=lower_bound(b+1,b+bin+1,w[i].x)-b,
		s[i].y=lower_bound(b+1,b+bin+1,w[i].y)-b;
	for (i=1;i<=m;++i)
	{
			 if (a[i].g==1) getadd(1,1,bin<<1,s[a[i].x].x*2-1,s[a[i].x].y*2-1, 1);
		else if (a[i].g==2) getadd(1,1,bin<<1,s[a[i].x].x*2-1,s[a[i].x].y*2-1,-1);
		else if (a[i].g==3)
		{
			x=max(s[a[i].x].x,s[a[i].y].x);
			y=min(s[a[i].x].y,s[a[i].y].y);
			if (x>y||getmin(1,1,bin<<1,x*2-1,y*2-1)>=3) puts("NO");
			else puts("YES");
		}
	}
}

#include <bits/stdc++.h>
#define SZ(X) ((int)(X).size())
#define ALL(X) (X).begin(), (X).end()
#define REP(I, N) for (int I = 0; I < (N); ++I)
#define REPP(I, A, B) for (int I = (A); I < (B); ++I)
#define RI(X) scanf("%d", &(X))
#define RII(X, Y) scanf("%d%d", &(X), &(Y))
#define RIII(X, Y, Z) scanf("%d%d%d", &(X), &(Y), &(Z))
#define DRI(X) int (X); scanf("%d", &X)
#define DRII(X, Y) int X, Y; scanf("%d%d", &X, &Y)
#define DRIII(X, Y, Z) int X, Y, Z; scanf("%d%d%d", &X, &Y, &Z)
#define RS(X) scanf("%s", (X))
#define CASET int ___T, case_n = 1; scanf("%d ", &___T); while (___T-- > 0)
#define MP make_pair
#define PB push_back
#define MS0(X) memset((X), 0, sizeof((X)))
#define MS1(X) memset((X), -1, sizeof((X)))
#define LEN(X) strlen(X)
#define PII pair<int,int>
#define VI vector<int>
#define VL vector<long long>
#define VPII vector<pair<int,int> >
#define PLL pair<long long,long long>
#define VPLL vector<pair<long long,long long> >
#define F first
#define S second
typedef long long LL;
using namespace std;
const int INF = 1e9+7;
const int SIZE = 1e6+10;
int R,N;
int in[SIZE][3];
PII R_R[SIZE];
VPII pp;
bool cmp(PII x,PII y){
    if((x.S>=0)!=(y.S>=0)){
        return x.F<y.F;
    }
    return (LL)x.F*y.S-(LL)x.S*y.F>0;
}
PII sat[SIZE],ll[SIZE],rr[SIZE];
int sid;
int my_gcd(int x,int y){
    x=abs(x);y=abs(y);
    if(!x||!y)return x+y;
    return __gcd(x,y);
}
PII get_left(int x,int y){
    x+=R;
    int gg=my_gcd(x,y);
    x/=gg;
    y/=gg;
    return MP(x,y);
}
PII get_right(int x,int y){
    x-=R;
    int gg=my_gcd(x,y);
    x/=gg;
    y/=gg;
    if(x<=0)return MP(y,-x);
    return MP(y,-x);
}
int mi[SIZE*4],pb[SIZE*4];
void push(int x){
    if(!pb[x])return;
    REP(i,2){
        mi[x*2+i]+=pb[x];
        pb[x*2+i]+=pb[x];
    }
    pb[x]=0;
}
void ins(int L,int R,int id,int x,int y,int v){
    //if(v==-1)printf("[%d,%d]:%d,%d\n",L,R,mi[id],pb[id]);
    if(R<x||L>y)return;
    if(L>=x&&R<=y){
        mi[id]+=v;
        pb[id]+=v;
        return;
    }
    int mm=(L+R)/2;
    push(id);
    ins(L,mm,id*2,x,y,v);
    ins(mm+1,R,id*2+1,x,y,v);
    mi[id]=min(mi[id*2],mi[id*2+1]);

}
int qq(int L,int R,int id,int x,int y){
    //printf("{%d,%d}:%d,%d\n",L,R,mi[id],pb[id]);
    if(L>y||R<x)return INF;
    if(L>=x&&R<=y){
        return mi[id];
    }
    int mm=(L+R)/2;
    push(id);
    return min(qq(L,mm,id*2,x,y),qq(mm+1,R,id*2+1,x,y));
}
void print(int L,int R,int id){
    printf("{%d,%d}:%d,%d\n",L,R,mi[id],pb[id]);
    if(L==R)return;
    int mm=(L+R)/2;
    print(L,mm,id*2);
    print(mm+1,R,id*2+1);
}
int main(){
    sid=0;
    RII(R,N);
    REP(i,N){
        RII(in[i][0],in[i][1]);
        if(in[i][0]!=2)RI(in[i][2]);
        if(in[i][0]==1){
            int x=in[i][1];
            int y=in[i][2];
            sid++;
            ll[sid]=get_left(x,y),rr[sid]=get_right(x,y);
            pp.PB(ll[sid]);
            pp.PB(rr[sid]);
            in[i][1]=sid;
        }
    }
    sort(ALL(pp),cmp);
    pp.resize(unique(ALL(pp))-pp.begin());
    map<PII,int>get_id;
    REP(i,SZ(pp))get_id[pp[i]]=i+1;
    REPP(i,1,sid+1)R_R[i]=MP(get_id[rr[i]],get_id[ll[i]]);
    //REPP(i,1,sid+1)printf("(%d,%d)\n",R_R[i].F,R_R[i].S);
    REP(i,N){
        //printf("op %d:\n",i);
        if(in[i][0]==1){
            ins(1,sid*4,1,R_R[in[i][1]].F*2,R_R[in[i][1]].S*2,1);
            if(N==500000)printf("(%d,%d)\n",R_R[in[i][1]].F*2,R_R[in[i][1]].S*2);
        }
        else if(in[i][0]==2){
            ins(1,sid*4,1,R_R[in[i][1]].F*2,R_R[in[i][1]].S*2,-1);
            if(N==500000)printf("(%d,%d)\n",R_R[in[i][1]].F*2,R_R[in[i][1]].S*2);
        }
        else{
            int x=max(R_R[in[i][1]].F,R_R[in[i][2]].F);
            int y=min(R_R[in[i][1]].S,R_R[in[i][2]].S);
            if(N==500000)printf("[%d,%d]\n",x*2,y*2);
            if(x>y)puts("NO");
            else{
                if(qq(1,sid*4,1,x*2,y*2)==2)puts("YES");
                else puts("NO");
            }
        }
        //print(1,sid*4,1);
    }
    return 0;
}

#include <cstdio>
#include <algorithm>
#include <cstring>
#include <queue>
#include <cmath>
#define ll long long
#define ld double
#define l(a) (a<<1)
#define r(a) (a<<1|1)
#define MN 500005
#define MM 1000005
#define MD 4200005
#define eps 1e-12
using namespace std;
struct meg{int g,x,y;}a[MN];
struct itv1{ld x,y;}w[MN];
struct itv2{int x,y;}s[MN];
struct Que
{
	priority_queue <int> A,B;
	void push(int x) {A.push(x);}
	void dele(int x) {B.push(x);}
	int top()
	{
		while (!B.empty()&&A.top()==B.top()) A.pop(),B.pop();
		if (!A.empty()) return A.top(); else return 0;
	}
}q[MM];
ld b0[MM],b1[MM];
ll ra;
int m,MQ,tin,b0in,b1in;
int t[MD];

inline int read()
{
	int n=0,f=1; char c=getchar();
	while (c<'0' || c>'9') {if(c=='-')f=-1; c=getchar();}
	while (c>='0' && c<='9') {n=n*10+c-'0'; c=getchar();}
	return n*f;
}

inline void getcg(int x,int z) {for (t[x+=MQ]=z,x>>=1;x;x>>=1) t[x]=max(t[l(x)],t[r(x)]);}
inline int getmax(int L,int R)
{
	int sum=0;
	for (L+=MQ,R+=MQ;L<=R;L>>=1,R>>=1)
	{
		if ( L&1) sum=max(sum,t[L++]);
		if (~R&1) sum=max(sum,t[R--]);
	}
	return sum;
}

void cghp(int x,int y,int g)
{
	int lt=q[x].top();
	if (g==1) q[x].push(y); else q[x].dele(y);
	if (lt!=q[x].top()) getcg(x,q[x].top());
}

int main()
{
	register int i,x,y,lt=0;
	ra=read(); m=read();
	for (i=1;i<=m;++i)
	{
		a[i].g=read();
		if (a[i].g==1)
		{
			x=read(); y=read(); a[i].x=++tin;
			w[tin].x=atan2(y,x-ra);
			w[tin].y=atan2(y,x+ra);
			b0[++b0in]=w[tin].x;
			b1[++b1in]=w[tin].y;
		}
		else if (a[i].g==2) a[i].x=read();
		else if (a[i].g==3) a[i].x=read(),a[i].y=read();
	}
	sort(b0+1,b0+b0in+1); sort(b1+1,b1+b1in+1);
	for (i=2,lt=0;i<=b0in;++i) {if (b0[i]-b0[i-1]<eps) ++lt; b0[i-lt]=b0[i];} b0in-=lt;
	for (i=2,lt=0;i<=b1in;++i) {if (b1[i]-b1[i-1]<eps) ++lt; b1[i-lt]=b1[i];} b1in-=lt;
	for (i=1;i<=tin;++i)
		s[i].x=lower_bound(b0+1,b0+b0in+1,w[i].x)-b0,
		s[i].y=lower_bound(b1+1,b1+b1in+1,w[i].y)-b1;
//	for (i=1;i<=tin;++i) printf("%.6lf %.6lf\n",w[i].x,w[i].y);
	for (MQ=1;MQ<b0in;MQ<<=1); --MQ;
	for (i=1;i<=m;++i)
	{
		if (a[i].g<3) cghp(s[a[i].x].x,s[a[i].x].y,a[i].g);
		else if (a[i].g==3)
		{
			if (max(w[a[i].x].x,w[a[i].y].x)-min(w[a[i].x].y,w[a[i].y].y)>acos(0)-eps) {puts("NO"); continue;}
			x=max(s[a[i].x].x,s[a[i].y].x); y=min(s[a[i].x].y,s[a[i].y].y);
			cghp(s[a[i].x].x,s[a[i].x].y,2);
			cghp(s[a[i].y].x,s[a[i].y].y,2);
			if (getmax(1,x)>=y) puts("NO"); else puts("YES");
			cghp(s[a[i].x].x,s[a[i].x].y,1);
			cghp(s[a[i].y].x,s[a[i].y].y,1);
		}
	}
}

#include<iostream>
#include<cstdlib>
#include<stdio.h>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<vector>
#include<set>
#include<map>
using namespace std;
long long r;
int n,cnt,list[501000],cnt_list,mf[1001000];
struct segment_tree
{
	int l,r,min_vl,lazy;
};
segment_tree tree[1<<21];
struct point
{
	long long x,y;
	bool operator <(const point &temp)const
	{
		  return y*temp.x<x*temp.y;
	}
};
point pt[1000001];
struct query
{
	int u,v,flag,id;
	long long x,y;
	point l,r;
};
query qy[501000];
void build(int left,int right,int id)
{
	int l=2*id+1,r=2*id+2,mid=(left+right)>>1;
	tree[id].min_vl=tree[id].lazy=0;
	tree[id].l=left;
	tree[id].r=right;
	if(left==right)
	    return;
    build(left,mid,l);
    build(mid+1,right,r);
}
void zz(int id)
{
	if(tree[id].lazy==0)
	    return;
	int l=2*id+1,r=2*id+2;
	if(tree[id].l!=tree[id].r)
	{
		tree[l].lazy+=tree[id].lazy;
		tree[r].lazy+=tree[id].lazy;
	}
	tree[id].min_vl+=tree[id].lazy;
	tree[id].lazy=0;
}
void update(int left,int right,int vl,int id)
{
	int l=2*id+1,r=2*id+2;
	if(tree[id].l>right||tree[id].r<left)
	{
	     zz(id);
	     return;
	}
    if(tree[id].l>=left&&tree[id].r<=right)
    {
    	tree[id].lazy+=vl;
    	zz(id);
    	return;
    }
    zz(id);
    update(left,right,vl,l);
    update(left,right,vl,r);
    tree[id].min_vl=min(tree[l].min_vl,tree[r].min_vl);
}
int qw(int left,int right,int id)
{
	int l=2*id+1,r=2*id+2;
	zz(id);
	if(tree[id].l>right||tree[id].r<left)
	    return 1e9+9;
    if(tree[id].l>=left&&tree[id].r<=right)
    	return tree[id].min_vl;
	return min(qw(left,right,l),qw(left,right,r));
}
int binary(int left,int right,point now)
{
	int mid;
	while(left<=right)
	{
		mid=(left+right)>>1;
		if(pt[mid]<now)
			left=mid+1;
		else if(now<pt[mid])
		    right=mid-1;
        else
            return mid;
	}
}
int main()
{
	scanf("%lld%d",&r,&n);
	int i,j,s,p,q,l_id,r_id;
	long long ru;
	cnt=0;
	cnt_list=0;
	for(i=0;i<n;i++)
	{
		scanf("%d",&qy[i].flag);
		if(qy[i].flag==1)
		{
			list[cnt_list++]=i;
            scanf("%lld%lld",&qy[i].x,&qy[i].y);
            pt[cnt].x=qy[i].x-r;
            pt[cnt++].y=qy[i].y;
			qy[i].r=pt[cnt-1];
            pt[cnt].x=qy[i].x+r;
            pt[cnt++].y=qy[i].y;
			qy[i].id=cnt_list-1;
		    qy[i].l=pt[cnt-1];
		}
		else if(qy[i].flag==2)
        {
           scanf("%d",&qy[i].u);
           qy[i].u--;
        }
        else
        {
        	scanf("%d%d",&qy[i].u,&qy[i].v);
        	qy[i].u--;
        	qy[i].v--;
        }
	}
	sort(pt,pt+cnt);
	int nn=0;
	for(i=0;i<cnt;i++)
	{
		if(nn==0||(pt[i].x!=pt[nn-1].x||pt[i].y!=pt[nn-1].y))
		    pt[nn++]=pt[i];
	}
	while(nn!=cnt)
	   puts("orz");
	cnt=nn;
	build(0,cnt-1,0);
	point ll,rr;
	memset(mf,0,sizeof(mf));
	for(i=0;i<n;i++)
	{
		int flag;
		if(qy[i].flag==1)
		{
		   flag=1;
		   ll=qy[i].l;
		   rr=qy[i].r;
		}
		else if(qy[i].flag==2)
		{
			flag=-1;
			ll=qy[list[qy[i].u]].l;
			rr=qy[list[qy[i].u]].r;
		}
		if(qy[i].flag==1||qy[i].flag==2)
		{
    		l_id=binary(0,cnt-1,ll);
    		r_id=binary(0,cnt-1,rr);
    		mf[r_id]+=flag;
    		if(l_id<r_id)
    		   update(l_id,r_id-1,flag,0);
		}
		else
		{
			int id1,id2;
			id1=qy[i].u;
			id2=qy[i].v;
		    ll=qy[list[id1]].l;
		    rr=qy[list[id1]].r;
            if(ll<qy[list[id2]].l)
               ll=qy[list[id2]].l;
            if(qy[list[id2]].r<rr)
               rr=qy[list[id2]].r;
            bool ans;
            if(rr<ll)
               ans=0;
            else
            {
            	l_id=binary(0,cnt-1,ll);
            	r_id=binary(0,cnt-1,rr);
            	ans=(l_id<r_id&&qw(l_id,r_id-1,0)<=2);
    	        ans|=mf[r_id]+qw(r_id,r_id,0)<=2;
            }
            if(ans)
               puts("YES");
            else
               puts("NO");
		}
	}
	return 0;
}
/*

100000000 5
1 -106382777 300000523
1 -75340202 300000165
1 -148918484 300000552
1 96360393 300000458
3 3 2
*/

#include <bits/stdc++.h>

const int MAXN = 500010;
typedef long long LL;
typedef long double db;
typedef LL VT;
struct vec {
	VT x, y;
	vec() { x = y = 0; }
	vec(VT a, VT b) { x = a, y = b; }
	VT operator ^ (vec b) const { return x * b.y - y * b.x; }
	VT operator * (vec b) const { return x * b.x + y * b.y; }
	VT norm2() const { return x * x + y * y; }
	db norm() const { return sqrt(x * x + y * y); }
	vec operator - (vec b) const { return vec(x - b.x, y - b.y); }
	vec operator + (vec b) const { return vec(x + b.x, y + b.y); }
	vec operator * (db k) const { return vec(x * k, y * k); }
	friend bool operator < (const vec & a, const vec & b) {
		return (a ^ b) > 0;
	}
	friend std::istream & operator >> (std::istream & in, vec & x) {
		in >> x.x >> x.y;
		return in;
	}
	friend std::ostream & operator << (std::ostream & out, vec x) {
		out << '(' << x.x << ',' << x.y << ')';
		return out;
	}
} ;
typedef std::pair<vec, int> pi;
int bel[MAXN], lll[MAXN], rrr[MAXN];
int discr(std::vector<pi> v, int * tar) {
	const int L = v.size();
	std::sort(v.begin(), v.end());
	int rnk = 0;
	for (int i = 0; i != L; ++i) {
		if (i != 0 && !(v[i].first < v[i - 1].first || v[i - 1].first < v[i].first)) ;
		else ++rnk;
		bel[tar[v[i].second] = i + 1] = rnk;
		if (!lll[rnk]) lll[rnk] = i + 1;
		rrr[rnk] = i + 1;
	}
	return L;
}
vec ps[MAXN];
int opt[MAXN], xs[MAXN], ys[MAXN];
const int NINF = 0xcfcfcfcf;
int tree[MAXN << 2];
void add(int u, int l, int r, int tar, int v) {
	if (l == r) return (void) (tree[u] = v);
	int mid = l + r >> 1;
	if (tar <= mid) add(u << 1, l, mid, tar, v);
	else add(u << 1 | 1, mid + 1, r, tar, v);
	tree[u] = std::max(tree[u << 1], tree[u << 1 | 1]);
}
int qry(int u, int l, int r, int L, int R) {
	if (L <= l && r <= R) return tree[u];
	int mid = l + r >> 1, res = NINF;
	if (L <= mid) res = qry(u << 1, l, mid, L, R);
	if (mid < R) res = std::max(res, qry(u << 1 | 1, mid + 1, r, L, R));
	return res;
}
int n;
inline int tr(int x, int y) { return x == 1 ? y : NINF; }
int nl;
void add(int i, int v) {
	add(1, 1, nl, ys[i], tr(v, xs[i]));
}
LL R;
typedef __int128 LLL;
bool incir(vec x, vec y) {
	x.x *= x.x, x.y *= x.y;
	y.x *= y.x, y.y *= y.y;
	LLL t = x.x * ((LLL) y.x + y.y) + y.x * ((LLL) x.x + x.y);
	t -= ((LLL)x.x + x.y) * ((LLL) y.x + y.y);
	if (t > 0) return true;
	return false;
}
int trans[MAXN];
int main() {
	memset(tree, 0xcf, sizeof tree);
	std::ios_base::sync_with_stdio(false), std::cin.tie(0);
	std::cin >> R >> n;
	vec pol(-R, 0), por(R, 0);
	std::vector<pi> ll;
	for (int i = 1, bak = 0; i <= n; ++i) {
		std::cin >> opt[i] >> xs[i];
		if (opt[i] != 2) std::cin >> ys[i];
		if (opt[i] == 1) {
			ps[i] = vec(xs[i], ys[i]);
			ll.emplace_back(ps[i] - pol , i);
			ll.emplace_back(ps[i] - por, i + n);
			trans[++bak] = i;
		} else xs[i] = trans[xs[i]], ys[i] = trans[ys[i]];
	}
	static int ls[MAXN << 1], app[MAXN];
	nl = discr(ll, ls);
	for (int i = 1; i <= n; ++i) if (opt[i] == 1)
		xs[i] = ls[i], ys[i] = ls[i + n];
	for (int T = 1; T <= n; ++T) {
		if (opt[T] == 1) add(T, 1), app[T] = true;
		else if (opt[T] == 2) add(xs[T], -1), app[xs[T]] = false;
		else {
			bool can = true;
			int A = xs[T], B = ys[T];
			if (!incir( std::min(ps[A] - pol, ps[B] - pol),
						std::max(ps[A] - por, ps[B] - por) )) {
				int l = lll[bel[std::min(xs[A], xs[B])]];
				int r = rrr[bel[std::max(ys[A], ys[B])]];
				if (app[A]) add(A, -1);
				if (app[B]) add(B, -1);
				can = qry(1, 1, nl, 1, r) >= l;
				if (app[A]) add(A, 1);
				if (app[B]) add(B, 1);
			}
			std::cout << (can ? "NO" : "YES") << '\n';
		}
	}

	return 0;
}

#pragma comment(linker, "/stack:200000000")
#pragma GCC optimize("Ofast")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")

#include <bits/stdc++.h>

#define F0R(i, a) for (int i = 0; i < (a); i++)
#define FOR(i, a, b) for (int i = (a); i < (b); i++)
#define R0F(i, a) for (int i = (a) - 1; i >= 0; i--)
#define ROF(i, a, b) for (int i = (b) - 1; i >= (a); i--)

#define ran() (rand() & 0x7FFF)
#define rand31() ((ran() << 16) | (ran() << 1) | (ran() & 1))
#define rand32() ((ran() << 17) | (ran() << 2) | (ran() & 3))
#define rand63() (((ll)ran() << 48) | ((ll)ran() << 33) | ((ll)ran() << 18) | ((ll)ran() << 3) | ((ll)ran() & 7))
#define rand64() (((ll)ran() << 49) | ((ll)ran() << 34) | ((ll)ran() << 19) | ((ll)ran() << 4) | ((ll)ran() & 15))

#define F first
#define S second
#define PB push_back
#define MP make_pair
#define MT make_tuple
#define UB upper_bound
#define LB lower_bound
#define X real()
#define Y imag()

#define INF 1e18
#define PI acos(-1)

#define sz(x) ((int)(x).size())
#define all(x) (x).begin(), (x).end()
#define SQ(x) ((x) * (x))

using namespace std;

typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef vector<int> vi;
typedef vector<pii> vpii;
typedef vector<ll> vll;
typedef vector<ull> vul;
typedef complex<ld> point;
typedef complex<ld> cld;
typedef vector<cld> vcld;

#define MAXN 500000

struct angle {

ll y, x;

bool operator<(const angle& a2) const {
    return x * a2.y - y * a2.x > 0;
}

bool operator==(const angle& a2) const {
    return x * a2.y == y * a2.x;
}

bool operator<=(const angle& a2) const { return *this < a2 || *this == a2; }

bool operator>=(const angle& a2) const { return a2 < *this; }

angle operator+(const angle& a2) const {
    return {y * a2.x + a2.y * x, x * a2.x - y * a2.y};
}

};

struct SegTree{

int sz;
angle *tree;

SegTree(int _sz) {
    sz = 1 << (32 - __builtin_clz(_sz - 1));
    tree = new angle[2 * sz];
    F0R(i, 2 * sz) tree[i] = angle({0, 1});
}

void upd(int idx, angle v) {
    idx += sz;
    tree[idx] = v;
    for (idx /= 2; idx > 0; idx /= 2) tree[idx] = max(tree[2 * idx], tree[2 * idx + 1]);
}

angle query(int lo, int hi) {
    lo += sz, hi += sz;
    angle res = angle({0, 1});
    while(lo <= hi) {
        if ((lo % 2) == 1) res = max(res, tree[lo++]);
        if ((hi % 2) == 0) res = max(res, tree[hi--]);
        lo /= 2;
        hi /= 2;
    }
    return res;
}

};

ll r;
angle alpha[MAXN], beta123[MAXN];
int n, q, posof[MAXN];
vector<pair<angle, int>> order;
vpii updates;
vector<pair<int, pii>> queries;

SegTree st(2);

void toggle(int idx) {
int pos = posof[idx];
if (st.query(pos, pos) == angle({0, 1})) st.upd(pos, beta123[idx]);
else st.upd(pos, {0, 1});
}

int main() {
    ios::sync_with_stdio(0);
    cin.tie(0);
    cin >> r >> q;
    F0R(i, q) {
        int t;
        cin >> t;
        switch(t) {
            case 1:
                ll x, y;
                cin >> x >> y;
                alpha[n] = {y, r - x};
                beta123[n] = {y, x + r};
                updates.PB(MP(i, n++));
                break;
            case 2:
                int idx;
                cin >> idx;
                idx--;
                updates.PB(MP(i, idx));
                break;
            case 3:
                int a, b;
                cin >> a >> b;
                a--, b--;
                queries.PB(MP(i, MP(a, b)));
                break;
        }
    }
    F0R(i, n) order.PB(MP(alpha[i], i));
    sort(all(order));
    F0R(i, n) posof[order[i].S] = i;
    reverse(all(updates));
    reverse(all(queries));
    st = SegTree(n);
    while (!updates.empty() || !queries.empty()) {
        if (queries.empty() || (!updates.empty() && updates.back().F < queries.back().F)) {
            int idx = updates.back().S;
            updates.pop_back();
            toggle(idx);
        } else {
            int a = queries.back().S.F;
            int b = queries.back().S.S;
            queries.pop_back();
            angle _alpha = min(alpha[a], alpha[b]);
            angle _beta123 = min(beta123[a], beta123[b]);
            if(_alpha + _beta123 < angle({0, 1})) cout << "NO\n";
                else {
                    toggle(a);
                    toggle(b);

                    int lo = LB(all(order), MP(_alpha, 0)) - order.begin();
                    if (st.query(lo, n - 1) >= _beta123) cout << "NO\n";
                    else cout << "YES\n";

                    toggle(a);
                    toggle(b);
                }
            }
        }
}

#include<iostream>
#include<cstdlib>
#include<stdio.h>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<vector>
#include<set>
#include<map>
using namespace std;
long long r;
int n,cnt,list[501000],cnt_list;
struct segment_tree
{
	int l,r,min_vl,lazy;
};
segment_tree tree[1<<21];
struct point
{
	long long x,y;
	bool operator <(const point &temp)const
	{
		  return y*temp.x<x*temp.y;
	}
};
point pt[1000001];
struct query
{
	int u,v,flag,id;
	long long x,y;
	point l,r;
};
query qy[501000];
void build(int left,int right,int id)
{
	int l=2*id+1,r=2*id+2,mid=(left+right)>>1;
	tree[id].min_vl=tree[id].lazy=0;
	tree[id].l=left;
	tree[id].r=right;
	if(left==right)
	    return;
    build(left,mid,l);
    build(mid+1,right,r);
}
void zz(int id)
{
	if(tree[id].lazy==0)
	    return;
	int l=2*id+1,r=2*id+2;
	if(tree[id].l!=tree[id].r)
	{
		tree[l].lazy+=tree[id].lazy;
		tree[r].lazy+=tree[id].lazy;
	}
	tree[id].min_vl+=tree[id].lazy;
	tree[id].lazy=0;
}
void update(int left,int right,int vl,int id)
{
	int l=2*id+1,r=2*id+2;
	if(tree[id].l>right||tree[id].r<left)
	{
	     zz(id);
	     return;
	}
    if(tree[id].l>=left&&tree[id].r<=right)
    {
    	tree[id].lazy+=vl;
    	zz(id);
    	return;
    }
    zz(id);
    update(left,right,vl,l);
    update(left,right,vl,r);
    tree[id].min_vl=min(tree[l].min_vl,tree[r].min_vl);
}
int qw(int left,int right,int id)
{
	int l=2*id+1,r=2*id+2;
	zz(id);
	if(tree[id].l>right||tree[id].r<left)
	    return 1e9+9;
    if(tree[id].l>=left&&tree[id].r<=right)
    	return tree[id].min_vl;
	return min(qw(left,right,l),qw(left,right,r));
}
int binary(int left,int right,point now)
{
	int mid;
	while(left<=right)
	{
		mid=(left+right)>>1;
		if(pt[mid]<now)
			left=mid+1;
		else if(now<pt[mid])
		    right=mid-1;
        else
            return mid;
	}
}
int main()
{
	scanf("%lld%d",&r,&n);
	int i,j,s,p,q,l_id,r_id;
	long long ru;
	cnt=0;
	cnt_list=0;
	for(i=0;i<n;i++)
	{
		scanf("%d",&qy[i].flag);
		if(qy[i].flag==1)
		{
			list[cnt_list++]=i;
            scanf("%lld%lld",&qy[i].x,&qy[i].y);
            pt[cnt].x=qy[i].x-r;
            pt[cnt++].y=qy[i].y;
			qy[i].r=pt[cnt-1];
            pt[cnt].x=qy[i].x+r;
            pt[cnt++].y=qy[i].y;
			qy[i].id=cnt_list-1;
		    qy[i].l=pt[cnt-1];
		}
		else if(qy[i].flag==2)
        {
           scanf("%d",&qy[i].u);
           qy[i].u--;
        }
        else
        {
        	scanf("%d%d",&qy[i].u,&qy[i].v);
        	qy[i].u--;
        	qy[i].v--;
        }
	}
	sort(pt,pt+cnt);
	int nn=0;
	for(i=0;i<cnt;i++)
	{
		if(nn==0||(pt[i].x!=pt[nn-1].x||pt[i].y!=pt[nn-1].y))
		    pt[nn++]=pt[i];
	}
	cnt=nn;
	build(0,cnt-1,0);
	point ll,rr;
	for(i=0;i<n;i++)
	{
		int flag;
		if(qy[i].flag==1)
		{
		   flag=1;
		   ll=qy[i].l;
		   rr=qy[i].r;
		}
		else if(qy[i].flag==2)
		{
			flag=-1;
			ll=qy[list[qy[i].u]].l;
			rr=qy[list[qy[i].u]].r;
		}
		if(qy[i].flag==1||qy[i].flag==2)
		{
    		l_id=binary(0,cnt-1,ll);
    		r_id=binary(0,cnt-1,rr);
    		if(l_id<r_id)
    		   update(l_id,r_id-1,flag,0);
		}
		else
		{
			//ll.x=r;
		//	ll.y=0;
		//	rr.x=-r;
		//	rr.y=0;
			int id1,id2;
			id1=qy[i].u;
			id2=qy[i].v;
		    ll=qy[list[id1]].l;
		    rr=qy[list[id1]].r;
            if(ll<qy[list[id2]].l)
               ll=qy[list[id2]].l;
            if(qy[list[id2]].r<rr)
               rr=qy[list[id2]].r;
            bool ans;
            if(rr<ll)
               ans=0;
            else
            {
            	l_id=binary(0,cnt-1,ll);
            	r_id=binary(0,cnt-1,rr);
            	ans=(l_id<r_id&&qw(l_id,r_id-1,0)<=2);
            	int mf=2;
            	if(!(rr<qy[list[id1]].r))
            	    mf--;
        	    if(!(rr<qy[list[id2]].r))
        	        mf--;
    	        ans|=qw(r_id,r_id,0)<=mf;
            }
            if(ans)
               puts("YES");
            else
               puts("NO");
		}
	}
	return 0;
}
/*

100000000 5
1 -106382777 300000523
1 -75340202 300000165
1 -148918484 300000552
1 96360393 300000458
3 3 2
*/

#include <cstdio>
#include <algorithm>
#include <cstring>
#include <queue>
#include <cmath>
#define ld double
#define l(a) (a<<1)
#define r(a) (a<<1|1)
#define MN 500005
#define MM 1000005
#define MD 4200005
#define eps 1e-13
//#define EPS 1e-14
using namespace std;
struct meg{int g,x,y;}a[MN];
struct itv1{ld x,y;}w[MN];
struct itv2{int x,y;}s[MN];
struct Que
{
	priority_queue <int> A,B;
	void push(int x) {A.push(x);}
	void dele(int x) {B.push(x);}
	int top()
	{
		while (!B.empty()&&A.top()==B.top()) A.pop(),B.pop();
		if (!A.empty()) return A.top(); else return 0;
	}
}q[MM];
ld b0[MM],b1[MM];
int m,MQ,tin,b0in,b1in,ra;
int t[MD];

inline int read()
{
	int n=0,f=1; char c=getchar();
	while (c<'0' || c>'9') {if(c=='-')f=-1; c=getchar();}
	while (c>='0' && c<='9') {n=n*10+c-'0'; c=getchar();}
	return n*f;
}

inline void getcg(int x,int z) {for (t[x+=MQ]=z,x>>=1;x;x>>=1) t[x]=max(t[l(x)],t[r(x)]);}
inline int getmax(int L,int R)
{
	int sum=0;
	for (L+=MQ,R+=MQ;L<=R;L>>=1,R>>=1)
	{
		if ( L&1) sum=max(sum,t[L++]);
		if (~R&1) sum=max(sum,t[R--]);
	}
	return sum;
}

void cghp(int x,int y,int g)
{
	int lt=q[x].top();
	if (g==1) q[x].push(y); else q[x].dele(y);
	if (lt!=q[x].top()) getcg(x,q[x].top());
}

int main()
{
	register int i,x,y,lt=0;
	ra=read(); m=read();
	for (i=1;i<=m;++i)
	{
		a[i].g=read();
		if (a[i].g==1)
		{
			x=read(); y=read(); a[i].x=++tin;
			w[tin].x=atan2(y,x-ra);
			w[tin].y=atan2(y,x+ra);
			b0[++b0in]=w[tin].x;
			b1[++b1in]=w[tin].y;
		}
		else if (a[i].g==2) a[i].x=read();
		else if (a[i].g==3) a[i].x=read(),a[i].y=read();
	}
	sort(b0+1,b0+b0in+1); sort(b1+1,b1+b1in+1);
	for (i=2,lt=0;i<=b0in;++i) {if (b0[i]-b0[i-1]<eps) ++lt; b0[i-lt]=b0[i];} b0in-=lt;
	for (i=2,lt=0;i<=b1in;++i) {if (b1[i]-b1[i-1]<eps) ++lt; b1[i-lt]=b1[i];} b1in-=lt;
	for (i=1;i<=tin;++i)
		s[i].x=lower_bound(b0+1,b0+b0in+1,w[i].x)-b0,
		s[i].y=lower_bound(b1+1,b1+b1in+1,w[i].y)-b1;
	for (MQ=1;MQ<b0in;MQ<<=1); --MQ;
	for (i=1;i<=m;++i)
	{
		if (a[i].g<3) cghp(s[a[i].x].x,s[a[i].x].y,a[i].g);
		else if (a[i].g==3)
		{
			if (max(w[a[i].x].x,w[a[i].y].x)-min(w[a[i].x].y,w[a[i].y].y)>acos(0)) {puts("NO"); continue;}
			x=max(s[a[i].x].x,s[a[i].y].x); y=min(s[a[i].x].y,s[a[i].y].y);
			cghp(s[a[i].x].x,s[a[i].x].y,2);
			cghp(s[a[i].y].x,s[a[i].y].y,2);
			if (getmax(1,x)>=y) puts("NO"); else puts("YES");
			cghp(s[a[i].x].x,s[a[i].x].y,1);
			cghp(s[a[i].y].x,s[a[i].y].y,1);
		}
	}
}

#include <cstdio>
#include <algorithm>
#include <cstring>
#include <queue>
#include <cmath>
#define ld double
#define l(a) (a<<1)
#define r(a) (a<<1|1)
#define MN 500005
#define MM 1000005
#define MD 4200005
#define eps 1e-14
#define EPS 1e-9
using namespace std;
struct meg{int g,x,y;}a[MN];
struct itv1{ld x,y;}w[MN];
struct itv2{int x,y;}s[MN];
struct itv3{int x[2],y[2];}d[MN];
struct Que
{
	priority_queue <int> A,B;
	void push(int x) {A.push(x);}
	void dele(int x) {B.push(x);}
	int top()
	{
		while (!B.empty()&&A.top()==B.top()) A.pop(),B.pop();
		if (!A.empty()) return A.top(); else return 0;
	}
}q[MM];
ld b0[MM],b1[MM];
int m,MQ,tin,b0in,b1in,ra;
int t[MD];

inline int read()
{
	int n=0,f=1; char c=getchar();
	while (c<'0' || c>'9') {if(c=='-')f=-1; c=getchar();}
	while (c>='0' && c<='9') {n=n*10+c-'0'; c=getchar();}
	return n*f;
}

inline void getcg(int x,int z) {for (t[x+=MQ]=z,x>>=1;x;x>>=1) t[x]=max(t[l(x)],t[r(x)]);}
inline int getmax(int L,int R)
{
	int sum=0;
	for (L+=MQ,R+=MQ;L<=R;L>>=1,R>>=1)
	{
		if ( L&1) sum=max(sum,t[L++]);
		if (~R&1) sum=max(sum,t[R--]);
	}
	return sum;
}

void cghp(int x,int y,int g)
{
	int lt=q[x].top();
	if (g==1) q[x].push(y); else q[x].dele(y);
	if (lt!=q[x].top()) getcg(x,q[x].top());
}

bool check(int x,int y)
{
	int cs1,cs2;
	if (s[x].x>s[y].x) cs1=x; else cs1=y;
	if (s[x].y<s[y].y) cs2=x; else cs2=y;
//	printf("1=%d 2=%d\n",cs1,cs2);
//	printf("%.14lf,%.14lf\n",atan2(d[cs2].y[0],-d[cs2].y[1]),atan2(d[cs1].x[1],d[cs1].x[0]));
	if (atan2(d[cs2].y[0],-d[cs2].y[1])+EPS<atan2(d[cs1].x[1],d[cs1].x[0])) return true; else return false;
}

int main()
{
	register int i,x,y,lt=0;
	ra=read(); m=read();
	for (i=1;i<=m;++i)
	{
		a[i].g=read();
		if (a[i].g==1)
		{
			x=read(); y=read(); a[i].x=++tin;
			w[tin].x=atan2(d[tin].x[1]=y,d[tin].x[0]=x-ra);
//			printf("x=%.6lf\n",w[tin].x);
			w[tin].y=atan2(d[tin].y[1]=y,d[tin].y[0]=x+ra);
			b0[++b0in]=w[tin].x;
			b1[++b1in]=w[tin].y;
		}
		else if (a[i].g==2) a[i].x=read();
		else if (a[i].g==3) a[i].x=read(),a[i].y=read();
	}
//	printf("bin=%d,%d\n",b0in,b1in);
	sort(b0+1,b0+b0in+1); sort(b1+1,b1+b1in+1);
	for (i=2,lt=0;i<=b0in;++i) {if (b0[i]-b0[i-1]<eps) ++lt; b0[i-lt]=b0[i];} b0in-=lt;
	for (i=2,lt=0;i<=b1in;++i) {if (b1[i]-b1[i-1]<eps) ++lt; b1[i-lt]=b1[i];} b1in-=lt;
	for (i=1;i<=tin;++i)
		s[i].x=lower_bound(b0+1,b0+b0in+1,w[i].x)-b0,
		s[i].y=lower_bound(b1+1,b1+b1in+1,w[i].y)-b1;
//	printf("bin=%d,%d\n",b0in,b1in);
//	for (i=1;i<=tin;++i) printf("s[%d].lf=%d\n",i,s[i].x);
	for (MQ=1;MQ<b0in;MQ<<=1); --MQ;
	for (i=1;i<=m;++i)
	{
		if (a[i].g<3) cghp(s[a[i].x].x,s[a[i].x].y,a[i].g);
		else if (a[i].g==3)
		{
			if (check(a[i].x,a[i].y)) {puts("NO"); continue;}
//			puts("sb");
			x=max(s[a[i].x].x,s[a[i].y].x); y=min(s[a[i].x].y,s[a[i].y].y);
			cghp(s[a[i].x].x,s[a[i].x].y,2);
			cghp(s[a[i].y].x,s[a[i].y].y,2);
			if (getmax(1,x)>=y) puts("NO"); else puts("YES");
			cghp(s[a[i].x].x,s[a[i].x].y,1);
			cghp(s[a[i].y].x,s[a[i].y].y,1);
		}
	}
}

#include <bits/stdc++.h>

const int MAXN = 500010;
typedef long long LL;
typedef long double db;
typedef LL VT;
struct vec {
	VT x, y;
	vec() { x = y = 0; }
	vec(VT a, VT b) { x = a, y = b; }
// WARN: modify following 4 functions if VT is int
// 1. A * B    2. return LL
	VT operator ^ (vec b) const { return x * b.y - y * b.x; }
	VT operator * (vec b) const { return x * b.x + y * b.y; }
	VT norm2() const { return x * x + y * y; }
	db norm() const { return sqrt(x * x + y * y); }
	vec operator - (vec b) const { return vec(x - b.x, y - b.y); }
	vec operator + (vec b) const { return vec(x + b.x, y + b.y); }
	vec operator * (db k) const { return vec(x * k, y * k); }
	friend bool operator < (const vec & a, const vec & b) {
		return (a ^ b) > 0;
	}
	friend std::istream & operator >> (std::istream & in, vec & x) {
		in >> x.x >> x.y;
		return in;
	}
	friend std::ostream & operator << (std::ostream & out, vec x) {
		out << '(' << x.x << ',' << x.y << ')';
		return out;
	}
} ;
typedef std::vector<vec> VP;
inline LL cross(vec a, vec b, vec c) {
	return (b - a) ^ (c - a);
}
typedef std::pair<vec, int> pi;
int bel[MAXN], lll[MAXN], rrr[MAXN];
int discr(std::vector<pi> v, int * tar) {
	const int L = v.size();
	std::sort(v.begin(), v.end());
	int rnk = 0;
	for (int i = 0; i != L; ++i) {
		if (i != 0 && !(v[i].first < v[i - 1].first || v[i - 1].first < v[i].first)) ;
		else ++rnk;
		bel[tar[v[i].second] = i + 1] = rnk;
		if (!lll[rnk]) lll[rnk] = i + 1;
		rrr[rnk] = i + 1;
	}
	return L;
}
vec ps[MAXN];
int opt[MAXN], xs[MAXN], ys[MAXN];
const int NINF = 0xcfcfcfcf;
int tree[MAXN << 2];
void add(int u, int l, int r, int tar, int v) {
	if (l == r) return (void) (tree[u] = v);
	int mid = l + r >> 1;
	if (tar <= mid) add(u << 1, l, mid, tar, v);
	else add(u << 1 | 1, mid + 1, r, tar, v);
	tree[u] = std::max(tree[u << 1], tree[u << 1 | 1]);
}
int qry(int u, int l, int r, int L, int R) {
	if (L <= l && r <= R) return tree[u];
	int mid = l + r >> 1, res = NINF;
	if (L <= mid) res = qry(u << 1, l, mid, L, R);
	if (mid < R) res = std::max(res, qry(u << 1 | 1, mid + 1, r, L, R));
	return res;
}
int n;
inline int tr(int x, int y) { return x == 1 ? y : NINF; }
int nl;
void add(int i, int v) {
	add(1, 1, nl, ys[i], tr(v, xs[i]));
}
LL R;
typedef __int128 LLL;
bool incir(vec x, vec y) {
	x.x *= x.x, x.y *= x.y;
	y.x *= y.x, y.y *= y.y;
	LLL t = (LLL) x.x * (y.x + y.y) + (LLL) y.x * (x.x + x.y);
	t -= (LLL) (x.x + x.y) * (y.x + y.y);
	if (t > 0) return true;
	return false;
}
int trans[MAXN];
int main() {
	memset(tree, 0xcf, sizeof tree);
	std::ios_base::sync_with_stdio(false), std::cin.tie(0);
	std::cin >> R >> n;
	vec pol(-R, 0), por(R, 0);
	std::vector<pi> ll;
	for (int i = 1, bak = 0; i <= n; ++i) {
		std::cin >> opt[i] >> xs[i];
		if (opt[i] != 2) std::cin >> ys[i];
		if (opt[i] == 1) {
			ps[i] = vec(xs[i], ys[i]);
			ll.emplace_back(ps[i] - pol , i);
			ll.emplace_back(ps[i] - por, i + n);
			trans[++bak] = i;
		} else xs[i] = trans[xs[i]], ys[i] = trans[ys[i]];
	}
	static int ls[MAXN << 1], app[MAXN];
	nl = discr(ll, ls);
	for (int i = 1; i <= n; ++i) if (opt[i] == 1)
		xs[i] = ls[i], ys[i] = ls[i + n];
	for (int T = 1; T <= n; ++T) {
		if (opt[T] == 1) add(T, 1), app[T] = true;
		else if (opt[T] == 2) add(xs[T], -1), app[xs[T]] = false;
		else {
			bool can = true;
			int A = xs[T], B = ys[T];
			if (!incir( std::min(ps[A] - pol, ps[B] - pol),
						std::max(ps[A] - por, ps[B] - por) )) {
				int l = lll[bel[std::min(xs[A], xs[B])]];
				int r = rrr[bel[std::max(ys[A], ys[B])]];
				if (app[A]) add(A, -1);
				if (app[B]) add(B, -1);
				can = qry(1, 1, nl, 1, r) >= l;
				if (app[A]) add(A, 1);
				if (app[B]) add(B, 1);
			}
			std::cout << (can ? "NO" : "YES") << '\n';
		}
	}

	return 0;
}

#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#define ll long long
#define ld long double
#define l(a) (a<<1)
#define r(a) (a<<1|1)
#define MN 500005
#define MM 8000005
#define eps 1e-13
using namespace std;
struct meg{int g,x,y;}a[MN];
struct itv1{ld x,y;}w[MN];
struct itv2{int x,y;}s[MN];
ld b[MN<<1];
ll ra;
int m,tin,bin;
int t[MM],tg[MM];

inline int read()
{
	int n=0,f=1; char c=getchar();
	while (c<'0' || c>'9') {if(c=='-')f=-1; c=getchar();}
	while (c>='0' && c<='9') {n=n*10+c-'0'; c=getchar();}
	return n*f;
}

inline void mark(int x,int z) {tg[x]+=z; t[x]+=z;}
inline void down(int x) {if (tg[x]) mark(l(x),tg[x]),mark(r(x),tg[x]),tg[x]=0;}
inline void update(int x) {t[x]=min(t[l(x)],t[r(x)]);}

void getadd(int x,int L,int R,int ql,int qr,int ad)
{
	if (ql==L&&qr==R) {mark(x,ad); return;}
	down(x);
	int mid=L+R>>1;
	if (qr<=mid) getadd(l(x),L,mid,ql,qr,ad);
	else if (ql>mid) getadd(r(x),mid+1,R,ql,qr,ad);
	else getadd(l(x),L,mid,ql,mid,ad),getadd(r(x),mid+1,R,mid+1,qr,ad);
	update(x);
}

int getmin(int x,int L,int R,int ql,int qr)
{
	if (ql==L&&qr==R) return t[x];
	down(x);
	int mid=L+R>>1;
	if (qr<=mid) return getmin(l(x),L,mid,ql,qr);
	else if (ql>mid) return getmin(r(x),mid+1,R,ql,qr);
	else return min(getmin(l(x),L,mid,ql,mid),getmin(r(x),mid+1,R,mid+1,qr));
}

int main()
{
	register int i,x,y,lt=0;
	ll x1,y1,x0,y0;
	ld bi,ki;
	ra=read(); m=read();
	for (i=1;i<=m;++i)
	{
		a[i].g=read();
		if (a[i].g==1)
		{
			x1=read(); y1=read(); a[i].x=++tin;
			x0=ra; y0=0;
			if (x1>=x0) w[tin].x=acos(1);
			else
			{
				ki=(ld)(y1-y0)/(x1-x0);
				bi=(ld)y0-(ld)x0*(y1-y0)/(x1-x0);
				w[tin].x=acos((ld)(bi*bi-ra*ra)/(ki*ki+1)/(ra*ra));
			}
			x0=-ra; y0=0;
			if (x1<=x0) w[tin].y=acos(-1);
			else
			{
				ki=(ld)(y1-y0)/(x1-x0);
				bi=(ld)y0-(ld)x0*(y1-y0)/(x1-x0);
				w[tin].y=acos((ld)(ra*ra-bi*bi)/(ki*ki+1)/(ra*ra));
			}
			b[++bin]=w[tin].x; b[++bin]=w[tin].y;
		}
		else if (a[i].g==2) a[i].x=read();
		else if (a[i].g==3) a[i].x=read(),a[i].y=read();
	}
	sort(b+1,b+bin+1);
	for (i=2;i<=bin;++i)
	{
		if (b[i]-b[i-1]<eps) ++lt;
		b[i-lt]=b[i];
	}
	bin-=lt;
	for (i=1;i<=tin;++i)
		s[i].x=lower_bound(b+1,b+bin+1,w[i].x)-b,
		s[i].y=lower_bound(b+1,b+bin+1,w[i].y)-b;
	for (i=1;i<=m;++i)
	{
			 if (a[i].g==1) getadd(1,1,bin<<1,s[a[i].x].x*2-1,s[a[i].x].y*2-1, 1);
		else if (a[i].g==2) getadd(1,1,bin<<1,s[a[i].x].x*2-1,s[a[i].x].y*2-1,-1);
		else if (a[i].g==3)
		{
			x=max(s[a[i].x].x,s[a[i].y].x);
			y=min(s[a[i].x].y,s[a[i].y].y);
			if (x>y||getmin(1,1,bin<<1,x*2-1,y*2-1)>=3) puts("NO");
			else puts("YES");
		}
	}
}

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <memory.h>
#include <math.h>
#include <assert.h>
#include <stack>
#include <queue>
#include <map>
#include <set>
#include <string>
#include <algorithm>
#include <iostream>
#include <functional>
#include <unordered_set>
#include <bitset>
#include <time.h>
#include <limits.h>

using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
#define Fi first
#define Se second
#define pb(x) push_back(x)
#define szz(x) (int)x.size()
#define rep(i,n) for(int i=0;i<n;i++)
#define all(x) x.begin(),x.end()
typedef tuple<int, int, int> t3;

int R, N;
int L;
pii q[500050];
vector <t3> P;
vector <t3> query;
pii Lx[500050];

int T[1<<20]; const int ADD = 1<<19;
set <int> Sx[500050], Sy[500050];

void Ins(int x, int y) {
	Sx[x].insert(y);
	Sy[y].insert(x);
	T[x+ADD] = *Sx[x].begin(); x = (x + ADD) >> 1;
	while(x) T[x] = min(T[x<<1], T[x<<1|1]), x >>= 1;
}
void Del(int x, int y) {
	Sx[x].erase(y);
	Sy[y].erase(x);
	int v = (szz(Sx[x]) ? *Sx[x].begin() : 1e9);
	T[x+ADD] = v; x = (x + ADD) >> 1;
	while(x) T[x] = min(T[x<<1], T[x<<1|1]), x >>= 1;
}

int read_t(int l, int r) {
	l += ADD, r += ADD;
	int res = 1e9;
	while(l <= r) {
		if(l & 1) res = min(res, T[l++]);
		if(!(r & 1)) res = min(res, T[r--]);
		l >>= 1, r >>= 1;
	}
	return res;
}

int Query(int x, int y) {
	int xv = max(Lx[x].Fi, Lx[y].Fi);
	int yv = max(Lx[x].Se, Lx[y].Se);
	if(read_t(1, xv - 1) <= yv - 1) return 0;
	int cnt = 0;
	for(auto it=Sx[xv].begin();it!=Sx[xv].end();++it) {
		if(*it > yv) break;
		++cnt;
		if(cnt > 1) return 0;
	}
	cnt = 0;
	for(auto it=Sy[yv].begin();it!=Sy[yv].end();++it) {
		if(*it > xv) break;
		++cnt;
		if(cnt > 1) return 0;
	}

	pii v1, v2;
	if(Lx[x].Fi >= Lx[y].Fi) v1 = pii(q[x].Fi + R, q[x].Se);
	else v1 = pii(q[y].Fi + R, q[y].Se);
	if(Lx[x].Se >= Lx[y].Se) v2 = pii(q[x].Fi - R, q[x].Se);
	else v2 = pii(q[y].Fi - R, q[y].Se);
	if((ll)v1.Fi * v2.Fi + (ll)v1.Se * v2.Se >= 0) return 1;
	return 0;
}

int main() {
	scanf("%d%d", &R, &N);
	for(int i=1;i<=N;i++) {
		int cmd; scanf("%d", &cmd);
		if(cmd == 1) {
			int x, y; scanf("%d%d", &x, &y);
			P.pb(t3(x, y, ++L));
			q[L] = pii(x, y);
			query.pb(t3(1, L, -1));
		}
		else if(cmd == 2) {
			int x; scanf("%d", &x);
			query.pb(t3(2, x, -1));
		}
		else {
			int x, y; scanf("%d%d", &x, &y);
			query.pb(t3(3, x, y));
		}
	}
	int xz = 1, yz = 1;
	auto comp = [&](const t3 &a, const t3 &b) {
		return (ll)(get<0>(a)+R) * get<1>(b) - (ll)get<1>(a) * (get<0>(b)+R) < 0;
	};
	sort(all(P), comp);
	for(int i=0;i<szz(P);i++) {
		Lx[get<2>(P[i])].Fi = xz;
		if(i < szz(P)-1 && comp(P[i], P[i+1])) ++xz;
	}
	auto comp2 = [&](const t3 &a, const t3 &b) {
		return (ll)(get<0>(a)-R) * get<1>(b) - (ll)get<1>(a) * (get<0>(b)-R) > 0;
	};
	sort(all(P), comp2);
	for(int i=0;i<szz(P);i++) {
		Lx[get<2>(P[i])].Se = yz;
		if(i < szz(P)-1 && comp2(P[i], P[i+1])) ++yz;
	}

	rep(i, 1<<20) T[i] = 1e9;
//	for(int i=1;i<=L;i++) printf("%d %d\n", Lx[i].Fi, Lx[i].Se);

	for(t3 e : query) {
		int cmd, x, y;
		tie(cmd, x, y) = e;
		if(cmd == 1) {
			int xv = Lx[x].Fi, yv = Lx[x].Se;
			Ins(xv, yv);
		}
		else if(cmd == 2) {
			int xv = Lx[x].Fi, yv = Lx[x].Se;
			Del(xv, yv);
		}
		else {
			int v = Query(x, y);

			printf("%s\n", v ? "YES" : "NO");
		}
	}

	return 0;
}

#include<cstdio>
#include<algorithm>
#include<vector>
#define N_ 510000
#define SZ (1<<19)
using namespace std;
struct point {
	long long x, y;
	int num;
	bool operator<(const point &p)const {
		return x*p.y  < p.x*y ;
	}
}A[N_], B[N_];
long long Mul(point a, point b) {
	return a.x*b.x + a.y*b.y;
}
int R, n, cnt;
struct AA{
	int b, e, num;
	bool operator<(const AA &p)const {
		return b != p.b ? b < p.b : e < p.e;
	}
}w[N_];
int ReNum[N_];
struct QQ {
	int ck, a, b;
}Q[N_];
int IT[SZ + SZ];
void Ins(int a) {
	a = ReNum[a];
	int y = w[a].e;
	a += SZ;
	IT[a] = y;
	while (a != 1) {
		a >>= 1;
		IT[a] = max(IT[a + a], IT[a + a + 1]);
	}
}
void Del(int a) {
	a = ReNum[a];
	a += SZ;
	IT[a] = 0;
	while (a != 1) {
		a >>= 1;
		IT[a] = max(IT[a + a], IT[a + a + 1]);
	}
}
int Max(int b, int e) {
	int r = 0;
	b += SZ, e += SZ;
	while (b <= e) {
		r = max(r, max(IT[b], IT[e]));
		b = (b + 1) >> 1;
		e = (e - 1) >> 1;
	}
	return r;
}
bool Valid(int a, int b) {
	if (Mul(A[a], B[b]) < 0)return false;
	return true;
}
int main() {
	int i, ck, x, y;
	scanf("%d%d", &R, &n);
	for (i = 1; i <= n; i++) {
		scanf("%d", &ck);
		if (ck == 1) {
			scanf("%d%d", &x, &y);
			cnt++;
			Q[i] = { 1,cnt,0 };
			A[cnt] = { x + R,y,cnt };
			B[cnt] = { x - R,y,cnt };
		}
		else if (ck == 2) {
			scanf("%d", &x);
			Q[i] = { 2,x,0 };
		}
		else {
			scanf("%d%d", &x, &y);
			Q[i] = { 3,x,y };
		}
	}
	sort(A + 1, A + cnt + 1);
	sort(B + 1, B + cnt + 1);
	int pv1 = 1, pv2 = 1;
	for (i = 1; i <= cnt; i++) {
		if (A[pv1] < A[i])pv1 = i;
		if (B[pv2] < B[i])pv2 = i;
		w[A[i].num].b = pv1;
		w[B[i].num].e = pv2;
		w[i].num = i;
	}
	sort(w + 1, w + cnt + 1);
	for (i = 1; i <= cnt; i++)ReNum[w[i].num] = i;
	for (i = 1; i <= n; i++) {
		if (Q[i].ck == 1) {
			Ins(Q[i].a);
		}
		if (Q[i].ck == 2) {
			Del(Q[i].a);
		}
		if (Q[i].ck == 3) {
			Del(Q[i].a), Del(Q[i].b);
			int a = ReNum[Q[i].a], b = ReNum[Q[i].b];
			int aa = max(w[a].b, w[b].b), bb = min(w[a].e, w[b].e);
			if (!Valid(aa, bb)) {
				printf("NO\n");
				continue;
			}
			AA tp = { aa + 1,0,0 };
			int t = lower_bound(w + 1, w + cnt + 1, tp) - w - 1;
			if (Max(1, t) >= bb) {
				printf("NO\n");
			}
			else printf("YES\n");

			Ins(Q[i].a), Ins(Q[i].b);
		}
	}
}

#include <cstdio>
#include <algorithm>
#include <cstring>
#include <queue>
#include <cmath>
#define ld double
#define l(a) (a<<1)
#define r(a) (a<<1|1)
#define MN 500005
#define MM 1000005
#define MD 4200005
#define eps 1e-14
#define EPS 1e-8
using namespace std;
struct meg{int g,x,y;}a[MN];
struct itv1{ld x,y;}w[MN];
struct itv2{int x,y;}s[MN];
struct itv3{int x[2],y[2];}d[MN];
struct Que
{
	priority_queue <int> A,B;
	void push(int x) {A.push(x);}
	void dele(int x) {B.push(x);}
	int top()
	{
		while (!B.empty()&&A.top()==B.top()) A.pop(),B.pop();
		if (!A.empty()) return A.top(); else return 0;
	}
}q[MM];
ld b0[MM],b1[MM];
int m,MQ,tin,b0in,b1in,ra;
int t[MD];

inline int read()
{
	int n=0,f=1; char c=getchar();
	while (c<'0' || c>'9') {if(c=='-')f=-1; c=getchar();}
	while (c>='0' && c<='9') {n=n*10+c-'0'; c=getchar();}
	return n*f;
}

inline void getcg(int x,int z) {for (t[x+=MQ]=z,x>>=1;x;x>>=1) t[x]=max(t[l(x)],t[r(x)]);}
inline int getmax(int L,int R)
{
	int sum=0;
	for (L+=MQ,R+=MQ;L<=R;L>>=1,R>>=1)
	{
		if ( L&1) sum=max(sum,t[L++]);
		if (~R&1) sum=max(sum,t[R--]);
	}
	return sum;
}

void cghp(int x,int y,int g)
{
	int lt=q[x].top();
	if (g==1) q[x].push(y); else q[x].dele(y);
	if (lt!=q[x].top()) getcg(x,q[x].top());
}

bool check(int x,int y)
{
	int cs1,cs2;
	if (s[x].x>s[y].x) cs1=x; else cs1=y;
	if (s[x].y<s[y].y) cs2=x; else cs2=y;
//	printf("1=%d 2=%d\n",cs1,cs2);
//	printf("%.14lf,%.14lf\n",atan2(d[cs2].y[0],-d[cs2].y[1]),atan2(d[cs1].x[1],d[cs1].x[0]));
	if (atan2(d[cs2].y[0],-d[cs2].y[1])+eps<atan2(d[cs1].x[1],d[cs1].x[0])) return true; else return false;
}

int main()
{
	register int i,x,y,lt=0;
	ra=read(); m=read();
	for (i=1;i<=m;++i)
	{
		a[i].g=read();
		if (a[i].g==1)
		{
			x=read(); y=read(); a[i].x=++tin;
			w[tin].x=atan2(d[tin].x[1]=y,d[tin].x[0]=x-ra);
//			printf("x=%.6lf\n",w[tin].x);
			w[tin].y=atan2(d[tin].y[1]=y,d[tin].y[0]=x+ra);
			b0[++b0in]=w[tin].x;
			b1[++b1in]=w[tin].y;
		}
		else if (a[i].g==2) a[i].x=read();
		else if (a[i].g==3) a[i].x=read(),a[i].y=read();
	}
//	printf("bin=%d,%d\n",b0in,b1in);
	sort(b0+1,b0+b0in+1); sort(b1+1,b1+b1in+1);
	for (i=2,lt=0;i<=b0in;++i) {if (b0[i]-b0[i-1]<eps) ++lt; b0[i-lt]=b0[i];} b0in-=lt;
	for (i=2,lt=0;i<=b1in;++i) {if (b1[i]-b1[i-1]<eps) ++lt; b1[i-lt]=b1[i];} b1in-=lt;
	for (i=1;i<=tin;++i)
		s[i].x=lower_bound(b0+1,b0+b0in+1,w[i].x)-b0,
		s[i].y=lower_bound(b1+1,b1+b1in+1,w[i].y)-b1;
//	printf("bin=%d,%d\n",b0in,b1in);
//	for (i=1;i<=tin;++i) printf("s[%d].lf=%d\n",i,s[i].x);
	for (MQ=1;MQ<b0in;MQ<<=1); --MQ;
	for (i=1;i<=m;++i)
	{
		if (a[i].g<3) cghp(s[a[i].x].x,s[a[i].x].y,a[i].g);
		else if (a[i].g==3)
		{
			if (check(a[i].x,a[i].y)) {puts("NO"); continue;}
//			puts("sb");
			x=max(s[a[i].x].x,s[a[i].y].x); y=min(s[a[i].x].y,s[a[i].y].y);
			cghp(s[a[i].x].x,s[a[i].x].y,2);
			cghp(s[a[i].y].x,s[a[i].y].y,2);
			if (getmax(1,x)>=y) puts("NO"); else puts("YES");
			cghp(s[a[i].x].x,s[a[i].x].y,1);
			cghp(s[a[i].y].x,s[a[i].y].y,1);
		}
	}
}

#include <cstdio>
#include <algorithm>
#include <cstring>
#include <queue>
#include <cmath>
#define ll long long
#define ld double
#define l(a) (a<<1)
#define r(a) (a<<1|1)
#define MN 500005
#define MM 1000005
#define MD 4200005
#define eps 1e-12
using namespace std;
struct meg{int g,x,y;}a[MN];
struct itv1{ld x,y;}w[MN];
struct itv2{int x,y;}s[MN];
struct Que
{
	priority_queue <int> A,B;
	void push(int x) {A.push(x);}
	void dele(int x) {B.push(x);}
	int top()
	{
		while (!B.empty()&&A.top()==B.top()) A.pop(),B.pop();
		if (!A.empty()) return A.top(); else return 0;
	}
}q[MM];
ld b0[MM],b1[MM];
ll ra;
int m,MQ,tin,b0in,b1in;
int t[MD];

inline int read()
{
	int n=0,f=1; char c=getchar();
	while (c<'0' || c>'9') {if(c=='-')f=-1; c=getchar();}
	while (c>='0' && c<='9') {n=n*10+c-'0'; c=getchar();}
	return n*f;
}

inline void getcg(int x,int z) {for (t[x+=MQ]=z,x>>=1;x;x>>=1) t[x]=max(t[l(x)],t[r(x)]);}
inline int getmax(int L,int R)
{
	int sum=0;
	for (L+=MQ,R+=MQ;L<=R;L>>=1,R>>=1)
	{
		if ( L&1) sum=max(sum,t[L++]);
		if (~R&1) sum=max(sum,t[R--]);
	}
	return sum;
}

void cghp(int x,int y,int g)
{
	int lt=q[x].top();
	if (g==1) q[x].push(y); else q[x].dele(y);
	if (lt!=q[x].top()) getcg(x,q[x].top());
}

int main()
{
	register int i,x,y,lt=0;
	ra=read(); m=read();
	for (i=1;i<=m;++i)
	{
		a[i].g=read();
		if (a[i].g==1)
		{
			x=read(); y=read(); a[i].x=++tin;
			w[tin].x=atan2(x-ra,y);
			w[tin].y=atan2(x+ra,y);
			b0[++b0in]=w[tin].x;
			b1[++b1in]=w[tin].y;
		}
		else if (a[i].g==2) a[i].x=read();
		else if (a[i].g==3) a[i].x=read(),a[i].y=read();
	}
	sort(b0+1,b0+b0in+1); sort(b1+1,b1+b1in+1);
	for (i=2,lt=0;i<=b0in;++i) {if (b0[i]-b0[i-1]<eps) ++lt; b0[i-lt]=b0[i];} b0in-=lt;
	for (i=2,lt=0;i<=b1in;++i) {if (b1[i]-b1[i-1]<eps) ++lt; b1[i-lt]=b1[i];} b1in-=lt;
	for (i=1;i<=tin;++i)
		s[i].x=lower_bound(b0+1,b0+b0in+1,w[i].x)-b0,
		s[i].y=lower_bound(b1+1,b1+b1in+1,w[i].y)-b1;
	for (MQ=1;MQ<b0in;MQ<<=1); --MQ;
	for (i=1;i<=m;++i)
	{
		if (a[i].g<3) cghp(s[a[i].x].x,s[a[i].x].y,a[i].g);
		else if (a[i].g==3)
		{
			if (max(w[a[i].x].x,w[a[i].y].x)-min(w[a[i].x].y,w[a[i].y].y)>acos(0)-eps) {puts("NO"); continue;}
			x=max(s[a[i].x].x,s[a[i].y].x); y=min(s[a[i].x].y,s[a[i].y].y);
			cghp(s[a[i].x].x,s[a[i].x].y,2);
			cghp(s[a[i].y].x,s[a[i].y].y,2);
			if (getmax(1,x)>=y) puts("NO"); else puts("YES");
			cghp(s[a[i].x].x,s[a[i].x].y,1);
			cghp(s[a[i].y].x,s[a[i].y].y,1);
		}
	}
}

#include <bits/stdc++.h>
#define SZ(X) ((int)(X).size())
#define ALL(X) (X).begin(), (X).end()
#define REP(I, N) for (int I = 0; I < (N); ++I)
#define REPP(I, A, B) for (int I = (A); I < (B); ++I)
#define RI(X) scanf("%d", &(X))
#define RII(X, Y) scanf("%d%d", &(X), &(Y))
#define RIII(X, Y, Z) scanf("%d%d%d", &(X), &(Y), &(Z))
#define DRI(X) int (X); scanf("%d", &X)
#define DRII(X, Y) int X, Y; scanf("%d%d", &X, &Y)
#define DRIII(X, Y, Z) int X, Y, Z; scanf("%d%d%d", &X, &Y, &Z)
#define RS(X) scanf("%s", (X))
#define CASET int ___T, case_n = 1; scanf("%d ", &___T); while (___T-- > 0)
#define MP make_pair
#define PB push_back
#define MS0(X) memset((X), 0, sizeof((X)))
#define MS1(X) memset((X), -1, sizeof((X)))
#define LEN(X) strlen(X)
#define PII pair<int,int>
#define VI vector<int>
#define VL vector<long long>
#define VPII vector<pair<int,int> >
#define PLL pair<long long,long long>
#define VPLL vector<pair<long long,long long> >
#define F first
#define S second
typedef long long LL;
using namespace std;
const int INF = 1e9+7;
const int SIZE = 1e6+10;
int R,N;
int in[SIZE][3];
PII R_R[SIZE];
VPII pp;
bool cmp(PII x,PII y){
    if((x.S>=0)!=(y.S>=0)){
        return x.F<y.F;
    }
    return (LL)x.F*y.S-(LL)x.S*y.F>0;
}
PII sat[SIZE],ll[SIZE],rr[SIZE];
int sid;
int my_gcd(int x,int y){
    x=abs(x);y=abs(y);
    if(!x||!y)return x+y;
    return __gcd(x,y);
}
PII get_left(int x,int y){
    x+=R;
    int gg=my_gcd(x,y);
    x/=gg;
    y/=gg;
    return MP(x,y);
}
PII get_right(int x,int y){
    x-=R;
    int gg=my_gcd(x,y);
    x/=gg;
    y/=gg;
    if(x<=0)return MP(y,-x);
    return MP(y,-x);
}
int mi[SIZE*8],pb[SIZE*8];
void push(int x){
    if(!pb[x])return;
    REP(i,2){
        mi[x*2+i]+=pb[x];
        pb[x*2+i]+=pb[x];
    }
    pb[x]=0;
}
void ins(int L,int R,int id,int x,int y,int v){
    //if(v==-1)printf("[%d,%d]:%d,%d\n",L,R,mi[id],pb[id]);
    if(R<x||L>y)return;
    if(L>=x&&R<=y){
        mi[id]+=v;
        pb[id]+=v;
        return;
    }
    int mm=(L+R)/2;
    push(id);
    ins(L,mm,id*2,x,y,v);
    ins(mm+1,R,id*2+1,x,y,v);
    mi[id]=min(mi[id*2],mi[id*2+1]);

}
int qq(int L,int R,int id,int x,int y){
    if(L>y||R<x)return INF;
    if(L>=x&&R<=y){
        return mi[id];
    }
    int mm=(L+R)/2;
    push(id);
    int ret=min(qq(L,mm,id*2,x,y),qq(mm+1,R,id*2+1,x,y));
    mi[id]=min(mi[id*2],mi[id*2+1]);
    return ret;
}
void print(int L,int R,int id){
    printf("{%d,%d}:%d,%d\n",L,R,mi[id],pb[id]);
    if(L==R)return;
    int mm=(L+R)/2;
    print(L,mm,id*2);
    print(mm+1,R,id*2+1);
}
int tmp[SIZE];
int main(){
    sid=0;
    RII(R,N);
    REP(i,N){
        RII(in[i][0],in[i][1]);
        if(in[i][0]!=2)RI(in[i][2]);
        if(in[i][0]==1){
            int x=in[i][1];
            int y=in[i][2];
            sid++;
            ll[sid]=get_left(x,y),rr[sid]=get_right(x,y);
            pp.PB(ll[sid]);
            pp.PB(rr[sid]);
            in[i][1]=sid;
        }
    }
    sort(ALL(pp),cmp);
    pp.resize(unique(ALL(pp))-pp.begin());
    map<PII,int>get_id;
    REP(i,SZ(pp))get_id[pp[i]]=i+1;
    REPP(i,1,sid+1)R_R[i]=MP(get_id[rr[i]],get_id[ll[i]]);
    //REPP(i,1,sid+1)printf("(%d,%d)\n",R_R[i].F,R_R[i].S);
    REP(i,N){
        //printf("op %d:\n",i);
        if(in[i][0]==1){
            ins(1,sid*4,1,R_R[in[i][1]].F*2,R_R[in[i][1]].S*2,1);
        }
        else if(in[i][0]==2){
            ins(1,sid*4,1,R_R[in[i][1]].F*2,R_R[in[i][1]].S*2,-1);
        }
        else{
            int x=max(R_R[in[i][1]].F,R_R[in[i][2]].F);
            int y=min(R_R[in[i][1]].S,R_R[in[i][2]].S);
            if(x>y)puts("NO");
            else{
                if(qq(1,sid*4,1,x*2,y*2)==2)puts("YES");
                else puts("NO");
            }
        }
        //print(1,sid*4,1);
    }
    return 0;
}

#include<iostream>
#include<cstdlib>
#include<stdio.h>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<vector>
#include<set>
#include<map>
using namespace std;
long long r;
int n,cnt,list[501000],cnt_list,mf[1001000];
struct segment_tree
{
	int l,r,min_vl,lazy;
};
segment_tree tree[1<<21];
struct point
{
	long long x,y;
	int z;
	bool operator <(const point &temp)const
	{
		  return y*temp.x<x*temp.y;
	}
};
point pt[1000001];
struct query
{
	int u,v,flag,id;
	long long x,y;
	point l,r;
};
query qy[501000];
void build(int left,int right,int id)
{
	int l=2*id+1,r=2*id+2,mid=(left+right)>>1;
	tree[id].min_vl=tree[id].lazy=0;
	tree[id].l=left;
	tree[id].r=right;
	if(left==right)
	    return;
    build(left,mid,l);
    build(mid+1,right,r);
}
void zz(int id)
{
	if(tree[id].lazy==0)
	    return;
	int l=2*id+1,r=2*id+2;
	if(tree[id].l!=tree[id].r)
	{
		tree[l].lazy+=tree[id].lazy;
		tree[r].lazy+=tree[id].lazy;
	}
	tree[id].min_vl+=tree[id].lazy;
	tree[id].lazy=0;
}
void update(int left,int right,int vl,int id)
{
	int l=2*id+1,r=2*id+2;
	if(tree[id].l>right||tree[id].r<left)
	{
	     zz(id);
	     return;
	}
    if(tree[id].l>=left&&tree[id].r<=right)
    {
    	tree[id].lazy+=vl;
    	zz(id);
    	return;
    }
    zz(id);
    update(left,right,vl,l);
    update(left,right,vl,r);
    tree[id].min_vl=min(tree[l].min_vl,tree[r].min_vl);
}
int qw(int left,int right,int id)
{
	int l=2*id+1,r=2*id+2;
	zz(id);
	if(tree[id].l>right||tree[id].r<left)
	    return 1e9+9;
    if(tree[id].l>=left&&tree[id].r<=right)
    	return tree[id].min_vl;
	return min(qw(left,right,l),qw(left,right,r));
}
int binary(int left,int right,point now)
{
	int mid;
	while(left<=right)
	{
		mid=(left+right)>>1;
		if(pt[mid]<now)
			left=mid+1;
		else if(now<pt[mid])
		    right=mid-1;
        else
            return mid;
	}
}
int main()
{
	scanf("%lld%d",&r,&n);
	int i,j,s,p,q,l_id,r_id;
	long long ru;
	cnt=0;
	cnt_list=0;
	for(i=0;i<n;i++)
	{
		scanf("%d",&qy[i].flag);
		if(qy[i].flag==1)
		{
			list[cnt_list++]=i;
            scanf("%lld%lld",&qy[i].x,&qy[i].y);
		   	pt[cnt].x=qy[i].y;
            pt[cnt++].y=r-qy[i].x;
			qy[i].r=pt[cnt-1];
		   	pt[cnt].x=qy[i].x+r;
            pt[cnt++].y=qy[i].y;
			qy[i].id=cnt_list-1;
		    qy[i].l=pt[cnt-1];
		    if(qy[i].r<qy[i].l)
		        swap(qy[i].l,qy[i].r);
		}
		else if(qy[i].flag==2)
        {
           scanf("%d",&qy[i].u);
           qy[i].u--;
        }
        else
        {
        	scanf("%d%d",&qy[i].u,&qy[i].v);
        	qy[i].u--;
        	qy[i].v--;
        }
	}
	sort(pt,pt+cnt);
	int nn=0;
	for(i=0;i<cnt;i++)
	{
		if(nn==0||(pt[i].x!=pt[nn-1].x||pt[i].y!=pt[nn-1].y))
		    pt[nn++]=pt[i];
	}
	cnt=nn;
	build(0,cnt-1,0);
	point ll,rr;
	memset(mf,0,sizeof(mf));
	for(i=0;i<n;i++)
	{
		int flag;
		if(qy[i].flag==1)
		{
		   flag=1;
		   ll=qy[i].l;
		   rr=qy[i].r;
		}
		else if(qy[i].flag==2)
		{
			flag=-1;
			ll=qy[list[qy[i].u]].l;
			rr=qy[list[qy[i].u]].r;
		}
		if(qy[i].flag==1||qy[i].flag==2)
		{
    		l_id=binary(0,cnt-1,ll);
    		r_id=binary(0,cnt-1,rr);
    		mf[r_id]+=flag;
    		if(l_id<r_id)
    		   update(l_id,r_id-1,flag,0);
		}
		else
		{
			int id1,id2;
			id1=qy[i].u;
			id2=qy[i].v;
		    ll=qy[list[id1]].l;
		    rr=qy[list[id1]].r;
            if(ll<qy[list[id2]].l)
               ll=qy[list[id2]].l;
            if(qy[list[id2]].r<rr)
               rr=qy[list[id2]].r;
            bool ans;
            if(rr<ll)
               ans=0;
            else
            {
            	l_id=binary(0,cnt-1,ll);
            	r_id=binary(0,cnt-1,rr);
            	ans=(l_id<r_id&&qw(l_id,r_id-1,0)<=2);
    	        ans|=mf[r_id]+qw(r_id,r_id,0)<=2;
            }
            if(ans)
               puts("YES");
            else
               puts("NO");
		}
	}
	return 0;
}
/*

100000000 5
1 -106382777 300000523
1 -75340202 300000165
1 -148918484 300000552
1 96360393 300000458
3 3 2
*/

#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <string>
#include <cstring>
#include <cmath>
#include <set>
#include <map>
#include <cstdio>
#include <stdlib.h>
#include <stack>
#include <numeric>
#include <bitset>
#include <cctype>
#include <list>
#include <assert.h>
#include <random>
#include <unordered_map>
#include <ctime>
typedef  long long ll;
using namespace std;
#define INF 2147483647
#define infL (1LL<<60)
#define inf (1<<30)
#define inf9 (1000000000)
#define MOD 1000000007
#define EPS 1e-9
#define Gr 9.8
#define PI acos(-1)
#define REP(i,n) for(int (i)=0;(i)<(int)(n);(i)++)
#define REQ(i,n) for(int (i)=1;(i)<=(int)(n);(i)++)
#define lch (rt<<1)
#define rch (rt<<1|1)
#define readmp(n) for(int i=0,u,v;i<n;i++) {scanf("%d%d",&u,&v); mp[u].push_back(v); mp[v].push_back(u);}
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef long double ld;
typedef unsigned int uint;
#define MAX 500105
bool debug = 0;
int n,m,k;
int dx[4] = {0,1,0,-1}, dy[4] = {1,0,-1,0};
string direc="RDLU";
ll ln, lk, lm;
void etp(bool f = 0) {
    puts(f ?"YES" : "NO");
    exit(0);
}
void addmod(int &x, int y, int mod = MOD) {
    assert(y>=0);
    x+=y; if (x>=mod) x-=mod;
    assert(x>=0 && x<mod);
}
void et() {
    puts("-1"); exit(0);
}
ll fastPow(ll x, ll y, int mod=MOD) {
    ll ans = 1;
    while(y>0) {
        if(y&1) ans = (x * ans)%mod;
        x = x*x%mod;
        y>>=1;
    }
    return ans;
}
ll gcd1(ll x, ll y) {
    ll z = y;
    while(x%y!=0) {
        z = x%y; x = y; y = z;
    }
    return z;
}

struct Frac {
    ll x, y;
    Frac() { }
    Frac(ll x, ll y) : x(x), y(y) {}
    ld absVal() const { return (ld)x/y; }
    void uni() {
        if (y<0) {y*=-1; x*=-1;}
        assert(y!=0);
        if (x==0) y=1;
        else {
            ll g=gcd1(abs(x), abs(y));
            x/=g; y/=g;
        }
    }
    Frac operator*(Frac o) const { return Frac(x * o.x, y * o.y); }
    Frac operator+(const Frac& o) const { return Frac(x*o.y+y*o.x, y * o.y); }
    Frac operator-(const Frac& o) const { return Frac(x*o.y-y*o.x, y * o.y); }
    bool operator<(const Frac& o) const {
        return x*o.y < y*o.x;
    }
    friend bool operator == (const Frac &r1,const Frac &r2) {return r1.x*r2.y == r1.y*r2.x;}
};
int R;
Frac lt[MAX],rt[MAX];
int sateCnt;
struct mb {
    int t,x,y, id;
    void rd() {
        scanf("%d", &t);
        if (t==2) scanf("%d", &id);
        else scanf("%d%d", &x,&y);
    }
}q[MAX];
map<Frac, int> mp;
int li[MAX], ri[MAX],cnt;

const int MN=(1<<21)+5;
struct mbt {
    int M; Frac T[MN];
    void init(int sz) {
        for(M=1;sz+2>M;M<<=1);
        REP(i,MN) T[i]={-1,1};
    }
    void uptSingleMax(int l, Frac val) {
        l+=M; T[l]=val;
        while(l>1) {
            T[l>>1] = max(T[l],T[l^1]); l>>=1;
        }
    }
    Frac qyRangeMax(int l, int r) {
        Frac ans = {-1, 1};
        for(l=l+M-1,r=r+M+1;l^r^1;l>>=1,r>>=1){
            if(~l&1) ans = max(ans, T[l^1]);
            if(r&1) ans = max(ans, T[r^1]);
        }
        return ans;
    }
}T;
bool del[MAX];
priority_queue<pair<Frac,int>> Q[MAX];
void add(int staId) {
    del[staId] = 0;
    bool cg = Q[li[staId]].empty() || Q[li[staId]].top().second != staId;
    Q[li[staId]].push({rt[staId], staId});
    if (cg) {
        T.uptSingleMax(li[staId], rt[staId]);
    }
}
void rmv(int staId) {
    del[staId] = 1;
    int k = li[staId];
    while(!Q[k].empty() && del[Q[k].top().second]) {
        Q[k].pop();
    }
    if (Q[k].empty()) T.uptSingleMax(k, Frac(-1,1));
    else T.uptSingleMax(li[staId], Q[k].top().first);
}
void fmain(int tid) {
    scanf("%d%d", &R, &n);
    REQ(i,n) {
        q[i].rd();
        if (q[i].t == 1) {
            int x=q[i].x,y=q[i].y;
            sateCnt++;

            if (x<=-R) lt[sateCnt] = Frac(0,1);
            else lt[sateCnt] = Frac(x+R,y);

            if (x>=R) rt[sateCnt] = Frac(inf9+1, 1);
            else rt[sateCnt] = Frac(y,R-x);
            q[i].id = sateCnt;
        }
    }
    REQ(i,sateCnt) {
        mp[lt[i]]; mp[rt[i]];
    }
    for(auto &p : mp) {
        p.second = ++cnt;
    }
    REQ(i,sateCnt) {
        li[i] = mp[lt[i]];
        ri[i]=mp[rt[i]];
//        printf("%d %d\n", li[i],ri[i]);
    }
    T.init(cnt);
    REQ(i,n) {
        if (q[i].t==1) {
            add(q[i].id);
        } else if (q[i].t==2) {
            rmv(q[i].id);
        } else {
            int x=q[i].x,y=q[i].y;
            if(li[x]>li[y]) swap(x,y);
            bool ok = 0;
            if (ri[x]>=li[y]) {
                int idx = li[y];
                rmv(x); rmv(y);
//                Frac tmp = T.qyRangeMax(1, idx);
                ok = T.qyRangeMax(1, idx) < min(rt[x],rt[y]);
                add(x); add(y);
            }
            puts(ok ? "YES" : "NO");
        }
    }
}
int main() {
    int t=1;
//    scanf("%d", &t);
    REQ(i,t) {
        fmain(i);
    }
    return 0;
}

#define ONLINE_JUDGE
#include <bits/stdc++.h>

#define inf 0x3f3f3f3f

#define MOD 1000000007

#define pb push_back

#define sq(x) ((x)*(x))

#define x first

#define y second

#define eps 1e-8

#define bpt(x) (__builtin_popcount(x))

#define bptl(x) (__builtin_popcountll(x))

#define bit(x, y) (((x)>>(y))&1)

#define bclz(x) (__builtin_clz(x))

#define bclzl(x) (__builtin_clzll(x))

#define bctz(x) (__builtin_ctz(x))

#define bctzl(x) (__builtin_ctzll(x))

#define PQ priority_queue<pii, vector<pii>, greater<pii> >

using namespace std;

typedef long long INT;

typedef vector<int> VI;

typedef pair<int, int> pii;

typedef pair<pii, int> pi3;

typedef double DO;

template<typename T, typename U> inline void smin(T &a, U b) {if (a>b) a=b;}

template<typename T, typename U> inline void smax(T &a, U b) {if (a<b) a=b;}

template<class T>inline void gn(T &x) {char c, sg=0; while (c=getchar(), (c>'9' || c<'0') && c!='-');for((c=='-'?sg=1, c=getchar():0), x=0; c>='0' && c<='9'; c=getchar()) x=(x<<1)+(x<<3)+c-'0';if (sg) x=-x;}

template<class T, class T1>inline void gn(T &x, T1 &y) {gn(x); gn(y);}

template<class T, class T1, class T2>inline void gn(T &x, T1 &y, T2 &z) {gn(x); gn(y); gn(z);}

template<class T>inline void print(T x) {if (x<0) {putchar('-');return print(-x);}if (x<10) {putchar('0'+x);return;} print(x/10);putchar(x%10+'0');}

int power(int a, int b, int m, int ans=1) {

	for (; b; b>>=1, a=1LL*a*a%m) if (b&1) ans=1LL*ans*a%m;

	return ans;

}

#ifndef ONLINE_JUDGE

void debug() {cout << endl;}

template<typename T, typename... Args>void debug(T&& head, Args&&... tail) {cout << head << ' ';debug(tail...);}

#endif

#define NN 500010

struct Node {

	int ax, ay, bx, by;

	int st, en;

	int flag;

};

Node mem[4*NN];

int x[NN], y[NN];

int I[NN];

INT ans;

void select(int k, int st, int en, int *val) {

	int le, ri, ll, ho, a, i, j;

	le=st; ri=en-1;

	while (1) {

		if (ri<=le+1) {

			if (ri==le+1 && val[I[le]]>val[I[ri]]) swap(I[le], I[ri]);

			return;

		}

		ll=le+1;

		ho=le+rand()%(ri-le+1);

		swap(I[ho], I[ll]);

		if (val[I[ri]]<val[I[le]]) swap(I[ri], I[le]);

		if (val[I[ll]]>val[I[ri]]) swap(I[ri], I[ll]);

		if (val[I[le]]>val[I[ll]]) swap(I[le], I[ll]);

		a=val[I[ll]];

		i=ll; j=ri;

		while (1) {

			do i++; while (val[I[i]]<a);

			do j--; while (val[I[j]]>a);

			if (i>j) break;

			swap(I[i], I[j]);

		}

		swap(I[ll], I[j]);

		if (k<=j) ri=j;

		else if (k>=i) le=i;

		else break;

	}

}

#define MIN(x, y)((x)<(y)?(x):(y))

#define MAX(x, y)((x)>(y)?(x):(y))

void make_tree(int u, int st, int en, int dp) {

	int mid, le, ri;

	mem[u].st=st; mem[u].en=en;

	mem[u].flag=0;

	if (en==st+1) {

		mem[u].ax=mem[u].bx=x[I[st]];

		mem[u].ay=mem[u].by=y[I[st]];

		return;

	}

	mid=(st+en)/2; le=2*u; ri=2*u+1;

	if (dp&1) select(mid, st, en, x);

	else select(mid, st, en, y);

	make_tree(le, st, mid, 1-dp);

	make_tree(ri, mid, en, 1-dp);

	mem[u].ax=MIN(mem[le].ax, mem[ri].ax);

	mem[u].ay=MIN(mem[le].ay, mem[ri].ay);

	mem[u].bx=MAX(mem[le].bx, mem[ri].bx);

	mem[u].by=MAX(mem[le].by, mem[ri].by);

	return;

}

INT sqr(int t) {

	return (INT)t*t;

}

INT dis(int t, int r) {

	return sqr(x[t]-x[r])+sqr(y[t]-y[r]);

}

#define ls (u<<1)

#define rs (ls|1)

int find(int u, int idx) {

	if (x[idx]<mem[u].ax) return 0;

	if (x[idx]>mem[u].bx) return 0;

	if (y[idx]<mem[u].ay) return 0;

	if (y[idx]>mem[u].by) return 0;

	if (mem[u].en==mem[u].st+1) {

		mem[u].flag^=1;

		return 1;

	}

	find(ls, idx);

	find(rs, idx);

	mem[u].flag=mem[ls].flag|mem[rs].flag;

}

int calc(int u, int tx, int ty) {

	if (mem[u].bx<tx) return 0;

	if (mem[u].ay>ty) return 0;

	if (!mem[u].flag) return 0;

	if (mem[u].st+1==mem[u].en) return 1;

	if (calc(ls, tx, ty)) return 1;

	return calc(rs, tx, ty);

}

int t[NN], II[NN];

double X[NN], XX[NN], Y[NN], YY[NN];

const double pi2=acosl(-1.0)/2;

void print_tree(int u=1) {

	if (mem[u].st+1==mem[u].en) {

		printf("%d %d %d\n", mem[u].bx, mem[u].by, mem[u].flag);

		return ;

	}

	print_tree(ls);

	print_tree(rs);

}

int can(int uu, int vv) {

	int u=II[uu], v=II[vv];

	if (x[u]>x[v]) swap(u, v);

	if (x[u]==x[v] && y[u]>y[v]) swap(u, v);

	int tx=min(x[u], x[v]);

	int ty=max(y[u], y[v]);

	find(1, u); find(1, v);

	int ok=(Y[ty]-X[tx]>pi2+1e-10) || calc(1, tx, ty);

	find(1, u); find(1, v);

	return !ok;

}

int main() {

#ifndef ONLINE_JUDGE

	freopen("in.in", "r", stdin);

	freopen("out.out", "w", stdout);

#endif

	int r, n, u, v;

	gn(r); gn(n);

	int nn=0, nx=0, ny=0;

	VI a, b;

	for (int i=0; i<n; i++) {

		gn(t[i]);

		if (t[i]==1) {

			gn(u, v);

			X[nx++]=XX[nn]=atan2l(v, u+r);

			Y[ny++]=YY[nn]=atan2l(v, u-r);

			nn++;

		}

		if (t[i]==2) {

			gn(u);

			a.pb(u);

		}

		if (t[i]==3) {

			gn(u, v);

			b.pb(u); b.pb(v);

		}

	}

	sort(X, X+nx); nx=unique(X, X+nx)-X;

	sort(Y, Y+ny); ny=unique(Y, Y+ny)-Y;

	map<pii, int> mp;

	int E=0;

	for (int i=0; i<nn; i++) {

		pii aa=pii(lower_bound(X, X+nx, XX[i]-1e-10)-X, lower_bound(Y, Y+ny, YY[i]-1e-10)-Y);

		if (mp.count(aa)) II[i]=mp[aa];

		else {

			x[E]=aa.x;

			y[E]=aa.y;

			I[E]=E;

			II[i]=(mp[aa]=E++);

		}

	}

	make_tree(1, 0, E, 0);

	int id=0, id1=0, id2=0;

	for (int i=0; i<n; i++) {

		if (t[i]==1) find(1, II[id++]);

		if (t[i]==2) find(1, II[a[id1++]-1]);

		if (t[i]==3) {

			u=b[id2++]-1, v=b[id2++]-1;

			puts(can(u, v)?"YES":"NO");

		}

	}

	return 0;

}

#include <bits/stdc++.h>
using namespace std;

#define ms(s, n) memset(s, n, sizeof(s))
#define FOR(i, a, b) for (int i = (a); i < (b); i++)
#define FORd(i, a, b) for (int i = (a) - 1; i >= (b); i--)
#define FORall(it, a) for (__typeof((a).begin()) it = (a).begin(); it != (a).end(); it++)
#define sz(a) int((a).size())
#define present(t, x) (t.find(x) != t.end())
#define all(a) (a).begin(), (a).end()
#define uni(a) (a).erase(unique(all(a)), (a).end())
#define pb push_back
#define pf push_front
#define mp make_pair
#define fi first
#define se second
#define prec(n) fixed<<setprecision(n)
#define bit(n, i) (((n) >> (i)) & 1)
#define bitcount(n) __builtin_popcountll(n)
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef pair<int, int> pi;
typedef vector<int> vi;
typedef vector<pi> vii;
const int MOD = (int) 1e9 + 7;
const int MOD2 = 1007681537;
const int INF = (int) 1e9;
const ll LINF = (ll) 1e18;
const ld PI = acos((ld) -1);
const ld EPS = 1e-9;
inline ll gcd(ll a, ll b) {ll r; while (b) {r = a % b; a = b; b = r;} return a;}
inline ll lcm(ll a, ll b) {return a / gcd(a, b) * b;}
inline ll fpow(ll n, ll k, int p = MOD) {ll r = 1; for (; k; k >>= 1) {if (k & 1) r = r * n % p; n = n * n % p;} return r;}
template<class T> inline int chkmin(T& a, const T& val) {return val < a ? a = val, 1 : 0;}
template<class T> inline int chkmax(T& a, const T& val) {return a < val ? a = val, 1 : 0;}
inline ll isqrt(ll k) {ll r = sqrt(k) + 1; while (r * r > k) r--; return r;}
inline ll icbrt(ll k) {ll r = cbrt(k) + 1; while (r * r * r > k) r--; return r;}
inline void addmod(int& a, int val, int p = MOD) {if ((a = (a + val)) >= p) a -= p;}
inline void submod(int& a, int val, int p = MOD) {if ((a = (a - val)) < 0) a += p;}
inline int mult(int a, int b, int p = MOD) {return (ll) a * b % p;}
inline int inv(int a, int p = MOD) {return fpow(a, p - 2, p);}
inline int sign(ld x) {return x < -EPS ? -1 : x > +EPS;}
inline int sign(ld x, ld y) {return sign(x - y);}
#define db(x) cerr << #x << " = " << (x) << " ";
#define endln cerr << "\n";

const int maxn = 5e5 + 5;
int n, d, k;
int op[maxn];
int x[maxn];
int y[maxn];
int z[maxn];
int l[maxn];
int r[maxn];
int a[maxn];
int b[maxn];

long long ff1(int i, int j) {
    int x1 = x[i] + d;
    int y1 = y[i] + 0;
    int x2 = x[j] + d;
    int y2 = y[j] + 0;
    return (long long) x1 * y2 - (long long) x2 * y1;
}

long long ff2(int i, int j) {
    int x1 = x[i] - d;
    int y1 = y[i] - 0;
    int x2 = x[j] - d;
    int y2 = y[j] - 0;
    return (long long) x1 * y2 - (long long) x2 * y1;
}

int cmp1(int i, int j) {
    long long cr = ff1(i, j);
    if (cr) return cr > 0;
    return i < j;
}

int cmp2(int i, int j) {
    long long cr = ff2(i, j);
    if (cr) return cr > 0;
    return i < j;
}

multiset<int> heap[maxn];
int st[maxn << 1];
void upd(int p, int n, int val) {
    for (st[p += n] = val; p > 1; ) p >>= 1, st[p] = min(st[p << 1], st[p << 1 | 1]);
}
int query(int l, int r, int n) {
    int res = INF;
    for (l += n, r += n + 1; l < r; l >>= 1, r >>= 1) {
        if (l & 1) chkmin(res, st[l++]);
        if (r & 1) chkmin(res, st[--r]);
    }
    return res;
}

void upd(int u, int n) {
    int val = sz(heap[u]) ? *heap[u].begin() : INF;
    upd(u, n, val);
}

long long dot(pi a, pi b) {
    return (long long) a.fi * b.fi + (long long) a.se * b.se;
}

void solve() {
    cin >> d >> n;
    FOR(i, 0, n) {
        cin >> op[i];
        if (op[i] == 1) {
            cin >> x[k] >> y[k], k++;
        }
        else if (op[i] == 2) {
            cin >> z[i], z[i]--;
        }
        else {
            cin >> l[i] >> r[i], l[i]--, r[i]--;
        }
    }
    vi ver; FOR(i, 0, k) ver.pb(i);
    sort(all(ver), cmp1);
    int st1 = 0;
    FOR(i, 0, k) {
        if (i && ff1(ver[i - 1], ver[i])) st1++;
        a[ver[i]] = st1;
    }
    FOR(i, 0, k) a[i] = st1 - a[i];
    int st2 = 0;
    sort(all(ver), cmp2);
    FOR(i, 0, k) {
        if (i && ff2(ver[i - 1], ver[i])) st2++;
        b[ver[i]] = st2;
    }
    FOR(i, 0, k + k) st[i] = INF;
    k = 0;
    FOR(i, 0, n) {
        if (op[i] == 1) {
            heap[a[k]].insert(b[k]);
            upd(a[k], st1 + 1);
            k++;
        }
        else if (op[i] == 2) {
            int ix = z[i];
            heap[a[ix]].erase(b[ix]);
            upd(a[ix], st1 + 1);
        }
        else {
            int ix1 = l[i];
            int ix2 = r[i];
            int u = max(a[ix1], a[ix2]);
            int v = max(b[ix1], b[ix2]);
            pi c, d;
            if (a[ix1] > a[ix2]) {
                c = mp(x[ix1], y[ix1]);
            }
            else {
                c = mp(x[ix2], y[ix2]);
            }
            if (b[ix1] > b[ix2]) {
                d = mp(x[ix1], y[ix1]);
            }
            else {
                d = mp(x[ix2], y[ix2]);
            }
            heap[a[ix1]].erase(b[ix1]);
            upd(a[ix1], st1 + 1);
            heap[a[ix2]].erase(b[ix2]);
            upd(a[ix2], st1 + 1);
            if (dot(c, d) < 0 || query(0, u, st1 + 1) <= v) {
                cout << "NO\n";
            }
            else {
                cout << "YES\n";
            }
            heap[a[ix1]].insert(b[ix1]);
            upd(a[ix1], st1 + 1);
            heap[a[ix2]].insert(b[ix2]);
            upd(a[ix2], st1 + 1);
        }
    }
}

int main() {
    int JUDGE_ONLINE = 1;
    if (fopen("in.txt", "r")) {
        JUDGE_ONLINE = 0;
        assert(freopen("in.txt", "r", stdin));
        //assert(freopen("out.txt", "w", stdout));
    }
    else {
        ios_base::sync_with_stdio(0), cin.tie(0);
    }
    solve();
    if (!JUDGE_ONLINE) {
        //cout << "\nTime elapsed: " << 1000 * clock() / CLOCKS_PER_SEC << "ms\n";
    }
    return 0;
}

#include <cstdio>
#include <algorithm>
#include <cstring>
#include <queue>
#include <cmath>
#define ll long long
#define ld long double
#define l(a) (a<<1)
#define r(a) (a<<1|1)
#define MN 500005
#define MM 1000005
#define MD 4200005
#define eps 1e-15
using namespace std;
int INF;
struct meg{int g,x,y;}a[MN];
struct itv1{ld x,y;}w[MN];
struct itv2{int x,y;}s[MN];
struct Que
{
	priority_queue <int,vector<int>,greater<int> > A,B;
	void push(int x) {A.push(x);}
	void dele(int x) {B.push(x);}
	int top()
	{
		while (!B.empty()&&A.top()==B.top()) A.pop(),B.pop();
		if (!A.empty()) return A.top(); else return INF;
	}
}q[MM];
ld b[MM];
ll ra;
int m,MQ,tin,bin;
int t[MD];

inline int read()
{
	int n=0,f=1; char c=getchar();
	while (c<'0' || c>'9') {if(c=='-')f=-1; c=getchar();}
	while (c>='0' && c<='9') {n=n*10+c-'0'; c=getchar();}
	return n*f;
}

inline void getcg(int x,int z) {for (t[x+=MQ]=z,x>>=1;x;x>>=1) t[x]=min(t[l(x)],t[r(x)]);}
inline int getmin(int L,int R)
{
	int sum=INF;
	for (L+=MQ,R+=MQ;L<=R;L>>=1,R>>=1)
	{
		if ( L&1) sum=min(sum,t[L++]);
		if (~R&1) sum=min(sum,t[R--]);
	}
	return sum;
}

ld cal(ll x0,ll y0,ll x1,ll y1,ll g)
{
	ld ki,bi;
	ki=(ld)(y1-y0)/(x1-x0);
	bi=(ld)y0-(ld)x0*(y1-y0)/(x1-x0);
	return acos((ld)(bi*bi-ra*ra)*g/(ki*ki+1)/(ra*ra));
}
void cghp(int x,int y,int g)
{
	int lt=q[x].top();
	if (g==1) q[x].push(y); else q[x].dele(y);
	if (lt!=q[x].top()) getcg(x,q[x].top());
}

int main()
{
	register int i,x,y,lt=0;
	ra=read(); m=read();
	for (i=1;i<=m;++i)
	{
		a[i].g=read();
		if (a[i].g==1)
		{
			x=read(); y=read(); a[i].x=++tin;
			w[tin].x=(ll)x>= ra?acos( 1):cal( ra,0,(ll)x,(ll)y, 1);
			w[tin].y=(ll)x<=-ra?acos(-1):cal(-ra,0,(ll)x,(ll)y,-1);
			b[++bin]=w[tin].x; b[++bin]=w[tin].y;
		}
		else if (a[i].g==2) a[i].x=read();
		else if (a[i].g==3) a[i].x=read(),a[i].y=read();
	}
	sort(b+1,b+bin+1);
	for (i=2;i<=bin;++i) {if (b[i]-b[i-1]<eps) ++lt; b[i-lt]=b[i];}
	bin-=lt;
	for (i=1;i<=tin;++i)
		s[i].x=lower_bound(b+1,b+bin+1,w[i].x)-b,
		s[i].y=lower_bound(b+1,b+bin+1,w[i].y)-b;
//		s[i].x=s[i].x*2-1,s[i].y=s[i].y*2-1;
	for (MQ=1;MQ<bin;MQ<<=1); --MQ;
	memset(t,100,sizeof(t)); INF=t[0];
	for (i=1;i<=m;++i)
	{
		if (a[i].g<3) cghp(s[a[i].x].y,s[a[i].x].x,a[i].g);
		else if (a[i].g==3)
		{
			x=max(s[a[i].x].x,s[a[i].y].x); y=min(s[a[i].x].y,s[a[i].y].y);
			if (x>y) {puts("NO"); continue;}
			cghp(s[a[i].x].y,s[a[i].x].x,2);
			cghp(s[a[i].y].y,s[a[i].y].x,2);
			if (getmin(y,bin)<=x) puts("NO"); else puts("YES");
			cghp(s[a[i].x].y,s[a[i].x].x,1);
			cghp(s[a[i].y].y,s[a[i].y].x,1);
		}
	}
}

#pragma comment(linker, "/stack:200000000")
#pragma GCC optimize("Ofast")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")

#include <bits/stdc++.h>

#define F0R(i, a) for (int i = 0; i < (a); i++)
#define FOR(i, a, b) for (int i = (a); i < (b); i++)
#define R0F(i, a) for (int i = (a) - 1; i >= 0; i--)
#define ROF(i, a, b) for (int i = (b) - 1; i >= (a); i--)

#define ran() (rand() & 0x7FFF)
#define rand31() ((ran() << 16) | (ran() << 1) | (ran() & 1))
#define rand32() ((ran() << 17) | (ran() << 2) | (ran() & 3))
#define rand63() (((ll)ran() << 48) | ((ll)ran() << 33) | ((ll)ran() << 18) | ((ll)ran() << 3) | ((ll)ran() & 7))
#define rand64() (((ll)ran() << 49) | ((ll)ran() << 34) | ((ll)ran() << 19) | ((ll)ran() << 4) | ((ll)ran() & 15))

#define F first
#define S second
#define PB push_back
#define MP make_pair
#define MT make_tuple
#define UB upper_bound
#define LB lower_bound
#define X real()
#define Y imag()

#define INF 1e18
#define PI acos(-1)

#define sz(x) ((int)(x).size())
#define all(x) (x).begin(), (x).end()
#define SQ(x) ((x) * (x))

using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef vector<int> vi;
typedef vector<pii> vpii;
typedef vector<ll> vll;
typedef vector<ull> vul;

#define MAXN 500000

struct angle {

ll y, x;

bool operator<(const angle& a2) const {
    return x * a2.y - y * a2.x > 0;
}

bool operator==(const angle& a2) const {
    return x * a2.y == y * a2.x;
}

bool operator<=(const angle& a2) const { return *this < a2 || *this == a2; }

bool operator>=(const angle& a2) const { return a2 < *this; }

angle operator+(const angle& a2) const {
    return {y * a2.x + a2.y * x, x * a2.x - y * a2.y};
}

};

struct SegTree{

int sz;
angle *tree;

SegTree(int _sz) {
    sz = 1 << (32 - __builtin_clz(_sz - 1));
    tree = new angle[2 * sz];
    F0R(i, 2 * sz) tree[i] = angle({0, 1});
}

void upd(int idx, angle v) {
    idx += sz;
    tree[idx] = v;
    for (idx /= 2; idx > 0; idx /= 2) tree[idx] = max(tree[2 * idx], tree[2 * idx + 1]);
}

angle query(int lo, int hi) {
    lo += sz, hi += sz;
    angle res = angle({0, 1});
    while(lo <= hi) {
        if ((lo % 2) == 1) res = max(res, tree[lo++]);
        if ((hi % 2) == 0) res = max(res, tree[hi--]);
        lo /= 2;
        hi /= 2;
    }
    return res;
}

};

ll r;
angle alpha[MAXN], beta123[MAXN];
int n, q, posof[MAXN];
vector<pair<angle, int>> order;
vpii updates;
vector<pair<int, pii>> queries;

SegTree st(2);

void toggle(int idx) {
    int pos = posof[idx];
    if (st.query(pos, pos) == angle({0, 1})) st.upd(pos, beta123[idx]);
    else st.upd(pos, {0, 1});
}

int main() {
    ios::sync_with_stdio(0);
    cin.tie(0);
    cin >> r >> q;
    F0R(i, q) {
        int t;
        cin >> t;
        switch(t) {
            case 1:
                ll x, y;
                cin >> x >> y;
                alpha[n] = {y, r - x};
                beta123[n] = {y, x + r};
                updates.PB(MP(i, n++));
                break;
            case 2:
                int idx;
                cin >> idx;
                idx--;
                updates.PB(MP(i, idx));
                break;
            case 3:
                int a, b;
                cin >> a >> b;
                a--, b--;
                queries.PB(MP(i, MP(a, b)));
                break;
        }
    }
    F0R(i, n) order.PB(MP(alpha[i], i));
    sort(all(order));
    F0R(i, n) posof[order[i].S] = i;
    reverse(all(updates));
    reverse(all(queries));
    st = SegTree(n);
    while (!updates.empty() || !queries.empty()) {
        if (queries.empty() || (!updates.empty() && updates.back().F < queries.back().F)) {
            int idx = updates.back().S;
            updates.pop_back();
            toggle(idx);
        } else {
            int a = queries.back().S.F;
            int b = queries.back().S.S;
            queries.pop_back();
            angle _alpha = min(alpha[a], alpha[b]);
            angle _beta123 = min(beta123[a], beta123[b]);
            if(_alpha + _beta123 <= angle({1, 0})) {
                cout << "NO\n";
            } else {
                toggle(a);
                toggle(b);

                int lo = LB(all(order), MP(_alpha, 0)) - order.begin();
                assert(lo == 0 || order[lo - 1].F < _alpha);
                if (st.query(lo, n - 1) >= _beta123) cout << "NO\n";
                else cout << "YES\n";

                toggle(a);
                toggle(b);
            }
        }
    }
}

#include<bits/stdc++.h>
using namespace std;
typedef double DB;
const DB EPS = 1e-12;
const int N = 500000+10;
DB r, x[N], y[N], ha[N], hb[N], ang1[N], ang2[N];
int t[N], a[N], b[N], ida[N], idb[N];

vector<int> VEC[N], vec[N];

void Add(int x, int y) {
	for (++x; x < N; x += x & -x) VEC[x].push_back(y);
}

void add(int x, int y, int val) {
	for (++x; x < N; x += x & -x) {
		int p = lower_bound(VEC[x].begin(), VEC[x].end(), y) - VEC[x].begin();
		for (++p; p < vec[x].size(); p += p & -p) {
			vec[x][p] += val;
		}
	}
}

int get(int x, int y) {
	int ret = 0;
	for (++x; x; x -= x & -x) {
		int p = upper_bound(VEC[x].begin(), VEC[x].end(), y) - VEC[x].begin() - 1;
		for (++p; p; p -= p & -p) {
			ret += vec[x][p];
		}
	}
	return ret;
}

int main() {
	int n; cin >> r >> n;
	int now = 1;
	for (int i = 0; i < n; i ++) {
		scanf("%d", t+i);
		if (t[i] == 1) {
			scanf("%lf%lf", x+now, y+now);
			++now;
		}
		if (t[i] == 2) {
			scanf("%d", a+i);
		}
		if (t[i] == 3) {
			scanf("%d%d", a+i, b+i);
		}
	}
	int han = 0, hbn = 0;
	for (int i = 1; i < now; i ++) {
		ang1[i] = atan2(y[i], x[i] + r);
		ang2[i] = atan2(y[i], x[i] - r);
		ha[han++] = ang1[i];
		hb[hbn++] = ang2[i];
	}
	sort(ha, ha + han);
	sort(hb, hb + hbn);
	for (int i = 1; i < now; i ++) {
		ida[i] = lower_bound(ha, ha + han, ang1[i] - EPS) - ha;
		idb[i] = lower_bound(hb, hb + hbn, ang2[i] - EPS) - hb;
	}
	for (int i = 1; i < now; i ++) Add(ida[i], idb[i]);
	for (int i = 0; i < N; i ++) {
		sort(VEC[i].begin(), VEC[i].end());
		vec[i].resize(VEC[i].size() + 1);
	}
	now = 1;
	for (int i = 0; i < n; i ++) {
		if (t[i] == 1) {
			add(ida[now], idb[now], 1);
			++now;
		}
		if (t[i] == 2) {
			add(ida[a[i]], idb[a[i]], -1);
		}
		if (t[i] == 3) {
			int xmin, ymin, xmax, ymax;
			xmin = ida[a[i]], xmax = ida[b[i]];
			if (xmin > xmax) swap(xmin, xmax);
			ymin = idb[a[i]], ymax = idb[b[i]];
			if (ymin > ymax) swap(ymin, ymax);
			--xmin, --ymin;
			int ret = get(xmax, ymax) - get(xmax, ymin) - get(xmin, ymax) + get(xmin, ymin);
			if (ret > 2) puts("NO");
			else puts("YES");
		}
	}
	return 0;
}

#include <bits/stdc++.h>
using namespace std;

#define ms(s, n) memset(s, n, sizeof(s))
#define FOR(i, a, b) for (int i = (a); i < (b); i++)
#define FORd(i, a, b) for (int i = (a) - 1; i >= (b); i--)
#define FORall(it, a) for (__typeof((a).begin()) it = (a).begin(); it != (a).end(); it++)
#define sz(a) int((a).size())
#define present(t, x) (t.find(x) != t.end())
#define all(a) (a).begin(), (a).end()
#define uni(a) (a).erase(unique(all(a)), (a).end())
#define pb push_back
#define pf push_front
#define mp make_pair
#define fi first
#define se second
#define prec(n) fixed<<setprecision(n)
#define bit(n, i) (((n) >> (i)) & 1)
#define bitcount(n) __builtin_popcountll(n)
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef pair<int, int> pi;
typedef vector<int> vi;
typedef vector<pi> vii;
const int MOD = (int) 1e9 + 7;
const int MOD2 = 1007681537;
const int INF = (int) 1e9;
const ll LINF = (ll) 1e18;
const ld PI = acos((ld) -1);
const ld EPS = 1e-9;
inline ll gcd(ll a, ll b) {ll r; while (b) {r = a % b; a = b; b = r;} return a;}
inline ll lcm(ll a, ll b) {return a / gcd(a, b) * b;}
inline ll fpow(ll n, ll k, int p = MOD) {ll r = 1; for (; k; k >>= 1) {if (k & 1) r = r * n % p; n = n * n % p;} return r;}
template<class T> inline int chkmin(T& a, const T& val) {return val < a ? a = val, 1 : 0;}
template<class T> inline int chkmax(T& a, const T& val) {return a < val ? a = val, 1 : 0;}
inline ll isqrt(ll k) {ll r = sqrt(k) + 1; while (r * r > k) r--; return r;}
inline ll icbrt(ll k) {ll r = cbrt(k) + 1; while (r * r * r > k) r--; return r;}
inline void addmod(int& a, int val, int p = MOD) {if ((a = (a + val)) >= p) a -= p;}
inline void submod(int& a, int val, int p = MOD) {if ((a = (a - val)) < 0) a += p;}
inline int mult(int a, int b, int p = MOD) {return (ll) a * b % p;}
inline int inv(int a, int p = MOD) {return fpow(a, p - 2, p);}
inline int sign(ld x) {return x < -EPS ? -1 : x > +EPS;}
inline int sign(ld x, ld y) {return sign(x - y);}
#define db(x) cerr << #x << " = " << (x) << " ";
#define endln cerr << "\n";

const int maxn = 5e5 + 5;
int n, d, k;
int op[maxn];
int x[maxn];
int y[maxn];
int z[maxn];
int l[maxn];
int r[maxn];
int a[maxn];
int b[maxn];

long long ff1(int i, int j) {
    int x1 = x[i] + d;
    int y1 = y[i] + 0;
    int x2 = x[j] + d;
    int y2 = y[j] + 0;
    return (long long) x1 * y2 - (long long) x2 * y1;
}

long long ff2(int i, int j) {
    int x1 = x[i] - d;
    int y1 = y[i] - 0;
    int x2 = x[j] - d;
    int y2 = y[j] - 0;
    return (long long) x1 * y2 - (long long) x2 * y1;
}

int cmp1(int i, int j) {
    long long cr = ff1(i, j);
    if (cr) return cr > 0;
    return i < j;
}

int cmp2(int i, int j) {
    long long cr = ff2(i, j);
    if (cr) return cr > 0;
    return i < j;
}

multiset<int> heap[maxn];
int st[maxn << 1];
void upd(int p, int n, int val) {
    for (st[p += n] = val; p > 1; ) p >>= 1, st[p] = min(st[p << 1], st[p << 1 | 1]);
}
int query(int l, int r, int n) {
    int res = INF;
    for (l += n, r += n + 1; l < r; l >>= 1, r >>= 1) {
        if (l & 1) chkmin(res, st[l++]);
        if (r & 1) chkmin(res, st[--r]);
    }
    return res;
}

void upd(int u, int n) {
    int val = sz(heap[u]) ? *heap[u].begin() : INF;
    upd(u, n, val);
}

long long dot(pi a, pi b) {
    return (long long) a.fi * b.fi + (long long) a.se * b.se;
}

void solve() {
    cin >> d >> n;
    FOR(i, 0, n) {
        cin >> op[i];
        if (op[i] == 1) {
            cin >> x[k] >> y[k], k++;
        }
        else if (op[i] == 2) {
            cin >> z[i], z[i]--;
        }
        else {
            cin >> l[i] >> r[i], l[i]--, r[i]--;
        }
    }
    vi ver; FOR(i, 0, k) ver.pb(i);
    sort(all(ver), cmp1);
    int st1 = 0;
    FOR(i, 0, k) {
        if (i && ff1(ver[i - 1], ver[i])) st1++;
        a[ver[i]] = st1;
    }
    FOR(i, 0, k) a[i] = st1 - a[i];
    int st2 = 0;
    sort(all(ver), cmp2);
    FOR(i, 0, k) {
        if (i && ff2(ver[i - 1], ver[i])) st2++;
        b[ver[i]] = st2;
    }
    FOR(i, 0, k + k) st[i] = INF;
    k = 0;
    FOR(i, 0, n) {
        if (op[i] == 1) {
            heap[a[k]].insert(b[k]);
            upd(a[k], st1 + 1);
            k++;
        }
        else if (op[i] == 2) {
            int ix = z[i];
            heap[a[ix]].erase(heap[a[ix]].find(b[ix]));
            upd(a[ix], st1 + 1);
        }
        else {
            int ix1 = l[i];
            int ix2 = r[i];
            int u = max(a[ix1], a[ix2]);
            int v = max(b[ix1], b[ix2]);
            pi c, d;
            if (a[ix1] > a[ix2]) {
                c = mp(x[ix1], y[ix1]);
            }
            else {
                c = mp(x[ix2], y[ix2]);
            }
            if (b[ix1] > b[ix2]) {
                d = mp(x[ix1], y[ix1]);
            }
            else {
                d = mp(x[ix2], y[ix2]);
            }
            heap[a[ix1]].erase(heap[a[ix1]].find(b[ix1]));
            upd(a[ix1], st1 + 1);
            heap[a[ix2]].erase(heap[a[ix2]].find(b[ix2]));
            upd(a[ix2], st1 + 1);
            if (dot(c, d) < 0 || query(0, u, st1 + 1) <= v) {
                cout << "NO\n";
            }
            else {
                cout << "YES\n";
            }
            heap[a[ix1]].insert(b[ix1]);
            upd(a[ix1], st1 + 1);
            heap[a[ix2]].insert(b[ix2]);
            upd(a[ix2], st1 + 1);
        }
    }
}

int main() {
    int JUDGE_ONLINE = 1;
    if (fopen("in.txt", "r")) {
        JUDGE_ONLINE = 0;
        assert(freopen("in.txt", "r", stdin));
        //assert(freopen("out.txt", "w", stdout));
    }
    else {
        ios_base::sync_with_stdio(0), cin.tie(0);
    }
    solve();
    if (!JUDGE_ONLINE) {
        //cout << "\nTime elapsed: " << 1000 * clock() / CLOCKS_PER_SEC << "ms\n";
    }
    return 0;
}

#include<iostream>
#include<cstdlib>
#include<stdio.h>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<vector>
#include<set>
#include<map>
using namespace std;
long long r;
int n,cnt,list[501000],cnt_list,mf[1010000];
struct segment_tree
{
	int l,r,min_vl,lazy;
};
segment_tree tree[1<<21];
struct point
{
	long long x,y;
	int z;
	bool operator <(const point &temp)const
	{
		  return y*temp.x<x*temp.y;
	}
};
point pt[1000001];
struct query
{
	int u,v,flag,id;
	long long x,y;
	point l,r;
};
query qy[501000];
void build(int left,int right,int id)
{
	int l=2*id+1,r=2*id+2,mid=(left+right)>>1;
	tree[id].min_vl=tree[id].lazy=0;
	tree[id].l=left;
	tree[id].r=right;
	if(left==right)
	    return;
    build(left,mid,l);
    build(mid+1,right,r);
}
void zz(int id)
{
	if(tree[id].lazy==0)
	    return;
	int l=2*id+1,r=2*id+2;
	if(tree[id].l!=tree[id].r)
	{
		tree[l].lazy+=tree[id].lazy;
		tree[r].lazy+=tree[id].lazy;
	}
	tree[id].min_vl+=tree[id].lazy;
	tree[id].lazy=0;
}
void update(int left,int right,int vl,int id)
{
	int l=2*id+1,r=2*id+2;
	if(tree[id].l>right||tree[id].r<left)
	{
	     zz(id);
	     return;
	}
    if(tree[id].l>=left&&tree[id].r<=right)
    {
    	tree[id].lazy+=vl;
    	zz(id);
    	return;
    }
    zz(id);
    update(left,right,vl,l);
    update(left,right,vl,r);
    tree[id].min_vl=min(tree[l].min_vl,tree[r].min_vl);
}
int qw(int left,int right,int id)
{
	int l=2*id+1,r=2*id+2;
	zz(id);
	if(tree[id].l>right||tree[id].r<left)
	    return 1e9+9;
    if(tree[id].l>=left&&tree[id].r<=right)
    	return tree[id].min_vl;
	return min(qw(left,right,l),qw(left,right,r));
}
int binary(int left,int right,point now)
{
	int mid;
	while(left<=right)
	{
		mid=(left+right)>>1;
		if(pt[mid]<now)
			left=mid+1;
		else if(now<pt[mid])
		    right=mid-1;
        else
            return mid;
	}
}
int main()
{
	scanf("%lld%d",&r,&n);
	int i,j,s,p,q,l_id,r_id;
	long long ru;
	cnt=0;
	cnt_list=0;
	memset(mf,0,sizeof(mf));
	for(i=0;i<n;i++)
	{
		scanf("%d",&qy[i].flag);
		if(qy[i].flag==1)
		{
			list[cnt_list++]=i;
            scanf("%lld%lld",&qy[i].x,&qy[i].y);
		   	pt[cnt].x=qy[i].y;
            pt[cnt++].y=r-qy[i].x;
			qy[i].r=pt[cnt-1];
		   	pt[cnt].x=qy[i].x+r;
            pt[cnt++].y=qy[i].y;
			qy[i].id=cnt_list-1;
		    qy[i].l=pt[cnt-1];
		    if(qy[i].r<qy[i].l)
		        swap(qy[i].l,qy[i].r);
		}
		else if(qy[i].flag==2)
        {
           scanf("%d",&qy[i].u);
           qy[i].u--;
        }
        else
        {
        	scanf("%d%d",&qy[i].u,&qy[i].v);
        	qy[i].u--;
        	qy[i].v--;
        }
	}
	sort(pt,pt+cnt);
	int nn=0;
	for(i=0;i<cnt;i++)
	{
		if(nn==0||(pt[i].x!=pt[nn-1].x||pt[i].y!=pt[nn-1].y))
		    pt[nn++]=pt[i];
	}
	cnt=nn;
	build(0,cnt-1,0);
	point ll,rr;
	for(i=0;i<n;i++)
	{
		int flag;
		if(qy[i].flag==1)
		{
		   flag=1;
		   ll=qy[i].l;
		   rr=qy[i].r;
		}
		else if(qy[i].flag==2)
		{
			flag=-1;
			ll=qy[list[qy[i].u]].l;
			rr=qy[list[qy[i].u]].r;
		}
		if(qy[i].flag==1||qy[i].flag==2)
		{
    		l_id=binary(0,cnt-1,ll);
    		r_id=binary(0,cnt-1,rr);
    		mf[r_id]+=flag;
    		if(l_id<r_id)
    	        update(l_id,r_id-1,flag,0);
		}
		else
		{
			int id1,id2;
			id1=qy[i].u;
			id2=qy[i].v;
		    ll=qy[list[id1]].l;
		    rr=qy[list[id1]].r;
            if(ll<qy[list[id2]].l)
               ll=qy[list[id2]].l;
            if(qy[list[id2]].r<rr)
               rr=qy[list[id2]].r;
            bool ans;
            if(rr<ll)
               ans=0;
            else
            {
            	l_id=binary(0,cnt-1,ll);
            	r_id=binary(0,cnt-1,rr);
               	ans=l_id<r_id&&qw(l_id,r_id-1,0)<=2;
            	ans|=mf[r_id]+qw(r_id,r_id,0)<=2;
            }
            if(ans)
               puts("YES");
            else
               puts("NO");
		}
	}
	return 0;
}
/*

100000000 5
1 -106382777 300000523
1 -75340202 300000165
1 -148918484 300000552
1 96360393 300000458
3 3 2
*/

#include <bits/stdc++.h>
#ifndef ONLINE_JUDGE
# include <sys/time.h>
# include <sys/resource.h>
#endif

/*** TEMPLATE CODE STARTS HERE ***/

#ifndef M_PI
#define M_PI 3.1415926535897932384626433832795028841971693993751
#endif

using namespace std;

typedef vector<string> vs;
typedef long long ll;
typedef vector<ll> vi;
typedef pair<ll, ll> pii;

#define RA(x) begin(x), end(x)
#define FE(i, x) for (auto i = begin(x); i != end(x); ++i)
#define SZ(x) ((int) (x).size())

template<class T>
void splitstr(const string &s, vector<T> &out)
{
    istringstream in(s);
    out.clear();
    copy(istream_iterator<T>(in), istream_iterator<T>(), back_inserter(out));
}

template<class T> T gcd(T a, T b) { return b ? gcd(b, a % b) : a; }

static void redirect(int argc, const char **argv)
{
#ifndef ONLINE_JUDGE
    struct rlimit rlim;
    getrlimit(RLIMIT_STACK, &rlim);
    rlim.rlim_cur = 256 * 1024 * 1024;
    setrlimit(RLIMIT_STACK, &rlim);
    getrlimit(RLIMIT_DATA, &rlim);
    rlim.rlim_cur = 256 * 1024 * 1024;
    setrlimit(RLIMIT_DATA, &rlim);
#endif

    ios::sync_with_stdio(false);
    cin.tie(NULL);
    if (argc > 1)
    {
        static filebuf f;
        f.open(argv[1], ios::in);
        cin.rdbuf(&f);
        if (!cin)
        {
            cerr << "Failed to open '" << argv[1] << "'" << endl;
            exit(1);
        }
    }

    if (argc > 2)
    {
        static filebuf f;
        f.open(argv[2], ios::out | ios::trunc);
        cout.rdbuf(&f);
        if (!cout)
        {
            cerr << "Failed to open '" << argv[2] << "'" << endl;
        }
    }
}

typedef std::complex<ll> pnt;

static inline ll dot(const pnt &a, const pnt &b)
{
    return real(conj(a) * b);
}

static inline ll cross(const pnt &a, const pnt &b)
{
    return imag(conj(a) * b);
}

static inline ll cross(const pnt &a, const pnt &b, const pnt &c)
{
    return cross(b - a, c - a);
}

class CompareAngle
{
private:
    const pnt base;

public:
    explicit CompareAngle(const pnt &base) : base(base) {}

    bool operator()(const pnt &a, const pnt &b) const
    {
        const pnt da = a - base;
        const pnt db = b - base;
        bool fa = da.imag() > 0 || (da.imag() == 0 && da.real() >= 0);
        bool fb = db.imag() > 0 || (db.imag() == 0 && db.real() >= 0);
        if (fa != fb)
            return fa;
        else
        {
            ll c = cross(da, db);
            if (c != 0)
                return c > 0;
            else
                return dot(da, da) < dot(db, db);
        }
    }
};

template<typename T, typename Op = std::plus<T>>
class SegTree
{
    typedef std::size_t size_type;

    T identity;
    Op op;
    std::vector<T> nodes;

public:
    explicit SegTree(std::size_t n = 0, const T &identity = T(), const Op &op = Op())
        : identity(identity), op(op), nodes(2 * n, this->identity)
    {
        for (int i = n - 1; i > 0; i--)
            nodes[i] = this->op(nodes[2 * i], nodes[2 * i + 1]);
    }

    template<typename Iterator>
    SegTree(Iterator first, Iterator last, const T &identity = T(), const Op &op = Op())
        : identity(identity), op(op)
    {
        size_type n = std::distance(first, last);
        nodes.reserve(2 * n);
        nodes.resize(n, this->identity);
        nodes.insert(nodes.end(), first, last);
        for (int i = n - 1; i > 0; i--)
            nodes[i] = this->op(nodes[2 * i], nodes[2 * i + 1]);
    }

    size_type size() const { return nodes.size() / 2;}

    void set(size_type idx, T value)
    {
        assert(0 <= idx && idx < size());
        idx += size();
        nodes[idx] = std::move(value);
        while (idx > 0)
        {
            idx /= 2;
            nodes[idx] = op(nodes[2 * idx], nodes[2 * idx + 1]);
        }
    }

    const T &operator[](size_type idx) const
    {
        assert(0 <= idx && idx < size());
        return nodes[idx + size()];
    }

    T query(size_type a, size_type b) const
    {
        assert(0 <= a && a <= size());
        assert(0 <= b && b <= size());
        a += size();
        b += size();
        T left = identity, right = identity;
        while (a < b)
        {
            if (a & 1)
                left = op(left, nodes[a++]);
            if (b & 1)
                right = op(nodes[--b], right);
            a /= 2;
            b /= 2;
        }
        return op(left, right);
    }
};

class Bignum
{
public:
    static const int radix = 256;

private:
    std::vector<int> digits;

    void set(int d, int v)
    {
        if (d >= (int) digits.size())
            digits.resize(d + 1);
        digits[d] = v;
    }

    void reduce()
    {
        while (!digits.empty() && digits.back() == 0)
            digits.pop_back();
    }

public:
    Bignum() : digits() {}

    int get(int d) const
    {
        return d < (int) digits.size() ? digits[d] : 0;
    }

    bool empty() const { return digits.empty(); }
    int size() const { return digits.size(); }

    Bignum(long long initial)
    {
        assert(initial >= 0);
        while (initial > 0)
        {
            digits.push_back(initial % radix);
            initial /= radix;
        }
    }

    Bignum operator+(const Bignum &b) const
    {
        Bignum ans;
        int carry = 0;
        for (int i = 0; i < size() || i < b.size() || carry; i++)
        {
            carry += get(i) + b.get(i);
            if (carry >= radix)
            {
                ans.set(i, carry - radix);
                carry = 1;
            }
            else
            {
                ans.set(i, carry);
                carry = 0;
            }
        }
        return ans;
    }

    Bignum &operator+=(const Bignum &b)
    {
        int carry = 0;
        for (int i = 0; i < b.size() || carry; i++)
        {
            carry += get(i) + b.get(i);
            if (carry >= radix)
            {
                set(i, carry - radix);
                carry = 1;
            }
            else
            {
                set(i, carry);
                carry = 0;
            }
        }
        return *this;
    }

    Bignum operator-(const Bignum &b) const
    {
        Bignum ans;

        assert(size() >= b.size());
        int carry = 0;
        for (int i = 0; i < size(); i++)
        {
            carry = carry + get(i) - b.get(i);
            if (carry >= 0)
            {
                ans.set(i, carry);
                carry = 0;
            }
            else
            {
                ans.set(i, carry + radix);
                carry = -1;
            }
        }
        assert(carry == 0);
        ans.reduce();
        return ans;
    }

    Bignum &operator-=(const Bignum &b)
    {
        assert(size() >= b.size());
        int carry = 0;
        for (int i = 0; i < b.size() || carry; i++)
        {
            assert(i < size());
            carry = carry + get(i) - b.get(i);
            if (carry >= 0)
            {
                set(i, carry);
                carry = 0;
            }
            else
            {
                set(i, carry + radix);
                carry = -1;
            }
        }
        reduce();
        return *this;
    }

    Bignum operator*(const Bignum &b) const
    {
        Bignum ans;
        if (!empty() && !b.empty())
        {
            int carry = 0;
            for (int i = 0; i < size() + b.size() - 1 || carry; i++)
            {
                for (int j = std::max(i - b.size(), 0); j < std::min(i + 1, size()); j++)
                    carry += get(j) * b.get(i - j);
                ans.set(i, carry % radix);
                carry /= radix;
            }
        }
        return ans;
    }

    Bignum &operator*=(const Bignum &b)
    {
        return *this = *this * b;
    }

    // Multiplies by power of radix, not power of 2
    Bignum operator<<(int shift) const
    {
        assert(shift >= 0);
        Bignum ans;
        if (!empty())
        {
            ans.digits.resize(size() + shift);
            for (int i = 0; i < size(); i++)
            {
                ans.digits[i + shift] = digits[i];
            }
        }
        return ans;
    }

    Bignum &operator<<=(int shift)
    {
        assert(shift >= 0);
        if (!empty())
        {
            int old = size();
            digits.resize(old + shift);
            for (int i = old - 1; i >= 0; i--)
                digits[i + shift] = digits[i];
            std::fill(digits.begin(), digits.begin() + shift, 0);
        }
        return *this;
    }

    Bignum operator>>(int shift) const
    {
        assert(shift >= 0);
        Bignum ans;
        if (shift < size())
        {
            ans.digits.resize(size() - shift);
            for (int i = 0; i < size() - shift; i++)
                ans.digits[i] = digits[i + shift];
        }
        return ans;
    }

    Bignum &operator>>=(int shift)
    {
        assert(shift >= 0);
        if (shift < size())
        {
            for (int i = 0; i < size() - shift; i++)
                digits[i] = digits[i + shift];
            digits.resize(size() - shift);
        }
        else
            digits.clear();
        return *this;
    }

    bool operator<(const Bignum &b) const
    {
        if (size() != b.size())
            return size() < b.size();
        for (int i = size() - 1; i >= 0; i--)
            if (get(i) != b.get(i))
                return get(i) < b.get(i);
        return false;
    }

    bool operator==(const Bignum &b) const
    {
        if (size() != b.size())
            return false;
        return digits == b.digits;
    }

    bool operator>(const Bignum &b) const { return b < *this; }
    bool operator<=(const Bignum &b) const { return !(b < *this); }
    bool operator>=(const Bignum &b) const { return !(*this < b); }
    bool operator!=(const Bignum &b) const { return !(*this == b); }

    operator bool() const { return !digits.empty(); }
    bool operator!() const { return digits.empty(); }
};

/*** TEMPLATE CODE ENDS HERE */

typedef array<pair<int, int>, 3> sample;

struct opmin
{
    sample operator()(const sample &a, const sample &b) const
    {
        array<pair<int, int>, 6> comb;
        for (int i = 0; i < 3; i++)
        {
            comb[i] = a[i];
            comb[i + 3] = b[i];
        }
        sort(RA(comb));
        sample out;
        for (int i = 0; i < 3; i++)
            out[i] = comb[i];
        return out;
    }
};

struct event
{
    int t;
    int x, y;
};

static Bignum diff(Bignum a, Bignum b)
{
    return (b < a) ? a - b : b - a;
}

static Bignum calc(ll a, ll b, ll c, ll d)
{
    Bignum ab = Bignum(abs(a)) * Bignum(abs(b));
    Bignum cd = Bignum(abs(c)) * Bignum(abs(d));
    int sign = (a > 0) + (b > 0) + (c > 0) + (d > 0);
    if (sign & 1)
        return diff(ab, cd);
    else
        return ab + cd;
}

static bool cut_within(const pnt &a, const pnt &b, const pnt &p, const pnt &q, ll R)
{
#if 0
    ll c1 = cross(a, b, p);
    ll c2 = cross(a, b, q);
    ll det = c2 - c1;
    Bignum x = calc(c2, p.real(), -c1, q.real());
    Bignum y = calc(c2, p.imag(), -c1, q.imag());
    Bignum d = Bignum(abs(det)) * Bignum(R);
    return x * x + y * y < d * d;
#else
    ll c1 = cross(a, b, p);
    ll c2 = cross(a, b, q);
    ll det = c2 - c1;
    pnt scut = p * c2 - q * c1;
    ll x = scut.real();
    ll y = scut.imag();
    ll r = det * R;
    return x * x + y * y < r * r;
#endif
}

int main(int argc, const char **argv)
{
    redirect(argc, argv);
    ll R, N;
    cin >> R >> N;
    vector<event> events;
    vector<pnt> pnts;
    for (int i = 0; i < N; i++)
    {
        int t;
        cin >> t;
        if (t == 1)
        {
            int x, y;
            cin >> x >> y;
            events.push_back(event{1, SZ(pnts), -1});
            pnts.emplace_back(x, y);
        }
        else if (t == 2)
        {
            int idx;
            cin >> idx;
            idx--;
            events.push_back(event{2, idx, -1});
        }
        else
        {
            int a, b;
            cin >> a >> b;
            events.push_back(event{3, a - 1, b - 1});
        }
    }

    pnt A(-R, 0);
    pnt B(R, 0);
    int P = SZ(pnts);
    vector<int> byA(P);
    for (int i = 0; i < P; i++)
        byA[i] = i;
    auto byB = byA;
    CompareAngle cmpA(A);
    CompareAngle cmpB(B);
    sort(RA(byA), [&](int a, int b) { return cmpA(pnts[b], pnts[a]); });
    sort(RA(byB), [&](int a, int b) { return cmpB(pnts[a], pnts[b]); });
    vector<pair<int, int>> rank(P);

    rank[byA[0]].first = 0;
    int nxt = 0;
    for (int i = 1; i < P; i++)
    {
        if (cmpA(pnts[byA[i]], pnts[byA[i - 1]]))
            nxt++;
        rank[byA[i]].first = nxt;
    }
    int NA = nxt + 1;

    rank[byB[0]].second = 0;
    nxt = 0;
    for (int i = 1; i < P; i++)
    {
        if (cmpB(pnts[byB[i - 1]], pnts[byB[i]]))
            nxt++;
        rank[byB[i]].second = nxt;
    }

    set<int> active;
    vector<set<pair<int, int>>> line(NA);
    for (int i = 0; i < NA; i++)
        for (int j = 0; j < 3; j++)
            line[i].emplace(INT_MAX, INT_MAX);
    auto get_sample = [&](int row)
    {
        sample out;
        int p = 0;
        for (auto it = line[row].begin(); it != line[row].end() && p < 3; ++it, p++)
            out[p] = *it;
        for (int i = p; i < 3; i++)
            out[i] = make_pair(INT_MAX, INT_MAX);
        return out;
    };
    SegTree<sample, opmin> seg(NA, get_sample(0));
    for (const event &ev : events)
    {
        if (ev.t == 1)
        {
            active.insert(ev.x);
            auto r = rank[ev.x];
            line[r.first].emplace(r.second, ev.x);
            seg.set(r.first, get_sample(r.first));
        }
        else if (ev.t == 2)
        {
            active.erase(ev.x);
            auto r = rank[ev.x];
            line[r.first].erase(line[r.first].find(make_pair(r.second, ev.x)));
            seg.set(r.first, get_sample(r.first));
        }
        else
        {
            int ar = max(rank[ev.x].first, rank[ev.y].first);
            int br = max(rank[ev.x].second, rank[ev.y].second);
            bool good = true;
            if (cut_within(A, pnts[byA[ar]], B, pnts[byB[br]], R))
                good = false;
            else
            {
                sample samp = seg.query(0, ar + 1);
                for (int i = 0; i < 3; i++)
                    if (samp[i].first <= br && samp[i].second != ev.x && samp[i].second != ev.y)
                        good = false;
            }
            cout << (good ? "YES\n" : "NO\n");
        }
    }

    return 0;
}

#include <bits/stdc++.h>
#define SZ(X) ((int)(X).size())
#define ALL(X) (X).begin(), (X).end()
#define REP(I, N) for (int I = 0; I < (N); ++I)
#define REPP(I, A, B) for (int I = (A); I < (B); ++I)
#define RI(X) scanf("%d", &(X))
#define RII(X, Y) scanf("%d%d", &(X), &(Y))
#define RIII(X, Y, Z) scanf("%d%d%d", &(X), &(Y), &(Z))
#define DRI(X) int (X); scanf("%d", &X)
#define DRII(X, Y) int X, Y; scanf("%d%d", &X, &Y)
#define DRIII(X, Y, Z) int X, Y, Z; scanf("%d%d%d", &X, &Y, &Z)
#define RS(X) scanf("%s", (X))
#define CASET int ___T, case_n = 1; scanf("%d ", &___T); while (___T-- > 0)
#define MP make_pair
#define PB push_back
#define MS0(X) memset((X), 0, sizeof((X)))
#define MS1(X) memset((X), -1, sizeof((X)))
#define LEN(X) strlen(X)
#define PII pair<int,int>
#define VI vector<int>
#define VL vector<long long>
#define VPII vector<pair<int,int> >
#define PLL pair<long long,long long>
#define VPLL vector<pair<long long,long long> >
#define F first
#define S second
typedef long long LL;
using namespace std;
const int INF = 1e9+7;
const int SIZE = 1e6+10;
int R,N;
int in[SIZE][3];
PII R_R[SIZE];
VPII pp;
bool cmp(PII x,PII y){
    if((x.S>=0)!=(y.S>=0)){
        return x.F<y.F;
    }
    return (LL)x.F*y.S-(LL)x.S*y.F>0;
}
PII sat[SIZE],ll[SIZE],rr[SIZE];
int sid;
int my_gcd(int x,int y){
    x=abs(x);y=abs(y);
    if(!x||!y)return x+y;
    return __gcd(x,y);
}
PII get_left(int x,int y){
    x+=R;
    int gg=my_gcd(x,y);
    x/=gg;
    y/=gg;
    return MP(x,y);
}
PII get_right(int x,int y){
    x-=R;
    int gg=my_gcd(x,y);
    x/=gg;
    y/=gg;
    if(x<=0)return MP(y,-x);
    return MP(y,-x);
}
int mi[SIZE*4],pb[SIZE*4];
void push(int x){
    if(!pb[x])return;
    REP(i,2){
        mi[x*2+i]+=pb[x];
        pb[x*2+i]+=pb[x];
    }
    pb[x]=0;
}
void ins(int L,int R,int id,int x,int y,int v){
    //if(v==-1)printf("[%d,%d]:%d,%d\n",L,R,mi[id],pb[id]);
    if(R<x||L>y)return;
    if(L>=x&&R<=y){
        mi[id]+=v;
        pb[id]+=v;
        return;
    }
    int mm=(L+R)/2;
    push(id);
    ins(L,mm,id*2,x,y,v);
    ins(mm+1,R,id*2+1,x,y,v);
    mi[id]=min(mi[id*2],mi[id*2+1]);

}
int qq(int L,int R,int id,int x,int y){
    //printf("{%d,%d}:%d,%d\n",L,R,mi[id],pb[id]);
    if(L>y||R<x)return INF;
    if(L>=x&&R<=y){
        return mi[id];
    }
    int mm=(L+R)/2;
    push(id);
    return min(qq(L,mm,id*2,x,y),qq(mm+1,R,id*2+1,x,y));
}
void print(int L,int R,int id){
    printf("{%d,%d}:%d,%d\n",L,R,mi[id],pb[id]);
    if(L==R)return;
    int mm=(L+R)/2;
    print(L,mm,id*2);
    print(mm+1,R,id*2+1);
}
int main(){
    sid=0;
    RII(R,N);
    REP(i,N){
        RII(in[i][0],in[i][1]);
        if(in[i][0]!=2)RI(in[i][2]);
        if(in[i][0]==1){
            int x=in[i][1];
            int y=in[i][2];
            sid++;
            ll[sid]=get_left(x,y),rr[sid]=get_right(x,y);
            pp.PB(ll[sid]);
            pp.PB(rr[sid]);
            in[i][1]=sid;
        }
    }
    sort(ALL(pp),cmp);
    pp.resize(unique(ALL(pp))-pp.begin());
    map<PII,int>get_id;
    REP(i,SZ(pp))get_id[pp[i]]=i+1;
    REPP(i,1,sid+1)R_R[i]=MP(get_id[rr[i]],get_id[ll[i]]);
    //REPP(i,1,sid+1)printf("(%d,%d)\n",R_R[i].F,R_R[i].S);
    REP(i,N){
        //printf("op %d:\n",i);
        if(in[i][0]==1){
            ins(1,sid*4,1,R_R[in[i][1]].F*2,R_R[in[i][1]].S*2,1);
        }
        else if(in[i][0]==2){
            ins(1,sid*4,1,R_R[in[i][1]].F*2,R_R[in[i][1]].S*2,-1);
        }
        else{
            int x=max(R_R[in[i][1]].F,R_R[in[i][2]].F);
            int y=min(R_R[in[i][1]].S,R_R[in[i][2]].S);
            if(x>y)puts("NO");
            else{
                if(qq(1,sid*4,1,x*2,y*2)==2)puts("YES");
                else puts("NO");
            }
        }
        //print(1,sid*4,1);
    }
    return 0;
}

#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
inline int read()
{
	int x,f=1;char c;
	while((c=getchar())<'0'||c>'9')if(c=='-')f=0;
	for(x=c-'0';(c=getchar())>='0'&&c<='9';)x=x*10+c-'0';
	return f?x:-x;
}
#define MN 500000
#define N 524288
struct work{int t,z;double x,y;}w[MN+5],q[MN+5];
bool cmp(const work&a,const work&b){return a.x==b.x?a.t>b.t:a.x<b.x;}
double l[MN+5],r[MN+5],c[MN+5];
int cnt,ans[MN+5],t[N*2+5],qn;
void add(int k,int x){for(k+=N;k;k>>=1)t[k]+=x;}
int query(int l,int r)
{
	int res=0;
	for(l+=N-1,r+=N+1;l^r^1;l>>=1,r>>=1)
	{
		if(~l&1)res+=t[l+1];
		if( r&1)res+=t[r-1];
	}
	return res;
}
void solve(int l,int r)
{
	int mid=l+r>>1,i;
	if(l<r)solve(l,mid),solve(mid+1,r);
	for(qn=0,i=l;i<=mid;++i)if(w[i].t>0)q[++qn]=w[i];
	for(;i<=r;++i)if(!w[i].t)q[++qn]=w[i];
	sort(q+1,q+qn+1,cmp);
	for(i=1;i<=qn;++i)
		if(q[i].t)add(lower_bound(c+1,c+cnt+1,q[i].y)-c,q[i].z);
		else ans[q[i].z]+=query(lower_bound(c+1,c+cnt+1,q[i].y)-c,cnt);
	for(i=1;i<=qn;++i)if(q[i].t)add(lower_bound(c+1,c+cnt+1,q[i].y)-c,-q[i].z);
}
int main()
{
	int R=read(),n=read(),i,t,x,y;
	for(i=1;i<=n;++i)
	{
		t=read();x=read();
		if(t==1)
		{
			l[++cnt]=-atan2(y=read(),x+R);
			c[cnt]=r[cnt]=-atan2(y,x-R);
			w[i]=(work){1,1,l[cnt],r[cnt]};
		}
		if(t==2)w[i]=(work){1,-1,l[x],r[x]};
		if(t==3)
		{
			if(l[x]>l[y=read()])x^=y^=x^=y;
			if(r[x]+acos(-1)/2<l[y])w[i]=(work){-1,0,0,0},ans[i]=3;
			else w[i]=(work){0,i,l[y],r[x]<r[y]?r[x]:r[y]};
		}
	}
	sort(c+1,c+cnt+1);cnt=unique(c+1,c+cnt+1)-c-1;solve(1,n);
	for(i=1;i<=n;++i)if(ans[i])puts(ans[i]>2?"NO":"YES");
}

#include <cstdio>
#include <algorithm>
#include <cstring>
#include <queue>
#include <cmath>
#define ld double
#define l(a) (a<<1)
#define r(a) (a<<1|1)
#define MN 500005
#define MM 1000005
#define MD 4200005
#define eps 1e-13
using namespace std;
struct meg{int g,x,y;}a[MN];
struct itv1{ld x,y;}w[MN];
struct itv2{int x,y;}s[MN];
struct Que
{
	priority_queue <int> A,B;
	void push(int x) {A.push(x);}
	void dele(int x) {B.push(x);}
	int top()
	{
		while (!B.empty()&&A.top()==B.top()) A.pop(),B.pop();
		if (!A.empty()) return A.top(); else return 0;
	}
}q[MM];
ld b0[MM],b1[MM];
int m,MQ,tin,b0in,b1in,ra;
int t[MD];

inline int read()
{
	int n=0,f=1; char c=getchar();
	while (c<'0' || c>'9') {if(c=='-')f=-1; c=getchar();}
	while (c>='0' && c<='9') {n=n*10+c-'0'; c=getchar();}
	return n*f;
}

inline void getcg(int x,int z) {for (t[x+=MQ]=z,x>>=1;x;x>>=1) t[x]=max(t[l(x)],t[r(x)]);}
inline int getmax(int L,int R)
{
	int sum=0;
	for (L+=MQ,R+=MQ;L<=R;L>>=1,R>>=1)
	{
		if ( L&1) sum=max(sum,t[L++]);
		if (~R&1) sum=max(sum,t[R--]);
	}
	return sum;
}

void cghp(int x,int y,int g)
{
	int lt=q[x].top();
	if (g==1) q[x].push(y); else q[x].dele(y);
	if (lt!=q[x].top()) getcg(x,q[x].top());
}

int main()
{
	register int i,x,y,lt=0;
	ra=read(); m=read();
	for (i=1;i<=m;++i)
	{
		a[i].g=read();
		if (a[i].g==1)
		{
			x=read(); y=read(); a[i].x=++tin;
			w[tin].x=atan2(y,x-ra);
			w[tin].y=atan2(y,x+ra);
			b0[++b0in]=w[tin].x;
			b1[++b1in]=w[tin].y;
		}
		else if (a[i].g==2) a[i].x=read();
		else if (a[i].g==3) a[i].x=read(),a[i].y=read();
	}
	sort(b0+1,b0+b0in+1); sort(b1+1,b1+b1in+1);
	for (i=2,lt=0;i<=b0in;++i) {if (b0[i]-b0[i-1]<eps) ++lt; b0[i-lt]=b0[i];} b0in-=lt;
	for (i=2,lt=0;i<=b1in;++i) {if (b1[i]-b1[i-1]<eps) ++lt; b1[i-lt]=b1[i];} b1in-=lt;
	for (i=1;i<=tin;++i)
		s[i].x=lower_bound(b0+1,b0+b0in+1,w[i].x)-b0,
		s[i].y=lower_bound(b1+1,b1+b1in+1,w[i].y)-b1;
	for (MQ=1;MQ<b0in;MQ<<=1); --MQ;
	for (i=1;i<=m;++i)
	{
		if (a[i].g<3) cghp(s[a[i].x].x,s[a[i].x].y,a[i].g);
		else if (a[i].g==3)
		{
			if (max(w[a[i].x].x,w[a[i].y].x)-min(w[a[i].x].y,w[a[i].y].y)>acos(0)+eps) {puts("NO"); continue;}
			x=max(s[a[i].x].x,s[a[i].y].x); y=min(s[a[i].x].y,s[a[i].y].y);
			cghp(s[a[i].x].x,s[a[i].x].y,2);
			cghp(s[a[i].y].x,s[a[i].y].y,2);
			if (getmax(1,x)>=y) puts("NO"); else puts("YES");
			cghp(s[a[i].x].x,s[a[i].x].y,1);
			cghp(s[a[i].y].x,s[a[i].y].y,1);
		}
	}
}

#include <bits/stdc++.h>
#define SZ(X) ((int)(X).size())
#define ALL(X) (X).begin(), (X).end()
#define REP(I, N) for (int I = 0; I < (N); ++I)
#define REPP(I, A, B) for (int I = (A); I < (B); ++I)
#define RI(X) scanf("%d", &(X))
#define RII(X, Y) scanf("%d%d", &(X), &(Y))
#define RIII(X, Y, Z) scanf("%d%d%d", &(X), &(Y), &(Z))
#define DRI(X) int (X); scanf("%d", &X)
#define DRII(X, Y) int X, Y; scanf("%d%d", &X, &Y)
#define DRIII(X, Y, Z) int X, Y, Z; scanf("%d%d%d", &X, &Y, &Z)
#define RS(X) scanf("%s", (X))
#define CASET int ___T, case_n = 1; scanf("%d ", &___T); while (___T-- > 0)
#define MP make_pair
#define PB push_back
#define MS0(X) memset((X), 0, sizeof((X)))
#define MS1(X) memset((X), -1, sizeof((X)))
#define LEN(X) strlen(X)
#define PII pair<int,int>
#define VI vector<int>
#define VL vector<long long>
#define VPII vector<pair<int,int> >
#define PLL pair<long long,long long>
#define VPLL vector<pair<long long,long long> >
#define F first
#define S second
typedef long long LL;
using namespace std;
const int INF = 1e9+7;
const int SIZE = 1e6+10;
int R,N;
int in[SIZE][3];
PII R_R[SIZE];
VPII pp;
bool cmp(PII x,PII y){
    if((x.S>=0)!=(y.S>=0)){
        return x.S<y.S;
    }
    return (LL)x.F*y.S-(LL)x.S*y.F>0;
}
PII sat[SIZE],ll[SIZE],rr[SIZE];
int sid;
int my_gcd(int x,int y){
    x=abs(x);y=abs(y);
    if(!x||!y)return x+y;
    return __gcd(x,y);
}
PII get_left(int x,int y){
    x+=R;
    int gg=my_gcd(x,y);
    x/=gg;
    y/=gg;
    return MP(x,y);
}
PII get_right(int x,int y){
    x-=R;
    int gg=my_gcd(x,y);
    x/=gg;
    y/=gg;
    if(x<=0)return MP(y,-x);
    return MP(y,-x);
}
int mi[SIZE*8],pb[SIZE*8];
int tmp[SIZE*2];
void push(int x){
    if(!pb[x])return;
    REP(i,2){
        mi[x*2+i]+=pb[x];
        pb[x*2+i]+=pb[x];
    }
    pb[x]=0;
}
void ins(int L,int R,int id,int x,int y,int v){
    if(R<x||L>y)return;
    if(L>=x&&R<=y){
        mi[id]+=v;
        pb[id]+=v;
        return;
    }
    int mm=(L+R)/2;
    push(id);
    ins(L,mm,id*2,x,y,v);
    ins(mm+1,R,id*2+1,x,y,v);
    mi[id]=min(mi[id*2],mi[id*2+1]);

}
int qq(int L,int R,int id,int x,int y){
    if(L>y||R<x)return INF;
    if(L>=x&&R<=y){
        return mi[id];
    }
    int mm=(L+R)/2;
    push(id);
    int ret=min(qq(L,mm,id*2,x,y),qq(mm+1,R,id*2+1,x,y));
    mi[id]=min(mi[id*2],mi[id*2+1]);
    return ret;
}
int main(){
    sid=0;
    RII(R,N);
    REP(i,N){
        RII(in[i][0],in[i][1]);
        if(in[i][0]!=2)RI(in[i][2]);
        if(in[i][0]==1){
            int x=in[i][1];
            int y=in[i][2];
            sid++;
            ll[sid]=get_left(x,y),rr[sid]=get_right(x,y);
            pp.PB(ll[sid]);
            pp.PB(rr[sid]);
            in[i][1]=sid;
        }
    }
    sort(ALL(pp),cmp);
    pp.resize(unique(ALL(pp))-pp.begin());
    map<PII,int>get_id;
    REP(i,SZ(pp))get_id[pp[i]]=i+1;
    REPP(i,1,sid+1)R_R[i]=MP(get_id[rr[i]],get_id[ll[i]]);
    REP(i,N){
        if(in[i][0]==1){
            ins(1,sid*4,1,R_R[in[i][1]].F*2,R_R[in[i][1]].S*2,1);
        }
        else if(in[i][0]==2){
            ins(1,sid*4,1,R_R[in[i][1]].F*2,R_R[in[i][1]].S*2,-1);
        }
        else{
            int x=max(R_R[in[i][1]].F,R_R[in[i][2]].F);
            int y=min(R_R[in[i][1]].S,R_R[in[i][2]].S);
            if(x>y)puts("NO");
            else{
                if(qq(1,sid*4,1,x*2,y*2)==2)puts("YES");
                else puts("NO");
            }
        }
    }
    return 0;
}

#include <cstdio>
#include <algorithm>
#include <cstring>
#include <queue>
#include <cmath>
#define ll long long
#define ld long double
#define l(a) (a<<1)
#define r(a) (a<<1|1)
#define MN 500005
#define MM 1000005
#define MD 4200005
#define eps 1e-12
using namespace std;
int INF;
struct meg{int g,x,y;}a[MN];
struct itv1{ld x,y;}w[MN];
struct itv2{int x,y;}s[MN];
struct Que
{
	priority_queue <int,vector<int>,greater<int> > A,B;
	void push(int x) {A.push(x);}
	void dele(int x) {B.push(x);}
	int top()
	{
		while (!B.empty()&&A.top()==B.top()) A.pop(),B.pop();
		if (!A.empty()) return A.top(); else return INF;
	}
}q[MM];
ld b[MM];
ll ra;
int m,MQ,tin,bin;
int t[MD];

inline int read()
{
	int n=0,f=1; char c=getchar();
	while (c<'0' || c>'9') {if(c=='-')f=-1; c=getchar();}
	while (c>='0' && c<='9') {n=n*10+c-'0'; c=getchar();}
	return n*f;
}

inline void getcg(int x,int z) {for (t[x+=MQ]=z,x>>=1;x;x>>=1) t[x]=min(t[l(x)],t[r(x)]);}
inline int getmin(int L,int R)
{
	int sum=INF;
	for (L+=MQ,R+=MQ;L<=R;L>>=1,R>>=1)
	{
		if ( L&1) sum=min(sum,t[L++]);
		if (~R&1) sum=min(sum,t[R--]);
	}
	return sum;
}

ld cal(ll x0,ll y0,ll x1,ll y1,ll g)
{
	ld ki,bi;
	ki=(ld)(y1-y0)/(x1-x0);
	bi=(ld)y0-(ld)x0*(y1-y0)/(x1-x0);
	return acos((ld)(bi*bi-ra*ra)*g/(ki*ki+1)/(ra*ra));
}
void cghp(int x,int y,int g)
{
	int lt=q[x].top();
	if (g==1) q[x].push(y); else q[x].dele(y);
	if (lt!=q[x].top()) getcg(x,q[x].top());
}

int main()
{
	register int i,x,y,lt=0;
	ra=read(); m=read();
	for (i=1;i<=m;++i)
	{
		a[i].g=read();
		if (a[i].g==1)
		{
			x=read(); y=read(); a[i].x=++tin;
			w[tin].x=(ll)x>= ra?acos( 1):cal( ra,0,(ll)x,(ll)y, 1);
			w[tin].y=(ll)x<=-ra?acos(-1):cal(-ra,0,(ll)x,(ll)y,-1);
			b[++bin]=w[tin].x; b[++bin]=w[tin].y;
		}
		else if (a[i].g==2) a[i].x=read();
		else if (a[i].g==3) a[i].x=read(),a[i].y=read();
	}
	sort(b+1,b+bin+1);
	for (i=2;i<=bin;++i) {if (b[i]-b[i-1]<eps) ++lt; b[i-lt]=b[i];}
	bin-=lt;
	for (i=1;i<=tin;++i)
		s[i].x=lower_bound(b+1,b+bin+1,w[i].x)-b,
		s[i].y=lower_bound(b+1,b+bin+1,w[i].y)-b;
//		s[i].x=s[i].x*2-1,s[i].y=s[i].y*2-1;
	for (MQ=1;MQ<bin;MQ<<=1); --MQ;
	memset(t,100,sizeof(t)); INF=t[0];
	for (i=1;i<=m;++i)
	{
		if (a[i].g<3) cghp(s[a[i].x].y,s[a[i].x].x,a[i].g);
		else if (a[i].g==3)
		{
			x=max(s[a[i].x].x,s[a[i].y].x); y=min(s[a[i].x].y,s[a[i].y].y);
			if (x>y) {puts("NO"); continue;}
			cghp(s[a[i].x].y,s[a[i].x].x,2);
			cghp(s[a[i].y].y,s[a[i].y].x,2);
			if (getmin(y,bin)<=x) puts("NO"); else puts("YES");
			cghp(s[a[i].x].y,s[a[i].x].x,1);
			cghp(s[a[i].y].y,s[a[i].y].x,1);
		}
	}
}

#include<iostream>
#include<cstdlib>
#include<stdio.h>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<vector>
#include<set>
#include<map>
using namespace std;
long long r;
int n,cnt,list[501000],cnt_list,mf[1001000];
struct segment_tree
{
	int l,r,min_vl,lazy;
};
segment_tree tree[1<<21];
struct point
{
	long long x,y;
	bool operator <(const point &temp)const
	{
		  return y*temp.x<x*temp.y;
	}
};
point pt[1000001];
struct query
{
	int u,v,flag,id;
	long long x,y;
	point l,r;
};
query qy[501000];
void build(int left,int right,int id)
{
	int l=2*id+1,r=2*id+2,mid=(left+right)>>1;
	tree[id].min_vl=tree[id].lazy=0;
	tree[id].l=left;
	tree[id].r=right;
	if(left==right)
	    return;
    build(left,mid,l);
    build(mid+1,right,r);
}
void zz(int id)
{
	if(tree[id].lazy==0)
	    return;
	int l=2*id+1,r=2*id+2;
	if(tree[id].l!=tree[id].r)
	{
		tree[l].lazy+=tree[id].lazy;
		tree[r].lazy+=tree[id].lazy;
	}
	tree[id].min_vl+=tree[id].lazy;
	tree[id].lazy=0;
}
void update(int left,int right,int vl,int id)
{
	int l=2*id+1,r=2*id+2;
	if(tree[id].l>right||tree[id].r<left)
	{
	     zz(id);
	     return;
	}
    if(tree[id].l>=left&&tree[id].r<=right)
    {
    	tree[id].lazy+=vl;
    	zz(id);
    	return;
    }
    zz(id);
    update(left,right,vl,l);
    update(left,right,vl,r);
    tree[id].min_vl=min(tree[l].min_vl,tree[r].min_vl);
}
int qw(int left,int right,int id)
{
	int l=2*id+1,r=2*id+2;
	zz(id);
	if(tree[id].l>right||tree[id].r<left)
	    return 1e9+9;
    if(tree[id].l>=left&&tree[id].r<=right)
    	return tree[id].min_vl;
	return min(qw(left,right,l),qw(left,right,r));
}
int binary(int left,int right,point now)
{
	int mid;
	while(left<=right)
	{
		mid=(left+right)>>1;
		if(pt[mid]<now)
			left=mid+1;
		else if(now<pt[mid])
		    right=mid-1;
        else
            return mid;
	}
}
int main()
{
	scanf("%lld%d",&r,&n);
	int i,j,s,p,q,l_id,r_id;
	long long ru;
	cnt=0;
	cnt_list=0;
	for(i=0;i<n;i++)
	{
		scanf("%d",&qy[i].flag);
		if(qy[i].flag==1)
		{
			list[cnt_list++]=i;
            scanf("%lld%lld",&qy[i].x,&qy[i].y);
            pt[cnt].x=qy[i].x-r;
            pt[cnt++].y=qy[i].y;
			qy[i].r=pt[cnt-1];
            pt[cnt].x=qy[i].x+r;
            pt[cnt++].y=qy[i].y;
			qy[i].id=cnt_list-1;
		    qy[i].l=pt[cnt-1];
		}
		else if(qy[i].flag==2)
        {
           scanf("%d",&qy[i].u);
           qy[i].u--;
        }
        else
        {
        	scanf("%d%d",&qy[i].u,&qy[i].v);
        	qy[i].u--;
        	qy[i].v--;
        }
	}
	sort(pt,pt+cnt);
	int nn=0;
	for(i=0;i<cnt;i++)
	{
		if(nn==0||(pt[i].x!=pt[nn-1].x||pt[i].y!=pt[nn-1].y))
		    pt[nn++]=pt[i];
	}
	cnt=nn;
	build(0,cnt-1,0);
	point ll,rr;
	memset(mf,0,sizeof(mf));
	for(i=0;i<n;i++)
	{
		int flag;
		if(qy[i].flag==1)
		{
		   flag=1;
		   ll=qy[i].l;
		   rr=qy[i].r;
		}
		else if(qy[i].flag==2)
		{
			flag=-1;
			ll=qy[list[qy[i].u]].l;
			rr=qy[list[qy[i].u]].r;
		}
		if(qy[i].flag==1||qy[i].flag==2)
		{
    		l_id=binary(0,cnt-1,ll);
    		r_id=binary(0,cnt-1,rr);
    		mf[r_id]+=flag;
    		if(l_id<r_id)
    		   update(l_id,r_id-1,flag,0);
		}
		else
		{
			int id1,id2;
			id1=qy[i].u;
			id2=qy[i].v;
		    ll=qy[list[id1]].l;
		    rr=qy[list[id1]].r;
            if(ll<qy[list[id2]].l)
               ll=qy[list[id2]].l;
            if(qy[list[id2]].r<rr)
               rr=qy[list[id2]].r;
            bool ans;
            if(rr<ll)
               ans=0;
            else
            {
            	l_id=binary(0,cnt-1,ll);
            	r_id=binary(0,cnt-1,rr);
            	ans=(l_id<r_id&&qw(l_id,r_id-1,0)<=2);
    	        ans|=mf[r_id]+qw(r_id,r_id,0)<=2;
            }
            if(ans)
               puts("YES");
            else
               puts("NO");
		}
	}
	return 0;
}
/*

100000000 5
1 -106382777 300000523
1 -75340202 300000165
1 -148918484 300000552
1 96360393 300000458
3 3 2
*/

#pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")
#pragma GCC optimize("no-stack-protector")
#pragma GCC target("sse,sse2,ssse3,sse3,sse4,popcnt,avx,mmx,abm,tune=native")
#include <bits/stdc++.h>
#define DEBUG 1
using namespace std;

namespace output{
    void __(short x){cout<<x;}
    void __(unsigned x){cout<<x;}
    void __(int x){cout<<x;}
    void __(long long x){cout<<x;}
    void __(unsigned long long x){cout<<x;}
    void __(double x){cout<<x;}
    void __(long double x){cout<<x;}
    void __(char x){cout<<x;}
    void __(const char*x){cout<<x;}
    void __(const string&x){cout<<x;}
    void __(bool x){cout<<(x?"true":"false");}
    template<class S,class T>
    void __(const pair<S,T>&x){__(DEBUG?"(":""),__(x.first),__(DEBUG?", ":" "),__(x.second),__(DEBUG?")":"");}
    template<class T>
    void __(const vector<T>&x){__(DEBUG?"{":"");bool _=0;for(const auto&v:x)__(_?DEBUG?", ":" ":""),__(v),_=1;__(DEBUG?"}":"");}
    template<class T>
    void __(const set<T>&x){__(DEBUG?"{":"");bool _=0;for(const auto&v:x)__(_?DEBUG?", ":" ":""),__(v),_=1;__(DEBUG?"}":"");}
    template<class T>
    void __(const multiset<T>&x){__(DEBUG?"{":"");bool _=0;for(const auto&v:x)__(_?DEBUG?", ":" ":""),__(v),_=1;__(DEBUG?"}":"");}
    template<class S,class T>
    void __(const map<S,T>&x){__(DEBUG?"{":"");bool _=0;for(const auto&v:x)__(_?DEBUG?", ":" ":""),__(v),_=1;__(DEBUG?"}":"");}
    void pr(){cout<<"\n";}
    template<class S,class... T>
    void pr(const S&a,const T&...b){__(a);if(sizeof...(b))__(' ');pr(b...);}
}

using namespace output;

typedef long long ll;
typedef long double ld;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
typedef pair<int,char> pic;
typedef pair<double,double> pdd;
typedef pair<ld,ld> pld;
typedef vector<int> vi;
typedef vector<ll> vl;

#define pb push_back
#define fox(i,x,y) for(int i=(x);i<=(y);i++)
#define foxr(i,x,y) for(int i=(y);i>=(x);i--)
#define F first
#define S second

const int MN = 5e5+5;
const ld PI = (ld)4*atan((ld)1), eps = (ld)5e-19;
int N, R, i, j, x, y, cnt, nxt; ld st[3*MN];
map<ld,int> mp; set<ld> pnt[MN];
ld aa[MN], bb[MN];
struct qur{int t, x, y;}q[MN];

bool ok(int i,int j){
    ld x=min(aa[i],aa[j]);
    ld y=min(bb[i],bb[j]);
    return (x+y+eps>=PI/2);
}

void upd(int i,int s,int e,int ind,ld val,bool del=0){
    if(s!=e){
        if((s+e)/2<ind) upd(2*i+1,(s+e)/2+1,e,ind,val,del);
        else upd(2*i,s,(s+e)/2,ind,val,del);
        st[i]=max(st[2*i],st[2*i+1]);
    }
    else{
        if(del) pnt[s].erase(val);
        else pnt[s].insert(val);
        if(pnt[s].empty()) st[i]=-1;
        else{
            auto it=pnt[s].end(); it--;
            st[i]=*it;
        }
    }
}

ld qu(int i,int s,int e,int ss,int se){
    if(s>=ss&&e<=se) return st[i];
    else if((s+e)/2<ss) return qu(2*i+1,(s+e)/2+1,e,ss,se);
    else if((s+e)/2>=se) return qu(2*i,s,(s+e)/2,ss,se);
    else return max(qu(2*i,s,(s+e)/2,ss,se),qu(2*i+1,(s+e)/2+1,e,ss,se));
}

int main(){
    scanf("%d%d",&R,&N);
    for(i=1;i<=N;i++){
        scanf("%d%d",&q[i].t,&q[i].x);
        if(q[i].t==1){
            cnt ++;
            scanf("%d",&q[i].y);
            aa[cnt] = (ld)atan2((ld)q[i].y,(ld)q[i].x+R);
            bb[cnt] = PI-(ld)atan2((ld)q[i].y,(ld)q[i].x-R);
            //printf(">>> %.20Lf %.20Lf\n",aa[cnt],bb[cnt]);
            mp[aa[cnt]]=0;
        }
        else if(q[i].t==3)
            scanf("%d",&q[i].y);
    }
    for(auto it=mp.begin();it!=mp.end();it++)
        it->second = ++nxt;
    cnt = 0;
    for(i=1;i<=N;i++){
        if(q[i].t==1){
            cnt ++;
            upd(1,1,nxt,mp[aa[cnt]],bb[cnt],0);
        }
        else if(q[i].t==2){
            upd(1,1,nxt,mp[aa[q[i].x]],bb[q[i].x],1);
        }
        else{
            x=q[i].x, y=q[i].y;
            if(!ok(x,y)) printf("NO\n");
            else{
                ld ix=min(aa[x],aa[y]);
                ld iy=min(bb[x],bb[y]);
                int inx = mp.lower_bound(ix-eps)->second;
                upd(1,1,nxt,mp[aa[x]],bb[x],1);
                upd(1,1,nxt,mp[aa[y]],bb[y],1);
                if(qu(1,1,nxt,inx,nxt)>=iy) printf("NO\n");
                else printf("YES\n");
                upd(1,1,nxt,mp[aa[x]],bb[x],0);
                upd(1,1,nxt,mp[aa[y]],bb[y],0);
            }
        }
    }
    return 0;
}

#include<iostream>
#include<cstdlib>
#include<stdio.h>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<vector>
#include<set>
#include<map>
using namespace std;
const long double eps=1e-11;
long double r;
int n,cnt,list[501000],cnt_list;
struct segment_tree
{
	int l,r,min_vl,lazy;
};
segment_tree tree[1<<21];
struct point
{
	long double x,y;
	bool operator <(const point &temp)const
	{
		 int fg[2];
		 if(fabs(y)<eps)
		 {
 			if(fabs(x-r)<eps)
 			   fg[0]=-1;
	        if(fabs(x+r)<eps)
	            fg[0]=1;
 		}
 		else
 		   fg[0]=0;
        if(fabs(temp.y)<eps)
        {
        	if(fabs(temp.x-r)<eps)
        	   fg[1]==-1;
     	    if(fabs(temp.x+r)<eps)
     	       fg[1]=1;
        }
        else
            fg[1]=0;
        if(fg[0]!=fg[1])
            return fg[0]<fg[1];
		 return y*temp.x<x*temp.y-eps;
	}
};
point pt[1000001];
struct query
{
	int u,v,flag,id;
	long double x,y;
	point l,r;
};
query qy[501000];
void build(int left,int right,int id)
{
	int l=2*id+1,r=2*id+2,mid=(left+right)>>1;
	tree[id].min_vl=tree[id].lazy=0;
	tree[id].l=left;
	tree[id].r=right;
	if(left==right)
	    return;
    build(left,mid,l);
    build(mid+1,right,r);
}
void zz(int id)
{
	if(tree[id].lazy==0)
	    return;
	int l=2*id+1,r=2*id+2;
	if(tree[id].l!=tree[id].r)
	{
		tree[l].lazy+=tree[id].lazy;
		tree[r].lazy+=tree[id].lazy;
	}
	tree[id].min_vl+=tree[id].lazy;
	tree[id].lazy=0;
}
void update(int left,int right,int vl,int id)
{
	int l=2*id+1,r=2*id+2;
	if(tree[id].l>right||tree[id].r<left)
	{
	     zz(id);
	     return;
	}
    if(tree[id].l>=left&&tree[id].r<=right)
    {
    	tree[id].lazy+=vl;
    	zz(id);
    	return;
    }
    zz(id);
    update(left,right,vl,l);
    update(left,right,vl,r);
    tree[id].min_vl=min(tree[l].min_vl,tree[r].min_vl);
}
int qw(int left,int right,int id)
{
	int l=2*id+1,r=2*id+2;
	zz(id);
	if(tree[id].l>right||tree[id].r<left)
	    return 1e9+9;
    if(tree[id].l>=left&&tree[id].r<=right)
    	return tree[id].min_vl;
	return min(qw(left,right,l),qw(left,right,r));
}
int binary(int left,int right,point now)
{
	int mid;
	while(left<=right)
	{
		mid=(left+right)>>1;
		if(pt[mid]<now)
			left=mid+1;
		else if(now<pt[mid])
		    right=mid-1;
        else
            return mid;
	}
}
int main()
{
	double bx,by;
	scanf("%lf%d",&bx,&n);
	r=bx;
	int i,j,s,p,q,l_id,r_id;
	long double ru;
	//double bx,by;
	cnt=0;
	cnt_list=0;
	for(i=0;i<n;i++)
	{
		scanf("%d",&qy[i].flag);
		if(qy[i].flag==1)
		{
			list[cnt_list++]=i;
		    scanf("%lf%lf",&bx,&by);
		    qy[i].x=bx;
		    qy[i].y=by;
			//scanf("%lf%lf",&qy[i].x,&qy[i].y);
	        ru=(qy[i].x*qy[i].x+qy[i].y*qy[i].y-r*r)/(qy[i].x*qy[i].x+qy[i].y*qy[i].y+r*r+2*qy[i].x*r);
	        if(ru>=0&&ru<=1)
	        {
		        pt[cnt].x=qy[i].x+(-r-qy[i].x)*ru;
	            pt[cnt].y=qy[i].y+(0-qy[i].y)*ru;
	        }
	        else
	        {
	            pt[cnt].x=-r;
	            pt[cnt].y=0;
			}
			cnt++;
			qy[i].r=pt[cnt-1];
			ru=(qy[i].x*qy[i].x+qy[i].y*qy[i].y-r*r)/(qy[i].x*qy[i].x+qy[i].y*qy[i].y+r*r-2*qy[i].x*r);
			if(ru>=0&&ru<=1)
			{
				pt[cnt].x=qy[i].x+(r-qy[i].x)*ru;
				pt[cnt].y=qy[i].y+(0-qy[i].y)*ru;
			}
			else
			{
				pt[cnt].x=r;
				pt[cnt].y=0;
			}
			cnt++;
			qy[i].id=cnt_list-1;
		    qy[i].l=pt[cnt-1];
		}
		else if(qy[i].flag==2)
        {
           scanf("%d",&qy[i].u);
           qy[i].u--;
        }
        else
        {
        	scanf("%d%d",&qy[i].u,&qy[i].v);
        	qy[i].u--;
        	qy[i].v--;
        }
	}
	sort(pt,pt+cnt);
	int nn=0;
	for(i=0;i<cnt;i++)
	{
		if(nn==0||(fabs(pt[i].x-pt[nn-1].x)+fabs(pt[i].y-pt[nn-1].y))>eps)
		    pt[nn++]=pt[i];
	}
	cnt=nn;
	build(0,cnt-1,0);
	point ll,rr;
	for(i=0;i<n;i++)
	{
		int flag;
		if(qy[i].flag==1)
		{
		   flag=1;
		   ll=qy[i].l;
		   rr=qy[i].r;
		}
		else if(qy[i].flag==2)
		{
			flag=-1;
			ll=qy[list[qy[i].u]].l;
			rr=qy[list[qy[i].u]].r;
		}
		if(qy[i].flag==1||qy[i].flag==2)
		{
    		l_id=binary(0,cnt-1,ll);
    		r_id=binary(0,cnt-1,rr);
    	//	printf("l_id=%d,r_id=%d\n",l_id,r_id);
    	//	while(l_id==r_id)
    	//	   puts("orz");
    		if(l_id<r_id)
    		   update(l_id,r_id-1,flag,0);
		}
		else
		{
			ll.x=r;
			ll.y=0;
			rr.x=-r;
			rr.y=0;
			int id1,id2;
			id1=qy[i].u;
			id2=qy[i].v;
			if(ll<qy[list[id1]].l)
			   ll=qy[list[id1]].l;
            if(ll<qy[list[id2]].l)
               ll=qy[list[id2]].l;
		    if(qy[list[id1]].r<rr)
		       rr=qy[list[id1]].r;
            if(qy[list[id2]].r<rr)
               rr=qy[list[id2]].r;
            bool ans;
            if(rr<ll)
               ans=0;
            else
            {
            	l_id=binary(0,cnt-1,ll);
            	r_id=binary(0,cnt-1,rr);
            	//printf("l_id=%d,r_id=%d\n",l_id,r_id);
            	ans=(l_id<r_id&&qw(l_id,r_id-1,0)<=2);
            	int mf=2;
            	if(!(rr<qy[list[id1]].r))
            	    mf--;
        	    if(!(rr<qy[list[id2]].r))
        	        mf--;
    	        ans|=qw(r_id,r_id,0)<=mf;
            }
            if(ans)
               puts("YES");
            else
               puts("NO");
		}
	}
	return 0;
}
/*

100000000 5
1 -106382777 300000523
1 -75340202 300000165
1 -148918484 300000552
1 96360393 300000458
3 3 2
*/

//https://codeforces.com/contest/856/problem/E

#include<bits/stdc++.h>
const int N = 5e5 + 5;
using namespace std;

struct point{
    int id, x, y;

    point(int id, int x, int y) : id(id), x(x), y(y) {}

    point() {}

    bool operator < (const point&a) const{
        return 1LL * x * a.y < 1LL * y * a.x;
    }

    bool operator == (const point&a) const{
        return 1LL * x * a.y == 1LL * y * a.x;
    }
} p[N];

vector <point> mv[2];

multiset <int> ms[N];
int r, n, type[N], a[N], b[N], cnt, m;
int f[N][2], it[N << 2];

void update(int i, int l, int r, int pos, int val, int v){
    if (l > pos || pos > r) return;
    if (l == r){
        if (v) ms[l].insert(val);
        else ms[l].erase(ms[l].lower_bound(val));
        it[i] = ((ms[l].size()) ? *ms[l].begin() : N);
        return;
    }
    int mid = (l + r) >> 1;
    update(i << 1, l, mid, pos, val, v); update(i << 1 | 1, mid+1, r, pos, val, v);
    it[i] = min(it[i << 1], it[i << 1 | 1]);
}

int get(int i, int l, int r, int L, int R){
    if (L > r || l > R) return N;
    if (L <= l && r <= R) return it[i];
    int mid = (l + r) >> 1;
    return min(get(i << 1, l, mid, L, R), get(i << 1 | 1, mid+1, r, L, R));
}

void ins(int a, int b){
    update(1, 1, m, b, a, 1);
}

void del(int a, int b){
    update(1, 1, m, b, a, 0);
}

bool cross(point a, point b, point c, point d){
    double x = a.y - b.y, y = b.x - a.x, z = a.x * x + a.y * y;
    double X = c.y - d.y, Y = d.x - c.x, Z = c.x * x + c.y * y;
    if (x == 0) swap(x, X); swap(y, Y); swap(z, Z);
    Y -= (X / x) * y; Z -= (X / x) * z;
    z -= (Y / y) * Z;
    Z /= Y; z /= x;
    return sqrt(z*z + Z*Z) >= r;
}

bool ck(int a, int b){
    bool res = true;
    int x = max(f[a][0], f[b][0]), y = min(f[a][1], f[b][1]);
    del(f[a][0], f[a][1]); del(f[b][0], f[b][1]);
    if (get(1, 1, m, y, m) <= x) res = false;
    ins(f[a][0], f[a][1]); ins(f[b][0], f[b][1]);

    if (f[a][0] > f[b][0]) swap(a, b);
    if (f[a][0] < f[b][0] && f[a][1] < f[b][1]){
        if (!cross(p[a], point(0, 5, 0), p[b], point(0, -5, 0))) res = false;
    }

    return res;
}

int main(){
    ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);
    for (int i = 0; i < N; i++) it[i] = N;
    cin >> r >> n;
    for (int i = 1; i <= n; i++) {
        cin >> type[i] >> a[i];
        if (type[i] != 2) cin >> b[i];
        if (type[i] == 1) cnt++, mv[0].push_back(point(cnt, a[i]+r, b[i])), mv[1].push_back(point(cnt, a[i]-r, b[i])), p[cnt] = point(0, a[i], b[i]);
    }
    sort(mv[0].begin(), mv[0].end()); sort(mv[1].begin(), mv[1].end());
    for (int i = 0; i < (int)mv[0].size(); i++){
        if (i == 0 || !(mv[0][i] == mv[0][i-1])) m++;
        f[mv[0][i].id][0] = m;
    }
    m = 0;
    for (int i = 0; i < (int)mv[1].size(); i++){
        if (i == 0 || !(mv[1][i] == mv[1][i-1])) m++;
        f[mv[1][i].id][1] = m;
    }
    cnt = 0;
    for (int i = 1; i <= n; i++){
        if (type[i] == 1) cnt++, ins(f[cnt][0], f[cnt][1]);
        if (type[i] == 2) del(f[a[i]][0], f[a[i]][1]);
        if (type[i] == 3) cout << (ck(a[i], b[i]) ? "YES" : "NO") << "\n";
    }
}

#include <bits/stdc++.h>

const int MAXN = 500010;
typedef long long LL;
typedef long double db;
typedef LL VT;
struct vec {
	VT x, y;
	vec() { x = y = 0; }
	vec(VT a, VT b) { x = a, y = b; }
// WARN: modify following 4 functions if VT is int
// 1. A * B    2. return LL
	VT operator ^ (vec b) const { return x * b.y - y * b.x; }
	VT operator * (vec b) const { return x * b.x + y * b.y; }
	VT norm2() const { return x * x + y * y; }
	db norm() const { return sqrt(x * x + y * y); }
	vec operator - (vec b) const { return vec(x - b.x, y - b.y); }
	vec operator + (vec b) const { return vec(x + b.x, y + b.y); }
	vec operator * (db k) const { return vec(x * k, y * k); }
	friend bool operator < (const vec & a, const vec & b) {
		return (a ^ b) > 0;
	}
	friend std::istream & operator >> (std::istream & in, vec & x) {
		in >> x.x >> x.y;
		return in;
	}
	friend std::ostream & operator << (std::ostream & out, vec x) {
		out << '(' << x.x << ',' << x.y << ')';
		return out;
	}
} ;
typedef std::vector<vec> VP;
inline LL cross(vec a, vec b, vec c) {
	return (b - a) ^ (c - a);
}
typedef std::pair<vec, int> pi;
int bel[MAXN], lll[MAXN], rrr[MAXN];
int discr(std::vector<pi> v, int * tar) {
	const int L = v.size();
	std::sort(v.begin(), v.end());
	int rnk = 0;
	for (int i = 0; i != L; ++i) {
		if (i != 0 && !(v[i].first < v[i - 1].first || v[i - 1].first < v[i].first)) ;
		else ++rnk;
		bel[tar[v[i].second] = i + 1] = rnk;
		if (!lll[rnk]) lll[rnk] = i + 1;
		rrr[rnk] = i + 1;
	}
	return L;
}
vec ps[MAXN];
int opt[MAXN], xs[MAXN], ys[MAXN];
const int NINF = 0xcfcfcfcf;
int tree[MAXN << 2];
void add(int u, int l, int r, int tar, int v) {
	if (l == r) return (void) (tree[u] = v);
	int mid = l + r >> 1;
	if (tar <= mid) add(u << 1, l, mid, tar, v);
	else add(u << 1 | 1, mid + 1, r, tar, v);
	tree[u] = std::max(tree[u << 1], tree[u << 1 | 1]);
}
int qry(int u, int l, int r, int L, int R) {
	if (L <= l && r <= R) return tree[u];
	int mid = l + r >> 1, res = NINF;
	if (L <= mid) res = qry(u << 1, l, mid, L, R);
	if (mid < R) res = std::max(res, qry(u << 1 | 1, mid + 1, r, L, R));
	return res;
}
int n;
inline int tr(int x, int y) { return x == 1 ? y : NINF; }
int nl;
void add(int i, int v) {
	add(1, 1, nl, ys[i], tr(v, xs[i]));
}
LL R;
typedef __int128 LLL;
bool incir(vec x, vec y) {
	typedef long double ld;
	x.x *= x.x, x.y *= x.y;
	y.x *= y.x, y.y *= y.y;
	ld t = (LLL) x.x * (y.x + y.y) + (LLL) y.x * (x.x + x.y);
	t -= (LLL) (x.x + x.y) * (y.x + y.y);
	if (t > 0) return true;
	return false;
}
int trans[MAXN];
int main() {
	memset(tree, 0xcf, sizeof tree);
	std::ios_base::sync_with_stdio(false), std::cin.tie(0);
	std::cin >> R >> n;
	vec pol(-R, 0), por(R, 0);
	std::vector<pi> ll;
	for (int i = 1, bak = 0; i <= n; ++i) {
		std::cin >> opt[i] >> xs[i];
		if (opt[i] != 2) std::cin >> ys[i];
		if (opt[i] == 1) {
			ps[i] = vec(xs[i], ys[i]);
			ll.emplace_back(ps[i] - pol , i);
			ll.emplace_back(ps[i] - por, i + n);
			trans[++bak] = i;
		} else xs[i] = trans[xs[i]], ys[i] = trans[ys[i]];
	}
	static int ls[MAXN << 1], app[MAXN];
	nl = discr(ll, ls);
	for (int i = 1; i <= n; ++i) if (opt[i] == 1)
		xs[i] = ls[i], ys[i] = ls[i + n];
	for (int T = 1; T <= n; ++T) {
		if (opt[T] == 1) add(T, 1), app[T] = true;
		else if (opt[T] == 2) add(xs[T], -1), app[xs[T]] = false;
		else {
			bool can = true;
			int A = xs[T], B = ys[T];
			if (!incir( std::min(ps[A] - pol, ps[B] - pol),
						std::max(ps[A] - por, ps[B] - por) )) {
				int l = lll[bel[std::min(xs[A], xs[B])]];
				int r = rrr[bel[std::max(ys[A], ys[B])]];
				if (app[A]) add(A, -1);
				if (app[B]) add(B, -1);
				can = qry(1, 1, nl, 1, r) >= l;
				if (app[A]) add(A, 1);
				if (app[B]) add(B, 1);
			}
			std::cout << (can ? "NO" : "YES") << '\n';
		}
	}

	return 0;
}

#include <bits/stdc++.h>
using namespace std;
const int N = 5e5 + 7;
int cnt;
struct frac {
	int x, y;
};
frac X[N], Y[N];
bool operator < (const frac &a, const frac &b) {
	return 1LL * a.x * b.y > 1LL * a.y * b.x;
	/*if (a.x == 0) return b.x > 0;
	if (b.x == 0) return a.x < 0;
	if (a.x < 0 && b.x > 0) return 1 < 0;
	if (a.x > 0 && b.x < 0) return 0 < 1;
	if (a.x >= 0) {
		return 1LL * a.y * b.x < 1LL * a.x * b.y;
	}
	return 1LL * a.y * b.x > 1LL * a.x * b.y;*/
}
bool operator == (const frac &a, const frac &b) {
	return !(a < b || b < a);
}
struct event {
	bool is_modify;
	int id; frac x, y;
};
bool operator < (const event &a, const event &b) {
	if (!(a.y == b.y)) return b.y < a.y;
	return a.is_modify > b.is_modify;
}
vector<event> all;
int ans[N], Tree[N], tick[N], xxx, n;
int &tree(int x) {
	if (tick[x] < xxx) {
		tick[x] = xxx;
		Tree[x] = 0;
	}
	return Tree[x];
}
void add(int x, int c) {
	while (x <= n) {
		tree(x) += c;
		x += x & -x;
	}
}
int query(int x) {
	int res = 0;
	while (x) {
		res += tree(x);
		x -= x & -x;
	}
	return res;
}
void divide_time(int l, int r) {
	if (l >= r) return;
	int mid = (l + r) / 2;
	divide_time(l, mid);
	divide_time(mid + 1, r);
	vector<event> bll;
	vector<frac> ax;
	for (int i = l; i <= mid; ++ i) {
		if (all[i].is_modify) {
			bll.push_back(all[i]);
			ax.push_back(all[i].x);
		}
	}
	for (int i = mid + 1; i <= r; ++ i) {
		if (!all[i].is_modify) {
			bll.push_back(all[i]);
			ax.push_back(all[i].x);
		}
	}
	sort(bll.begin(), bll.end());
	sort(ax.begin(), ax.end());
	ax.erase(unique(ax.begin(), ax.end()), ax.end());
	xxx ++;
	::n = ax.size();
	for (auto e : bll) {
		int x = lower_bound(ax.begin(), ax.end(), e.x) - ax.begin() + 1;
		if (e.is_modify) {
			int c = (e.id > 0 ? 1 : -1);
			add(n - x + 1, c);
		}
		else {
			ans[e.id] += query(n - x + 1);
		}
	}
}
bool debug = 0;
int main() {
	int R, m, n = 0;
	if (debug) R = 1000, m = 50000; else
	scanf("%d%d", &R, &m);
	for (int r = 0; r < m; ++ r) {
		int type;
		if (debug) type = (cnt == 0 ? 1 : rand() % 2 * 2 + 1); else
		scanf("%d", &type);
		if (type == 1) {
			++ cnt;
			int x, y;
			if (debug) {
				x = rand() % 20000 - 10000;
				y = rand() % 10000;
				while (1LL * x * x + 1LL * y * y <= 1LL * R * R) {
					x = rand() % 20000 - 10000;
					y = rand() % 10000;
				}
			} else
			scanf("%d%d", &x, &y);
			X[cnt] = (frac) {x + R, y};
			Y[cnt] = (frac) {R - x, y};
			all.push_back((event) {1, cnt, X[cnt], Y[cnt]});
		}
		else if (type == 2) {
			int x;
			scanf("%d", &x);
			all.push_back((event) {1, -x, X[x], Y[x]});
		}
		else {
			int x, y;
			if (debug) {
				x = rand() % cnt + 1;
				y = rand() % cnt + 1;
			} else
			scanf("%d%d", &x, &y);
			all.push_back((event) {0, n ++, min(X[x], X[y]), min(Y[x], Y[y])});
		}
	}
	divide_time(0, (int) all.size() - 1);
	for (int i = 0; i < n; ++ i) puts(ans[i] <= 2 ? "YES" : "NO");
}

#include<iostream>
#include<cstdlib>
#include<stdio.h>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<vector>
#include<set>
#include<map>
using namespace std;
long long r;
int n,cnt,list[501000],cnt_list;
struct segment_tree
{
	int l,r,min_vl,lazy;
};
segment_tree tree[1<<21];
struct point
{
	long long x,y;
	bool operator <(const point &temp)const
	{
		  return y*temp.x<x*temp.y;
	}
};
point pt[1000001];
struct query
{
	int u,v,flag,id;
	long long x,y;
	point l,r;
};
query qy[501000];
void build(int left,int right,int id)
{
	int l=2*id+1,r=2*id+2,mid=(left+right)>>1;
	tree[id].min_vl=tree[id].lazy=0;
	tree[id].l=left;
	tree[id].r=right;
	if(left==right)
	    return;
    build(left,mid,l);
    build(mid+1,right,r);
}
void zz(int id)
{
	if(tree[id].lazy==0)
	    return;
	int l=2*id+1,r=2*id+2;
	if(tree[id].l!=tree[id].r)
	{
		tree[l].lazy+=tree[id].lazy;
		tree[r].lazy+=tree[id].lazy;
	}
	tree[id].min_vl+=tree[id].lazy;
	tree[id].lazy=0;
}
void update(int left,int right,int vl,int id)
{
	int l=2*id+1,r=2*id+2;
	if(tree[id].l>right||tree[id].r<left)
	{
	     zz(id);
	     return;
	}
    if(tree[id].l>=left&&tree[id].r<=right)
    {
    	tree[id].lazy+=vl;
    	zz(id);
    	return;
    }
    zz(id);
    update(left,right,vl,l);
    update(left,right,vl,r);
    tree[id].min_vl=min(tree[l].min_vl,tree[r].min_vl);
}
int qw(int left,int right,int id)
{
	int l=2*id+1,r=2*id+2;
	zz(id);
	if(tree[id].l>right||tree[id].r<left)
	    return 1e9+9;
    if(tree[id].l>=left&&tree[id].r<=right)
    	return tree[id].min_vl;
	return min(qw(left,right,l),qw(left,right,r));
}
int binary(int left,int right,point now)
{
	int mid;
	while(left<=right)
	{
		mid=(left+right)>>1;
		if(pt[mid]<now)
			left=mid+1;
		else if(now<pt[mid])
		    right=mid-1;
        else
            return mid;
	}
}
int main()
{
	scanf("%lld%d",&r,&n);
	int i,j,s,p,q,l_id,r_id;
	long long ru;
	//double bx,by;
	cnt=0;
	cnt_list=0;
	for(i=0;i<n;i++)
	{
		scanf("%d",&qy[i].flag);
		if(qy[i].flag==1)
		{
			list[cnt_list++]=i;
            scanf("%lld%lld",&qy[i].x,&qy[i].y);
            pt[cnt].x=qy[i].x-r;
            pt[cnt++].y=qy[i].y;
			qy[i].r=pt[cnt-1];
            pt[cnt].x=qy[i].x+r;
            pt[cnt++].y=qy[i].y;
			qy[i].id=cnt_list-1;
		    qy[i].l=pt[cnt-1];
		}
		else if(qy[i].flag==2)
        {
           scanf("%d",&qy[i].u);
           qy[i].u--;
        }
        else
        {
        	scanf("%d%d",&qy[i].u,&qy[i].v);
        	qy[i].u--;
        	qy[i].v--;
        }
	}
	sort(pt,pt+cnt);
	int nn=0;
	for(i=0;i<cnt;i++)
	{
		if(nn==0||(pt[i].x!=pt[nn-1].x||pt[i].y!=pt[nn-1].y))
		    pt[nn++]=pt[i];
	}
	cnt=nn;
	build(0,cnt-1,0);
	point ll,rr;
	for(i=0;i<n;i++)
	{
		int flag;
		if(qy[i].flag==1)
		{
		   flag=1;
		   ll=qy[i].l;
		   rr=qy[i].r;
		}
		else if(qy[i].flag==2)
		{
			flag=-1;
			ll=qy[list[qy[i].u]].l;
			rr=qy[list[qy[i].u]].r;
		}
		if(qy[i].flag==1||qy[i].flag==2)
		{
    		l_id=binary(0,cnt-1,ll);
    		r_id=binary(0,cnt-1,rr);
    		if(l_id<r_id)
    		   update(l_id,r_id-1,flag,0);
		}
		else
		{
			ll.x=r;
			ll.y=0;
			rr.x=-r;
			rr.y=0;
			int id1,id2;
			id1=qy[i].u;
			id2=qy[i].v;
			if(ll<qy[list[id1]].l)
			   ll=qy[list[id1]].l;
            if(ll<qy[list[id2]].l)
               ll=qy[list[id2]].l;
		    if(qy[list[id1]].r<rr)
		       rr=qy[list[id1]].r;
            if(qy[list[id2]].r<rr)
               rr=qy[list[id2]].r;
            bool ans;
            if(rr<ll)
               ans=0;
            else
            {
            	l_id=binary(0,cnt-1,ll);
            	r_id=binary(0,cnt-1,rr);
            	ans=(l_id<r_id&&qw(l_id,r_id-1,0)<=2);
            	int mf=2;
            	if(!(rr<qy[list[id1]].r))
            	    mf--;
        	    if(!(rr<qy[list[id2]].r))
        	        mf--;
    	        ans|=qw(r_id,r_id,0)<=mf;
            }
            if(ans)
               puts("YES");
            else
               puts("NO");
		}
	}
	return 0;
}
/*

100000000 5
1 -106382777 300000523
1 -75340202 300000165
1 -148918484 300000552
1 96360393 300000458
3 3 2
*/

#include <cstdio>
#include <algorithm>
#include <cstring>
#include <queue>
#include <cmath>
#define ld long double
#define l(a) (a<<1)
#define r(a) (a<<1|1)
#define MN 500005
#define MM 1000005
#define MD 4200005
#define eps 1e-15
#define EPS 1e-15
using namespace std;
struct meg{int g,x,y;}a[MN];
struct itv1{ld x,y;}w[MN];
struct itv2{int x,y;}s[MN];
struct Que
{
	priority_queue <int> A,B;
	void push(int x) {A.push(x);}
	void dele(int x) {B.push(x);}
	int top()
	{
		while (!B.empty()&&A.top()==B.top()) A.pop(),B.pop();
		if (!A.empty()) return A.top(); else return 0;
	}
}q[MM];
ld b0[MM],b1[MM];
int m,MQ,tin,b0in,b1in,ra;
int t[MD];

inline int read()
{
	int n=0,f=1; char c=getchar();
	while (c<'0' || c>'9') {if(c=='-')f=-1; c=getchar();}
	while (c>='0' && c<='9') {n=n*10+c-'0'; c=getchar();}
	return n*f;
}

inline void getcg(int x,int z) {for (t[x+=MQ]=z,x>>=1;x;x>>=1) t[x]=max(t[l(x)],t[r(x)]);}
inline int getmax(int L,int R)
{
	int sum=0;
	for (L+=MQ,R+=MQ;L<=R;L>>=1,R>>=1)
	{
		if ( L&1) sum=max(sum,t[L++]);
		if (~R&1) sum=max(sum,t[R--]);
	}
	return sum;
}

void cghp(int x,int y,int g)
{
	int lt=q[x].top();
	if (g==1) q[x].push(y); else q[x].dele(y);
	if (lt!=q[x].top()) getcg(x,q[x].top());
}

int main()
{
	register int i,x,y,lt=0;
	ra=read(); m=read();
	for (i=1;i<=m;++i)
	{
		a[i].g=read();
		if (a[i].g==1)
		{
			x=read(); y=read(); a[i].x=++tin;
			w[tin].x=atan2(y,x-ra);
			w[tin].y=atan2(y,x+ra);
			b0[++b0in]=w[tin].x;
			b1[++b1in]=w[tin].y;
		}
		else if (a[i].g==2) a[i].x=read();
		else if (a[i].g==3) a[i].x=read(),a[i].y=read();
	}
	sort(b0+1,b0+b0in+1); sort(b1+1,b1+b1in+1);
	for (i=2,lt=0;i<=b0in;++i) {if (b0[i]==b0[i-1]) ++lt; b0[i-lt]=b0[i];} b0in-=lt;
	for (i=2,lt=0;i<=b1in;++i) {if (b1[i]==b1[i-1]) ++lt; b1[i-lt]=b1[i];} b1in-=lt;
	for (i=1;i<=tin;++i)
		s[i].x=lower_bound(b0+1,b0+b0in+1,w[i].x)-b0,
		s[i].y=lower_bound(b1+1,b1+b1in+1,w[i].y)-b1;
	for (MQ=1;MQ<b0in;MQ<<=1); --MQ;
	for (i=1;i<=m;++i)
	{
		if (a[i].g<3) cghp(s[a[i].x].x,s[a[i].x].y,a[i].g);
		else if (a[i].g==3)
		{
			if (max(w[a[i].x].x,w[a[i].y].x)-min(w[a[i].x].y,w[a[i].y].y)>acos(0)+EPS) {puts("NO"); continue;}
			x=max(s[a[i].x].x,s[a[i].y].x); y=min(s[a[i].x].y,s[a[i].y].y);
			cghp(s[a[i].x].x,s[a[i].x].y,2);
			cghp(s[a[i].y].x,s[a[i].y].y,2);
			if (getmax(1,x)>=y) puts("NO"); else puts("YES");
			cghp(s[a[i].x].x,s[a[i].x].y,1);
			cghp(s[a[i].y].x,s[a[i].y].y,1);
		}
	}
}

#include <bits/stdc++.h>
using namespace std;
const int N = 5e5 + 5;
int cnt;
struct frac {
	int x, y;
};
frac X[N], Y[N];
bool operator < (const frac &a, const frac &b) {
	if (a.x < 0 && b.x > 0) return 1 < 0;
	if (a.x > 0 && b.x < 0) return 0 < 1;
	if (a.x >= 0) {
		return 1LL * a.y * b.x < 1LL * a.x * b.y;
	}
	return 1LL * a.y * b.x > 1LL * a.x * b.y;
}
bool operator == (const frac &a, const frac &b) {
	return !(a < b || b < a);
}
struct event {
	bool is_modify;
	int id; frac x, y;
};
bool operator < (const event &a, const event &b) {
	if (!(a.y == b.y)) return b.y < a.y;
	return a.is_modify > b.is_modify;
}
vector<event> all;
int ans[N], Tree[N], tick[N], xxx, n;
int &tree(int x) {
	if (tick[x] < xxx) {
		tick[x] = xxx;
		Tree[x] = 0;
	}
	return Tree[x];
}
void add(int x, int c) {
	while (x <= n) {
		tree(x) += c;
		x += x & -x;
	}
}
int query(int x) {
	int res = 0;
	while (x) {
		res += tree(x);
		x -= x & -x;
	}
	return res;
}
void divide_time(int l, int r) {
	if (l >= r) return;
	int mid = (l + r) / 2;
	divide_time(l, mid);
	divide_time(mid + 1, r);
	vector<event> bll;
	vector<frac> ax;
	for (int i = l; i <= mid; ++ i) {
		if (all[i].is_modify) {
			bll.push_back(all[i]);
			ax.push_back(all[i].x);
		}
	}
	for (int i = mid + 1; i <= r; ++ i) {
		if (!all[i].is_modify) {
			bll.push_back(all[i]);
			ax.push_back(all[i].x);
		}
	}
	sort(bll.begin(), bll.end());
	sort(ax.begin(), ax.end());
	ax.erase(unique(ax.begin(), ax.end()), ax.end());
	xxx ++;
	::n = ax.size();
	for (auto e : bll) {
		int x = lower_bound(ax.begin(), ax.end(), e.x) - ax.begin() + 1;
		if (e.is_modify) {
			int c = (e.id > 0 ? 1 : -1);
			add(n - x + 1, c);
		}
		else {
			ans[e.id] += query(n - x + 1);
		}
	}
}
int main() {
	int R, m, n;
	scanf("%d%d", &R, &m);
	for (int r = 0; r < m; ++ r) {
		int type;
		scanf("%d", &type);
		if (type == 1) {
			++ cnt;
			int x, y;
			scanf("%d%d", &x, &y);
			X[cnt] = (frac) {x + R, y};
			Y[cnt] = (frac) {x - R, y};
			all.push_back((event) {1, cnt, X[cnt], Y[cnt]});
		}
		else if (type == 2) {
			int x;
			scanf("%d", &x);
			all.push_back((event) {1, -x, X[x], Y[x]});
		}
		else {
			int x, y;
			scanf("%d%d", &x, &y);
			all.push_back((event) {0, n ++, min(X[x], X[y]), min(Y[x], Y[y])});
		}
	}
	divide_time(0, (int) all.size() - 1);
	for (int i = 0; i < n; ++ i) puts(ans[i] <= 2 ? "YES" : "NO");
}

#include <cstdio>
#include <algorithm>
#include <cstring>
#include <queue>
#include <cmath>
#define ld double
#define l(a) (a<<1)
#define r(a) (a<<1|1)
#define MN 500005
#define MM 1000005
#define MD 4200005
#define eps 1e-13
//#define EPS 1e-14
using namespace std;
struct meg{int g,x,y;}a[MN];
struct itv1{ld x,y;}w[MN];
struct itv2{int x,y;}s[MN];
struct Que
{
	priority_queue <int> A,B;
	void push(int x) {A.push(x);}
	void dele(int x) {B.push(x);}
	int top()
	{
		while (!B.empty()&&A.top()==B.top()) A.pop(),B.pop();
		if (!A.empty()) return A.top(); else return 0;
	}
}q[MM];
ld b0[MM],b1[MM];
int m,MQ,tin,b0in,b1in,ra;
int t[MD];

inline int read()
{
	int n=0,f=1; char c=getchar();
	while (c<'0' || c>'9') {if(c=='-')f=-1; c=getchar();}
	while (c>='0' && c<='9') {n=n*10+c-'0'; c=getchar();}
	return n*f;
}

inline void getcg(int x,int z) {for (t[x+=MQ]=z,x>>=1;x;x>>=1) t[x]=max(t[l(x)],t[r(x)]);}
inline int getmax(int L,int R)
{
	int sum=0;
	for (L+=MQ,R+=MQ;L<=R;L>>=1,R>>=1)
	{
		if ( L&1) sum=max(sum,t[L++]);
		if (~R&1) sum=max(sum,t[R--]);
	}
	return sum;
}

void cghp(int x,int y,int g)
{
	int lt=q[x].top();
	if (g==1) q[x].push(y); else q[x].dele(y);
	if (lt!=q[x].top()) getcg(x,q[x].top());
}

int main()
{
	register int i,x,y,lt=0;
	ra=read(); m=read();
	for (i=1;i<=m;++i)
	{
		a[i].g=read();
		if (a[i].g==1)
		{
			x=read(); y=read(); a[i].x=++tin;
			w[tin].x=atan2(y,x-ra);
			w[tin].y=atan2(y,x+ra);
			b0[++b0in]=w[tin].x;
			b1[++b1in]=w[tin].y;
		}
		else if (a[i].g==2) a[i].x=read();
		else if (a[i].g==3) a[i].x=read(),a[i].y=read();
	}
	sort(b0+1,b0+b0in+1); sort(b1+1,b1+b1in+1);
	for (i=2,lt=0;i<=b0in;++i) {if (b0[i]-b0[i-1]<eps) ++lt; b0[i-lt]=b0[i];} b0in-=lt;
	for (i=2,lt=0;i<=b1in;++i) {if (b1[i]-b1[i-1]<eps) ++lt; b1[i-lt]=b1[i];} b1in-=lt;
	for (i=1;i<=tin;++i)
		s[i].x=lower_bound(b0+1,b0+b0in+1,w[i].x)-b0,
		s[i].y=lower_bound(b1+1,b1+b1in+1,w[i].y)-b1;
	for (MQ=1;MQ<b0in;MQ<<=1); --MQ;
	for (i=1;i<=m;++i)
	{
		if (a[i].g<3) cghp(s[a[i].x].x,s[a[i].x].y,a[i].g);
		else if (a[i].g==3)
		{
			if (max(w[a[i].x].x,w[a[i].y].x)-min(w[a[i].x].y,w[a[i].y].y)>acos(0)) {puts("NO"); continue;}
			x=max(s[a[i].x].x,s[a[i].y].x); y=min(s[a[i].x].y,s[a[i].y].y);
			cghp(s[a[i].x].x,s[a[i].x].y,2);
			cghp(s[a[i].y].x,s[a[i].y].y,2);
			if (getmax(1,x)>=y) puts("NO"); else puts("YES");
			cghp(s[a[i].x].x,s[a[i].x].y,1);
			cghp(s[a[i].y].x,s[a[i].y].y,1);
		}
	}
}

#pragma comment(linker, "/stack:200000000")
#pragma GCC optimize("Ofast")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")

#include <bits/stdc++.h>

#define F0R(i, a) for (int i = 0; i < (a); i++)
#define FOR(i, a, b) for (int i = (a); i < (b); i++)
#define R0F(i, a) for (int i = (a) - 1; i >= 0; i--)
#define ROF(i, a, b) for (int i = (b) - 1; i >= (a); i--)

#define ran() (rand() & 0x7FFF)
#define rand31() ((ran() << 16) | (ran() << 1) | (ran() & 1))
#define rand32() ((ran() << 17) | (ran() << 2) | (ran() & 3))
#define rand63() (((ll)ran() << 48) | ((ll)ran() << 33) | ((ll)ran() << 18) | ((ll)ran() << 3) | ((ll)ran() & 7))
#define rand64() (((ll)ran() << 49) | ((ll)ran() << 34) | ((ll)ran() << 19) | ((ll)ran() << 4) | ((ll)ran() & 15))

#define F first
#define S second
#define PB push_back
#define MP make_pair
#define MT make_tuple
#define UB upper_bound
#define LB lower_bound
#define X real()
#define Y imag()

#define INF 1e18
#define PI acos(-1)

#define sz(x) ((int)(x).size())
#define all(x) (x).begin(), (x).end()
#define SQ(x) ((x) * (x))

using namespace std;

typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef vector<int> vi;
typedef vector<pii> vpii;
typedef vector<ll> vll;
typedef vector<ull> vul;
typedef complex<ld> point;
typedef complex<ld> cld;
typedef vector<cld> vcld;

#define MAXN 500000

struct angle {

ll y, x;

bool operator<(const angle& a2) const {
    return x * a2.y - y * a2.x > 0;
}

bool operator==(const angle& a2) const {
    return x * a2.y == y * a2.x;
}

bool operator<=(const angle& a2) const { return *this < a2 || *this == a2; }

bool operator>=(const angle& a2) const { return a2 < *this; }

angle operator+(const angle& a2) const {
    angle res = {y * a2.x + a2.y * x, x * a2.x - y * a2.y};
    assert(abs(atan2(res.y, res.x) - atan2(y, x) - atan2(a2.y, a2.x)) < 1e-5);
    return res;
}

};

struct SegTree{

int sz;
angle *tree;

SegTree(int _sz) {
    sz = 1 << (32 - __builtin_clz(_sz - 1));
    tree = new angle[2 * sz];
    F0R(i, 2 * sz) tree[i] = angle({0, 1});
}

void upd(int idx, angle v) {
    idx += sz;
    tree[idx] = v;
    for (idx /= 2; idx > 0; idx /= 2) tree[idx] = max(tree[2 * idx], tree[2 * idx + 1]);
}

angle query(int lo, int hi) {
    lo += sz, hi += sz;
    angle res = angle({0, 1});
    while(lo <= hi) {
        if ((lo % 2) == 1) res = max(res, tree[lo++]);
        if ((hi % 2) == 0) res = max(res, tree[hi--]);
        lo /= 2;
        hi /= 2;
    }
    return res;
}

};

ll r;
angle alpha[MAXN], beta123[MAXN];
int n, q, posof[MAXN];
vector<pair<angle, int>> order;
vpii updates;
vector<pair<int, pii>> queries;

SegTree st(2);

void toggle(int idx) {
int pos = posof[idx];
if (st.query(pos, pos) == angle({0, 1})) st.upd(pos, beta123[idx]);
else st.upd(pos, {0, 1});
}

int main() {
    ios::sync_with_stdio(0);
    cin.tie(0);
    cin >> r >> q;
    F0R(i, q) {
        int t;
        cin >> t;
        switch(t) {
            case 1:
                ll x, y;
                cin >> x >> y;
                alpha[n] = {y, r - x};
                beta123[n] = {y, x + r};
                updates.PB(MP(i, n++));
                break;
            case 2:
                int idx;
                cin >> idx;
                idx--;
                updates.PB(MP(i, idx));
                break;
            case 3:
                int a, b;
                cin >> a >> b;
                a--, b--;
                queries.PB(MP(i, MP(a, b)));
                break;
        }
    }
    F0R(i, n) order.PB(MP(alpha[i], i));
    sort(all(order));
    F0R(i, n) posof[order[i].S] = i;
    reverse(all(updates));
    reverse(all(queries));
    st = SegTree(n);
    while (!updates.empty() || !queries.empty()) {
        if (queries.empty() || (!updates.empty() && updates.back().F < queries.back().F)) {
            int idx = updates.back().S;
            updates.pop_back();
            toggle(idx);
        } else {
            int a = queries.back().S.F;
            int b = queries.back().S.S;
            queries.pop_back();
            angle _alpha = min(alpha[a], alpha[b]);
            angle _beta123 = min(beta123[a], beta123[b]);
            if(_alpha + _beta123 < angle({1, 0})) cout << "NO\n";
                else {
                    toggle(a);
                    toggle(b);

                    int lo = LB(all(order), MP(_alpha, 0)) - order.begin();
                    if (st.query(lo, n - 1) >= _beta123) cout << "NO\n";
                    else cout << "YES\n";

                    toggle(a);
                    toggle(b);
                }
            }
        }
}

#include <cstdio>
#include <algorithm>
#include <cstring>
#include <queue>
#include <cmath>
#define ll long long
#define ld double
#define l(a) (a<<1)
#define r(a) (a<<1|1)
#define MN 500005
#define MM 1000005
#define MD 4200005
#define eps 1e-12
using namespace std;
struct meg{int g,x,y;}a[MN];
struct itv1{ld x,y;}w[MN];
struct itv2{int x,y;}s[MN];
struct Que
{
	priority_queue <int> A,B;
	void push(int x) {A.push(x);}
	void dele(int x) {B.push(x);}
	int top()
	{
		while (!B.empty()&&A.top()==B.top()) A.pop(),B.pop();
		if (!A.empty()) return A.top(); else return 0;
	}
}q[MM];
ld b0[MM],b1[MM];
ll ra;
int m,MQ,tin,b0in,b1in;
int t[MD];

inline int read()
{
	int n=0,f=1; char c=getchar();
	while (c<'0' || c>'9') {if(c=='-')f=-1; c=getchar();}
	while (c>='0' && c<='9') {n=n*10+c-'0'; c=getchar();}
	return n*f;
}

inline void getcg(int x,int z) {for (t[x+=MQ]=z,x>>=1;x;x>>=1) t[x]=max(t[l(x)],t[r(x)]);}
inline int getmax(int L,int R)
{
	int sum=0;
	for (L+=MQ,R+=MQ;L<=R;L>>=1,R>>=1)
	{
		if ( L&1) sum=max(sum,t[L++]);
		if (~R&1) sum=max(sum,t[R--]);
	}
	return sum;
}

void cghp(int x,int y,int g)
{
	int lt=q[x].top();
	if (g==1) q[x].push(y); else q[x].dele(y);
	if (lt!=q[x].top()) getcg(x,q[x].top());
}

int main()
{
	register int i,x,y,lt=0;
	ra=read(); m=read();
	for (i=1;i<=m;++i)
	{
		a[i].g=read();
		if (a[i].g==1)
		{
			x=read(); y=read(); a[i].x=++tin;
			w[tin].x=atan2(y,x-ra);
			w[tin].y=atan2(y,x+ra);
			b0[++b0in]=w[tin].x;
			b1[++b1in]=w[tin].y;
		}
		else if (a[i].g==2) a[i].x=read();
		else if (a[i].g==3) a[i].x=read(),a[i].y=read();
	}
	sort(b0+1,b0+b0in+1); sort(b1+1,b1+b1in+1);
	for (i=2,lt=0;i<=b0in;++i) {if (b0[i]-b0[i-1]<eps) ++lt; b0[i-lt]=b0[i];} b0in-=lt;
	for (i=2,lt=0;i<=b1in;++i) {if (b1[i]-b1[i-1]<eps) ++lt; b1[i-lt]=b1[i];} b1in-=lt;
	for (i=1;i<=tin;++i)
		s[i].x=lower_bound(b0+1,b0+b0in+1,w[i].x)-b0,
		s[i].y=lower_bound(b1+1,b1+b1in+1,w[i].y)-b1;
//	for (i=1;i<=tin;++i) printf("%.6lf %.6lf\n",w[i].x,w[i].y);
	for (MQ=1;MQ<b0in;MQ<<=1); --MQ;
	for (i=1;i<=m;++i)
	{
		if (a[i].g<3) cghp(s[a[i].x].x,s[a[i].x].y,a[i].g);
		else if (a[i].g==3)
		{
			if (max(w[a[i].x].x,w[a[i].y].x)-min(w[a[i].x].y,w[a[i].y].y)>acos(0)) {puts("NO"); continue;}
			x=max(s[a[i].x].x,s[a[i].y].x); y=min(s[a[i].x].y,s[a[i].y].y);
			cghp(s[a[i].x].x,s[a[i].x].y,2);
			cghp(s[a[i].y].x,s[a[i].y].y,2);
			if (getmax(1,x)>=y) puts("NO"); else puts("YES");
			cghp(s[a[i].x].x,s[a[i].x].y,1);
			cghp(s[a[i].y].x,s[a[i].y].y,1);
		}
	}
}

#include <cstdio>
#include <algorithm>
#include <cstring>
#include <queue>
#include <cmath>
#define ld double
#define l(a) (a<<1)
#define r(a) (a<<1|1)
#define MN 500005
#define MM 1000005
#define MD 4200005
#define eps 1e-13
#define EPS 1e-14
using namespace std;
struct meg{int g,x,y;}a[MN];
struct itv1{ld x,y;}w[MN];
struct itv2{int x,y;}s[MN];
struct Que
{
	priority_queue <int> A,B;
	void push(int x) {A.push(x);}
	void dele(int x) {B.push(x);}
	int top()
	{
		while (!B.empty()&&A.top()==B.top()) A.pop(),B.pop();
		if (!A.empty()) return A.top(); else return 0;
	}
}q[MM];
ld b0[MM],b1[MM];
int m,MQ,tin,b0in,b1in,ra;
int t[MD];

inline int read()
{
	int n=0,f=1; char c=getchar();
	while (c<'0' || c>'9') {if(c=='-')f=-1; c=getchar();}
	while (c>='0' && c<='9') {n=n*10+c-'0'; c=getchar();}
	return n*f;
}

inline void getcg(int x,int z) {for (t[x+=MQ]=z,x>>=1;x;x>>=1) t[x]=max(t[l(x)],t[r(x)]);}
inline int getmax(int L,int R)
{
	int sum=0;
	for (L+=MQ,R+=MQ;L<=R;L>>=1,R>>=1)
	{
		if ( L&1) sum=max(sum,t[L++]);
		if (~R&1) sum=max(sum,t[R--]);
	}
	return sum;
}

void cghp(int x,int y,int g)
{
	int lt=q[x].top();
	if (g==1) q[x].push(y); else q[x].dele(y);
	if (lt!=q[x].top()) getcg(x,q[x].top());
}

int main()
{
	register int i,x,y,lt=0;
	ra=read(); m=read();
	for (i=1;i<=m;++i)
	{
		a[i].g=read();
		if (a[i].g==1)
		{
			x=read(); y=read(); a[i].x=++tin;
			w[tin].x=atan2(y,x-ra);
			w[tin].y=atan2(y,x+ra);
			b0[++b0in]=w[tin].x;
			b1[++b1in]=w[tin].y;
		}
		else if (a[i].g==2) a[i].x=read();
		else if (a[i].g==3) a[i].x=read(),a[i].y=read();
	}
	sort(b0+1,b0+b0in+1); sort(b1+1,b1+b1in+1);
	for (i=2,lt=0;i<=b0in;++i) {if (b0[i]-b0[i-1]<eps) ++lt; b0[i-lt]=b0[i];} b0in-=lt;
	for (i=2,lt=0;i<=b1in;++i) {if (b1[i]-b1[i-1]<eps) ++lt; b1[i-lt]=b1[i];} b1in-=lt;
	for (i=1;i<=tin;++i)
		s[i].x=lower_bound(b0+1,b0+b0in+1,w[i].x)-b0,
		s[i].y=lower_bound(b1+1,b1+b1in+1,w[i].y)-b1;
	for (MQ=1;MQ<b0in;MQ<<=1); --MQ;
	for (i=1;i<=m;++i)
	{
		if (a[i].g<3) cghp(s[a[i].x].x,s[a[i].x].y,a[i].g);
		else if (a[i].g==3)
		{
			if (max(w[a[i].x].x,w[a[i].y].x)-min(w[a[i].x].y,w[a[i].y].y)>acos(0)+EPS) {puts("NO"); continue;}
			x=max(s[a[i].x].x,s[a[i].y].x); y=min(s[a[i].x].y,s[a[i].y].y);
			cghp(s[a[i].x].x,s[a[i].x].y,2);
			cghp(s[a[i].y].x,s[a[i].y].y,2);
			if (getmax(1,x)>=y) puts("NO"); else puts("YES");
			cghp(s[a[i].x].x,s[a[i].x].y,1);
			cghp(s[a[i].y].x,s[a[i].y].y,1);
		}
	}
}

#include<iostream>
#include<cstdlib>
#include<stdio.h>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<vector>
#include<set>
#include<map>
using namespace std;
long long r;
int n,cnt,list[501000],cnt_list,mf[1001000];
struct segment_tree
{
	int l,r,min_vl,lazy;
};
segment_tree tree[1<<21];
struct point
{
	long long x,y;
	bool operator <(const point &temp)const
	{
		  return y*temp.x<x*temp.y;
	}
};
point pt[1000001];
struct query
{
	int u,v,flag,id;
	long long x,y;
	point l,r;
};
query qy[501000];
void build(int left,int right,int id)
{
	int l=2*id+1,r=2*id+2,mid=(left+right)>>1;
	tree[id].min_vl=tree[id].lazy=0;
	tree[id].l=left;
	tree[id].r=right;
	if(left==right)
	    return;
    build(left,mid,l);
    build(mid+1,right,r);
}
void zz(int id)
{
	if(tree[id].lazy==0)
	    return;
	int l=2*id+1,r=2*id+2;
	if(tree[id].l!=tree[id].r)
	{
		tree[l].lazy+=tree[id].lazy;
		tree[r].lazy+=tree[id].lazy;
	}
	tree[id].min_vl+=tree[id].lazy;
	tree[id].lazy=0;
}
void update(int left,int right,int vl,int id)
{
	int l=2*id+1,r=2*id+2;
	if(tree[id].l>right||tree[id].r<left)
	{
	     zz(id);
	     return;
	}
    if(tree[id].l>=left&&tree[id].r<=right)
    {
    	tree[id].lazy+=vl;
    	zz(id);
    	return;
    }
    zz(id);
    update(left,right,vl,l);
    update(left,right,vl,r);
    tree[id].min_vl=min(tree[l].min_vl,tree[r].min_vl);
}
int qw(int left,int right,int id)
{
	int l=2*id+1,r=2*id+2;
	zz(id);
	if(tree[id].l>right||tree[id].r<left)
	    return 1e9+9;
    if(tree[id].l>=left&&tree[id].r<=right)
    	return tree[id].min_vl;
	return min(qw(left,right,l),qw(left,right,r));
}
int binary(int left,int right,point now)
{
	int mid;
	while(left<=right)
	{
		mid=(left+right)>>1;
		if(pt[mid]<now)
			left=mid+1;
		else if(now<pt[mid])
		    right=mid-1;
        else
            return mid;
	}
}
int main()
{
	scanf("%lld%d",&r,&n);
	int i,j,s,p,q,l_id,r_id;
	long long ru;
	cnt=0;
	cnt_list=0;
	for(i=0;i<n;i++)
	{
		scanf("%d",&qy[i].flag);
		if(qy[i].flag==1)
		{
			list[cnt_list++]=i;
            scanf("%lld%lld",&qy[i].x,&qy[i].y);
            pt[cnt].x=qy[i].x-r;
            pt[cnt++].y=qy[i].y;
			qy[i].r=pt[cnt-1];
            pt[cnt].x=qy[i].x+r;
            pt[cnt++].y=qy[i].y;
			qy[i].id=cnt_list-1;
		    qy[i].l=pt[cnt-1];
		}
		else if(qy[i].flag==2)
        {
           scanf("%d",&qy[i].u);
           qy[i].u--;
        }
        else
        {
        	scanf("%d%d",&qy[i].u,&qy[i].v);
        	qy[i].u--;
        	qy[i].v--;
        }
	}
	sort(pt,pt+cnt);
	int nn=0;
	for(i=0;i<cnt;i++)
	{
		if(nn==0||(pt[i].x!=pt[nn-1].x||pt[i].y!=pt[nn-1].y))
		    pt[nn++]=pt[i];
	}
	cnt=nn;
	build(0,cnt-1,0);
	point ll,rr;
	for(i=0;i<n;i++)
	{
		int flag;
		if(qy[i].flag==1)
		{
		   flag=1;
		   ll=qy[i].l;
		   rr=qy[i].r;
		}
		else if(qy[i].flag==2)
		{
			flag=-1;
			ll=qy[list[qy[i].u]].l;
			rr=qy[list[qy[i].u]].r;
		}
		if(qy[i].flag==1||qy[i].flag==2)
		{
    		l_id=binary(0,cnt-1,ll);
    		r_id=binary(0,cnt-1,rr);
    		mf[r_id]+=flag;
    		if(l_id<r_id)
    		   update(l_id,r_id-1,flag,0);
		}
		else
		{
			int id1,id2;
			id1=qy[i].u;
			id2=qy[i].v;
		    ll=qy[list[id1]].l;
		    rr=qy[list[id1]].r;
            if(ll<qy[list[id2]].l)
               ll=qy[list[id2]].l;
            if(qy[list[id2]].r<rr)
               rr=qy[list[id2]].r;
            bool ans;
            if(rr<ll)
               ans=0;
            else
            {
            	l_id=binary(0,cnt-1,ll);
            	r_id=binary(0,cnt-1,rr);
            	ans=(l_id<r_id&&qw(l_id,r_id-1,0)<=2);
    	        ans|=mf[r_id]<=2;
            }
            if(ans)
               puts("YES");
            else
               puts("NO");
		}
	}
	return 0;
}
/*

100000000 5
1 -106382777 300000523
1 -75340202 300000165
1 -148918484 300000552
1 96360393 300000458
3 3 2
*/

#include <cstdio>
#include <algorithm>
#include <cstring>
#include <queue>
#include <cmath>
#define ll long long
#define ld long double
#define l(a) (a<<1)
#define r(a) (a<<1|1)
#define MN 500005
#define MM 1000005
#define MD 4200005
#define eps 1e-5
using namespace std;
int INF;
struct meg{int g,x,y;}a[MN];
struct itv1{ld x,y;}w[MN];
struct itv2{int x,y;}s[MN];
struct Que
{
	priority_queue <int,vector<int>,greater<int> > A,B;
	void push(int x) {A.push(x);}
	void dele(int x) {B.push(x);}
	int top()
	{
		while (!B.empty()&&A.top()==B.top()) A.pop(),B.pop();
		if (!A.empty()) return A.top(); else return INF;
	}
}q[MM];
ld b[MM];
ll ra;
int m,MQ,tin,bin;
int t[MD];

inline int read()
{
	int n=0,f=1; char c=getchar();
	while (c<'0' || c>'9') {if(c=='-')f=-1; c=getchar();}
	while (c>='0' && c<='9') {n=n*10+c-'0'; c=getchar();}
	return n*f;
}

inline void getcg(int x,int z) {for (t[x+=MQ]=z,x>>=1;x;x>>=1) t[x]=min(t[l(x)],t[r(x)]);}
inline int getmin(int L,int R)
{
	int sum=INF;
	for (L+=MQ,R+=MQ;L<=R;L>>=1,R>>=1)
	{
		if ( L&1) sum=min(sum,t[L++]);
		if (~R&1) sum=min(sum,t[R--]);
	}
	return sum;
}

ld cal(ll x0,ll y0,ll x1,ll y1,ll g)
{
	ld ki,bi;
	ki=(ld)(y1-y0)/(x1-x0);
	bi=(ld)y0-(ld)x0*(y1-y0)/(x1-x0);
	return acos((ld)(bi*bi-ra*ra)*g/(ki*ki+1)/(ra*ra));
}
void cghp(int x,int y,int g)
{
	int lt=q[x].top();
	if (g==1) q[x].push(y); else q[x].dele(y);
	if (lt!=q[x].top()) getcg(x,q[x].top());
}

int main()
{
	register int i,x,y,lt=0;
	ra=read(); m=read();
	for (i=1;i<=m;++i)
	{
		a[i].g=read();
		if (a[i].g==1)
		{
			x=read(); y=read(); a[i].x=++tin;
			w[tin].x=(ll)x>= ra?acos( 1):cal( ra,0,(ll)x,(ll)y, 1);
			w[tin].y=(ll)x<=-ra?acos(-1):cal(-ra,0,(ll)x,(ll)y,-1);
			b[++bin]=w[tin].x; b[++bin]=w[tin].y;
		}
		else if (a[i].g==2) a[i].x=read();
		else if (a[i].g==3) a[i].x=read(),a[i].y=read();
	}
	sort(b+1,b+bin+1);
	for (i=2;i<=bin;++i) {if (b[i]-b[i-1]<eps) ++lt; b[i-lt]=b[i];}
	bin-=lt;
	for (i=1;i<=tin;++i)
		s[i].x=lower_bound(b+1,b+bin+1,w[i].x)-b,
		s[i].y=lower_bound(b+1,b+bin+1,w[i].y)-b;
//		s[i].x=s[i].x*2-1,s[i].y=s[i].y*2-1;
	for (MQ=1;MQ<bin;MQ<<=1); --MQ;
	memset(t,100,sizeof(t)); INF=t[0];
	for (i=1;i<=m;++i)
	{
		if (a[i].g<3) cghp(s[a[i].x].y,s[a[i].x].x,a[i].g);
		else if (a[i].g==3)
		{
			x=max(s[a[i].x].x,s[a[i].y].x); y=min(s[a[i].x].y,s[a[i].y].y);
			if (x>y) {puts("NO"); continue;}
			cghp(s[a[i].x].y,s[a[i].x].x,2);
			cghp(s[a[i].y].y,s[a[i].y].x,2);
			if (getmin(y,bin)<=x) puts("NO"); else puts("YES");
			cghp(s[a[i].x].y,s[a[i].x].x,1);
			cghp(s[a[i].y].y,s[a[i].y].x,1);
		}
	}
}

#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <string>
#include <cstring>
#include <cmath>
#include <set>
#include <map>
#include <cstdio>
#include <stdlib.h>
#include <stack>
#include <numeric>
#include <bitset>
#include <cctype>
#include <list>
#include <assert.h>
#include <random>
#include <unordered_map>
#include <ctime>
typedef  long long ll;
using namespace std;
#define INF 2147483647
#define infL (1LL<<60)
#define inf (1<<30)
#define inf9 (1000000000)
#define MOD 1000000007
#define EPS 1e-9
#define Gr 9.8
#define PI acos(-1)
#define REP(i,n) for(int (i)=0;(i)<(int)(n);(i)++)
#define REQ(i,n) for(int (i)=1;(i)<=(int)(n);(i)++)
#define lch (rt<<1)
#define rch (rt<<1|1)
#define readmp(n) for(int i=0,u,v;i<n;i++) {scanf("%d%d",&u,&v); mp[u].push_back(v); mp[v].push_back(u);}
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef long double ld;
typedef unsigned int uint;
#define MAX 500105
bool debug = 0;
int n,m,k;
int dx[4] = {0,1,0,-1}, dy[4] = {1,0,-1,0};
string direc="RDLU";
ll ln, lk, lm;
void etp(bool f = 0) {
    puts(f ?"YES" : "NO");
    exit(0);
}
void addmod(int &x, int y, int mod = MOD) {
    assert(y>=0);
    x+=y; if (x>=mod) x-=mod;
    assert(x>=0 && x<mod);
}
void et() {
    puts("-1"); exit(0);
}
ll fastPow(ll x, ll y, int mod=MOD) {
    ll ans = 1;
    while(y>0) {
        if(y&1) ans = (x * ans)%mod;
        x = x*x%mod;
        y>>=1;
    }
    return ans;
}

struct Frac {
    ll x, y;
    int z;
    Frac() { }
    Frac(ll x, ll y, int z) : x(x), y(y) ,z(z){}
    bool operator<(const Frac& o) const {
        return z || (o.z==0 && (x*o.y < y*o.x));
    }
    friend bool operator == (const Frac &r1,const Frac &r2) {return r1.x*r2.y == r1.y*r2.x;}
};
int R;
Frac lt[MAX],rt[MAX];
int sateCnt;
struct mb {
    int t,x,y, id;
    void rd() {
        scanf("%d", &t);
        if (t==2) scanf("%d", &id);
        else scanf("%d%d", &x,&y);
    }
}q[MAX];
map<Frac, int> mp;
int li[MAX],cnt;

const int MN=(1<<21)+5;
struct mbt {
    int M; Frac T[MN];
    void init(int sz) {
        for(M=1;sz+2>M;M<<=1);
        REP(i,MN) T[i]={0,0,1};
    }
    void uptSingleMax(int l, Frac val) {
        l+=M; T[l]=val;
        while(l>1) {
            T[l>>1] = max(T[l],T[l^1]); l>>=1;
        }
    }
    Frac qyRangeMax(int l, int r) {
        Frac ans = {0,0,1};
        for(l=l+M-1,r=r+M+1;l^r^1;l>>=1,r>>=1){
            if(~l&1) ans = max(ans, T[l^1]);
            if(r&1) ans = max(ans, T[r^1]);
        }
        return ans;
    }
}T;
bool del[MAX];
priority_queue<pair<Frac,int>> Q[MAX];
void add(int staId) {
    del[staId] = 0;
    bool cg = Q[li[staId]].empty() || Q[li[staId]].top().second != staId;
    Q[li[staId]].push({rt[staId], staId});
    if (cg) {
        T.uptSingleMax(li[staId], rt[staId]);
    }
}
void rmv(int staId) {
    del[staId] = 1;
    int k = li[staId];
    while(!Q[k].empty() && del[Q[k].top().second]) {
        Q[k].pop();
    }
    if (Q[k].empty()) T.uptSingleMax(k, Frac(0,0,1));
    else T.uptSingleMax(li[staId], Q[k].top().first);
}
void fmain(int tid) {
    scanf("%d%d", &R, &n);
    REQ(i,n) {
        q[i].rd();
        if (q[i].t == 1) {
            int x=q[i].x,y=q[i].y;
            sateCnt++;
            lt[sateCnt] = Frac(x+R,y,0);
            rt[sateCnt] = Frac(y,R-x,0);
            q[i].id = sateCnt;
        }
    }
    REQ(i,sateCnt) {
        mp[lt[i]];
    }
    for(auto &p : mp) {
        p.second = ++cnt;
    }
    REQ(i,sateCnt) {
        li[i] = mp[lt[i]];
    }
    T.init(cnt);
    REQ(i,n) {
        if (q[i].t==1) {
            add(q[i].id);
        } else if (q[i].t==2) {
            rmv(q[i].id);
        } else {
            int x=q[i].x,y=q[i].y;
            if(lt[y] < lt[x]) swap(x,y);
            bool ok = 0;
            if (rt[x] < lt[y]) {
                puts("NO"); continue;
            }

                int idx = li[y];
                rmv(x); rmv(y);
                ok = T.qyRangeMax(1, idx) < min(rt[x],rt[y]);
                add(x); add(y);

            puts(ok ? "YES" : "NO");
        }
    }
}
int main() {
    int t=1;
//    scanf("%d", &t);
    REQ(i,t) {
        fmain(i);
    }
    return 0;
}

#include <cstdio>
#include <algorithm>
#include <cstring>
#include <queue>
#include <cmath>
#define ll long long
#define ld long double
#define l(a) (a<<1)
#define r(a) (a<<1|1)
#define MN 500005
#define MM 1000005
#define MD 4200005
//#define eps 1e-15
using namespace std;
int INF;
struct meg{int g,x,y;}a[MN];
struct itv1{ld x,y;}w[MN];
struct itv2{int x,y;}s[MN];
struct Que
{
	priority_queue <int,vector<int>,greater<int> > A,B;
	void push(int x) {A.push(x);}
	void dele(int x) {B.push(x);}
	int top()
	{
		while (!B.empty()&&A.top()==B.top()) A.pop(),B.pop();
		if (!A.empty()) return A.top(); else return INF;
	}
}q[MM];
ld b[MM];
ll ra;
int m,MQ,tin,bin;
int t[MD];

inline int read()
{
	int n=0,f=1; char c=getchar();
	while (c<'0' || c>'9') {if(c=='-')f=-1; c=getchar();}
	while (c>='0' && c<='9') {n=n*10+c-'0'; c=getchar();}
	return n*f;
}

inline void getcg(int x,int z) {for (t[x+=MQ]=z,x>>=1;x;x>>=1) t[x]=min(t[l(x)],t[r(x)]);}
inline int getmin(int L,int R)
{
	int sum=INF;
	for (L+=MQ,R+=MQ;L<=R;L>>=1,R>>=1)
	{
		if ( L&1) sum=min(sum,t[L++]);
		if (~R&1) sum=min(sum,t[R--]);
	}
	return sum;
}

ld cal(ll x0,ll y0,ll x1,ll y1,ll g)
{
	ld ki,bi;
	ki=(ld)(y1-y0)/(x1-x0);
	bi=(ld)y0-(ld)x0*(y1-y0)/(x1-x0);
	return acos((ld)(bi*bi-ra*ra)*g/(ki*ki+1)/(ra*ra));
}
void cghp(int x,int y,int g)
{
	int lt=q[x].top();
	if (g==1) q[x].push(y); else q[x].dele(y);
	if (lt!=q[x].top()) getcg(x,q[x].top());
}

int main()
{
	register int i,x,y,lt=0;
	ra=read(); m=read();
	for (i=1;i<=m;++i)
	{
		a[i].g=read();
		if (a[i].g==1)
		{
			x=read(); y=read(); a[i].x=++tin;
			w[tin].x=(ll)x>= ra?acos( 1):cal( ra,0,(ll)x,(ll)y, 1);
			w[tin].y=(ll)x<=-ra?acos(-1):cal(-ra,0,(ll)x,(ll)y,-1);
			b[++bin]=w[tin].x; b[++bin]=w[tin].y;
		}
		else if (a[i].g==2) a[i].x=read();
		else if (a[i].g==3) a[i].x=read(),a[i].y=read();
	}
	sort(b+1,b+bin+1);
	for (i=2;i<=bin;++i) {if (b[i]==b[i-1]) ++lt; b[i-lt]=b[i];}
	bin-=lt;
	for (i=1;i<=tin;++i)
		s[i].x=lower_bound(b+1,b+bin+1,w[i].x)-b,
		s[i].y=lower_bound(b+1,b+bin+1,w[i].y)-b;
//		s[i].x=s[i].x*2-1,s[i].y=s[i].y*2-1;
	for (MQ=1;MQ<bin;MQ<<=1); --MQ;
	memset(t,100,sizeof(t)); INF=t[0];
	for (i=1;i<=m;++i)
	{
		if (a[i].g<3) cghp(s[a[i].x].y,s[a[i].x].x,a[i].g);
		else if (a[i].g==3)
		{
			x=max(s[a[i].x].x,s[a[i].y].x); y=min(s[a[i].x].y,s[a[i].y].y);
			if (x>y) {puts("NO"); continue;}
			cghp(s[a[i].x].y,s[a[i].x].x,2);
			cghp(s[a[i].y].y,s[a[i].y].x,2);
			if (getmin(y,bin)<=x) puts("NO"); else puts("YES");
			cghp(s[a[i].x].y,s[a[i].x].x,1);
			cghp(s[a[i].y].y,s[a[i].y].x,1);
		}
	}
}

#pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")
#pragma GCC optimize("no-stack-protector")
#pragma GCC target("sse,sse2,ssse3,sse3,sse4,popcnt,avx,mmx,abm,tune=native")
#include <bits/stdc++.h>
#define DEBUG 1
using namespace std;

namespace output{
    void __(short x){cout<<x;}
    void __(unsigned x){cout<<x;}
    void __(int x){cout<<x;}
    void __(long long x){cout<<x;}
    void __(unsigned long long x){cout<<x;}
    void __(double x){cout<<x;}
    void __(long double x){cout<<x;}
    void __(char x){cout<<x;}
    void __(const char*x){cout<<x;}
    void __(const string&x){cout<<x;}
    void __(bool x){cout<<(x?"true":"false");}
    template<class S,class T>
    void __(const pair<S,T>&x){__(DEBUG?"(":""),__(x.first),__(DEBUG?", ":" "),__(x.second),__(DEBUG?")":"");}
    template<class T>
    void __(const vector<T>&x){__(DEBUG?"{":"");bool _=0;for(const auto&v:x)__(_?DEBUG?", ":" ":""),__(v),_=1;__(DEBUG?"}":"");}
    template<class T>
    void __(const set<T>&x){__(DEBUG?"{":"");bool _=0;for(const auto&v:x)__(_?DEBUG?", ":" ":""),__(v),_=1;__(DEBUG?"}":"");}
    template<class T>
    void __(const multiset<T>&x){__(DEBUG?"{":"");bool _=0;for(const auto&v:x)__(_?DEBUG?", ":" ":""),__(v),_=1;__(DEBUG?"}":"");}
    template<class S,class T>
    void __(const map<S,T>&x){__(DEBUG?"{":"");bool _=0;for(const auto&v:x)__(_?DEBUG?", ":" ":""),__(v),_=1;__(DEBUG?"}":"");}
    void pr(){cout<<"\n";}
    template<class S,class... T>
    void pr(const S&a,const T&...b){__(a);if(sizeof...(b))__(' ');pr(b...);}
}

using namespace output;

typedef long long ll;
typedef long double ld;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
typedef pair<int,char> pic;
typedef pair<double,double> pdd;
typedef pair<ld,ld> pld;
typedef vector<int> vi;
typedef vector<ll> vl;

#define pb push_back
#define fox(i,x,y) for(int i=(x);i<=(y);i++)
#define foxr(i,x,y) for(int i=(y);i>=(x);i--)
#define F first
#define S second

const int MN = 5e5+5;
const ld PI = (ld)acos((ld)-1);
int N, R, i, x, y, cnt;
map<ld,int> A, B;
ld aa[MN], bb[MN];
pii pos[MN];

bool ok(int i,int j){
    ld x=max(aa[i],aa[j]);
    ld y=PI-min(bb[i],bb[j]);
    return (x+y>=PI/2);
}

int main(){
    scanf("%d%d",&R,&N);
    while(N--){
        scanf("%d",&i);
        if(i==1){
            scanf("%d%d",&x,&y);
            cnt ++;
            pos[cnt] = {x,y};
            aa[cnt] = (ld)atan2((ld)y,(ld)x+R);
            bb[cnt] = (ld)atan2((ld)y,(ld)x-R);
            A[aa[cnt]]++;
            B[bb[cnt]]++;
        }
        else if(i==2){
            scanf("%d",&x);
            A[aa[x]]--;
            B[bb[x]]--;
            if(!A[aa[x]]) A.erase(aa[x]);
            if(!B[bb[x]]) B.erase(bb[x]);
        }
        else{
            scanf("%d%d",&x,&y);
            if(aa[x]==aa[y]){
                if(bb[x]>bb[y]) swap(x,y);
                auto it2=B.lower_bound(bb[x]);
                if(A[aa[x]]>2||it2->second!=1) printf("NO\n");
                else{
                    it2++;
                    if(it2==B.end()||it2->second!=1||it2->first!=bb[y]) printf("NO\n");
                    else printf("%s\n",ok(x,y)?"YES":"NO");
                }
                continue;
            }
            if(aa[x]>aa[y]) swap(x,y);
            auto it=A.lower_bound(aa[x]);
            if(it->second!=1) printf("NO\n");
            else{
                it++;
                if(it==A.end()||it->second!=1||it->first!=aa[y]) printf("NO\n");
                else{
                    if(bb[x]==bb[y]){
                        if(B[bb[x]]>2) printf("NO\n");
                        else printf("%s\n",ok(x,y)?"YES":"NO");
                        continue;
                    }
                    if(bb[x]>bb[y]) swap(x,y);
                    auto it2=B.lower_bound(bb[x]);
                    if(it2->second!=1) printf("NO\n");
                    else{
                        it2++;
                        if(it2==B.end()||it2->second!=1||it2->first!=bb[y]) printf("NO\n");
                        else printf("%s\n",ok(x,y)?"YES":"NO");
                    }
                }
            }
        }
    }
}

#pragma comment(linker, "/stack:200000000")
#pragma GCC optimize("Ofast")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")

#include <bits/stdc++.h>

#define F0R(i, a) for (int i = 0; i < (a); i++)
#define FOR(i, a, b) for (int i = (a); i < (b); i++)
#define R0F(i, a) for (int i = (a) - 1; i >= 0; i--)
#define ROF(i, a, b) for (int i = (b) - 1; i >= (a); i--)

#define ran() (rand() & 0x7FFF)
#define rand31() ((ran() << 16) | (ran() << 1) | (ran() & 1))
#define rand32() ((ran() << 17) | (ran() << 2) | (ran() & 3))
#define rand63() (((ll)ran() << 48) | ((ll)ran() << 33) | ((ll)ran() << 18) | ((ll)ran() << 3) | ((ll)ran() & 7))
#define rand64() (((ll)ran() << 49) | ((ll)ran() << 34) | ((ll)ran() << 19) | ((ll)ran() << 4) | ((ll)ran() & 15))

#define F first
#define S second
#define PB push_back
#define MP make_pair
#define MT make_tuple
#define UB upper_bound
#define LB lower_bound
#define X real()
#define Y imag()

#define INF 1e18
#define PI acos(-1)

#define sz(x) ((int)(x).size())
#define all(x) (x).begin(), (x).end()
#define SQ(x) ((x) * (x))

using namespace std;

typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef vector<int> vi;
typedef vector<pii> vpii;
typedef vector<ll> vll;
typedef vector<ull> vul;
typedef complex<ld> point;
typedef complex<ld> cld;
typedef vector<cld> vcld;

#define MAXN 500000

struct angle {

ll y, x;

bool operator<(const angle& a2) const {
    return x * a2.y - y * a2.x > 0;
}

angle operator+(const angle& a2) const {
    return {y * x * a2.x + a2.y * x * a2.x, x * a2.x - y * a2.y};
}

bool operator==(const angle& a2) const {
    return x * a2.y == y * a2.x;
}

bool operator<=(const angle& a2) const { return *this < a2 || *this == a2; }

bool operator>=(const angle& a2) const { return a2 < *this; }

};

struct SegTree{

int sz;
angle *tree;

SegTree(int _sz) {
    sz = 1 << (32 - __builtin_clz(_sz - 1));
    tree = new angle[2 * sz];
    F0R(i, 2 * sz) tree[i] = angle({0, 1});
}

void upd(int idx, angle v) {
    idx += sz;
    tree[idx] = v;
    for (idx /= 2; idx > 0; idx /= 2) tree[idx] = max(tree[2 * idx], tree[2 * idx + 1]);
}

angle query(int lo, int hi) {
    lo += sz, hi += sz;
    angle res = angle({0, 1});
    while(lo <= hi) {
        if ((lo % 2) == 1) res = max(res, tree[lo++]);
        if ((hi % 2) == 0) res = max(res, tree[hi--]);
        lo /= 2;
        hi /= 2;
    }
    return res;
}

};

ll r;
angle alpha[MAXN], beta123[MAXN];
int n, q, posof[MAXN];
vector<pair<angle, int>> order;
vpii updates;
vector<pair<int, pii>> queries;

SegTree st(2);

void toggle(int idx) {
int pos = posof[idx];
if (st.query(pos, pos) == angle({0, 1})) st.upd(pos, beta123[idx]);
else st.upd(pos, {0, 1});
}

int main() {
ios::sync_with_stdio(0);
cin.tie(0);
cin >> r >> q;
F0R(i, q) {
    int t;
    cin >> t;
    switch(t) {
        case 1:
            ll x, y;
            cin >> x >> y;
            alpha[n] = {y, r - x};
            beta123[n] = {y, x + r};
            updates.PB(MP(i, n++));
            break;
        case 2:
            int idx;
            cin >> idx;
            idx--;
            updates.PB(MP(i, idx));
            break;
        case 3:
            int a, b;
            cin >> a >> b;
            a--, b--;
            queries.PB(MP(i, MP(a, b)));
            break;
    }
}
F0R(i, n) order.PB(MP(alpha[i], i));
sort(all(order));
F0R(i, n) posof[order[i].S] = i;
reverse(all(updates));
reverse(all(queries));
st = SegTree(n);
while (!updates.empty() || !queries.empty()) {
    if (queries.empty() || (!updates.empty() && updates.back().F < queries.back().F)) {
        int idx = updates.back().S;
        updates.pop_back();
        toggle(idx);
    } else {
        int a = queries.back().S.F;
        int b = queries.back().S.S;
        queries.pop_back();
        angle _alpha = min(alpha[a], alpha[b]);
        angle _beta123 = min(beta123[a], beta123[b]);
        if(_alpha + _beta123 <= angle({0, 1})) cout << "NO\n";
            else {
                toggle(a);
                toggle(b);

                int lo = LB(all(order), MP(_alpha, 0)) - order.begin();
                if (st.query(lo, n - 1) >= _beta123) cout << "NO\n";
                else cout << "YES\n";

                toggle(a);
                toggle(b);
            }
        }
    }
    }

#include <bits/stdc++.h>

const int MAXN = 500010;
typedef long long LL;
typedef long double db;
typedef LL VT;
struct vec {
	VT x, y;
	vec() { x = y = 0; }
	vec(VT a, VT b) { x = a, y = b; }
// WARN: modify following 4 functions if VT is int
// 1. A * B    2. return LL
	VT operator ^ (vec b) const { return x * b.y - y * b.x; }
	VT operator * (vec b) const { return x * b.x + y * b.y; }
	VT norm2() const { return x * x + y * y; }
	db norm() const { return sqrt(x * x + y * y); }
	vec operator - (vec b) const { return vec(x - b.x, y - b.y); }
	vec operator + (vec b) const { return vec(x + b.x, y + b.y); }
	vec operator * (db k) const { return vec(x * k, y * k); }
	friend bool operator < (const vec & a, const vec & b) {
		return (a ^ b) > 0;
	}
	friend std::istream & operator >> (std::istream & in, vec & x) {
		in >> x.x >> x.y;
		return in;
	}
	friend std::ostream & operator << (std::ostream & out, vec x) {
		out << '(' << x.x << ',' << x.y << ')';
		return out;
	}
} ;
typedef std::vector<vec> VP;
inline LL cross(vec a, vec b, vec c) {
	return (b - a) ^ (c - a);
}
typedef std::pair<vec, int> pi;
int bel[MAXN], lll[MAXN], rrr[MAXN];
int discr(std::vector<pi> v, int * tar) {
	const int L = v.size();
	std::sort(v.begin(), v.end());
	int rnk = 0;
	for (int i = 0; i != L; ++i) {
		if (i != 0 && !(v[i].first < v[i - 1].first || v[i - 1].first < v[i].first)) ;
		else ++rnk;
		bel[tar[v[i].second] = i + 1] = rnk;
		if (!lll[rnk]) lll[rnk] = i + 1;
		rrr[rnk] = i + 1;
	}
	return L;
}
vec ps[MAXN];
int opt[MAXN], xs[MAXN], ys[MAXN];
const int NINF = 0xcfcfcfcf;
int tree[MAXN << 2];
void add(int u, int l, int r, int tar, int v) {
	if (l == r) return (void) (tree[u] = v);
	int mid = l + r >> 1;
	if (tar <= mid) add(u << 1, l, mid, tar, v);
	else add(u << 1 | 1, mid + 1, r, tar, v);
	tree[u] = std::max(tree[u << 1], tree[u << 1 | 1]);
}
int qry(int u, int l, int r, int L, int R) {
	if (L <= l && r <= R) return tree[u];
	int mid = l + r >> 1, res = NINF;
	if (L <= mid) res = qry(u << 1, l, mid, L, R);
	if (mid < R) res = std::max(res, qry(u << 1 | 1, mid + 1, r, L, R));
	return res;
}
int n;
inline int tr(int x, int y) { return x == 1 ? y : NINF; }
int nl;
void add(int i, int v) {
	add(1, 1, nl, ys[i], tr(v, xs[i]));
}
LL R;
bool incir(vec x, vec y) {
	typedef long double ld;
	x.x *= x.x, x.y *= x.y;
	y.x *= y.x, y.y *= y.y;
	ld t = (ld) x.x * (y.x + y.y) + (ld) y.x * (x.x + x.y);
	t -= (ld) (x.x + x.y) * (y.x + y.y);
	if (t > 1e-4) return true;
	return false;
}
int trans[MAXN];
int main() {
	memset(tree, 0xcf, sizeof tree);
	std::ios_base::sync_with_stdio(false), std::cin.tie(0);
	std::cin >> R >> n;
	vec pol(-R, 0), por(R, 0);
	std::vector<pi> ll;
	for (int i = 1, bak = 0; i <= n; ++i) {
		std::cin >> opt[i] >> xs[i];
		if (opt[i] != 2) std::cin >> ys[i];
		if (opt[i] == 1) {
			ps[i] = vec(xs[i], ys[i]);
			ll.emplace_back(ps[i] - pol , i);
			ll.emplace_back(ps[i] - por, i + n);
			trans[++bak] = i;
		} else xs[i] = trans[xs[i]], ys[i] = trans[ys[i]];
	}
	static int ls[MAXN << 1], app[MAXN];
	nl = discr(ll, ls);
	for (int i = 1; i <= n; ++i) if (opt[i] == 1)
		xs[i] = ls[i], ys[i] = ls[i + n];
	for (int T = 1; T <= n; ++T) {
		if (opt[T] == 1) add(T, 1), app[T] = true;
		else if (opt[T] == 2) add(xs[T], -1), app[xs[T]] = false;
		else {
			bool can = true;
			int A = xs[T], B = ys[T];
			if (!incir( std::min(ps[A] - pol, ps[B] - pol),
						std::max(ps[A] - por, ps[B] - por) )) {
				int l = lll[bel[std::min(xs[A], xs[B])]];
				int r = rrr[bel[std::max(ys[A], ys[B])]];
				if (app[A]) add(A, -1);
				if (app[B]) add(B, -1);
				can = qry(1, 1, nl, 1, r) >= l;
				if (app[A]) add(A, 1);
				if (app[B]) add(B, 1);
			}
			std::cout << (can ? "NO" : "YES") << '\n';
		}
	}

	return 0;
}

#include <bits/stdc++.h>

const int MAXN = 500010;
typedef long long LL;
typedef long double db;
typedef LL VT;
struct vec {
	VT x, y;
	vec() { x = y = 0; }
	vec(VT a, VT b) { x = a, y = b; }
	VT operator ^ (vec b) const { return x * b.y - y * b.x; }
	VT operator * (vec b) const { return x * b.x + y * b.y; }
	VT norm2() const { return x * x + y * y; }
	db norm() const { return sqrt(x * x + y * y); }
	vec operator - (vec b) const { return vec(x - b.x, y - b.y); }
	vec operator + (vec b) const { return vec(x + b.x, y + b.y); }
	vec operator * (db k) const { return vec(x * k, y * k); }
	friend bool operator < (const vec & a, const vec & b) {
		return (a ^ b) > 0;
	}
	friend std::istream & operator >> (std::istream & in, vec & x) {
		in >> x.x >> x.y;
		return in;
	}
	friend std::ostream & operator << (std::ostream & out, vec x) {
		out << '(' << x.x << ',' << x.y << ')';
		return out;
	}
} ;
typedef std::pair<vec, int> pi;
int bel[MAXN], lll[MAXN], rrr[MAXN];
int discr(std::vector<pi> v, int * tar) {
	const int L = v.size();
	std::sort(v.begin(), v.end());
	int rnk = 0;
	for (int i = 0; i != L; ++i) {
		if (i != 0 && !(v[i].first < v[i - 1].first || v[i - 1].first < v[i].first)) ;
		else ++rnk;
		bel[tar[v[i].second] = i + 1] = rnk;
		if (!lll[rnk]) lll[rnk] = i + 1;
		rrr[rnk] = i + 1;
	}
	return L;
}
vec ps[MAXN];
int opt[MAXN], xs[MAXN], ys[MAXN];
const int NINF = 0xcfcfcfcf;
int tree[MAXN << 2];
void add(int u, int l, int r, int tar, int v) {
	if (l == r) return (void) (tree[u] = v);
	int mid = l + r >> 1;
	if (tar <= mid) add(u << 1, l, mid, tar, v);
	else add(u << 1 | 1, mid + 1, r, tar, v);
	tree[u] = std::max(tree[u << 1], tree[u << 1 | 1]);
}
int qry(int u, int l, int r, int L, int R) {
	if (L <= l && r <= R) return tree[u];
	int mid = l + r >> 1, res = NINF;
	if (L <= mid) res = qry(u << 1, l, mid, L, R);
	if (mid < R) res = std::max(res, qry(u << 1 | 1, mid + 1, r, L, R));
	return res;
}
int n;
inline int tr(int x, int y) { return x == 1 ? y : NINF; }
int nl;
void add(int i, int v) {
	add(1, 1, nl, ys[i], tr(v, xs[i]));
}
LL R;
typedef __int128 LLL;
bool incir(vec x, vec y) {
	return (x * y) < 0 || (x ^ y) <= 0;
}
int trans[MAXN];
int main() {
	memset(tree, 0xcf, sizeof tree);
	std::ios_base::sync_with_stdio(false), std::cin.tie(0);
	std::cin >> R >> n;
	vec pol(-R, 0), por(R, 0);
	std::vector<pi> ll;
	for (int i = 1, bak = 0; i <= n; ++i) {
		std::cin >> opt[i] >> xs[i];
		if (opt[i] != 2) std::cin >> ys[i];
		if (opt[i] == 1) {
			ps[i] = vec(xs[i], ys[i]);
			ll.emplace_back(ps[i] - pol , i);
			ll.emplace_back(ps[i] - por, i + n);
			trans[++bak] = i;
		} else xs[i] = trans[xs[i]], ys[i] = trans[ys[i]];
	}
	static int ls[MAXN << 1], app[MAXN];
	nl = discr(ll, ls);
	for (int i = 1; i <= n; ++i) if (opt[i] == 1)
		xs[i] = ls[i], ys[i] = ls[i + n];
	for (int T = 1; T <= n; ++T) {
		if (opt[T] == 1) add(T, 1), app[T] = true;
		else if (opt[T] == 2) add(xs[T], -1), app[xs[T]] = false;
		else {
			bool can = true;
			int A = xs[T], B = ys[T];
			if (!incir( std::min(ps[A] - pol, ps[B] - pol),
						std::max(ps[A] - por, ps[B] - por) )) {
				int l = lll[bel[std::min(xs[A], xs[B])]];
				int r = rrr[bel[std::max(ys[A], ys[B])]];
				if (app[A]) add(A, -1);
				if (app[B]) add(B, -1);
				can = qry(1, 1, nl, 1, r) >= l;
				if (app[A]) add(A, 1);
				if (app[B]) add(B, 1);
			}
			std::cout << (can ? "NO" : "YES") << '\n';
		}
	}

	return 0;
}

#include <bits/stdc++.h>
#define SZ(X) ((int)(X).size())
#define ALL(X) (X).begin(), (X).end()
#define REP(I, N) for (int I = 0; I < (N); ++I)
#define REPP(I, A, B) for (int I = (A); I < (B); ++I)
#define RI(X) scanf("%d", &(X))
#define RII(X, Y) scanf("%d%d", &(X), &(Y))
#define RIII(X, Y, Z) scanf("%d%d%d", &(X), &(Y), &(Z))
#define DRI(X) int (X); scanf("%d", &X)
#define DRII(X, Y) int X, Y; scanf("%d%d", &X, &Y)
#define DRIII(X, Y, Z) int X, Y, Z; scanf("%d%d%d", &X, &Y, &Z)
#define RS(X) scanf("%s", (X))
#define CASET int ___T, case_n = 1; scanf("%d ", &___T); while (___T-- > 0)
#define MP make_pair
#define PB push_back
#define MS0(X) memset((X), 0, sizeof((X)))
#define MS1(X) memset((X), -1, sizeof((X)))
#define LEN(X) strlen(X)
#define PII pair<int,int>
#define VI vector<int>
#define VL vector<long long>
#define VPII vector<pair<int,int> >
#define PLL pair<long long,long long>
#define VPLL vector<pair<long long,long long> >
#define F first
#define S second
typedef long long LL;
using namespace std;
const int INF = 1e9+7;
const int SIZE = 1e6+10;
int R,N;
int in[SIZE][3];
PII R_R[SIZE];
VPII pp;
bool cmp(PII x,PII y){
    if((x.S>=0)!=(y.S>=0)){
        return x.F<y.F;
    }
    return (LL)x.F*y.S-(LL)x.S*y.F>0;
}
PII sat[SIZE],ll[SIZE],rr[SIZE];
int sid;
int my_gcd(int x,int y){
    x=abs(x);y=abs(y);
    if(!x||!y)return x+y;
    return __gcd(x,y);
}
PII get_left(int x,int y){
    x+=R;
    int gg=my_gcd(x,y);
    x/=gg;
    y/=gg;
    return MP(x,y);
}
PII get_right(int x,int y){
    x-=R;
    int gg=my_gcd(x,y);
    x/=gg;
    y/=gg;
    if(x<=0)return MP(y,-x);
    return MP(y,-x);
}
int mi[SIZE*4],pb[SIZE*4];
void push(int x){
    if(!pb[x])return;
    REP(i,2){
        mi[x*2+i]+=pb[x];
        pb[x*2+i]+=pb[x];
    }
    pb[x]=0;
}
void ins(int L,int R,int id,int x,int y,int v){
    //if(v==-1)printf("[%d,%d]:%d,%d\n",L,R,mi[id],pb[id]);
    if(R<x||L>y)return;
    if(L>=x&&R<=y){
        mi[id]+=v;
        pb[id]+=v;
        return;
    }
    int mm=(L+R)/2;
    push(id);
    ins(L,mm,id*2,x,y,v);
    ins(mm+1,R,id*2+1,x,y,v);
    mi[id]=min(mi[id*2],mi[id*2+1]);

}
int qq(int L,int R,int id,int x,int y){
    //printf("{%d,%d}:%d,%d\n",L,R,mi[id],pb[id]);
    if(L>y||R<x)return INF;
    if(L>=x&&R<=y){
        return mi[id];
    }
    int mm=(L+R)/2;
    push(id);
    int ret=min(qq(L,mm,id*2,x,y),qq(mm+1,R,id*2+1,x,y));
    mi[id]=min(mi[id*2],mi[id*2+1]);
    return ret;
}
void print(int L,int R,int id){
    printf("{%d,%d}:%d,%d\n",L,R,mi[id],pb[id]);
    if(L==R)return;
    int mm=(L+R)/2;
    print(L,mm,id*2);
    print(mm+1,R,id*2+1);
}
int main(){
    sid=0;
    RII(R,N);
    REP(i,N){
        RII(in[i][0],in[i][1]);
        if(in[i][0]!=2)RI(in[i][2]);
        if(in[i][0]==1){
            int x=in[i][1];
            int y=in[i][2];
            sid++;
            ll[sid]=get_left(x,y),rr[sid]=get_right(x,y);
            pp.PB(ll[sid]);
            pp.PB(rr[sid]);
            in[i][1]=sid;
        }
    }
    sort(ALL(pp),cmp);
    pp.resize(unique(ALL(pp))-pp.begin());
    map<PII,int>get_id;
    REP(i,SZ(pp))get_id[pp[i]]=i+1;
    REPP(i,1,sid+1)R_R[i]=MP(get_id[rr[i]],get_id[ll[i]]);
    //REPP(i,1,sid+1)printf("(%d,%d)\n",R_R[i].F,R_R[i].S);
    REP(i,N){
        //printf("op %d:\n",i);
        if(in[i][0]==1){
            ins(1,sid*4,1,R_R[in[i][1]].F*2,R_R[in[i][1]].S*2,1);
        }
        else if(in[i][0]==2){
            ins(1,sid*4,1,R_R[in[i][1]].F*2,R_R[in[i][1]].S*2,-1);
        }
        else{
            int x=max(R_R[in[i][1]].F,R_R[in[i][2]].F);
            int y=min(R_R[in[i][1]].S,R_R[in[i][2]].S);
            if(x>y)puts("NO");
            else{
                if(qq(1,sid*4,1,x*2,y*2)==2)puts("YES");
                else puts("NO");
            }
        }
        //print(1,sid*4,1);
    }
    return 0;
}

#include <bits/stdc++.h>

const int MAXN = 500010;
typedef long long LL;
typedef long double db;
typedef LL VT;
struct vec {
	VT x, y;
	vec() { x = y = 0; }
	vec(VT a, VT b) { x = a, y = b; }
	VT operator ^ (vec b) const { return x * b.y - y * b.x; }
	VT operator * (vec b) const { return x * b.x + y * b.y; }
	VT norm2() const { return x * x + y * y; }
	db norm() const { return sqrt(x * x + y * y); }
	vec operator - (vec b) const { return vec(x - b.x, y - b.y); }
	vec operator + (vec b) const { return vec(x + b.x, y + b.y); }
	vec operator * (db k) const { return vec(x * k, y * k); }
	friend bool operator < (const vec & a, const vec & b) {
		return (a ^ b) > 0;
	}
	friend std::istream & operator >> (std::istream & in, vec & x) {
		in >> x.x >> x.y;
		return in;
	}
	friend std::ostream & operator << (std::ostream & out, vec x) {
		out << '(' << x.x << ',' << x.y << ')';
		return out;
	}
} ;
typedef std::pair<vec, int> pi;
int bel[MAXN], lll[MAXN], rrr[MAXN];
int discr(std::vector<pi> v, int * tar) {
	const int L = v.size();
	std::sort(v.begin(), v.end());
	int rnk = 0;
	for (int i = 0; i != L; ++i) {
		if (i != 0 && !(v[i].first < v[i - 1].first || v[i - 1].first < v[i].first)) ;
		else ++rnk;
		bel[tar[v[i].second] = i + 1] = rnk;
		if (!lll[rnk]) lll[rnk] = i + 1;
		rrr[rnk] = i + 1;
	}
	return L;
}
vec ps[MAXN];
int opt[MAXN], xs[MAXN], ys[MAXN];
const int NINF = 0xcfcfcfcf;
int tree[MAXN << 3];
void add(int u, int l, int r, int tar, int v) {
	if (l == r) return (void) (tree[u] = v);
	int mid = l + r >> 1;
	if (tar <= mid) add(u << 1, l, mid, tar, v);
	else add(u << 1 | 1, mid + 1, r, tar, v);
	tree[u] = std::max(tree[u << 1], tree[u << 1 | 1]);
}
int qry(int u, int l, int r, int L, int R) {
	if (L <= l && r <= R) return tree[u];
	int mid = l + r >> 1, res = NINF;
	if (L <= mid) res = qry(u << 1, l, mid, L, R);
	if (mid < R) res = std::max(res, qry(u << 1 | 1, mid + 1, r, L, R));
	return res;
}
int n;
inline int tr(int x, int y) { return x == 1 ? y : NINF; }
int nl;
void add(int i, int v) {
	add(1, 1, nl, ys[i], tr(v, xs[i]));
}
LL R;
bool incir(vec x, vec y) {
	return (x * y) < 0 || (x ^ y) <= 0;
}
int trans[MAXN];
int main() {
	memset(tree, 0xcf, sizeof tree);
	std::ios_base::sync_with_stdio(false), std::cin.tie(0);
	std::cin >> R >> n;
	vec pol(-R, 0), por(R, 0);
	std::vector<pi> ll;
	for (int i = 1, bak = 0; i <= n; ++i) {
		std::cin >> opt[i] >> xs[i];
		if (opt[i] != 2) std::cin >> ys[i];
		if (opt[i] == 1) {
			ps[i] = vec(xs[i], ys[i]);
			ll.emplace_back(ps[i] - pol , i);
			ll.emplace_back(ps[i] - por, i + n);
			trans[++bak] = i;
		} else xs[i] = trans[xs[i]], ys[i] = trans[ys[i]];
	}
	static int ls[MAXN << 1], app[MAXN];
	nl = discr(ll, ls);
	for (int i = 1; i <= n; ++i) if (opt[i] == 1)
		xs[i] = ls[i], ys[i] = ls[i + n];
//	for (int i = 1; i <= n; ++i)
//		std::cout << xs[i] << ' ' << ys[i] << std::endl;
	for (int T = 1; T <= n; ++T) {
		if (opt[T] == 1) add(T, 1), app[T] = true;
		else if (opt[T] == 2) add(xs[T], -1), app[xs[T]] = false;
		else {
			bool can = true;
			int A = xs[T], B = ys[T];
			if (!incir( std::min(ps[A] - pol, ps[B] - pol),
						std::max(ps[A] - por, ps[B] - por) )) {
				int l = lll[bel[std::min(xs[A], xs[B])]];
				int r = rrr[bel[std::max(ys[A], ys[B])]];
				if (app[A]) add(A, -1);
				if (app[B]) add(B, -1);
				can = qry(1, 1, nl, 1, r) >= l;
				if (app[A]) add(A, 1);
				if (app[B]) add(B, 1);
			}
			std::cout << (can ? "NO" : "YES") << '\n';
		}
	}

	return 0;
}

#include <cstdio>
#include <algorithm>
#include <cstring>
#include <queue>
#include <cmath>
#define ll long long
#define ld long double
#define l(a) (a<<1)
#define r(a) (a<<1|1)
#define MN 500005
#define MM 2000005
#define MD 4200005
#define eps 1e-13
using namespace std;
int INF;
struct meg{int g,x,y;}a[MN];
struct itv1{ld x,y;}w[MN];
struct itv2{int x,y;}s[MN];
struct Que
{
	priority_queue <int,vector<int>,greater<int> > A,B;
	void push(int x) {A.push(x);}
	void dele(int x) {B.push(x);}
	int top()
	{
		while (!B.empty()&&A.top()==B.top()) A.pop(),B.pop();
		if (!A.empty()) return A.top(); else return INF;
	}
}q[MM];
ld b[MN<<1];
ll ra;
int m,MQ,tin,bin;
int t[MD];

inline int read()
{
	int n=0,f=1; char c=getchar();
	while (c<'0' || c>'9') {if(c=='-')f=-1; c=getchar();}
	while (c>='0' && c<='9') {n=n*10+c-'0'; c=getchar();}
	return n*f;
}

inline void getcg(int x,int z) {for (t[x+=MQ]=z,x>>=1;x;x>>=1) t[x]=min(t[l(x)],t[r(x)]);}
inline int getmin(int L,int R)
{
	int sum=INF;
	for (L+=MQ,R+=MQ;L<=R;L>>=1,R>>=1)
	{
		if ( L&1) sum=min(sum,t[L++]);
		if (~R&1) sum=min(sum,t[R--]);
	}
	return sum;
}

ld cal(ll x0,ll y0,ll x1,ll y1,ll g)
{
	ld ki,bi;
	ki=(ld)(y1-y0)/(x1-x0);
	bi=(ld)y0-(ld)x0*(y1-y0)/(x1-x0);
	return acos((ld)(bi*bi-ra*ra)*g/(ki*ki+1)/(ra*ra));
}
void cghp(int x,int y,int g)
{
	int lt=q[x].top();
	if (g==1) q[x].push(y); else q[x].dele(y);
	if (lt!=q[x].top()) getcg(x,q[x].top());
}

int main()
{
	register int i,x,y,lt=0;
	ra=read(); m=read();
	for (i=1;i<=m;++i)
	{
		a[i].g=read();
		if (a[i].g==1)
		{
			x=read(); y=read(); a[i].x=++tin;
			w[tin].x=x>= ra?acos( 1):cal( ra,0,(ll)x,(ll)y, 1);
			w[tin].y=x<=-ra?acos(-1):cal(-ra,0,(ll)x,(ll)y,-1);
			b[++bin]=w[tin].x; b[++bin]=w[tin].y;
		}
		else if (a[i].g==2) a[i].x=read();
		else if (a[i].g==3) a[i].x=read(),a[i].y=read();
	}
	sort(b+1,b+bin+1);
	for (i=2;i<=bin;++i) {if (b[i]-b[i-1]<eps) ++lt; b[i-lt]=b[i];}
	bin-=lt;
	for (i=1;i<=tin;++i)
		s[i].x=lower_bound(b+1,b+bin+1,w[i].x)-b,
		s[i].y=lower_bound(b+1,b+bin+1,w[i].y)-b,
		s[i].x=s[i].x*2-1,s[i].y=s[i].y*2-1;
	bin<<=1;
	for (MQ=1;MQ<bin;MQ<<=1); --MQ;
	memset(t,100,sizeof(t)); INF=t[0];
	for (i=1;i<=m;++i)
	{
		if (a[i].g<3) cghp(s[a[i].x].y,s[a[i].x].x,a[i].g);
		else if (a[i].g==3)
		{
			x=max(s[a[i].x].x,s[a[i].y].x); y=min(s[a[i].x].y,s[a[i].y].y);
			if (x>y) {puts("NO"); continue;}
			cghp(s[a[i].x].y,s[a[i].x].x,2);
			cghp(s[a[i].y].y,s[a[i].y].x,2);
			if (getmin(y,bin)<=x) puts("NO"); else puts("YES");
			cghp(s[a[i].x].y,s[a[i].x].x,1);
			cghp(s[a[i].y].y,s[a[i].y].x,1);
		}
	}
}

#include<iostream>
#include<cstdlib>
#include<stdio.h>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<vector>
#include<set>
#include<map>
using namespace std;
const double eps=1e-9;
double r;
int n,cnt,pos[2][501000],list[501000],cnt_list;
struct segment_tree
{
	int l,r,min_vl,lazy;
};
segment_tree tree[1<<21];
struct point
{
	double x,y;
	bool operator <(const point &temp)const
	{
		 int fg[2];
		 if(fabs(y)<eps)
		 {
 			if(fabs(x-r)<eps)
 			   fg[0]=-1;
	        if(fabs(x+r)<eps)
	            fg[0]=1;
 		}
 		else
 		   fg[0]=0;
        if(fabs(temp.y)<eps)
        {
        	if(fabs(temp.x-r)<eps)
        	   fg[1]==-1;
     	    if(fabs(temp.x+r)<eps)
     	       fg[1]=1;
        }
        else
            fg[1]=0;
        if(fg[0]!=fg[1])
            return fg[0]<fg[1];
		 return y*temp.x<x*temp.y-eps;
	}
};
point pt[1000001];
struct query
{
	int u,v,flag,id;
	double x,y;
	point l,r;
};
query qy[501000];
void build(int left,int right,int id)
{
	int l=2*id+1,r=2*id+2,mid=(left+right)>>1;
	tree[id].min_vl=tree[id].lazy=0;
	tree[id].l=left;
	tree[id].r=right;
	if(left==right)
	    return;
    build(left,mid,l);
    build(mid+1,right,r);
}
void zz(int id)
{
	if(tree[id].lazy==0)
	    return;
	int l=2*id+1,r=2*id+2;
	if(tree[id].l!=tree[id].r)
	{
		tree[l].lazy+=tree[id].lazy;
		tree[r].lazy+=tree[id].lazy;
	}
	tree[id].min_vl+=tree[id].lazy;
	tree[id].lazy=0;
}
void update(int left,int right,int vl,int id)
{
	int l=2*id+1,r=2*id+2;
	if(tree[id].l>right||tree[id].r<left)
	{
	     zz(id);
	     return;
	}
    if(tree[id].l>=left&&tree[id].r<=right)
    {
    	tree[id].lazy+=vl;
    	zz(id);
    	return;
    }
    zz(id);
    update(left,right,vl,l);
    update(left,right,vl,r);
    tree[id].min_vl=min(tree[l].min_vl,tree[r].min_vl);
}
int qw(int left,int right,int id)
{
	int l=2*id+1,r=2*id+2;
	zz(id);
	if(tree[id].l>right||tree[id].r<left)
	    return 1e9+9;
    if(tree[id].l>=left&&tree[id].r<=right)
    	return tree[id].min_vl;
	return min(qw(left,right,l),qw(left,right,r));
}
int binary(int left,int right,point now)
{
	int mid;
	while(left<=right)
	{
		mid=(left+right)>>1;
		if(pt[mid]<now)
			left=mid+1;
		else if(now<pt[mid])
		    right=mid-1;
        else
            return mid;
	}
}
int main()
{
	scanf("%lf%d",&r,&n);
	int i,j,s,p,q,l_id,r_id;
	double ru;
	cnt=0;
	cnt_list=0;
	for(i=0;i<n;i++)
	{
		scanf("%d",&qy[i].flag);
		if(qy[i].flag==1)
		{
			list[cnt_list++]=i;
		    scanf("%lf%lf",&qy[i].x,&qy[i].y);
	        ru=(qy[i].x*qy[i].x+qy[i].y*qy[i].y-r*r)/(qy[i].x*qy[i].x+qy[i].y*qy[i].y+r*r+2*qy[i].x*r);
	        if(ru>=0&&ru<=1)
	        {
		        pt[cnt].x=qy[i].x+(-r-qy[i].x)*ru;
	            pt[cnt].y=qy[i].y+(0-qy[i].y)*ru;
	        }
	        else
	        {
	            pt[cnt].x=-r;
	            pt[cnt].y=0;
			}
			cnt++;
			qy[i].r=pt[cnt-1];
			ru=(qy[i].x*qy[i].x+qy[i].y*qy[i].y-r*r)/(qy[i].x*qy[i].x+qy[i].y*qy[i].y+r*r-2*qy[i].x*r);
			if(ru>=0&&ru<=1)
			{
				pt[cnt].x=qy[i].x+(r-qy[i].x)*ru;
				pt[cnt].y=qy[i].y+(0-qy[i].y)*ru;
			}
			else
			{
				pt[cnt].x=r;
				pt[cnt].y=0;
			}
			cnt++;
			qy[i].id=cnt_list-1;
		    qy[i].l=pt[cnt-1];
		}
		else if(qy[i].flag==2)
        {
           scanf("%d",&qy[i].u);
           qy[i].u--;
        }
        else
        {
        	scanf("%d%d",&qy[i].u,&qy[i].v);
        	qy[i].u--;
        	qy[i].v--;
        }
	}
	sort(pt,pt+cnt);
	int nn=0;
	for(i=0;i<cnt;i++)
	{
		if(nn==0||(fabs(pt[i].x-pt[nn-1].x)+fabs(pt[i].y-pt[nn-1].y))>eps)
		    pt[nn++]=pt[i];
	}
	cnt=nn;
	build(0,cnt-1,0);
	point ll,rr;
	for(i=0;i<n;i++)
	{
		int flag;
		if(qy[i].flag==1)
		{
		   flag=1;
		   ll=qy[i].l;
		   rr=qy[i].r;
		}
		else if(qy[i].flag==2)
		{
			flag=-1;
			ll=qy[list[qy[i].u]].l;
			rr=qy[list[qy[i].u]].r;
		}
		if(qy[i].flag==1||qy[i].flag==2)
		{
    		l_id=binary(0,cnt-1,ll);
    		r_id=binary(0,cnt-1,rr);
    		if(l_id<r_id)
    		   update(l_id,r_id-1,flag,0);
		}
		else
		{
			ll.x=r;
			ll.y=0;
			rr.x=-r;
			rr.y=0;
			int id1,id2;
			id1=qy[i].u;
			id2=qy[i].v;
			if(ll<qy[list[id1]].l)
			   ll=qy[list[id1]].l;
            if(ll<qy[list[id2]].l)
               ll=qy[list[id2]].l;
		    if(qy[list[id1]].r<rr)
		       rr=qy[list[id1]].r;
            if(qy[list[id2]].r<rr)
               rr=qy[list[id2]].r;
            bool ans;
            if(rr<ll)
               ans=0;
            else
            {
            	l_id=binary(0,cnt-1,ll);
            	r_id=binary(0,cnt-1,rr);
            	ans=(l_id<r_id&&qw(l_id,r_id-1,0)<=2);
            	int mf=2;
            	if(!(rr<qy[list[id1]].r))
            	    mf--;
        	    if(!(rr<qy[list[id2]].r))
        	        mf--;
    	        ans|=qw(r_id,r_id,0)<=mf;
            }
            if(ans)
               puts("YES");
            else
               puts("NO");
		}
	}
	return 0;
}
/*
5 4
1 -5 8
1 -3 8
1 2 7
3 1 2
*/

#pragma comment(linker, "/stack:200000000")
#pragma GCC optimize("Ofast")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")

#include <bits/stdc++.h>

#define F0R(i, a) for (int i = 0; i < (a); i++)
#define FOR(i, a, b) for (int i = (a); i < (b); i++)
#define R0F(i, a) for (int i = (a) - 1; i >= 0; i--)
#define ROF(i, a, b) for (int i = (b) - 1; i >= (a); i--)

#define ran() (rand() & 0x7FFF)
#define rand31() ((ran() << 16) | (ran() << 1) | (ran() & 1))
#define rand32() ((ran() << 17) | (ran() << 2) | (ran() & 3))
#define rand63() (((ll)ran() << 48) | ((ll)ran() << 33) | ((ll)ran() << 18) | ((ll)ran() << 3) | ((ll)ran() & 7))
#define rand64() (((ll)ran() << 49) | ((ll)ran() << 34) | ((ll)ran() << 19) | ((ll)ran() << 4) | ((ll)ran() & 15))

#define F first
#define S second
#define PB push_back
#define MP make_pair
#define MT make_tuple
#define UB upper_bound
#define LB lower_bound
#define X real()
#define Y imag()

#define INF 1e18
#define PI acos(-1)

#define sz(x) ((int)(x).size())
#define all(x) (x).begin(), (x).end()
#define SQ(x) ((x) * (x))

using namespace std;

typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef vector<int> vi;
typedef vector<pii> vpii;
typedef vector<ll> vll;
typedef vector<ull> vul;
typedef complex<ld> point;
typedef complex<ld> cld;
typedef vector<cld> vcld;

#define MAXN 500000

struct angle {

ll y, x;

bool operator<(const angle& a2) const {
    return x * a2.y - y * a2.x > 0;
}

bool operator==(const angle& a2) const {
    return x * a2.y == y * a2.x;
}

bool operator<=(const angle& a2) const { return *this < a2 || *this == a2; }

bool operator>=(const angle& a2) const { return a2 < *this; }

};

struct SegTree{

int sz;
angle *tree;

SegTree(int _sz) {
    sz = 1 << (32 - __builtin_clz(_sz - 1));
    tree = new angle[2 * sz];
    F0R(i, 2 * sz) tree[i] = angle({0, 1});
}

void upd(int idx, angle v) {
    idx += sz;
    tree[idx] = v;
    for (idx /= 2; idx > 0; idx /= 2) tree[idx] = max(tree[2 * idx], tree[2 * idx + 1]);
}

angle query(int lo, int hi) {
    lo += sz, hi += sz;
    angle res = angle({0, 1});
    while(lo <= hi) {
        if ((lo % 2) == 1) res = max(res, tree[lo++]);
        if ((hi % 2) == 0) res = max(res, tree[hi--]);
        lo /= 2;
        hi /= 2;
    }
    return res;
}

};

ll r;
angle alpha[MAXN], beta123[MAXN];
int n, q, posof[MAXN];
vector<pair<angle, int>> order;
vpii updates;
vector<pair<int, pii>> queries;

SegTree st(2);

void toggle(int idx) {
int pos = posof[idx];
if (st.query(pos, pos) == angle({0, 1})) st.upd(pos, beta123[idx]);
else st.upd(pos, {0, 1});
}

int main() {
    ios::sync_with_stdio(0);
    cin.tie(0);
    cin >> r >> q;
    F0R(i, q) {
        int t;
        cin >> t;
        switch(t) {
            case 1:
                ll x, y;
                cin >> x >> y;
                alpha[n] = {y, r - x};
                beta123[n] = {y, x + r};
                updates.PB(MP(i, n++));
                break;
            case 2:
                int idx;
                cin >> idx;
                idx--;
                updates.PB(MP(i, idx));
                break;
            case 3:
                int a, b;
                cin >> a >> b;
                a--, b--;
                queries.PB(MP(i, MP(a, b)));
                break;
        }
    }
    F0R(i, n) order.PB(MP(alpha[i], i));
    sort(all(order));
    F0R(i, n) posof[order[i].S] = i;
    reverse(all(updates));
    reverse(all(queries));
    st = SegTree(n);
    while (!updates.empty() || !queries.empty()) {
        if (queries.empty() || (!updates.empty() && updates.back().F < queries.back().F)) {
            int idx = updates.back().S;
            updates.pop_back();
            toggle(idx);
        } else {
            int a = queries.back().S.F;
            int b = queries.back().S.S;
            queries.pop_back();
            angle _alpha = min(alpha[a], alpha[b]);
            angle _beta123 = min(beta123[a], beta123[b]);
            if(atan2(_alpha.y, _alpha.x) + atan2(_beta123.y, _beta123.x) < PI / 2
                    && !(_beta123 == angle({_alpha.x, _alpha.y}))) cout << "NO\n";
                else {
                    toggle(a);
                    toggle(b);

                    int lo = LB(all(order), MP(_alpha, 0)) - order.begin();
                    if (st.query(lo, n - 1) >= _beta123) cout << "NO\n";
                    else cout << "YES\n";

                    toggle(a);
                    toggle(b);
                }
            }
        }
}

#include<cstdio>
#include<algorithm>
using namespace std;
char B[1<<26],*S=B;
inline int read()
{
	int x,f=1;char c;
	while((c=*S++)<'0'||c>'9')if(c=='-')f=0;
	for(x=c-'0';(c=*S++)>='0'&&c<='9';)x=x*10+c-'0';
	return f?x:-x;
}
#define MN 500000
#define N 524288
struct vec
{
	int x,y;
	friend bool operator<(const vec&a,const vec&b){return 1LL*a.x*b.y<1LL*a.y*b.x;}
	friend bool operator==(const vec&a,const vec&b){return 1LL*a.x*b.y==1LL*a.y*b.x;}
};
vec rot(const vec&a){return (vec){a.y,-a.x};}
struct work{int t,z;vec x,y;}w[MN+5],q[MN+5];
bool cmp(const work&a,const work&b){return a.x==b.x?a.t>b.t:a.x<b.x;}
vec l[MN+5],r[MN+5],c[MN+5];
int cnt,ans[MN+5],t[N*2+5],qn,sa[MN+5],sb[MN+5];
void add(int k,int x){for(k+=N;k;k>>=1)t[k]+=x;}
int query(int l,int r)
{
	int res=0;
	for(l+=N-1,r+=N+1;l^r^1;l>>=1,r>>=1)
	{
		if(~l&1)res+=t[l+1];
		if( r&1)res+=t[r-1];
	}
	return res;
}
void solve(int l,int r)
{
	int mid=l+r>>1,i;
	if(sa[mid]==sa[l-1]||sb[r]==sb[mid])return;
	if(l<r)solve(l,mid),solve(mid+1,r);
	for(qn=0,i=l;i<=mid;++i)if(w[i].t>0)q[++qn]=w[i];
	for(;i<=r;++i)if(!w[i].t)q[++qn]=w[i];
	sort(q+1,q+qn+1,cmp);
	for(i=1;i<=qn;++i)
		if(q[i].t)add(lower_bound(c+1,c+cnt+1,q[i].y)-c,q[i].z);
		else ans[q[i].z]+=query(lower_bound(c+1,c+cnt+1,q[i].y)-c,cnt);
	for(i=1;i<=qn;++i)if(q[i].t)add(lower_bound(c+1,c+cnt+1,q[i].y)-c,-q[i].z);
}
int main()
{
	B[fread(B,1,1<<26,stdin)]=0;
	int R=read(),n=read(),i,t,x,y;
	for(i=1;i<=n;++i)
	{
		t=read();x=read();
		if(t==1)
		{
			l[++cnt]=(vec){x+R,y=read()};
			c[cnt]=r[cnt]=(vec){x-R,y};
			w[i]=(work){1,1,l[cnt],r[cnt]};
		}
		if(t==2)w[i]=(work){1,-1,l[x],r[x]};
		if(t==3)
		{
			if(l[y=read()]<l[x])x^=y^=x^=y;
			if(rot(r[x])<l[y])w[i]=(work){-1,0,0,0},ans[i]=3;
			else w[i]=(work){0,i,l[y],r[x]<r[y]?r[x]:r[y]};
		}
	}
	for(i=1;i<=n;++i)sa[i]=sa[i-1]+(w[i].t>0),sb[i]=sb[i-1]+!w[i].t;
	sort(c+1,c+cnt+1);cnt=unique(c+1,c+cnt+1)-c-1;solve(1,n);
	for(i=1;i<=n;++i)if(ans[i])puts(ans[i]>2?"NO":"YES");
}

#include <cstdio>
#include <algorithm>
#include <cstring>
#include <queue>
#include <cmath>
#define ld double
#define l(a) (a<<1)
#define r(a) (a<<1|1)
#define MN 500005
#define MM 1000005
#define MD 4200005
#define eps 1e-14
#define EPS 1e-9
using namespace std;
struct meg{int g,x,y;}a[MN];
struct itv1{ld x,y;}w[MN];
struct itv2{int x,y;}s[MN];
struct itv3{int x[2],y[2];}d[MN];
struct Que
{
	priority_queue <int> A,B;
	void push(int x) {A.push(x);}
	void dele(int x) {B.push(x);}
	int top()
	{
		while (!B.empty()&&A.top()==B.top()) A.pop(),B.pop();
		if (!A.empty()) return A.top(); else return 0;
	}
}q[MM];
ld b0[MM],b1[MM];
int m,MQ,tin,b0in,b1in,ra;
int t[MD];

inline int read()
{
	int n=0,f=1; char c=getchar();
	while (c<'0' || c>'9') {if(c=='-')f=-1; c=getchar();}
	while (c>='0' && c<='9') {n=n*10+c-'0'; c=getchar();}
	return n*f;
}

inline void getcg(int x,int z) {for (t[x+=MQ]=z,x>>=1;x;x>>=1) t[x]=max(t[l(x)],t[r(x)]);}
inline int getmax(int L,int R)
{
	int sum=0;
	for (L+=MQ,R+=MQ;L<=R;L>>=1,R>>=1)
	{
		if ( L&1) sum=max(sum,t[L++]);
		if (~R&1) sum=max(sum,t[R--]);
	}
	return sum;
}

void cghp(int x,int y,int g)
{
	int lt=q[x].top();
	if (g==1) q[x].push(y); else q[x].dele(y);
	if (lt!=q[x].top()) getcg(x,q[x].top());
}

bool check(int x,int y)
{
	int cs1,cs2;
	if (s[x].x>s[y].x) cs1=x; else cs1=y;
	if (s[x].y<s[y].y) cs2=x; else cs2=y;
//	printf("1=%d 2=%d\n",cs1,cs2);
//	printf("%.14lf,%.14lf\n",atan2(d[cs2].y[0],-d[cs2].y[1]),atan2(d[cs1].x[1],d[cs1].x[0]));
	if (atan2(d[cs2].y[0],-d[cs2].y[1])+EPS<atan2(d[cs1].x[1],d[cs1].x[0])) return true; else return false;
}

int main()
{
	register int i,x,y,lt=0;
	ra=read(); m=read();
	for (i=1;i<=m;++i)
	{
		a[i].g=read();
		if (a[i].g==1)
		{
			x=read(); y=read(); a[i].x=++tin;
			w[tin].x=atan2(d[tin].x[1]=y,d[tin].x[0]=x-ra);
//			printf("x=%.6lf\n",w[tin].x);
			w[tin].y=atan2(d[tin].y[1]=y,d[tin].y[0]=x+ra);
			b0[++b0in]=w[tin].x;
			b1[++b1in]=w[tin].y;
		}
		else if (a[i].g==2) a[i].x=read();
		else if (a[i].g==3) a[i].x=read(),a[i].y=read();
	}
//	printf("bin=%d,%d\n",b0in,b1in);
	sort(b0+1,b0+b0in+1); sort(b1+1,b1+b1in+1);
	for (i=2,lt=0;i<=b0in;++i) {if (b0[i]-b0[i-1]<eps) ++lt; b0[i-lt]=b0[i];} b0in-=lt;
	for (i=2,lt=0;i<=b1in;++i) {if (b1[i]-b1[i-1]<eps) ++lt; b1[i-lt]=b1[i];} b1in-=lt;
	for (i=1;i<=tin;++i)
		s[i].x=lower_bound(b0+1,b0+b0in+1,w[i].x)-b0,
		s[i].y=lower_bound(b1+1,b1+b1in+1,w[i].y)-b1;
//	printf("bin=%d,%d\n",b0in,b1in);
//	for (i=1;i<=tin;++i) printf("s[%d].lf=%d\n",i,s[i].x);
	for (MQ=1;MQ<b0in;MQ<<=1); --MQ;
	for (i=1;i<=m;++i)
	{
		if (a[i].g<3) cghp(s[a[i].x].x,s[a[i].x].y,a[i].g);
		else if (a[i].g==3)
		{
			if (check(a[i].x,a[i].y)) {puts("NO"); continue;}
//			puts("sb");
			x=max(s[a[i].x].x,s[a[i].y].x); y=min(s[a[i].x].y,s[a[i].y].y);
			cghp(s[a[i].x].x,s[a[i].x].y,2);
			cghp(s[a[i].y].x,s[a[i].y].y,2);
			if (getmax(1,x)>=y) puts("NO"); else puts("YES");
			cghp(s[a[i].x].x,s[a[i].x].y,1);
			cghp(s[a[i].y].x,s[a[i].y].y,1);
		}
	}
}

#include <cstdio>
#include <algorithm>
#include <cstring>
#include <queue>
#include <cmath>
#define ld double
#define l(a) (a<<1)
#define r(a) (a<<1|1)
#define MN 500005
#define MM 1000005
#define MD 4200005
#define eps 1e-12
#define EPS 1e-7
using namespace std;
struct meg{int g,x,y;}a[MN];
struct itv1{ld x,y;}w[MN];
struct itv2{int x,y;}s[MN];
struct itv3{int x[2],y[2];}d[MN];
struct Que
{
	priority_queue <int> A,B;
	void push(int x) {A.push(x);}
	void dele(int x) {B.push(x);}
	int top()
	{
		while (!B.empty()&&A.top()==B.top()) A.pop(),B.pop();
		if (!A.empty()) return A.top(); else return 0;
	}
}q[MM];
ld b0[MM],b1[MM];
int m,MQ,tin,b0in,b1in,ra;
int t[MD];

inline int read()
{
	int n=0,f=1; char c=getchar();
	while (c<'0' || c>'9') {if(c=='-')f=-1; c=getchar();}
	while (c>='0' && c<='9') {n=n*10+c-'0'; c=getchar();}
	return n*f;
}

inline void getcg(int x,int z) {for (t[x+=MQ]=z,x>>=1;x;x>>=1) t[x]=max(t[l(x)],t[r(x)]);}
inline int getmax(int L,int R)
{
	int sum=0;
	for (L+=MQ,R+=MQ;L<=R;L>>=1,R>>=1)
	{
		if ( L&1) sum=max(sum,t[L++]);
		if (~R&1) sum=max(sum,t[R--]);
	}
	return sum;
}

void cghp(int x,int y,int g)
{
	int lt=q[x].top();
	if (g==1) q[x].push(y); else q[x].dele(y);
	if (lt!=q[x].top()) getcg(x,q[x].top());
}

bool check(int x,int y)
{
	int cs1,cs2;
	if (s[x].x>s[y].x) cs1=x; else cs1=y;
	if (s[x].y<s[y].y) cs2=x; else cs2=y;
//	printf("1=%d 2=%d\n",cs1,cs2);
//	printf("%.14lf,%.14lf\n",atan2(d[cs2].y[0],-d[cs2].y[1]),atan2(d[cs1].x[1],d[cs1].x[0]));
	if (atan2(d[cs2].y[0],-d[cs2].y[1])+EPS<atan2(d[cs1].x[1],d[cs1].x[0])) return true; else return false;
}

int main()
{
	register int i,x,y,lt=0;
	ra=read(); m=read();
	for (i=1;i<=m;++i)
	{
		a[i].g=read();
		if (a[i].g==1)
		{
			x=read(); y=read(); a[i].x=++tin;
			w[tin].x=atan2(d[tin].x[1]=y,d[tin].x[0]=x-ra);
//			printf("x=%.6lf\n",w[tin].x);
			w[tin].y=atan2(d[tin].y[1]=y,d[tin].y[0]=x+ra);
			b0[++b0in]=w[tin].x;
			b1[++b1in]=w[tin].y;
		}
		else if (a[i].g==2) a[i].x=read();
		else if (a[i].g==3) a[i].x=read(),a[i].y=read();
	}
//	printf("bin=%d,%d\n",b0in,b1in);
	sort(b0+1,b0+b0in+1); sort(b1+1,b1+b1in+1);
	for (i=2,lt=0;i<=b0in;++i) {if (b0[i]-b0[i-1]<eps) ++lt; b0[i-lt]=b0[i];} b0in-=lt;
	for (i=2,lt=0;i<=b1in;++i) {if (b1[i]-b1[i-1]<eps) ++lt; b1[i-lt]=b1[i];} b1in-=lt;
	for (i=1;i<=tin;++i)
		s[i].x=lower_bound(b0+1,b0+b0in+1,w[i].x)-b0,
		s[i].y=lower_bound(b1+1,b1+b1in+1,w[i].y)-b1;
//	printf("bin=%d,%d\n",b0in,b1in);
//	for (i=1;i<=tin;++i) printf("s[%d].lf=%d\n",i,s[i].x);
	for (MQ=1;MQ<b0in;MQ<<=1); --MQ;
	for (i=1;i<=m;++i)
	{
		if (a[i].g<3) cghp(s[a[i].x].x,s[a[i].x].y,a[i].g);
		else if (a[i].g==3)
		{
			if (check(a[i].x,a[i].y)) {puts("NO"); continue;}
//			puts("sb");
			x=max(s[a[i].x].x,s[a[i].y].x); y=min(s[a[i].x].y,s[a[i].y].y);
			cghp(s[a[i].x].x,s[a[i].x].y,2);
			cghp(s[a[i].y].x,s[a[i].y].y,2);
			if (getmax(1,x)>=y) puts("NO"); else puts("YES");
			cghp(s[a[i].x].x,s[a[i].x].y,1);
			cghp(s[a[i].y].x,s[a[i].y].y,1);
		}
	}
}

#include <cstdio>
#include <algorithm>
#include <cstring>
#include <queue>
#include <cmath>
#define ll long long
#define ld long double
#define l(a) (a<<1)
#define r(a) (a<<1|1)
#define MN 500005
#define MM 1000005
#define MD 4200005
#define eps 1e-15
using namespace std;
int INF;
struct meg{int g,x,y;}a[MN];
struct itv1{ld x,y;}w[MN];
struct itv2{int x,y;}s[MN];
struct Que
{
	priority_queue <int,vector<int>,greater<int> > A,B;
	void push(int x) {A.push(x);}
	void dele(int x) {B.push(x);}
	int top()
	{
		while (!B.empty()&&A.top()==B.top()) A.pop(),B.pop();
		if (!A.empty()) return A.top(); else return INF;
	}
}q[MM];
ld b[MM];
ll ra;
int m,MQ,tin,bin;
int t[MD];

inline int read()
{
	int n=0,f=1; char c=getchar();
	while (c<'0' || c>'9') {if(c=='-')f=-1; c=getchar();}
	while (c>='0' && c<='9') {n=n*10+c-'0'; c=getchar();}
	return n*f;
}

inline void getcg(int x,int z) {for (t[x+=MQ]=z,x>>=1;x;x>>=1) t[x]=min(t[l(x)],t[r(x)]);}
inline int getmin(int L,int R)
{
	int sum=INF;
	for (L+=MQ,R+=MQ;L<=R;L>>=1,R>>=1)
	{
		if ( L&1) sum=min(sum,t[L++]);
		if (~R&1) sum=min(sum,t[R--]);
	}
	return sum;
}

ld cal(ll x0,ll y0,ll x1,ll y1,ll g)
{
	ld ki,bi;
	ki=(ld)(y1-y0)/(x1-x0);
	bi=(ld)y0-(ld)x0*(y1-y0)/(x1-x0);
	return acos((ld)(bi*bi-ra*ra)*g/(ki*ki+1)/(ra*ra));
}
void cghp(int x,int y,int g)
{
	int lt=q[x].top();
	if (g==1) q[x].push(y); else q[x].dele(y);
	if (lt!=q[x].top()) getcg(x,q[x].top());
}

int main()
{
	register int i,x,y,lt=0;
	ra=read(); m=read();
	for (i=1;i<=m;++i)
	{
		a[i].g=read();
		if (a[i].g==1)
		{
			x=read(); y=read(); a[i].x=++tin;
			w[tin].x=(ll)x>= ra?acos( 1):cal( ra,0,(ll)x,(ll)y, 1);
			w[tin].y=(ll)x<=-ra?acos(-1):cal(-ra,0,(ll)x,(ll)y,-1);
			b[++bin]=w[tin].x; b[++bin]=w[tin].y;
		}
		else if (a[i].g==2) a[i].x=read();
		else if (a[i].g==3) a[i].x=read(),a[i].y=read();
	}
	sort(b+1,b+bin+1);
	for (i=2;i<=bin;++i) {if (b[i]-b[i-1]<eps) ++lt; b[i-lt]=b[i];}
	bin-=lt;
	for (i=1;i<=tin;++i)
		s[i].x=lower_bound(b+1,b+bin+1,w[i].x)-b,
		s[i].y=lower_bound(b+1,b+bin+1,w[i].y)-b;
//		s[i].x=s[i].x*2-1,s[i].y=s[i].y*2-1;
	for (MQ=1;MQ<bin;MQ<<=1); --MQ;
	memset(t,100,sizeof(t)); INF=t[0];
	for (i=1;i<=m;++i)
	{
		if (a[i].g<3) cghp(s[a[i].x].y,s[a[i].x].x,a[i].g);
		else if (a[i].g==3)
		{
			x=max(s[a[i].x].x,s[a[i].y].x); y=min(s[a[i].x].y,s[a[i].y].y);
			if (x>y) {puts("NO"); continue;}
			cghp(s[a[i].x].y,s[a[i].x].x,2);
			cghp(s[a[i].y].y,s[a[i].y].x,2);
			if (getmin(y,bin)<=x) puts("NO"); else puts("YES");
			cghp(s[a[i].x].y,s[a[i].x].x,1);
			cghp(s[a[i].y].y,s[a[i].y].x,1);
		}
	}
}

#include <cstdio>
#include <algorithm>
#include <cstring>
#include <queue>
#include <cmath>
#define ld double
#define l(a) (a<<1)
#define r(a) (a<<1|1)
#define MN 500005
#define MM 1000005
#define MD 4200005
#define eps 1e-11
using namespace std;
struct meg{int g,x,y;}a[MN];
struct itv1{ld x,y;}w[MN];
struct itv2{int x,y;}s[MN];
struct Que
{
	priority_queue <int> A,B;
	void push(int x) {A.push(x);}
	void dele(int x) {B.push(x);}
	int top()
	{
		while (!B.empty()&&A.top()==B.top()) A.pop(),B.pop();
		if (!A.empty()) return A.top(); else return 0;
	}
}q[MM];
ld b0[MM],b1[MM];
int m,MQ,tin,b0in,b1in,ra;
int t[MD];

inline int read()
{
	int n=0,f=1; char c=getchar();
	while (c<'0' || c>'9') {if(c=='-')f=-1; c=getchar();}
	while (c>='0' && c<='9') {n=n*10+c-'0'; c=getchar();}
	return n*f;
}

inline void getcg(int x,int z) {for (t[x+=MQ]=z,x>>=1;x;x>>=1) t[x]=max(t[l(x)],t[r(x)]);}
inline int getmax(int L,int R)
{
	int sum=0;
	for (L+=MQ,R+=MQ;L<=R;L>>=1,R>>=1)
	{
		if ( L&1) sum=max(sum,t[L++]);
		if (~R&1) sum=max(sum,t[R--]);
	}
	return sum;
}

void cghp(int x,int y,int g)
{
	int lt=q[x].top();
	if (g==1) q[x].push(y); else q[x].dele(y);
	if (lt!=q[x].top()) getcg(x,q[x].top());
}

int main()
{
	register int i,x,y,lt=0;
	ra=read(); m=read();
	for (i=1;i<=m;++i)
	{
		a[i].g=read();
		if (a[i].g==1)
		{
			x=read(); y=read(); a[i].x=++tin;
			w[tin].x=atan2(y,x-ra);
			w[tin].y=atan2(y,x+ra);
			b0[++b0in]=w[tin].x;
			b1[++b1in]=w[tin].y;
		}
		else if (a[i].g==2) a[i].x=read();
		else if (a[i].g==3) a[i].x=read(),a[i].y=read();
	}
	sort(b0+1,b0+b0in+1); sort(b1+1,b1+b1in+1);
	for (i=2,lt=0;i<=b0in;++i) {if (b0[i]-b0[i-1]<eps) ++lt; b0[i-lt]=b0[i];} b0in-=lt;
	for (i=2,lt=0;i<=b1in;++i) {if (b1[i]-b1[i-1]<eps) ++lt; b1[i-lt]=b1[i];} b1in-=lt;
	for (i=1;i<=tin;++i)
		s[i].x=lower_bound(b0+1,b0+b0in+1,w[i].x)-b0,
		s[i].y=lower_bound(b1+1,b1+b1in+1,w[i].y)-b1;
	for (MQ=1;MQ<b0in;MQ<<=1); --MQ;
	for (i=1;i<=m;++i)
	{
		if (a[i].g<3) cghp(s[a[i].x].x,s[a[i].x].y,a[i].g);
		else if (a[i].g==3)
		{
			if (max(w[a[i].x].x,w[a[i].y].x)-min(w[a[i].x].y,w[a[i].y].y)>acos(0)+eps) {puts("NO"); continue;}
			x=max(s[a[i].x].x,s[a[i].y].x); y=min(s[a[i].x].y,s[a[i].y].y);
			cghp(s[a[i].x].x,s[a[i].x].y,2);
			cghp(s[a[i].y].x,s[a[i].y].y,2);
			if (getmax(1,x)>=y) puts("NO"); else puts("YES");
			cghp(s[a[i].x].x,s[a[i].x].y,1);
			cghp(s[a[i].y].x,s[a[i].y].y,1);
		}
	}
}

#include <cstdio>
#include <algorithm>
#include <cstring>
#include <queue>
#include <cmath>
#define ll long long
#define ld double
#define l(a) (a<<1)
#define r(a) (a<<1|1)
#define MN 500005
#define MM 1000005
#define MD 4200005
#define eps 1e-12
using namespace std;
struct meg{int g,x,y;}a[MN];
struct itv1{ld x,y;}w[MN];
struct itv2{int x,y;}s[MN];
struct Que
{
	priority_queue <int,vector<int>,greater<int> > A,B;
	void push(int x) {A.push(x);}
	void dele(int x) {B.push(x);}
	int top()
	{
		while (!B.empty()&&A.top()==B.top()) A.pop(),B.pop();
		if (!A.empty()) return A.top(); else return 0;
	}
}q[MM];
ld b[MM];
ll ra;
int m,MQ,tin,bin;
int t[MD];

inline int read()
{
	int n=0,f=1; char c=getchar();
	while (c<'0' || c>'9') {if(c=='-')f=-1; c=getchar();}
	while (c>='0' && c<='9') {n=n*10+c-'0'; c=getchar();}
	return n*f;
}

inline void getcg(int x,int z) {for (t[x+=MQ]=z,x>>=1;x;x>>=1) t[x]=max(t[l(x)],t[r(x)]);}
inline int getmax(int L,int R)
{
	int sum=0;
	for (L+=MQ,R+=MQ;L<=R;L>>=1,R>>=1)
	{
		if ( L&1) sum=max(sum,t[L++]);
		if (~R&1) sum=max(sum,t[R--]);
	}
	return sum;
}

ld cal(ll x0,ll y0,ll x1,ll y1,ll g)
{
	ld ki,bi;
	ki=(ld)(y1-y0)/(x1-x0);
	bi=(ld)y0-(ld)x0*(y1-y0)/(x1-x0);
	return acos((ld)(bi*bi-ra*ra)*g/(ki*ki+1)/(ra*ra));
}
void cghp(int x,int y,int g)
{
	int lt=q[x].top();
	if (g==1) q[x].push(y); else q[x].dele(y);
	if (lt!=q[x].top()) getcg(x,q[x].top());
}

int main()
{
	register int i,x,y,lt=0;
	ra=read(); m=read();
	for (i=1;i<=m;++i)
	{
		a[i].g=read();
		if (a[i].g==1)
		{
			x=read(); y=read(); a[i].x=++tin;
			w[tin].x=(ll)x>= ra?acos( 1):cal( ra,0,(ll)x,(ll)y, 1);
			w[tin].y=(ll)x<=-ra?acos(-1):cal(-ra,0,(ll)x,(ll)y,-1);
			b[++bin]=w[tin].x; b[++bin]=w[tin].y;
		}
		else if (a[i].g==2) a[i].x=read();
		else if (a[i].g==3) a[i].x=read(),a[i].y=read();
	}
	sort(b+1,b+bin+1);
	for (i=2;i<=bin;++i) {if (b[i]-b[i-1]<eps) ++lt; b[i-lt]=b[i];}
	bin-=lt;
	for (i=1;i<=tin;++i)
		s[i].x=lower_bound(b+1,b+bin+1,w[i].x)-b,
		s[i].y=lower_bound(b+1,b+bin+1,w[i].y)-b;
	for (MQ=1;MQ<bin;MQ<<=1); --MQ;
	for (i=1;i<=m;++i)
	{
		if (a[i].g<3) cghp(s[a[i].x].x,s[a[i].x].y,a[i].g);
		else if (a[i].g==3)
		{
			x=max(s[a[i].x].x,s[a[i].y].x); y=min(s[a[i].x].y,s[a[i].y].y);
			if (x>y) {puts("NO"); continue;}
			cghp(s[a[i].x].x,s[a[i].x].y,2);
			cghp(s[a[i].y].x,s[a[i].y].y,2);
			if (getmax(1,x)>=y) puts("NO"); else puts("YES");
			cghp(s[a[i].x].x,s[a[i].x].y,1);
			cghp(s[a[i].y].x,s[a[i].y].y,1);
		}
	}
}

#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#define ll long long
#define ld long double
#define l(a) (a<<1)
#define r(a) (a<<1|1)
#define MN 500005
#define MM 8000005
#define eps 1e-15
using namespace std;
struct meg{int g,x,y;}a[MN];
struct itv1{ld x,y;}w[MN];
struct itv2{int x,y;}s[MN];
ld b[MN<<1];
ll ra;
int m,tin,bin;
int t[MM],tg[MM];

inline int read()
{
	int n=0,f=1; char c=getchar();
	while (c<'0' || c>'9') {if(c=='-')f=-1; c=getchar();}
	while (c>='0' && c<='9') {n=n*10+c-'0'; c=getchar();}
	return n*f;
}

inline void mark(int x,int z) {tg[x]+=z; t[x]+=z;}
inline void down(int x) {if (tg[x]) mark(l(x),tg[x]),mark(r(x),tg[x]),tg[x]=0;}
inline void update(int x) {t[x]=min(t[l(x)],t[r(x)]);}

void getadd(int x,int L,int R,int ql,int qr,int ad)
{
	if (ql==L&&qr==R) {mark(x,ad); return;}
	down(x);
	int mid=L+R>>1;
	if (qr<=mid) getadd(l(x),L,mid,ql,qr,ad);
	else if (ql>mid) getadd(r(x),mid+1,R,ql,qr,ad);
	else getadd(l(x),L,mid,ql,mid,ad),getadd(r(x),mid+1,R,mid+1,qr,ad);
	update(x);
}

int getmin(int x,int L,int R,int ql,int qr)
{
	if (ql==L&&qr==R) return t[x];
	down(x);
	int mid=L+R>>1;
	if (qr<=mid) return getmin(l(x),L,mid,ql,qr);
	else if (ql>mid) return getmin(r(x),mid+1,R,ql,qr);
	else return min(getmin(l(x),L,mid,ql,mid),getmin(r(x),mid+1,R,mid+1,qr));
}

int main()
{
	register int i,x,y,lt=0;
	ll x1,y1,x0,y0;
	ld bi,ki;
	ra=read(); m=read();
	for (i=1;i<=m;++i)
	{
		a[i].g=read();
		if (a[i].g==1)
		{
			x1=read(); y1=read(); a[i].x=++tin;
			x0=ra; y0=0;
			if (x1>=x0) w[tin].x=acos(1);
			else
			{
				ki=(ld)(y1-y0)/(x1-x0);
				bi=(ld)y0-(ld)x0*(y1-y0)/(x1-x0);
				w[tin].x=acos((ld)(bi*bi-ra*ra)/(ki*ki+1)/(ra*ra));
			}
			x0=-ra; y0=0;
			if (x1<=x0) w[tin].y=acos(-1);
			else
			{
				ki=(ld)(y1-y0)/(x1-x0);
				bi=(ld)y0-(ld)x0*(y1-y0)/(x1-x0);
				w[tin].y=acos((ld)(ra*ra-bi*bi)/(ki*ki+1)/(ra*ra));
			}
			b[++bin]=w[tin].x; b[++bin]=w[tin].y;
		}
		else if (a[i].g==2) a[i].x=read();
		else if (a[i].g==3) a[i].x=read(),a[i].y=read();
	}
	sort(b+1,b+bin+1);
	for (i=2;i<=bin;++i)
	{
		if (b[i]-b[i-1]<eps) ++lt;
		b[i-lt]=b[i];
	}
	bin-=lt;
	for (i=1;i<=tin;++i)
		s[i].x=lower_bound(b+1,b+bin+1,w[i].x)-b,
		s[i].y=lower_bound(b+1,b+bin+1,w[i].y)-b;
	for (i=1;i<=m;++i)
	{
			 if (a[i].g==1) getadd(1,1,bin<<1,s[a[i].x].x*2-1,s[a[i].x].y*2-1, 1);
		else if (a[i].g==2) getadd(1,1,bin<<1,s[a[i].x].x*2-1,s[a[i].x].y*2-1,-1);
		else if (a[i].g==3)
		{
			x=max(s[a[i].x].x,s[a[i].y].x);
			y=min(s[a[i].x].y,s[a[i].y].y);
			if (x>y||getmin(1,1,bin<<1,x*2-1,y*2-1)>=3) puts("NO");
			else puts("YES");
		}
	}
}

#include <cstdio>
#include <algorithm>
#include <cstring>
#include <queue>
#include <cmath>
#define ll long long
#define ld double
#define l(a) (a<<1)
#define r(a) (a<<1|1)
#define MN 500005
#define MM 1000005
#define MD 4200005
#define eps 1e-12
using namespace std;
struct meg{int g,x,y;}a[MN];
struct itv1{ld x,y;}w[MN];
struct itv2{int x,y;}s[MN];
struct Que
{
	priority_queue <int> A,B;
	void push(int x) {A.push(x);}
	void dele(int x) {B.push(x);}
	int top()
	{
		while (!B.empty()&&A.top()==B.top()) A.pop(),B.pop();
		if (!A.empty()) return A.top(); else return 0;
	}
}q[MM];
ld b0[MM],b1[MM];
ll ra;
int m,MQ,tin,b0in,b1in;
int t[MD];

inline int read()
{
	int n=0,f=1; char c=getchar();
	while (c<'0' || c>'9') {if(c=='-')f=-1; c=getchar();}
	while (c>='0' && c<='9') {n=n*10+c-'0'; c=getchar();}
	return n*f;
}

inline void getcg(int x,int z) {for (t[x+=MQ]=z,x>>=1;x;x>>=1) t[x]=max(t[l(x)],t[r(x)]);}
inline int getmax(int L,int R)
{
	int sum=0;
	for (L+=MQ,R+=MQ;L<=R;L>>=1,R>>=1)
	{
		if ( L&1) sum=max(sum,t[L++]);
		if (~R&1) sum=max(sum,t[R--]);
	}
	return sum;
}

void cghp(int x,int y,int g)
{
	int lt=q[x].top();
	if (g==1) q[x].push(y); else q[x].dele(y);
	if (lt!=q[x].top()) getcg(x,q[x].top());
}

int main()
{
	register int i,x,y,lt=0;
	ra=read(); m=read();
	for (i=1;i<=m;++i)
	{
		a[i].g=read();
		if (a[i].g==1)
		{
			x=read(); y=read(); a[i].x=++tin;
			w[tin].x=atan2(x-ra,y);
			w[tin].y=atan2(x+ra,y);
			b0[++b0in]=w[tin].x;
			b1[++b1in]=w[tin].y;
		}
		else if (a[i].g==2) a[i].x=read();
		else if (a[i].g==3) a[i].x=read(),a[i].y=read();
	}
	sort(b0+1,b0+b0in+1); sort(b1+1,b1+b1in+1);
	for (i=2,lt=0;i<=b0in;++i) {if (b0[i]-b0[i-1]<eps) ++lt; b0[i-lt]=b0[i];} b0in-=lt;
	for (i=2,lt=0;i<=b1in;++i) {if (b1[i]-b1[i-1]<eps) ++lt; b1[i-lt]=b1[i];} b1in-=lt;
	for (i=1;i<=tin;++i)
		s[i].x=lower_bound(b0+1,b0+b0in+1,w[i].x)-b0,
		s[i].y=lower_bound(b1+1,b1+b1in+1,w[i].y)-b1;
	for (MQ=1;MQ<b0in;MQ<<=1); --MQ;
	for (i=1;i<=m;++i)
	{
		if (a[i].g<3) cghp(s[a[i].x].x,s[a[i].x].y,a[i].g);
		else if (a[i].g==3)
		{
			if (max(w[a[i].x].x,w[a[i].y].x)-min(w[a[i].x].y,w[a[i].y].y)>acos(0)+eps) {puts("NO"); continue;}
			x=max(s[a[i].x].x,s[a[i].y].x); y=min(s[a[i].x].y,s[a[i].y].y);
			cghp(s[a[i].x].x,s[a[i].x].y,2);
			cghp(s[a[i].y].x,s[a[i].y].y,2);
			if (getmax(1,x)>=y) puts("NO"); else puts("YES");
			cghp(s[a[i].x].x,s[a[i].x].y,1);
			cghp(s[a[i].y].x,s[a[i].y].y,1);
		}
	}
}

#include<bits/stdc++.h>
using namespace std;
#define beta Beta
typedef long long ll;
class vec
{
	public:
		int x,y;
		vec()
		{
			x=y=0;
		}
		vec(int tx,int ty)
		{
			x=tx,y=ty;
		}
		vec operator -(const vec &t)const
		{
			return vec(x-t.x,y-t.y);
		}
		vec operator +(const vec &t)const
		{
			return vec(x+t.x,y+t.y);
		}
		ll operator *(const vec &t)const
		{
			return (ll)x*t.y-(ll)y*t.x;
		}
		ll operator ^(const vec &t)const
		{
			return (ll)x*t.x+(ll)y*t.y;
		}
		bool operator <(const vec &t)const
		{
			return (*this)*t>0;
		}
		bool operator ==(const vec &t)const
		{
			return (*this)*t==0;
		}
}v[500010];
vector<vec> lsa,lsb;
int idcnt,Q,opt[500010],x[500010],y[500010],R,alpha[500010],beta[500010];
class delheap
{
	public:
		priority_queue<int> A,B;
		void insert(int v)
		{
			A.push(v);
		}
		void erase(int v)
		{
			B.push(v);
		}
		int top()
		{
			while(!A.empty()&&!B.empty()&&A.top()==B.top())A.pop(),B.pop();
			if(A.empty())return -1e9;
			return A.top();
		}
};
#define lc (p<<1)
#define rc ((p<<1)|1)
class sgt
{
	public:
		delheap q[500010];
		int mx[2000010];
		void build(int p,int l,int r)
		{
			mx[p]=-1e9;
			if(l==r)return;
			int mid=(l+r)>>1;
			build(lc,l,mid);
			build(rc,mid+1,r);
		}
		void modify(int p,int l,int r,int pos,int v,bool opt)
		{
			if(l==r)
			{
				if(opt)q[l].insert(v);
				else q[l].erase(v);
				mx[p]=q[l].top();
				return;
			}
			int mid=(l+r)>>1;
			if(pos<=mid)modify(lc,l,mid,pos,v,opt);
			else modify(rc,mid+1,r,pos,v,opt);
			mx[p]=max(mx[lc],mx[rc]);
		}
		int query(int p,int l,int r,int ql,int qr)
		{
			if(ql<=l&&r<=qr)return mx[p];
			int mid=(l+r)>>1,ret=-1e9;
			if(ql<=mid)ret=query(lc,l,mid,ql,qr);
			if(qr>mid)ret=max(ret,query(rc,mid+1,r,ql,qr));
			return ret;
		}
}T;
int main()
{
	scanf("%d%d",&R,&Q);
	for(int i=1;i<=Q;i++)
	{
		scanf("%d%d",&opt[i],&x[i]);
		if(opt[i]==1)
		{
			scanf("%d",&y[i]);
			v[++idcnt]=vec(x[i],y[i]);
			x[i]=idcnt;
		}
		else if(opt[i]==3)scanf("%d",&y[i]);
	}
	vec lft(-R,0),rgt(R,0);
	for(int i=1;i<=idcnt;i++)
	{
		lsa.push_back(v[i]-lft);
		lsb.push_back(v[i]-rgt);
	}
	sort(lsa.begin(),lsa.end());
	sort(lsb.begin(),lsb.end());
	lsa.erase(unique(lsa.begin(),lsa.end()),lsa.end());
	lsb.erase(unique(lsb.begin(),lsb.end()),lsb.end());
	T.build(1,0,lsb.size()-1);
	for(int i=1;i<=idcnt;i++)
	{
		alpha[i]=lower_bound(lsa.begin(),lsa.end(),v[i]-lft)-lsa.begin();
		beta[i]=lower_bound(lsb.begin(),lsb.end(),v[i]-rgt)-lsb.begin();
	}
	for(int i=1;i<=Q;i++)
	{
		if(opt[i]==1)
		{
			T.modify(1,0,lsb.size()-1,beta[x[i]],alpha[x[i]],1);
		}
		else if(opt[i]==2)
		{
			T.modify(1,0,lsb.size()-1,beta[x[i]],alpha[x[i]],0);
		}
		else
		{
			int ta=min(alpha[x[i]],alpha[y[i]]),tb=max(beta[x[i]],beta[y[i]]);
			if(lsa[ta]*lsb[tb]<0)puts("NO");
			else
			{
				T.modify(1,0,lsb.size()-1,beta[x[i]],alpha[x[i]],0);
				T.modify(1,0,lsb.size()-1,beta[y[i]],alpha[y[i]],0);
				if(T.query(1,0,lsb.size()-1,0,tb)>=ta)puts("NO");
				else puts("YES");
				T.modify(1,0,lsb.size()-1,beta[x[i]],alpha[x[i]],1);
				T.modify(1,0,lsb.size()-1,beta[y[i]],alpha[y[i]],1);
			}
		}
	}
	return 0;
}

#define ONLINE_JUDGE
#include <bits/stdc++.h>

#define inf 0x3f3f3f3f

#define MOD 1000000007

#define pb push_back

#define sq(x) ((x)*(x))

#define x first

#define y second

#define eps 1e-8

#define bpt(x) (__builtin_popcount(x))

#define bptl(x) (__builtin_popcountll(x))

#define bit(x, y) (((x)>>(y))&1)

#define bclz(x) (__builtin_clz(x))

#define bclzl(x) (__builtin_clzll(x))

#define bctz(x) (__builtin_ctz(x))

#define bctzl(x) (__builtin_ctzll(x))

#define PQ priority_queue<pii, vector<pii>, greater<pii> >

using namespace std;

typedef long long INT;

typedef vector<int> VI;

typedef pair<int, int> pii;

typedef pair<pii, int> pi3;

typedef double DO;

template<typename T, typename U> inline void smin(T &a, U b) {if (a>b) a=b;}

template<typename T, typename U> inline void smax(T &a, U b) {if (a<b) a=b;}

template<class T>inline void gn(T &x) {char c, sg=0; while (c=getchar(), (c>'9' || c<'0') && c!='-');for((c=='-'?sg=1, c=getchar():0), x=0; c>='0' && c<='9'; c=getchar()) x=(x<<1)+(x<<3)+c-'0';if (sg) x=-x;}

template<class T, class T1>inline void gn(T &x, T1 &y) {gn(x); gn(y);}

template<class T, class T1, class T2>inline void gn(T &x, T1 &y, T2 &z) {gn(x); gn(y); gn(z);}

template<class T>inline void print(T x) {if (x<0) {putchar('-');return print(-x);}if (x<10) {putchar('0'+x);return;} print(x/10);putchar(x%10+'0');}

int power(int a, int b, int m, int ans=1) {

	for (; b; b>>=1, a=1LL*a*a%m) if (b&1) ans=1LL*ans*a%m;

	return ans;

}

#ifndef ONLINE_JUDGE

void debug() {cout << endl;}

template<typename T, typename... Args>void debug(T&& head, Args&&... tail) {cout << head << ' ';debug(tail...);}

#endif

#define NN 500010

struct Node {

	int ax, ay, bx, by;

	int st, en;

	int flag;

};

Node mem[4*NN];

int x[NN], y[NN];

int I[NN];

INT ans;

void select(int k, int st, int en, int *val) {

	int le, ri, ll, ho, a, i, j;

	le=st; ri=en-1;

	while (1) {

		if (ri<=le+1) {

			if (ri==le+1 && val[I[le]]>val[I[ri]]) swap(I[le], I[ri]);

			return;

		}

		ll=le+1;

		ho=le+rand()%(ri-le+1);

		swap(I[ho], I[ll]);

		if (val[I[ri]]<val[I[le]]) swap(I[ri], I[le]);

		if (val[I[ll]]>val[I[ri]]) swap(I[ri], I[ll]);

		if (val[I[le]]>val[I[ll]]) swap(I[le], I[ll]);

		a=val[I[ll]];

		i=ll; j=ri;

		while (1) {

			do i++; while (val[I[i]]<a);

			do j--; while (val[I[j]]>a);

			if (i>j) break;

			swap(I[i], I[j]);

		}

		swap(I[ll], I[j]);

		if (k<=j) ri=j;

		else if (k>=i) le=i;

		else break;

	}

}

#define MIN(x, y)((x)<(y)?(x):(y))

#define MAX(x, y)((x)>(y)?(x):(y))

void make_tree(int u, int st, int en, int dp) {

	int mid, le, ri;

	mem[u].st=st; mem[u].en=en;

	mem[u].flag=0;

	if (en==st+1) {

		mem[u].ax=mem[u].bx=x[I[st]];

		mem[u].ay=mem[u].by=y[I[st]];

		return;

	}

	mid=(st+en)/2; le=2*u; ri=2*u+1;

	if (dp&1) select(mid, st, en, x);

	else select(mid, st, en, y);

	make_tree(le, st, mid, 1-dp);

	make_tree(ri, mid, en, 1-dp);

	mem[u].ax=MIN(mem[le].ax, mem[ri].ax);

	mem[u].ay=MIN(mem[le].ay, mem[ri].ay);

	mem[u].bx=MAX(mem[le].bx, mem[ri].bx);

	mem[u].by=MAX(mem[le].by, mem[ri].by);

	return;

}

#define ls (u<<1)

#define rs (ls|1)

int find(int u, int idx) {

	if (x[idx]<mem[u].ax) return 0;

	if (x[idx]>mem[u].bx) return 0;

	if (y[idx]<mem[u].ay) return 0;

	if (y[idx]>mem[u].by) return 0;

	if (mem[u].en==mem[u].st+1) {

		mem[u].flag^=1;

		return 1;

	}

	find(ls, idx);

	find(rs, idx);

	mem[u].flag=mem[ls].flag|mem[rs].flag;

}

int calc(int u, int tx, int ty) {

	if (mem[u].bx<tx) return 0;

	if (mem[u].ay>ty) return 0;

	if (!mem[u].flag) return 0;

	if (mem[u].st+1==mem[u].en) return 1;

	if (calc(ls, tx, ty)) return 1;

	return calc(rs, tx, ty);

}

int t[NN], II[NN];

double X[NN], XX[NN], Y[NN], YY[NN];

const double pi2=acosl(-1.0)/2;

void print_tree(int u=1) {

	if (mem[u].st+1==mem[u].en) {

		printf("%d %d %d\n", mem[u].bx, mem[u].by, mem[u].flag);

		return ;

	}

	print_tree(ls);

	print_tree(rs);

}

int can(int uu, int vv) {

	int u=II[uu], v=II[vv];

	if (x[u]>x[v]) swap(u, v);

	if (x[u]==x[v] && y[u]>y[v]) swap(u, v);

	int tx=min(x[u], x[v]);

	int ty=max(y[u], y[v]);

	find(1, u);

	if (u!=v) find(1, v);

	int ok=(Y[ty]-X[tx]>pi2+1e-12) || calc(1, tx, ty);

	find(1, u);

	if (u!=v) find(1, v);

	return !ok;

}

int main() {

#ifndef ONLINE_JUDGE

	freopen("in.in", "r", stdin);

	freopen("out.out", "w", stdout);

#endif

	int r, n, u, v;

	gn(r); gn(n);

	int nn=0, nx=0, ny=0;

	VI a, b;

	for (int i=0; i<n; i++) {

		gn(t[i]);

		if (t[i]==1) {

			gn(u, v);

			X[nx++]=XX[nn]=atan2l(v, u+r);

			Y[ny++]=YY[nn]=atan2l(v, u-r);

			nn++;

		}

		if (t[i]==2) {

			gn(u);

			a.pb(u);

		}

		if (t[i]==3) {

			gn(u, v);

			b.pb(u); b.pb(v);

		}

	}

	sort(X, X+nx); nx=unique(X, X+nx)-X;

	sort(Y, Y+ny); ny=unique(Y, Y+ny)-Y;

	map<pii, int> mp;

	int E=0;

	for (int i=0; i<nn; i++) {

		pii aa=pii(lower_bound(X, X+nx, XX[i]-1e-12)-X, lower_bound(Y, Y+ny, YY[i]-1e-12)-Y);

		if (mp.count(aa)) II[i]=mp[aa];

		else {

			x[E]=aa.x;

			y[E]=aa.y;

			I[E]=E;

			II[i]=mp[aa]=E;

			E++;

		}

	}

	make_tree(1, 0, E, 0);

	int id=0, id1=0, id2=0;

	for (int i=0; i<n; i++) {

		if (t[i]==1) find(1, II[id]), id++;

		if (t[i]==2) find(1, II[a[id1]-1]), id1++;

		if (t[i]==3) {

			u=b[id2++]-1, v=b[id2++]-1;

			puts(can(u, v)?"YES":"NO");

		}

	}

	return 0;

}

#include <cstdio>
#include <algorithm>
#include <cstring>
#include <queue>
#include <cmath>
#define ld double
#define l(a) (a<<1)
#define r(a) (a<<1|1)
#define MN 500005
#define MM 1000005
#define MD 4200005
#define eps 1e-13
//#define EPS 1e-14
using namespace std;
struct meg{int g,x,y;}a[MN];
struct itv1{ld x,y;}w[MN];
struct itv2{int x,y;}s[MN];
struct Que
{
	priority_queue <int> A,B;
	void push(int x) {A.push(x);}
	void dele(int x) {B.push(x);}
	int top()
	{
		while (!B.empty()&&A.top()==B.top()) A.pop(),B.pop();
		if (!A.empty()) return A.top(); else return 0;
	}
}q[MM];
ld b0[MM],b1[MM];
int m,MQ,tin,b0in,b1in,ra;
int t[MD];

inline int read()
{
	int n=0,f=1; char c=getchar();
	while (c<'0' || c>'9') {if(c=='-')f=-1; c=getchar();}
	while (c>='0' && c<='9') {n=n*10+c-'0'; c=getchar();}
	return n*f;
}

inline void getcg(int x,int z) {for (t[x+=MQ]=z,x>>=1;x;x>>=1) t[x]=max(t[l(x)],t[r(x)]);}
inline int getmax(int L,int R)
{
	int sum=0;
	for (L+=MQ,R+=MQ;L<=R;L>>=1,R>>=1)
	{
		if ( L&1) sum=max(sum,t[L++]);
		if (~R&1) sum=max(sum,t[R--]);
	}
	return sum;
}

void cghp(int x,int y,int g)
{
	int lt=q[x].top();
	if (g==1) q[x].push(y); else q[x].dele(y);
	if (lt!=q[x].top()) getcg(x,q[x].top());
}

int main()
{
	register int i,x,y,lt=0;
	ra=read(); m=read();
	for (i=1;i<=m;++i)
	{
		a[i].g=read();
		if (a[i].g==1)
		{
			x=read(); y=read(); a[i].x=++tin;
			w[tin].x=atan2(y,x-ra);
			w[tin].y=atan2(y,x+ra);
			b0[++b0in]=w[tin].x;
			b1[++b1in]=w[tin].y;
		}
		else if (a[i].g==2) a[i].x=read();
		else if (a[i].g==3) a[i].x=read(),a[i].y=read();
	}
	sort(b0+1,b0+b0in+1); sort(b1+1,b1+b1in+1);
	for (i=2,lt=0;i<=b0in;++i) {if (b0[i]-b0[i-1]<eps) ++lt; b0[i-lt]=b0[i];} b0in-=lt;
	for (i=2,lt=0;i<=b1in;++i) {if (b1[i]-b1[i-1]<eps) ++lt; b1[i-lt]=b1[i];} b1in-=lt;
	for (i=1;i<=tin;++i)
		s[i].x=lower_bound(b0+1,b0+b0in+1,w[i].x)-b0,
		s[i].y=lower_bound(b1+1,b1+b1in+1,w[i].y)-b1;
	for (MQ=1;MQ<b0in;MQ<<=1); --MQ;
	for (i=1;i<=m;++i)
	{
		if (a[i].g<3) cghp(s[a[i].x].x,s[a[i].x].y,a[i].g);
		else if (a[i].g==3)
		{
			if (max(w[a[i].x].x,w[a[i].y].x)-min(w[a[i].x].y,w[a[i].y].y)>acos(0)) {puts("NO"); continue;}
			x=max(s[a[i].x].x,s[a[i].y].x); y=min(s[a[i].x].y,s[a[i].y].y);
			cghp(s[a[i].x].x,s[a[i].x].y,2);
			cghp(s[a[i].y].x,s[a[i].y].y,2);
			if (getmax(1,x)>=y) puts("NO"); else puts("YES");
			cghp(s[a[i].x].x,s[a[i].x].y,1);
			cghp(s[a[i].y].x,s[a[i].y].y,1);
		}
	}
}

#include <cstdio>
#include <algorithm>
#include <cstring>
#include <queue>
#include <cmath>
#define ld double
#define l(a) (a<<1)
#define r(a) (a<<1|1)
#define MN 500005
#define MM 1000005
#define MD 4200005
#define eps 1e-12
#define EPS 1e-9
using namespace std;
struct meg{int g,x,y;}a[MN];
struct itv1{ld x,y;}w[MN];
struct itv2{int x,y;}s[MN];
struct itv3{int x[2],y[2];}d[MN];
struct Que
{
	priority_queue <int> A,B;
	void push(int x) {A.push(x);}
	void dele(int x) {B.push(x);}
	int top()
	{
		while (!B.empty()&&A.top()==B.top()) A.pop(),B.pop();
		if (!A.empty()) return A.top(); else return 0;
	}
}q[MM];
ld b0[MM],b1[MM];
int m,MQ,tin,b0in,b1in,ra;
int t[MD];

inline int read()
{
	int n=0,f=1; char c=getchar();
	while (c<'0' || c>'9') {if(c=='-')f=-1; c=getchar();}
	while (c>='0' && c<='9') {n=n*10+c-'0'; c=getchar();}
	return n*f;
}

inline void getcg(int x,int z) {for (t[x+=MQ]=z,x>>=1;x;x>>=1) t[x]=max(t[l(x)],t[r(x)]);}
inline int getmax(int L,int R)
{
	int sum=0;
	for (L+=MQ,R+=MQ;L<=R;L>>=1,R>>=1)
	{
		if ( L&1) sum=max(sum,t[L++]);
		if (~R&1) sum=max(sum,t[R--]);
	}
	return sum;
}

void cghp(int x,int y,int g)
{
	int lt=q[x].top();
	if (g==1) q[x].push(y); else q[x].dele(y);
	if (lt!=q[x].top()) getcg(x,q[x].top());
}

bool check(int x,int y)
{
	int cs1,cs2;
	if (s[x].x>s[y].x) cs1=x; else cs1=y;
	if (s[x].y<s[y].y) cs2=x; else cs2=y;
//	printf("1=%d 2=%d\n",cs1,cs2);
//	printf("%.14lf,%.14lf\n",atan2(d[cs2].y[0],-d[cs2].y[1]),atan2(d[cs1].x[1],d[cs1].x[0]));
	if (atan2(d[cs2].y[0],-d[cs2].y[1])+EPS<atan2(d[cs1].x[1],d[cs1].x[0])) return true; else return false;
}

int main()
{
	register int i,x,y,lt=0;
	ra=read(); m=read();
	for (i=1;i<=m;++i)
	{
		a[i].g=read();
		if (a[i].g==1)
		{
			x=read(); y=read(); a[i].x=++tin;
			w[tin].x=atan2(d[tin].x[1]=y,d[tin].x[0]=x-ra);
//			printf("x=%.6lf\n",w[tin].x);
			w[tin].y=atan2(d[tin].y[1]=y,d[tin].y[0]=x+ra);
			b0[++b0in]=w[tin].x;
			b1[++b1in]=w[tin].y;
		}
		else if (a[i].g==2) a[i].x=read();
		else if (a[i].g==3) a[i].x=read(),a[i].y=read();
	}
//	printf("bin=%d,%d\n",b0in,b1in);
	sort(b0+1,b0+b0in+1); sort(b1+1,b1+b1in+1);
	for (i=2,lt=0;i<=b0in;++i) {if (b0[i]-b0[i-1]<eps) ++lt; b0[i-lt]=b0[i];} b0in-=lt;
	for (i=2,lt=0;i<=b1in;++i) {if (b1[i]-b1[i-1]<eps) ++lt; b1[i-lt]=b1[i];} b1in-=lt;
	for (i=1;i<=tin;++i)
		s[i].x=lower_bound(b0+1,b0+b0in+1,w[i].x)-b0,
		s[i].y=lower_bound(b1+1,b1+b1in+1,w[i].y)-b1;
//	printf("bin=%d,%d\n",b0in,b1in);
//	for (i=1;i<=tin;++i) printf("s[%d].lf=%d\n",i,s[i].x);
	for (MQ=1;MQ<b0in;MQ<<=1); --MQ;
	for (i=1;i<=m;++i)
	{
		if (a[i].g<3) cghp(s[a[i].x].x,s[a[i].x].y,a[i].g);
		else if (a[i].g==3)
		{
			if (check(a[i].x,a[i].y)) {puts("NO"); continue;}
//			puts("sb");
			x=max(s[a[i].x].x,s[a[i].y].x); y=min(s[a[i].x].y,s[a[i].y].y);
			cghp(s[a[i].x].x,s[a[i].x].y,2);
			cghp(s[a[i].y].x,s[a[i].y].y,2);
			if (getmax(1,x)>=y) puts("NO"); else puts("YES");
			cghp(s[a[i].x].x,s[a[i].x].y,1);
			cghp(s[a[i].y].x,s[a[i].y].y,1);
		}
	}
}

#include<cstdio>
#include<algorithm>
using namespace std;
char B[1<<26],*S=B;
inline int read()
{
	int x,f=1;char c;
	while((c=*S++)<'0'||c>'9')if(c=='-')f=0;
	for(x=c-'0';(c=*S++)>='0'&&c<='9';)x=x*10+c-'0';
	return f?x:-x;
}
#define MN 500000
#define N 524288
struct vec
{
	int x,y;
	friend bool operator<(const vec&a,const vec&b){return 1LL*a.x*b.y<1LL*a.y*b.x;}
	friend bool operator==(const vec&a,const vec&b){return 1LL*a.x*b.y==1LL*a.y*b.x;}
};
vec rot(const vec&a){return (vec){a.y,-a.x};}
struct work{int t,z;vec x,y;}w[MN+5],q[MN+5];
bool cmp(const work&a,const work&b){return a.x==b.x?a.t>b.t:a.x<b.x;}
vec l[MN+5],r[MN+5],c[MN+5];
int cnt,ans[MN+5],t[N*2+5],qn,sa[MN+5],sb[MN+5];
void add(int k,int x){for(k+=N;k;k>>=1)t[k]+=x;}
int query(int l,int r)
{
	int res=0;
	for(l+=N-1,r+=N+1;l^r^1;l>>=1,r>>=1)
	{
		if(~l&1)res+=t[l+1];
		if( r&1)res+=t[r-1];
	}
	return res;
}
void solve(int l,int r)
{
	int mid=l+r>>1,i;
	if(sa[mid]==sa[l-1]||sb[r]==sb[mid])return;
	if(l<r)solve(l,mid),solve(mid+1,r);
	for(qn=0,i=l;i<=mid;++i)if(w[i].t>0)q[++qn]=w[i];
	for(;i<=r;++i)if(!w[i].t)q[++qn]=w[i];
	sort(q+1,q+qn+1,cmp);
	for(i=1;i<=qn;++i)
		if(q[i].t)add(lower_bound(c+1,c+cnt+1,q[i].y)-c,q[i].z);
		else ans[q[i].z]+=query(lower_bound(c+1,c+cnt+1,q[i].y)-c,cnt);
	for(i=1;i<=qn;++i)if(q[i].t)add(lower_bound(c+1,c+cnt+1,q[i].y)-c,-q[i].z);
}
int main()
{
	B[fread(B,1,1<<26,stdin)]=0;
	int R=read(),n=read(),i,t,x,y;
	for(i=1;i<=n;++i)
	{
		t=read();x=read();sa[i]=sa[i-1];sb[i]=sb[i-1];
		if(t==1)
		{
			l[++cnt]=(vec){x+R,y=read()};
			c[cnt]=r[cnt]=(vec){x-R,y};
			w[i]=(work){1,1,l[cnt],r[cnt]},++sa[i];
		}
		if(t==2)w[i]=(work){1,-1,l[x],r[x]},++sa[i];
		if(t==3)
		{
			if(l[y=read()]<l[x])x^=y^=x^=y;
			if(rot(r[x])<l[y])w[i]=(work){-1,0,0,0},ans[i]=3;
			else w[i]=(work){0,i,l[y],r[x]<r[y]?r[x]:r[y]},++sb[i];
		}
	}
	sort(c+1,c+cnt+1);cnt=unique(c+1,c+cnt+1)-c-1;solve(1,n);
	for(i=1;i<=n;++i)if(ans[i])puts(ans[i]>2?"NO":"YES");
}

#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
inline int read()
{
	int x,f=1;char c;
	while((c=getchar())<'0'||c>'9')if(c=='-')f=0;
	for(x=c-'0';(c=getchar())>='0'&&c<='9';)x=x*10+c-'0';
	return f?x:-x;
}
#define MN 500000
#define N 524288
#define double long double
struct work{int t,z;double x,y;}w[MN+5],q[MN+5];
bool cmp(const work&a,const work&b){return a.x==b.x?a.t>b.t:a.x<b.x;}
double l[MN+5],r[MN+5],c[MN+5];
int cnt,ans[MN+5],t[N*2+5],qn;
void add(int k,int x){for(k+=N;k;k>>=1)t[k]+=x;}
int query(int l,int r)
{
	int res=0;
	for(l+=N-1,r+=N+1;l^r^1;l>>=1,r>>=1)
	{
		if(~l&1)res+=t[l+1];
		if( r&1)res+=t[r-1];
	}
	return res;
}
void solve(int l,int r)
{
	int mid=l+r>>1,i;
	if(l<r)solve(l,mid),solve(mid+1,r);
	for(qn=0,i=l;i<=mid;++i)if(w[i].t>0)q[++qn]=w[i];
	for(;i<=r;++i)if(!w[i].t)q[++qn]=w[i];
	sort(q+1,q+qn+1,cmp);
	for(i=1;i<=qn;++i)
		if(q[i].t)add(lower_bound(c+1,c+cnt+1,q[i].y)-c,q[i].z);
		else ans[q[i].z]+=query(lower_bound(c+1,c+cnt+1,q[i].y)-c,cnt);
	for(i=1;i<=qn;++i)if(q[i].t)add(lower_bound(c+1,c+cnt+1,q[i].y)-c,-q[i].z);
}
int main()
{
	int R=read(),n=read(),i,t,x,y;
	for(i=1;i<=n;++i)
	{
		t=read();x=read();
		if(t==1)
		{
			l[++cnt]=-atan2(y=read(),x+R);
			c[cnt]=r[cnt]=-atan2(y,x-R);
			w[i]=(work){1,1,l[cnt],r[cnt]};
		}
		if(t==2)w[i]=(work){1,-1,l[x],r[x]};
		if(t==3)
		{
			if(l[x]>l[y=read()])x^=y^=x^=y;
			if(r[x]+acos(-1)/2<l[y])w[i]=(work){-1,0,0,0},ans[i]=3;
			else w[i]=(work){0,i,l[y],r[x]<r[y]?r[x]:r[y]};
		}
	}
	sort(c+1,c+cnt+1);cnt=unique(c+1,c+cnt+1)-c-1;solve(1,n);
	for(i=1;i<=n;++i)if(ans[i])puts(ans[i]>2?"NO":"YES");
}

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef long double DB;
const int maxn = 500001, BASE = (int)1e9;
int rad, n, tot;
struct Query {
	int typ, x, y;
} que[maxn];
struct Fraction {
	LL x, y;
	Fraction() {}
	Fraction(LL _x, LL _y) { // _y > 0
		LL r = __gcd(abs(_x), _y);
		x = _x / r;
		y = _y / r;
	}
	bool operator == (Fraction const &t) const {
		return x == t.x && y == t.y;
	}
	bool operator < (Fraction const &t) const {
		return (DB)x * t.y < (DB)t.x * y;
	}
} pL[maxn], pR[maxn], seq[maxn << 1 | 1];
int cnt, idx[maxn], ord[maxn], pos[maxn], seg[maxn << 1 | 1];
inline int seg_idx(int L, int R) {
	return (L + R) | (L < R);
}
void seg_upd(int L, int R, int x, int v) {
	int rt = seg_idx(L, R);
	if(L == R) {
		seg[rt] = v;
		return;
	}
	int M = (L + R) >> 1, lch = seg_idx(L, M), rch = seg_idx(M + 1, R);
	if(x <= M)
		seg_upd(L, M, x, v);
	else
		seg_upd(M + 1, R, x, v);
	seg[rt] = max(seg[lch], seg[rch]);
}
int seg_que(int L, int R, int l, int r) {
	if(l <= L && R <= r)
		return seg[seg_idx(L, R)];
	int M = (L + R) >> 1, ret = 0;
	if(l <= M)
		ret = max(ret, seg_que(L, M, l, r));
	if(M < r)
		ret = max(ret, seg_que(M + 1, R, l, r));
	return ret;
}
inline LL sqr(int x) {
	return (LL)x * x;
}
bool cmp(int const &u, int const &v) {
	return que[u].x < que[v].x;
}
int main() {
	scanf("%d%d", &rad, &n);
	for(int i = 1; i <= n; ++i) {
		int &typ = que[i].typ, &x = que[i].x, &y = que[i].y;
		scanf("%d%d", &typ, &x);
		if(typ != 2)
			scanf("%d", &y);
		if(typ != 1)
			continue;
		seq[++tot] = pL[i] = x >= -rad ? Fraction(sqr(x + rad) - sqr(y), sqr(x + rad) + sqr(y)) : Fraction(-1, 1);
		seq[++tot] = pR[i] = x <= rad ? Fraction(sqr(y) - sqr(x - rad), sqr(x - rad) + sqr(y)) : Fraction(1, 1);
	}
	sort(seq + 1, seq + tot + 1);
	tot = unique(seq + 1, seq + tot + 1) - seq - 1;
	for(int i = 1; i <= n; ++i) {
		int &typ = que[i].typ, &x = que[i].x, &y = que[i].y;
		if(typ == 1) {
			x = lower_bound(seq + 1, seq + tot + 1, pL[i]) - seq;
			y = lower_bound(seq + 1, seq + tot + 1, pR[i]) - seq;
			ord[++cnt] = i;
			idx[cnt] = i;
		}
	}
	sort(ord + 1, ord + cnt + 1, cmp);
	for(int i = 1; i <= cnt; ++i)
		pos[ord[i]] = i;
	for(int i = 1; i <= n; ++i) {
		int &typ = que[i].typ, &x = que[i].x, &y = que[i].y;
		if(typ == 1) {
			seg_upd(1, cnt, pos[i], que[i].y);
		} else if(typ == 2) {
			seg_upd(1, cnt, pos[idx[x]], 0);
		} else {
			x = idx[x], y = idx[y];
			int L = max(que[x].x, que[y].x), R = min(que[x].y, que[y].y);
			if(L <= R) {
				if(que[x].x < que[x].y)
					seg_upd(1, cnt, pos[x], 0);
				if(que[y].x < que[y].y)
					seg_upd(1, cnt, pos[y], 0);
				que[0] = (Query){0, L, R};
				int id = upper_bound(ord + 1, ord + cnt + 1, 0, cmp) - ord - 1;
				puts(seg_que(1, cnt, 1, id) < R ? "YES" : "NO");
				if(que[x].x < que[x].y)
					seg_upd(1, cnt, pos[x], que[x].y);
				if(que[y].x < que[y].y)
					seg_upd(1, cnt, pos[y], que[y].y);
			} else {
				puts("NO");
			}
		}
	}
	return 0;
}

#include <cstdio>
#include <algorithm>
#include <cstring>
#include <queue>
#include <cmath>
#define ld long double
#define l(a) (a<<1)
#define r(a) (a<<1|1)
#define MN 500005
#define MM 1000005
#define MD 4200005
#define eps 1e-13
#define EPS 1e-14
using namespace std;
struct meg{int g,x,y;}a[MN];
struct itv1{ld x,y;}w[MN];
struct itv2{int x,y;}s[MN];
struct Que
{
	priority_queue <int> A,B;
	void push(int x) {A.push(x);}
	void dele(int x) {B.push(x);}
	int top()
	{
		while (!B.empty()&&A.top()==B.top()) A.pop(),B.pop();
		if (!A.empty()) return A.top(); else return 0;
	}
}q[MM];
ld b0[MM],b1[MM];
int m,MQ,tin,b0in,b1in,ra;
int t[MD];

inline int read()
{
	int n=0,f=1; char c=getchar();
	while (c<'0' || c>'9') {if(c=='-')f=-1; c=getchar();}
	while (c>='0' && c<='9') {n=n*10+c-'0'; c=getchar();}
	return n*f;
}

inline void getcg(int x,int z) {for (t[x+=MQ]=z,x>>=1;x;x>>=1) t[x]=max(t[l(x)],t[r(x)]);}
inline int getmax(int L,int R)
{
	int sum=0;
	for (L+=MQ,R+=MQ;L<=R;L>>=1,R>>=1)
	{
		if ( L&1) sum=max(sum,t[L++]);
		if (~R&1) sum=max(sum,t[R--]);
	}
	return sum;
}

void cghp(int x,int y,int g)
{
	int lt=q[x].top();
	if (g==1) q[x].push(y); else q[x].dele(y);
	if (lt!=q[x].top()) getcg(x,q[x].top());
}

int main()
{
	register int i,x,y,lt=0;
	ra=read(); m=read();
	for (i=1;i<=m;++i)
	{
		a[i].g=read();
		if (a[i].g==1)
		{
			x=read(); y=read(); a[i].x=++tin;
			w[tin].x=atan2(y,x-ra);
			w[tin].y=atan2(y,x+ra);
			b0[++b0in]=w[tin].x;
			b1[++b1in]=w[tin].y;
		}
		else if (a[i].g==2) a[i].x=read();
		else if (a[i].g==3) a[i].x=read(),a[i].y=read();
	}
	sort(b0+1,b0+b0in+1); sort(b1+1,b1+b1in+1);
	for (i=2,lt=0;i<=b0in;++i) {if (b0[i]-b0[i-1]<eps) ++lt; b0[i-lt]=b0[i];} b0in-=lt;
	for (i=2,lt=0;i<=b1in;++i) {if (b1[i]-b1[i-1]<eps) ++lt; b1[i-lt]=b1[i];} b1in-=lt;
	for (i=1;i<=tin;++i)
		s[i].x=lower_bound(b0+1,b0+b0in+1,w[i].x)-b0,
		s[i].y=lower_bound(b1+1,b1+b1in+1,w[i].y)-b1;
	for (MQ=1;MQ<b0in;MQ<<=1); --MQ;
	for (i=1;i<=m;++i)
	{
		if (a[i].g<3) cghp(s[a[i].x].x,s[a[i].x].y,a[i].g);
		else if (a[i].g==3)
		{
			if (max(w[a[i].x].x,w[a[i].y].x)-min(w[a[i].x].y,w[a[i].y].y)>acos(0)+EPS) {puts("NO"); continue;}
			x=max(s[a[i].x].x,s[a[i].y].x); y=min(s[a[i].x].y,s[a[i].y].y);
			cghp(s[a[i].x].x,s[a[i].x].y,2);
			cghp(s[a[i].y].x,s[a[i].y].y,2);
			if (getmax(1,x)>=y) puts("NO"); else puts("YES");
			cghp(s[a[i].x].x,s[a[i].x].y,1);
			cghp(s[a[i].y].x,s[a[i].y].y,1);
		}
	}
}

#include <bits/stdc++.h>

#define FOR(i,b,e) for(int i=(b); i <= (e); ++i)
#define FORD(i,b,e) for(int i=(b); i >= (e); --i)
#define REP(i,n) for(int i=0; i < (n); ++i)
#define SIZE(c) (int) (c).size()
#define ALL(c) (c).begin(), (c).end()
#define PB push_back
#define MP make_pair
#define ST first
#define ND second
#define FWD(i,a,b) for (int i=(a); i<(b); ++i)
#define BCK(i,a,b) for (int i=(a); i>(b); --i)
#define PI 3.14159265358979311600
#define pb push_back
#define mp make_pair
#define st first
#define nd second

using namespace std;

typedef long long ll;
typedef pair <int, int> pii;
typedef pair <ll, ll> pll;

typedef vector < int > VI;
typedef vector<ll> VL;

typedef long double K;

struct pt {
	int x, y, id;

	friend pt operator + (const pt& a, const pt& b) {
		return {a.x + b.x, a.y + b.y};
	}

	friend pt operator - (const pt& a, const pt& b) {
		return {a.x - b.x, a.y - b.y};
	}

	friend ll operator * (const pt& a, const pt& b) {
		return 1LL*a.x*b.y - 1LL*a.y*b.x;
	}

	friend ll operator % (const pt& a, const pt& b) {
		return 1LL*a.x*b.x + 1LL*a.y*b.y;
	}
};

struct SegTree {
	int n;

	SegTree() {}
};

const int N = 500005;

int r, n, t[N], x[N], y[N], sz;
pt a[N];
int ps[N];

pt tree[4*N], lf, rt;

pt up(const pt& a, const pt& b) {
	return (a - rt) * (b - rt) > 0 ? a : b;
}

void build(int v, int tl, int tr) {
	if (tl == tr) {
		tree[v] = lf;
		return;
	}
	int tm = (tl + tr) / 2;
	build(2*v, tl, tm);
	build(2*v+1, tm+1, tr);
	tree[v] = up(tree[2*v], tree[2*v+1]);
}

pt go(int v, int tl, int tr, int l, int r) {
	if (l > r || l > tr || r < tl) return lf;
	if (l <= tl && r >= tr) return tree[v];
	int tm = (tl + tr) / 2;
	return up(go(2*v, tl, tm, l, r), go(2*v+1, tm+1, tr, l, r));
}

void update(int v, int tl, int tr, int pos, pt val) {
	if (tl == tr) {
		tree[v] = val;
		return;
	}
	int tm = (tl + tr) / 2;
	if (pos <= tm) {
		update(2*v, tl, tm, pos, val);
	} else {
		update(2*v+1, tm+1, tr, pos, val);
	}
	tree[v] = up(tree[2*v], tree[2*v+1]);
}

void add(int id) {
	// cout << "ADD: " << id << endl;
	update(1, 0, sz - 1, ps[id], a[ps[id]]);
}

void remove(int id) {
	// cout << "DELETE: " << id << endl;
	update(1, 0, sz - 1, ps[id], lf);
}

bool go(int x, int y) {
	pt f = a[ps[x]];
	pt s = a[ps[y]];
	pt lf = {-r, 0};
	pt rt = {+r, 0};
	pt first = (f - lf) * (s - lf) > 0 ? (f - lf) : (s - lf);
	pt second = (f - rt) * (s - rt) < 0 ? (f - rt) : (s - rt);

	if (first % second < 0) return false;
	// cout << "HELLO" << endl;
	// cout << first.x << ' ' << first.y << endl;
	// cout << second.x << ' ' << second.y << endl;
	int l = -1, r = sz;
	while (r - l > 1) {
		int m = (l + r) / 2;
		if (first * (a[m] - lf) < 0) l = m; else r = m;
	}
	// REP(i, sz) cout << first * (a[i] - lf) << ' '; cout << endl;
	// cout << r << ' ' << sz << endl;
	remove(x);
	remove(y);
	auto here = go(1, 0, sz - 1, r, sz - 1);
	// cout << here.x << ' ' << here.y << ' ' << here.id << endl;
	here = here - rt;
	add(x);
	add(y);
	if (here * second > 0) return false;
	return true;
}

void solve() {
	cin >> r >> n;

	REP(i, n) {
		cin >> t[i] >> x[i];
		if (t[i] != 2) cin >> y[i];
		if (t[i] == 1) {
			a[sz] = {x[i], y[i], sz};
			++sz;
			x[i] = sz;
		}
		--x[i]; --y[i];
	}
	lf = {-r, 0};
	rt = {+r, 0};
	sort(a, a + sz, [](const pt& a, const pt& b) {
		return (a - lf) * (b - lf) > 0;
	});
	REP(i, sz) ps[a[i].id] = i;
	// REP(i, sz) cout << i << " : " << a[i].id << endl;
	build(1, 0, sz - 1);
	REP(i, n) {
		if (t[i] == 1) {
			add(x[i]);
		}
		if (t[i] == 2) {
			remove(x[i]);
		}
		if (t[i] == 3) {
			cout << (go(x[i], y[i]) ? "YES" : "NO") << '\n';
		}
	}
}

int main() {
	ios_base::sync_with_stdio(false);
	cin.tie(0);

	int t = 1;
	REP(i, t) solve();

	return 0;
}

#pragma comment(linker, "/stack:200000000")
#pragma GCC optimize("Ofast")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")

#include <bits/stdc++.h>

#define F0R(i, a) for (int i = 0; i < (a); i++)
#define FOR(i, a, b) for (int i = (a); i < (b); i++)
#define R0F(i, a) for (int i = (a) - 1; i >= 0; i--)
#define ROF(i, a, b) for (int i = (b) - 1; i >= (a); i--)

#define ran() (rand() & 0x7FFF)
#define rand31() ((ran() << 16) | (ran() << 1) | (ran() & 1))
#define rand32() ((ran() << 17) | (ran() << 2) | (ran() & 3))
#define rand63() (((ll)ran() << 48) | ((ll)ran() << 33) | ((ll)ran() << 18) | ((ll)ran() << 3) | ((ll)ran() & 7))
#define rand64() (((ll)ran() << 49) | ((ll)ran() << 34) | ((ll)ran() << 19) | ((ll)ran() << 4) | ((ll)ran() & 15))

#define F first
#define S second
#define PB push_back
#define MP make_pair
#define MT make_tuple
#define UB upper_bound
#define LB lower_bound
#define X real()
#define Y imag()

#define INF 1e18
#define PI acos(-1)

#define sz(x) ((int)(x).size())
#define all(x) (x).begin(), (x).end()
#define SQ(x) ((x) * (x))

using namespace std;

typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef vector<int> vi;
typedef vector<pii> vpii;
typedef vector<ll> vll;
typedef vector<ull> vul;
typedef complex<ld> point;
typedef complex<ld> cld;
typedef vector<cld> vcld;

#define MAXN 500000

struct angle {

ll y, x;

bool operator<(const angle& a2) const {
    return x * a2.y - y * a2.x > 0;
}

bool operator==(const angle& a2) const {
    return x * a2.y == y * a2.x;
}

bool operator<=(const angle& a2) const { return *this < a2 || *this == a2; }

bool operator>=(const angle& a2) const { return a2 < *this; }

};

struct SegTree{

int sz;
angle *tree;

SegTree(int _sz) {
    sz = 1 << (32 - __builtin_clz(_sz - 1));
    tree = new angle[2 * sz];
    F0R(i, 2 * sz) tree[i] = angle({0, 1});
}

void upd(int idx, angle v) {
    idx += sz;
    tree[idx] = v;
    for (idx /= 2; idx > 0; idx /= 2) tree[idx] = max(tree[2 * idx], tree[2 * idx + 1]);
}

angle query(int lo, int hi) {
    lo += sz, hi += sz;
    angle res = angle({0, 1});
    while(lo <= hi) {
        if ((lo % 2) == 1) res = max(res, tree[lo++]);
        if ((hi % 2) == 0) res = max(res, tree[hi--]);
        lo /= 2;
        hi /= 2;
    }
    return res;
}

};

ll r;
angle alpha[MAXN], beta123[MAXN];
int n, q, posof[MAXN];
vector<pair<angle, int>> order;
vpii updates;
vector<pair<int, pii>> queries;

SegTree st(2);

void toggle(int idx) {
int pos = posof[idx];
if (st.query(pos, pos) == angle({0, 1})) st.upd(pos, beta123[idx]);
else st.upd(pos, {0, 1});
}

int main() {
    ios::sync_with_stdio(0);
    cin.tie(0);
    cin >> r >> q;
    F0R(i, q) {
        int t;
        cin >> t;
        switch(t) {
            case 1:
                ll x, y;
                cin >> x >> y;
                alpha[n] = {y, r - x};
                beta123[n] = {y, x + r};
                updates.PB(MP(i, n++));
                break;
            case 2:
                int idx;
                cin >> idx;
                idx--;
                updates.PB(MP(i, idx));
                break;
            case 3:
                int a, b;
                cin >> a >> b;
                a--, b--;
                queries.PB(MP(i, MP(a, b)));
                break;
        }
    }
    F0R(i, n) order.PB(MP(alpha[i], i));
    sort(all(order));
    F0R(i, n) posof[order[i].S] = i;
    reverse(all(updates));
    reverse(all(queries));
    st = SegTree(n);
    while (!updates.empty() || !queries.empty()) {
        if (queries.empty() || (!updates.empty() && updates.back().F < queries.back().F)) {
            int idx = updates.back().S;
            updates.pop_back();
            toggle(idx);
        } else {
            int a = queries.back().S.F;
            int b = queries.back().S.S;
            queries.pop_back();
            angle _alpha = min(alpha[a], alpha[b]);
            angle _beta123 = min(beta123[a], beta123[b]);
            if(atan2(_alpha.y, _alpha.x) + atan2(_beta123.y, _beta123.x) < PI / 2) cout << "NO\n";
                else {
                    toggle(a);
                    toggle(b);

                    int lo = LB(all(order), MP(_alpha, 0)) - order.begin();
                    if (st.query(lo, n - 1) >= _beta123) cout << "NO\n";
                    else cout << "YES\n";

                    toggle(a);
                    toggle(b);
                }
            }
        }
}

#include <cstdio>
#include <algorithm>
#include <cstring>
#include <queue>
#include <cmath>
#define ll long long
#define ld double
#define l(a) (a<<1)
#define r(a) (a<<1|1)
#define MN 500005
#define MM 1000005
#define MD 4200005
#define eps 1e-12
using namespace std;
int INF;
struct meg{int g,x,y;}a[MN];
struct itv1{ld x,y;}w[MN];
struct itv2{int x,y;}s[MN];
struct Que
{
	priority_queue <int,vector<int>,greater<int> > A,B;
	void push(int x) {A.push(x);}
	void dele(int x) {B.push(x);}
	int top()
	{
		while (!B.empty()&&A.top()==B.top()) A.pop(),B.pop();
		if (!A.empty()) return A.top(); else return INF;
	}
}q[MM];
ld b[MM];
ll ra;
int m,MQ,tin,bin;
int t[MD];

inline int read()
{
	int n=0,f=1; char c=getchar();
	while (c<'0' || c>'9') {if(c=='-')f=-1; c=getchar();}
	while (c>='0' && c<='9') {n=n*10+c-'0'; c=getchar();}
	return n*f;
}

inline void getcg(int x,int z) {for (t[x+=MQ]=z,x>>=1;x;x>>=1) t[x]=min(t[l(x)],t[r(x)]);}
inline int getmin(int L,int R)
{
	int sum=INF;
	for (L+=MQ,R+=MQ;L<=R;L>>=1,R>>=1)
	{
		if ( L&1) sum=min(sum,t[L++]);
		if (~R&1) sum=min(sum,t[R--]);
	}
	return sum;
}

ld cal(ll x0,ll y0,ll x1,ll y1,ll g)
{
	ld ki,bi;
	ki=(ld)(y1-y0)/(x1-x0);
	bi=(ld)y0-(ld)x0*(y1-y0)/(x1-x0);
	return acos((ld)(bi*bi-ra*ra)*g/(ki*ki+1)/(ra*ra));
}
void cghp(int x,int y,int g)
{
	int lt=q[x].top();
	if (g==1) q[x].push(y); else q[x].dele(y);
	if (lt!=q[x].top()) getcg(x,q[x].top());
}

int main()
{
	register int i,x,y,lt=0;
	ra=read(); m=read();
	for (i=1;i<=m;++i)
	{
		a[i].g=read();
		if (a[i].g==1)
		{
			x=read(); y=read(); a[i].x=++tin;
			w[tin].x=(ll)x>= ra?acos( 1):cal( ra,0,(ll)x,(ll)y, 1);
			w[tin].y=(ll)x<=-ra?acos(-1):cal(-ra,0,(ll)x,(ll)y,-1);
			b[++bin]=w[tin].x; b[++bin]=w[tin].y;
		}
		else if (a[i].g==2) a[i].x=read();
		else if (a[i].g==3) a[i].x=read(),a[i].y=read();
	}
	sort(b+1,b+bin+1);
	for (i=2;i<=bin;++i) {if (b[i]-b[i-1]<eps) ++lt; b[i-lt]=b[i];}
	bin-=lt;
	for (i=1;i<=tin;++i)
		s[i].x=lower_bound(b+1,b+bin+1,w[i].x)-b,
		s[i].y=lower_bound(b+1,b+bin+1,w[i].y)-b;
//		s[i].x=s[i].x*2-1,s[i].y=s[i].y*2-1;
//	for (i=1;i<=tin;++i) printf("%d %d\n",s[i].x,s[i].y);
	for (MQ=1;MQ<bin;MQ<<=1); --MQ;
	memset(t,100,sizeof(t)); INF=t[0];
	for (i=1;i<=m;++i)
	{
		if (a[i].g<3) cghp(s[a[i].x].y,s[a[i].x].x,a[i].g);
		else if (a[i].g==3)
		{
			x=max(s[a[i].x].x,s[a[i].y].x); y=min(s[a[i].x].y,s[a[i].y].y);
			if (x>y) {puts("NO"); continue;}
			cghp(s[a[i].x].y,s[a[i].x].x,2);
			cghp(s[a[i].y].y,s[a[i].y].x,2);
			if (getmin(y,bin)<=x) puts("NO"); else puts("YES");
			cghp(s[a[i].x].y,s[a[i].x].x,1);
			cghp(s[a[i].y].y,s[a[i].y].x,1);
		}
	}
}

#include<iostream>
#include<cstdlib>
#include<stdio.h>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<vector>
#include<set>
#include<map>
using namespace std;
long long r;
int n,cnt,list[501000],cnt_list,mf[1001000];
struct segment_tree
{
	int l,r,min_vl,lazy;
};
segment_tree tree[1<<21];
struct point
{
	long long x,y;
	int z;
	bool operator <(const point &temp)const
	{
		  return y*temp.x<x*temp.y;
	}
};
point pt[1000001];
struct query
{
	int u,v,flag,id;
	long long x,y;
	point l,r;
};
query qy[501000];
void build(int left,int right,int id)
{
	int l=2*id+1,r=2*id+2,mid=(left+right)>>1;
	tree[id].min_vl=tree[id].lazy=0;
	tree[id].l=left;
	tree[id].r=right;
	if(left==right)
	    return;
    build(left,mid,l);
    build(mid+1,right,r);
}
void zz(int id)
{
	if(tree[id].lazy==0)
	    return;
	int l=2*id+1,r=2*id+2;
	if(tree[id].l!=tree[id].r)
	{
		tree[l].lazy+=tree[id].lazy;
		tree[r].lazy+=tree[id].lazy;
	}
	tree[id].min_vl+=tree[id].lazy;
	tree[id].lazy=0;
}
void update(int left,int right,int vl,int id)
{
	int l=2*id+1,r=2*id+2;
	if(tree[id].l>right||tree[id].r<left)
	{
	     zz(id);
	     return;
	}
    if(tree[id].l>=left&&tree[id].r<=right)
    {
    	tree[id].lazy+=vl;
    	zz(id);
    	return;
    }
    zz(id);
    update(left,right,vl,l);
    update(left,right,vl,r);
    tree[id].min_vl=min(tree[l].min_vl,tree[r].min_vl);
}
int qw(int left,int right,int id)
{
	int l=2*id+1,r=2*id+2;
	zz(id);
	if(tree[id].l>right||tree[id].r<left)
	    return 1e9+9;
    if(tree[id].l>=left&&tree[id].r<=right)
    	return tree[id].min_vl;
	return min(qw(left,right,l),qw(left,right,r));
}
int binary(int left,int right,point now)
{
	int mid;
	while(left<=right)
	{
		mid=(left+right)>>1;
		if(pt[mid]<now)
			left=mid+1;
		else if(now<pt[mid])
		    right=mid-1;
        else
            return mid;
	}
}
int main()
{
	scanf("%lld%d",&r,&n);
	int i,j,s,p,q,l_id,r_id;
	long long ru;
	cnt=0;
	cnt_list=0;
	for(i=0;i<n;i++)
	{
		scanf("%d",&qy[i].flag);
		if(qy[i].flag==1)
		{
			list[cnt_list++]=i;
            scanf("%lld%lld",&qy[i].x,&qy[i].y);
		   	pt[cnt].x=qy[i].y;
            pt[cnt++].y=r-qy[i].x;
			qy[i].r=pt[cnt-1];
		   	pt[cnt].x=qy[i].x+r;
            pt[cnt++].y=qy[i].y;
			qy[i].id=cnt_list-1;
		    qy[i].l=pt[cnt-1];
		    if(qy[i].r<qy[i].l)
		        swap(qy[i].l,qy[i].r);
		}
		else if(qy[i].flag==2)
        {
           scanf("%d",&qy[i].u);
           qy[i].u--;
        }
        else
        {
        	scanf("%d%d",&qy[i].u,&qy[i].v);
        	qy[i].u--;
        	qy[i].v--;
        }
	}
	sort(pt,pt+cnt);
	int nn=0;
	for(i=0;i<cnt;i++)
	{
		if(nn==0||(pt[i].x!=pt[nn-1].x||pt[i].y!=pt[nn-1].y))
		    pt[nn++]=pt[i];
	}
	cnt=nn;
	build(0,cnt-1,0);
	point ll,rr;
	memset(mf,0,sizeof(mf));
	for(i=0;i<n;i++)
	{
		int flag;
		if(qy[i].flag==1)
		{
		   flag=1;
		   ll=qy[i].l;
		   rr=qy[i].r;
		}
		else if(qy[i].flag==2)
		{
			flag=-1;
			ll=qy[list[qy[i].u]].l;
			rr=qy[list[qy[i].u]].r;
		}
		if(qy[i].flag==1||qy[i].flag==2)
		{
    		l_id=binary(0,cnt-1,ll);
    		r_id=binary(0,cnt-1,rr);
    		mf[r_id]+=flag;
    		if(l_id<r_id)
    		   update(l_id,r_id,flag,0);
		}
		else
		{
			int id1,id2;
			id1=qy[i].u;
			id2=qy[i].v;
		    ll=qy[list[id1]].l;
		    rr=qy[list[id1]].r;
            if(ll<qy[list[id2]].l)
               ll=qy[list[id2]].l;
            if(qy[list[id2]].r<rr)
               rr=qy[list[id2]].r;
            bool ans;
            if(rr<ll)
               ans=0;
            else
            {
            	l_id=binary(0,cnt-1,ll);
            	r_id=binary(0,cnt-1,rr);
            	ans=qw(l_id,r_id,0)<=2;
            }
            if(ans)
               puts("YES");
            else
               puts("NO");
		}
	}
	return 0;
}
/*

100000000 5
1 -106382777 300000523
1 -75340202 300000165
1 -148918484 300000552
1 96360393 300000458
3 3 2
*/

#include <cstdio>
#include <algorithm>
#include <cstring>
#include <queue>
#include <cmath>
#define ll long long
#define ld long double
#define l(a) (a<<1)
#define r(a) (a<<1|1)
#define MN 500005
#define MM 1000005
#define MD 4200005
//#define eps 1e-15
using namespace std;
int INF;
struct meg{int g,x,y;}a[MN];
struct itv1{ld x,y;}w[MN];
struct itv2{int x,y;}s[MN];
struct Que
{
	priority_queue <int,vector<int>,greater<int> > A,B;
	void push(int x) {A.push(x);}
	void dele(int x) {B.push(x);}
	int top()
	{
		while (!B.empty()&&A.top()==B.top()) A.pop(),B.pop();
		if (!A.empty()) return A.top(); else return INF;
	}
}q[MM];
ld b[MM];
ll ra;
int m,MQ,tin,bin;
int t[MD];

inline int read()
{
	int n=0,f=1; char c=getchar();
	while (c<'0' || c>'9') {if(c=='-')f=-1; c=getchar();}
	while (c>='0' && c<='9') {n=n*10+c-'0'; c=getchar();}
	return n*f;
}

inline void getcg(int x,int z) {for (t[x+=MQ]=z,x>>=1;x;x>>=1) t[x]=min(t[l(x)],t[r(x)]);}
inline int getmin(int L,int R)
{
	int sum=INF;
	for (L+=MQ,R+=MQ;L<=R;L>>=1,R>>=1)
	{
		if ( L&1) sum=min(sum,t[L++]);
		if (~R&1) sum=min(sum,t[R--]);
	}
	return sum;
}

ld cal(ll x0,ll y0,ll x1,ll y1,ll g)
{
	ld ki,bi;
	ki=(ld)(y1-y0)/(x1-x0);
	bi=(ld)y0-(ld)x0*(y1-y0)/(x1-x0);
	return acos((ld)(bi*bi-ra*ra)*g/(ki*ki+1)/(ra*ra));
}
void cghp(int x,int y,int g)
{
	int lt=q[x].top();
	if (g==1) q[x].push(y); else q[x].dele(y);
	if (lt!=q[x].top()) getcg(x,q[x].top());
}

int main()
{
	register int i,x,y,lt=0;
	ra=read(); m=read();
	for (i=1;i<=m;++i)
	{
		a[i].g=read();
		if (a[i].g==1)
		{
			x=read(); y=read(); a[i].x=++tin;
			w[tin].x=(ll)x>= ra?acos( 1):cal( ra,0,(ll)x,(ll)y, 1);
			w[tin].y=(ll)x<=-ra?acos(-1):cal(-ra,0,(ll)x,(ll)y,-1);
			b[++bin]=w[tin].x; b[++bin]=w[tin].y;
		}
		else if (a[i].g==2) a[i].x=read();
		else if (a[i].g==3) a[i].x=read(),a[i].y=read();
	}
	sort(b+1,b+bin+1);
	for (i=2;i<=bin;++i) {if (b[i]==b[i-1]) ++lt; b[i-lt]=b[i];}
	bin-=lt;
	for (i=1;i<=tin;++i)
		s[i].x=lower_bound(b+1,b+bin+1,w[i].x)-b,
		s[i].y=lower_bound(b+1,b+bin+1,w[i].y)-b;
//		s[i].x=s[i].x*2-1,s[i].y=s[i].y*2-1;
	for (MQ=1;MQ<bin;MQ<<=1); --MQ;
	memset(t,100,sizeof(t)); INF=t[0];
	for (i=1;i<=m;++i)
	{
		if (a[i].g<3) cghp(s[a[i].x].y,s[a[i].x].x,a[i].g);
		else if (a[i].g==3)
		{
			x=max(s[a[i].x].x,s[a[i].y].x); y=min(s[a[i].x].y,s[a[i].y].y);
			if (x>y) {puts("NO"); continue;}
			cghp(s[a[i].x].y,s[a[i].x].x,2);
			cghp(s[a[i].y].y,s[a[i].y].x,2);
			if (getmin(y,bin)<=x) puts("NO"); else puts("YES");
			cghp(s[a[i].x].y,s[a[i].x].x,1);
			cghp(s[a[i].y].y,s[a[i].y].x,1);
		}
	}
}

#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <string>
#include <cstring>
#include <cmath>
#include <set>
#include <map>
#include <cstdio>
#include <stdlib.h>
#include <stack>
#include <numeric>
#include <bitset>
#include <cctype>
#include <list>
#include <assert.h>
#include <random>
#include <unordered_map>
#include <ctime>
typedef  long long ll;
using namespace std;
#define INF 2147483647
#define infL (1LL<<60)
#define inf (1<<30)
#define inf9 (1000000000)
#define MOD 1000000007
#define EPS 1e-9
#define Gr 9.8
#define PI acos(-1)
#define REP(i,n) for(int (i)=0;(i)<(int)(n);(i)++)
#define REQ(i,n) for(int (i)=1;(i)<=(int)(n);(i)++)
#define lch (rt<<1)
#define rch (rt<<1|1)
#define readmp(n) for(int i=0,u,v;i<n;i++) {scanf("%d%d",&u,&v); mp[u].push_back(v); mp[v].push_back(u);}
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef long double ld;
typedef unsigned int uint;
#define MAX 500105
bool debug = 0;
int n,m,k;
int dx[4] = {0,1,0,-1}, dy[4] = {1,0,-1,0};
string direc="RDLU";
ll ln, lk, lm;
void etp(bool f = 0) {
    puts(f ?"YES" : "NO");
    exit(0);
}
void addmod(int &x, int y, int mod = MOD) {
    assert(y>=0);
    x+=y; if (x>=mod) x-=mod;
    assert(x>=0 && x<mod);
}
void et() {
    puts("-1"); exit(0);
}
ll fastPow(ll x, ll y, int mod=MOD) {
    ll ans = 1;
    while(y>0) {
        if(y&1) ans = (x * ans)%mod;
        x = x*x%mod;
        y>>=1;
    }
    return ans;
}
ll gcd1(ll x, ll y) {
    ll z = y;
    while(x%y!=0) {
        z = x%y; x = y; y = z;
    }
    return z;
}

struct Frac {
    ll x, y;
    Frac() { }
    Frac(ll x, ll y) : x(x), y(y) {}
    ld absVal() const { return (ld)x/y; }
    void uni() {
        if (y<0) {y*=-1; x*=-1;}
        assert(y!=0);
        if (x==0) y=1;
        else {
            ll g=gcd1(abs(x), abs(y));
            x/=g; y/=g;
        }
    }
    Frac operator*(Frac o) const { return Frac(x * o.x, y * o.y); }
    Frac operator+(const Frac& o) const { return Frac(x*o.y+y*o.x, y * o.y); }
    Frac operator-(const Frac& o) const { return Frac(x*o.y-y*o.x, y * o.y); }
    bool operator<(const Frac& o) const {
        return x*o.y < y*o.x;
    }
    friend bool operator == (const Frac &r1,const Frac &r2) {return r1.x*r2.y == r1.y*r2.x;}
};
int R;
Frac lt[MAX],rt[MAX];
int sateCnt;
struct mb {
    int t,x,y, id;
    void rd() {
        scanf("%d", &t);
        if (t==2) scanf("%d", &id);
        else scanf("%d%d", &x,&y);
    }
}q[MAX];
map<Frac, int> mp;
int li[MAX], ri[MAX],cnt;

const int MN=(1<<21)+5;
Frac fcmin = Frac(-inf9-inf9-5, 1);
struct mbt {
    int M; Frac T[MN];
    void init(int sz) {
        for(M=1;sz+2>M;M<<=1);
        REP(i,MN) T[i]=fcmin;
    }
    void uptSingleMax(int l, Frac val) {
        l+=M; T[l]=val;
        while(l>1) {
            T[l>>1] = max(T[l],T[l^1]); l>>=1;
        }
    }
    Frac qyRangeMax(int l, int r) {
        Frac ans = fcmin;
        for(l=l+M-1,r=r+M+1;l^r^1;l>>=1,r>>=1){
            if(~l&1) ans = max(ans, T[l^1]);
            if(r&1) ans = max(ans, T[r^1]);
        }
        return ans;
    }
}T;
bool del[MAX];
priority_queue<pair<Frac,int>> Q[MAX];
void add(int staId) {
    del[staId] = 0;
    Q[li[staId]].push({rt[staId], staId});
    T.uptSingleMax(li[staId], Q[li[staId]].top().first);

}
void rmv(int staId) {
    del[staId] = 1;
    int k = li[staId];
    while(!Q[k].empty() && del[Q[k].top().second]) {
        Q[k].pop();
    }
    if (Q[k].empty()) T.uptSingleMax(k, fcmin);
    else T.uptSingleMax(li[staId], Q[k].top().first);
}
void fmain(int tid) {
    scanf("%d%d", &R, &n);
    REQ(i,n) {
        q[i].rd();
        if (q[i].t == 1) {
            int x=q[i].x,y=q[i].y;
            sateCnt++;

//            if (x<=-R) lt[sateCnt] = Frac(0,1);
//            else
                lt[sateCnt] = Frac(x+R,y);

//            if (x>=R) rt[sateCnt] = Frac(inf9+1, 1);
//            else
                rt[sateCnt] = Frac(y,R-x);
            q[i].id = sateCnt;
        }
    }
    REQ(i,sateCnt) {
        mp[lt[i]]; mp[rt[i]];
    }
    for(auto &p : mp) {
        p.second = ++cnt;
    }
    REQ(i,sateCnt) {
        li[i] = mp[lt[i]];
        ri[i]=mp[rt[i]];
//        printf("%d %d\n", li[i],ri[i]);
    }
    T.init(cnt);
    REQ(i,n) {
        if (q[i].t==1) {
            add(q[i].id);
        } else if (q[i].t==2) {
            rmv(q[i].id);
        } else {
            int x=q[i].x,y=q[i].y;
            if(li[x]>li[y]) swap(x,y);
            bool ok = 0;
            if (ri[x]>=li[y]) {
                int idx = li[y];
                rmv(x); rmv(y);
//                Frac tmp = T.qyRangeMax(1, idx);
                ok = T.qyRangeMax(1, idx) < min(rt[x],rt[y]);
                add(x); add(y);
            }
            puts(ok ? "YES" : "NO");
        }
    }
}
int main() {
    int t=1;
//    scanf("%d", &t);
    REQ(i,t) {
        fmain(i);
    }
    return 0;
}

#pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")
#pragma GCC optimize("no-stack-protector")
#pragma GCC target("sse,sse2,ssse3,sse3,sse4,popcnt,avx,mmx,abm,tune=native")
#include <bits/stdc++.h>
#define DEBUG 1
using namespace std;

namespace output{
    void __(short x){cout<<x;}
    void __(unsigned x){cout<<x;}
    void __(int x){cout<<x;}
    void __(long long x){cout<<x;}
    void __(unsigned long long x){cout<<x;}
    void __(double x){cout<<x;}
    void __(long double x){cout<<x;}
    void __(char x){cout<<x;}
    void __(const char*x){cout<<x;}
    void __(const string&x){cout<<x;}
    void __(bool x){cout<<(x?"true":"false");}
    template<class S,class T>
    void __(const pair<S,T>&x){__(DEBUG?"(":""),__(x.first),__(DEBUG?", ":" "),__(x.second),__(DEBUG?")":"");}
    template<class T>
    void __(const vector<T>&x){__(DEBUG?"{":"");bool _=0;for(const auto&v:x)__(_?DEBUG?", ":" ":""),__(v),_=1;__(DEBUG?"}":"");}
    template<class T>
    void __(const set<T>&x){__(DEBUG?"{":"");bool _=0;for(const auto&v:x)__(_?DEBUG?", ":" ":""),__(v),_=1;__(DEBUG?"}":"");}
    template<class T>
    void __(const multiset<T>&x){__(DEBUG?"{":"");bool _=0;for(const auto&v:x)__(_?DEBUG?", ":" ":""),__(v),_=1;__(DEBUG?"}":"");}
    template<class S,class T>
    void __(const map<S,T>&x){__(DEBUG?"{":"");bool _=0;for(const auto&v:x)__(_?DEBUG?", ":" ":""),__(v),_=1;__(DEBUG?"}":"");}
    void pr(){cout<<"\n";}
    template<class S,class... T>
    void pr(const S&a,const T&...b){__(a);if(sizeof...(b))__(' ');pr(b...);}
}

using namespace output;

typedef long long ll;
typedef long double ld;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
typedef pair<int,char> pic;
typedef pair<double,double> pdd;
typedef pair<ld,ld> pld;
typedef vector<int> vi;
typedef vector<ll> vl;

#define pb push_back
#define fox(i,x,y) for(int i=(x);i<=(y);i++)
#define foxr(i,x,y) for(int i=(y);i>=(x);i--)
#define F first
#define S second

const int MN = 5e5+5;
const ld PI = (ld)acos((ld)-1), eps = 5e-19;
int N, R, i, j, x, y, cnt, nxt; ld st[3*MN];
map<ld,int> mp; set<ld> pnt[MN];
ld aa[MN], bb[MN];
struct qur{int t, x, y;}q[MN];

bool ok(int i,int j){
    ld x=min(aa[i],aa[j]);
    ld y=min(bb[i],bb[j]);
    return (x+y+eps>=PI/2);
}

void upd(int i,int s,int e,int ind,ld val,bool del=0){
    if(s!=e){
        if((s+e)/2<ind) upd(2*i+1,(s+e)/2+1,e,ind,val,del);
        else upd(2*i,s,(s+e)/2,ind,val,del);
        st[i]=max(st[2*i],st[2*i+1]);
    }
    else{
        if(del) pnt[s].erase(val);
        else pnt[s].insert(val);
        if(pnt[s].empty()) st[i]=0;
        else{
            auto it=pnt[s].end(); it--;
            st[i]=*it;
        }
    }
}

ld qu(int i,int s,int e,int ss,int se){
    if(s>=ss&&e<=se) return st[i];
    else if((s+e)/2<ss) return qu(2*i+1,(s+e)/2+1,e,ss,se);
    else if((s+e)/2>=se) return qu(2*i,s,(s+e)/2,ss,se);
    else return max(qu(2*i,s,(s+e)/2,ss,se),qu(2*i+1,(s+e)/2+1,e,ss,se));
}

int main(){
    scanf("%d%d",&R,&N);
    for(i=1;i<=N;i++){
        scanf("%d%d",&q[i].t,&q[i].x);
        if(q[i].t==1){
            cnt ++;
            scanf("%d",&q[i].y);
            aa[cnt] = (ld)atan2((ld)q[i].y,(ld)q[i].x+R);
            bb[cnt] = PI-(ld)atan2((ld)q[i].y,(ld)q[i].x-R);
            //printf(">>> %.20Lf %.20Lf\n",aa[cnt],bb[cnt]);
            mp[aa[cnt]]=0;
        }
        else if(q[i].t==3)
            scanf("%d",&q[i].y);
    }
    for(auto it=mp.begin();it!=mp.end();it++)
        it->second = ++nxt;
    cnt = 0;
    for(i=1;i<=N;i++){
        if(q[i].t==1){
            cnt ++;
            upd(1,1,nxt,mp[aa[cnt]],bb[cnt],0);
        }
        else if(q[i].t==2){
            upd(1,1,nxt,mp[aa[q[i].x]],bb[q[i].x],1);
        }
        else{
            x=q[i].x, y=q[i].y;
            if(!ok(x,y)) printf("NO\n");
            else{
                ld ix=min(aa[x],aa[y]);
                ld iy=min(bb[x],bb[y]);
                int inx = mp[ix];
                upd(1,1,nxt,mp[aa[x]],bb[x],1);
                upd(1,1,nxt,mp[aa[y]],bb[y],1);
                if(qu(1,1,nxt,inx,nxt)+eps>=iy) printf("NO\n");
                else printf("YES\n");
                upd(1,1,nxt,mp[aa[x]],bb[x],0);
                upd(1,1,nxt,mp[aa[y]],bb[y],0);
            }
        }
    }
    return 0;
}

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <memory.h>
#include <math.h>
#include <assert.h>
#include <stack>
#include <queue>
#include <map>
#include <set>
#include <string>
#include <algorithm>
#include <iostream>
#include <functional>
#include <unordered_set>
#include <bitset>
#include <time.h>
#include <limits.h>

using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
#define Fi first
#define Se second
#define pb(x) push_back(x)
#define szz(x) (int)x.size()
#define rep(i,n) for(int i=0;i<n;i++)
#define all(x) x.begin(),x.end()
typedef tuple<int, int, int> t3;

int R, N;
int L;
pii q[500050];
vector <t3> P;
vector <t3> query;
pii Lx[500050];

int T[1<<20]; const int ADD = 1<<19;
set <int> Sx[500050], Sy[500050];

void Ins(int x, int y) {
	Sx[x].insert(y);
	Sy[y].insert(x);
	T[x+ADD] = *Sx[x].rbegin(); x = (x + ADD) >> 1;
	while(x) T[x] = min(T[x<<1], T[x<<1|1]), x >>= 1;
}
void Del(int x, int y) {
	Sx[x].erase(y);
	Sy[y].erase(x);
	int v = (szz(Sx[x]) ? *Sx[x].rbegin() : 1e9);
	T[x+ADD] = v; x = (x + ADD) >> 1;
	while(x) T[x] = min(T[x<<1], T[x<<1|1]), x >>= 1;
}

int read_t(int l, int r) {
	l += ADD, r += ADD;
	int res = 1e9;
	while(l <= r) {
		if(l & 1) res = min(res, T[l++]);
		if(!(r & 1)) res = min(res, T[r--]);
		l >>= 1, r >>= 1;
	}
	return res;
}

int Query(int x, int y) {
	int xv = max(Lx[x].Fi, Lx[y].Fi);
	int yv = max(Lx[x].Se, Lx[y].Se);
	if(read_t(1, xv - 1) <= yv - 1) return 0;
	int cnt = 0;
	for(auto it=Sx[xv].begin();it!=Sx[xv].end();++it) {
		if(*it > yv) break;
		++cnt;
		if(cnt > 1) return 0;
	}
	cnt = 0;
	for(auto it=Sy[yv].begin();it!=Sy[yv].end();++it) {
		if(*it > xv) break;
		++cnt;
		if(cnt > 1) return 0;
	}

	pii v1, v2;
	if(Lx[x].Fi >= Lx[y].Fi) v1 = pii(q[x].Fi + R, q[x].Se);
	else v1 = pii(q[y].Fi + R, q[y].Se);
	if(Lx[x].Se >= Lx[y].Se) v2 = pii(q[x].Fi - R, q[x].Se);
	else v2 = pii(q[y].Fi - R, q[y].Se);
	if((ll)v1.Fi * v2.Fi + (ll)v1.Se * v2.Se >= 0) return 1;
	return 0;
}

int main() {
	scanf("%d%d", &R, &N);
	for(int i=1;i<=N;i++) {
		int cmd; scanf("%d", &cmd);
		if(cmd == 1) {
			int x, y; scanf("%d%d", &x, &y);
			P.pb(t3(x, y, ++L));
			q[L] = pii(x, y);
			query.pb(t3(1, L, -1));
		}
		else if(cmd == 2) {
			int x; scanf("%d", &x);
			query.pb(t3(2, x, -1));
		}
		else {
			int x, y; scanf("%d%d", &x, &y);
			query.pb(t3(3, x, y));
		}
	}
	int xz = 1, yz = 1;
	auto comp = [&](const t3 &a, const t3 &b) {
		return (ll)(get<0>(a)+R) * get<1>(b) - (ll)get<1>(a) * (get<0>(b)+R) < 0;
	};
	sort(all(P), comp);
	for(int i=0;i<szz(P);i++) {
		Lx[get<2>(P[i])].Fi = xz;
		if(i < szz(P)-1 && comp(P[i], P[i+1])) ++xz;
	}
	auto comp2 = [&](const t3 &a, const t3 &b) {
		return (ll)(get<0>(a)-R) * get<1>(b) - (ll)get<1>(a) * (get<0>(b)-R) > 0;
	};
	sort(all(P), comp2);
	for(int i=0;i<szz(P);i++) {
		Lx[get<2>(P[i])].Se = yz;
		if(i < szz(P)-1 && comp2(P[i], P[i+1])) ++yz;
	}

	rep(i, 1<<20) T[i] = 1e9;
//	for(int i=1;i<=L;i++) printf("%d %d\n", Lx[i].Fi, Lx[i].Se);

	for(t3 e : query) {
		int cmd, x, y;
		tie(cmd, x, y) = e;
		if(cmd == 1) {
			int xv = Lx[x].Fi, yv = Lx[x].Se;
			Ins(xv, yv);
		}
		else if(cmd == 2) {
			int xv = Lx[x].Fi, yv = Lx[x].Se;
			Del(xv, yv);
		}
		else {
			int v = Query(x, y);

			printf("%s\n", v ? "YES" : "NO");
		}
	}

	return 0;
}

#include<iostream>
#include<cstdlib>
#include<stdio.h>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<vector>
#include<set>
#include<map>
using namespace std;
long long r;
int n,cnt,list[501000],cnt_list;
struct segment_tree
{
	int l,r,min_vl,lazy;
};
segment_tree tree[1<<21];
struct point
{
	long long x,y;
	int z;
	bool operator <(const point &temp)const
	{
		  return y*temp.x<x*temp.y;
	}
};
point pt[1000001];
struct query
{
	int u,v,flag,id;
	long long x,y;
	point l,r;
};
query qy[501000];
void build(int left,int right,int id)
{
	int l=2*id+1,r=2*id+2,mid=(left+right)>>1;
	tree[id].min_vl=tree[id].lazy=0;
	tree[id].l=left;
	tree[id].r=right;
	if(left==right)
	    return;
    build(left,mid,l);
    build(mid+1,right,r);
}
void zz(int id)
{
	if(tree[id].lazy==0)
	    return;
	int l=2*id+1,r=2*id+2;
	if(tree[id].l!=tree[id].r)
	{
		tree[l].lazy+=tree[id].lazy;
		tree[r].lazy+=tree[id].lazy;
	}
	tree[id].min_vl+=tree[id].lazy;
	tree[id].lazy=0;
}
void update(int left,int right,int vl,int id)
{
	int l=2*id+1,r=2*id+2;
	if(tree[id].l>right||tree[id].r<left)
	{
	     zz(id);
	     return;
	}
    if(tree[id].l>=left&&tree[id].r<=right)
    {
    	tree[id].lazy+=vl;
    	zz(id);
    	return;
    }
    zz(id);
    update(left,right,vl,l);
    update(left,right,vl,r);
    tree[id].min_vl=min(tree[l].min_vl,tree[r].min_vl);
}
int qw(int left,int right,int id)
{
	int l=2*id+1,r=2*id+2;
	zz(id);
	if(tree[id].l>right||tree[id].r<left)
	    return 1e9+9;
    if(tree[id].l>=left&&tree[id].r<=right)
    	return tree[id].min_vl;
	return min(qw(left,right,l),qw(left,right,r));
}
int binary(int left,int right,point now)
{
	int mid;
	while(left<=right)
	{
		mid=(left+right)>>1;
		if(pt[mid]<now)
			left=mid+1;
		else if(now<pt[mid])
		    right=mid-1;
        else
            return mid;
	}
}
int main()
{
	scanf("%lld%d",&r,&n);
	int i,j,s,p,q,l_id,r_id;
	long long ru;
	cnt=0;
	cnt_list=0;
	for(i=0;i<n;i++)
	{
		scanf("%d",&qy[i].flag);
		if(qy[i].flag==1)
		{
			list[cnt_list++]=i;
            scanf("%lld%lld",&qy[i].x,&qy[i].y);
		   	pt[cnt].x=qy[i].y;
            pt[cnt++].y=r-qy[i].x;
			qy[i].r=pt[cnt-1];
		   	pt[cnt].x=qy[i].x+r;
            pt[cnt++].y=qy[i].y;
			qy[i].id=cnt_list-1;
		    qy[i].l=pt[cnt-1];
		    if(qy[i].r<qy[i].l)
		        swap(qy[i].l,qy[i].r);
		}
		else if(qy[i].flag==2)
        {
           scanf("%d",&qy[i].u);
           qy[i].u--;
        }
        else
        {
        	scanf("%d%d",&qy[i].u,&qy[i].v);
        	qy[i].u--;
        	qy[i].v--;
        }
	}
	sort(pt,pt+cnt);
	int nn=0;
	for(i=0;i<cnt;i++)
	{
		if(nn==0||(pt[i].x!=pt[nn-1].x||pt[i].y!=pt[nn-1].y))
		    pt[nn++]=pt[i];
	}
	cnt=nn;
	build(0,cnt-1,0);
	point ll,rr;
	for(i=0;i<n;i++)
	{
		int flag;
		if(qy[i].flag==1)
		{
		   flag=1;
		   ll=qy[i].l;
		   rr=qy[i].r;
		}
		else if(qy[i].flag==2)
		{
			flag=-1;
			ll=qy[list[qy[i].u]].l;
			rr=qy[list[qy[i].u]].r;
		}
		if(qy[i].flag==1||qy[i].flag==2)
		{
    		l_id=binary(0,cnt-1,ll);
    		r_id=binary(0,cnt-1,rr);
    	    update(l_id,r_id,flag,0);
		}
		else
		{
			int id1,id2;
			id1=qy[i].u;
			id2=qy[i].v;
		    ll=qy[list[id1]].l;
		    rr=qy[list[id1]].r;
            if(ll<qy[list[id2]].l)
               ll=qy[list[id2]].l;
            if(qy[list[id2]].r<rr)
               rr=qy[list[id2]].r;
            bool ans;
            if(rr<ll)
               ans=0;
            else
            {
            	l_id=binary(0,cnt-1,ll);
            	r_id=binary(0,cnt-1,rr);
            	ans=qw(l_id,r_id,0)<=2;
            }
            if(ans)
               puts("YES");
            else
               puts("NO");
		}
	}
	return 0;
}
/*

100000000 5
1 -106382777 300000523
1 -75340202 300000165
1 -148918484 300000552
1 96360393 300000458
3 3 2
*/