#include <algorithm>
#include <cmath>
#include <cstdlib>
#include <iostream>
#include <vector>
using namespace std;

#define REP(i, a, b) for(int i = (a); i < int(b); ++i)
#define rep(i, n) REP(i, 0, n)
#define ALL(x) begin(x), end(x)

////////////////////////////// geometry library //////////////////////////////

constexpr double EPS = 1e-8;

struct point {
	double x, y;
	explicit point(double x_ = 0, double y_ = 0):x(x_), y(y_) {}
	point(const point &p):x(p.x), y(p.y) {}

	inline point operator+(const point &p) const {
		return point(x + p.x, y + p.y);
	}

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

inline istream &operator>>(istream &is, point &p) {
	return is >> p.x >> p.y;
}

typedef vector<point> polygon;

struct circle {
	point c;
	double r;
	circle(const point &c_, double r_):c(c_), r(r_) {}
};

double dot(const point &a, const point &b) {
	return a.x * b.x + a.y * b.y;
}

double cross(const point &a, const point &b) {
	return a.x * b.y - a.y * b.x;
}

inline double norm(const point &p) {
	return p.x * p.x + p.y * p.y;
}

inline double abs(const point &p) {
	return sqrt(norm(p));
}

inline double angle(const point &p) {
	return atan2(p.y, p.x);
}

inline bool intersect(const circle &c, const point &p) {
	return norm(c.c - p) <= c.r * c.r;
}

inline bool intersect(const circle &a, const circle &b) {
	return abs(a.c - b.c) < a.r + b.r + EPS && abs(a.r - b.r) < abs(a.c - b.c) + EPS;
}

inline bool contain(const polygon &P, const point &p) {
	const int n = P.size();
	bool res = false;
	rep(i, n) {
		point v1 = P[i] - p, v2 = P[(i + 1) % n] - p;
		if(v1.y > v2.y) swap(v1, v2);
		if(v1.y < EPS && EPS < v2.y && cross(v1, v2) > EPS) res = !res;
		if(abs(cross(v1, v2)) < EPS && dot(v1, v2) < EPS) return true;
	}
	return res;
}

////////////////////////////// solve problem //////////////////////////////

struct edge {
	int to;
	double theta;
	bool used;
	edge(int to_, double theta_):to(to_), theta(theta_), used(false) {}

	inline bool operator<(const edge &e) const {
		return theta < e.theta;
	}
};

vector<polygon> find_faces(const vector<circle> &circles) {
	// construct plane graph
	const int n = circles.size();

	vector<vector<edge>> G(n);

	rep(i, n) {
		const auto &c1 = circles[i];
		rep(j, i) {
			const auto &c2 = circles[j];
			if(intersect(c1, c2)) {
				G[i].emplace_back(j, angle(c2.c - c1.c));
				G[j].emplace_back(i, angle(c1.c - c2.c));
			}
		}
	}

	for(auto &edges : G) sort(ALL(edges));

	// find faces
	vector<polygon> res;

	rep(i, n) {
		rep(j, G[i].size()) {
			int v = i;
			int e_idx = j;
			polygon P;

			while(true) {
				edge &e = G[v][e_idx];
				if(e.used) break;

				e.used = true;
				P.emplace_back(circles[v].c);

				rep(k, G[e.to].size()) {
					if(G[e.to][k].to == v) {
						e_idx = (k + 1) % G[e.to].size();
						v = e.to;
						break;
					}
				}
			}

			if(P.size() >= 3) res.emplace_back(move(P));
		}
	}

	return res;
}

bool can_reach(const point &a, const point &b, const vector<circle> &circles, const vector<polygon> &faces) {

	bool contained_circle = false;

	for(const auto &c : circles) {
		const bool a_in = intersect(c, a);
		const bool b_in = intersect(c, b);
		if(a_in || b_in) {
			if(a_in != b_in) return false;
			contained_circle = true;
		}
	}

	if(contained_circle) return true;

	for(const auto &face : faces) {
		if(contain(face, a) != contain(face, b)) return false;
	}
	return true;
}

int main() {
	cin.tie(nullptr);
	ios::sync_with_stdio(false);

	for(int n, m; cin >> n >> m && n;) {
		vector<circle> circles;
		circles.reserve(n);

		rep(i, n) {
			point c;
			double r;
			cin >> c >> r;
			circles.emplace_back(c, r);
		}

		const vector<polygon> faces = find_faces(circles);

		rep(i, m) {
			point p, q;
			cin >> p >> q;
			cout << (can_reach(p, q, circles, faces) ? "YES" : "NO") << (i == m - 1 ? "\n" : " ");
		}
	}

	return EXIT_SUCCESS;
}

Measured memory_bytes: 1324