#include <cassert>// c
#include <ctime>
#include <iostream>// io
#include <iomanip>
#include <fstream>
#include <sstream>
#include <vector>// container
#include <map>
#include <set>
#include <queue>
#include <bitset>
#include <stack>
#include <algorithm>// other
#include <complex>
#include <numeric>
#include <functional>
#include <random>
#include <regex>

using namespace std;
typedef long long ll;

#define ALL(c) (c).begin(),(c).end()
#define FOR(i,l,r) for(int i=(int)l;i<(int)r;++i)
#define REP(i,n) FOR(i,0,n)
#define FORr(i,l,r) for(int i=(int)r-1;i>=(int)l;--i)
#define REPr(i,n) FORr(i,0,n)
#define EACH(i,c) for(__typeof((c).begin()) i=(c).begin(); i!=(c).end(); ++i)
#define IN(l,v,r) ((l)<=(v) && (v)<(r))
#define UNIQUE(v) v.erase(unique(ALL(v)),v.end())
//debug
#define DUMP(x)  cerr << #x << " = " << (x)
#define LINE()    cerr<< " (L" << __LINE__ << ")"

template<typename T,typename U> T pmod(T x,U M){return (x%M+M)%M;}

stringstream ss;

// must template
typedef long double D;
const D INF = 1e12,EPS = 1e-8;

typedef complex<D> P;
#define X real()
#define Y imag()
istream& operator >> (istream& is,complex<D>& p){ D x,y;is >> x >> y;p=P(x,y);return is; }

int sig(D a,D b=0){return a<b-EPS?-1:a>b+EPS?1:0;}
template<typename T> bool eq(const T& a,const T& b){return sig(abs(a-b))==0;}
bool compX (const P& a,const P& b){return !eq(a.X,b.X)?sig(a.X,b.X)<0:sig(a.Y,b.Y)<0;}
namespace std{
    bool operator <  (const P& a,const P& b){return compX(a,b);}
    bool operator == (const P& a,const P& b){return eq(a,b);}
};
// a×b
D cross(const P& a,const P& b){return imag(conj(a)*b);}
// a・b
D dot(const P& a,const P& b) {return real(conj(a)*b);}
int ccw(const P& a,P b,P c){
    b -= a; c -= a;
    if (cross(b,c) > EPS)   return +1;       // counter clockwise
    if (cross(b,c) < -EPS)   return -1;       // clockwise
    if (dot(b,c) < 0)     return +2;       // c--a--b on line
    if (norm(b) < norm(c)) return -2;       // a--b--c on line
    return 0; //a--c--b on line (c==b,c==a)
}
// //must template

typedef D Cost; Cost CINF=1e20;
struct Edge{
    int f,t;Cost c;D th;
    Edge(int f,int t,Cost c,D th) : f(f),t(t),c(c),th(th){};
    bool operator<(const Edge& r) const{return th<r.th;}
};
typedef vector<vector<Edge> >  Graph;

typedef vector<P> Poly,ConvexPoly;

enum { OUT, ON, IN };
int contains(const Poly& ps, const P& p) {
    bool in = false;int n=ps.size();
    REP(i,n){
        P a = ps[i] - p, b = ps[pmod(i+1,n)] - p;
        if (a.Y > b.Y) swap(a, b);
        if (a.Y <= 0 && 0 < b.Y)
        if (cross(a, b) < 0) in = !in;
            if (cross(a, b) == 0 && dot(a, b) <= 0) return ON;
    }
    return in ? IN : OUT;
}

vector<Poly> find_polys(const vector<P>& ps,Graph& g){
    const int n=g.size();
    REP(i,n)sort(ALL(g[i]));
    vector<vector<bool>> used(n); REP(i,n)used[i]=vector<bool>(g[i].size());
    vector<Poly> res;
    REP(i,n)REP(j,g[i].size()){
        int v=i,e_idx=j;
        Poly qs;
        while(true){
            if(used[v][e_idx]) break;
            used[v][e_idx] =true;
            Edge& e=g[v][e_idx];
            qs.push_back(ps[v]);
            REP(k,g[e.t].size())if(g[e.t][k].t==v){
                v=e.t;e_idx =(k+1)%g[e.t].size();
                break;
            }
        }
        if(qs.size()>=3)res.emplace_back(move(qs));
    }
    //remove ccw poly
    for(int idx=0;idx<res.size();){
        const P diff = res[idx][1] - res[idx][0], p = res[idx][0] + diff * 0.5L + diff * P(0,-1) * (2.0L * EPS /abs(diff));
        if(contains(res[idx], p)) ++idx;
        else res.erase(res.begin() + idx);
    }
    return res;
}

struct C {
    P o; D r;
    C(const P &o,D r) : o(o), r(r) { }
    C():o(P()),r(0){}
};

// 包含関係
enum RELATION{INCOMPARABLE=0,SAME=1,CONTAIN=2,OVER=4};
pair<RELATION,int> cRel(const C& c1,const C& c2){
    D d=abs(c1.o-c2.o);
    if(eq(c1.o,c2.o) && eq(c1.r,c2.r))return make_pair(SAME,1<<28);// c1 == c2
    if(sig(d,c1.r-c2.r)<0)return make_pair(OVER,0); // c2 ⊆ c1
    if(sig(d,c2.r-c1.r)<0)return make_pair(CONTAIN,0); // c1 ⊆ c2
    if(sig(d,c1.r-c2.r)==0)return make_pair(OVER,0);// c2 ⊆ c1,1点で接する
    if(sig(d,c2.r-c1.r)==0)return make_pair(CONTAIN,1);// c1 ⊆ c2,1点で接する
    if(sig(d,c1.r+c2.r)==0)return make_pair(INCOMPARABLE,1);// 1点で接する
    if(sig(d,c1.r+c2.r)<0)return make_pair(INCOMPARABLE,2);//  2点で接する
    return make_pair(INCOMPARABLE,0);// 交わらない
}
bool eq(const C& a,const C& b){return cRel(a,b).first==SAME;}


int main(){
    cin.tie(0); ios::sync_with_stdio(false);
    ss   <<fixed <<setprecision(20);
    cout <<fixed <<setprecision(20);
    cerr <<fixed <<setprecision(20);

    while(true){
        int N,M;cin >> N >> M;if(N==0 && M==0)break;
        vector<C> cs(N);REP(i,N) cin >> cs[i].o >> cs[i].r;

        REP(j,M){
            if(j!=0)cout <<" ";
            P a,b;cin >> a >> b;
            bool ok=true,inCirc=false;
            REP(i,N){
                bool ain=sig(abs(cs[i].o-a),cs[i].r)<0,bin=sig(abs(cs[i].o-b),cs[i].r)<0;
                if(ain^bin)ok=false;
                if(ain && bin)inCirc=true;
            }
            if(!inCirc){
                Graph g(N);
                REP(i,N)REP(j,N)if(i!=j)if(cRel(cs[i],cs[j])!=make_pair(INCOMPARABLE,0)){
                    g[i].emplace_back(i,j,abs(cs[j].o-cs[i].o),arg(cs[j].o-cs[i].o));
                }
                vector<P> ps(N);REP(i,N)ps[i]=cs[i].o;
                vector<Poly> pss=find_polys(ps,g);
                REP(i,pss.size()){
                    bool ain = contains(pss[i],a)==IN,bin = contains(pss[i],b)==IN;
                    if(ain^bin)ok=false;
                }
            }
            cout << (ok?"YES":"NO");
        }
        cout << endl;
    }
    return 0;
 }

Measured memory_bytes: 1320