#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

// 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<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]);
        }
    }
}

#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 <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);
		}
	}
}

#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 <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);
		}
	}
}

//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>
//#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 <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);
		}
	}
}

#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
*/

#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<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;
}

#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
*/

#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;

}

#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;
}

/*
 * 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 <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 <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 <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;
}

#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>
#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
*/