#include <algorithm>
#include <cmath>
#include <cstdint>
#include <fstream>
#include <iomanip>
#include <iostream>
#include <limits>
#include <map>
#include <tuple>
#include <vector>
namespace lc {
struct Edge {
	int to;
	Edge() : to(0) { }
	explicit Edge(int to) : to(to) { }
};
}
namespace lc {
template <typename EdgeType>
class AdjacencyList {
public:
	typedef std::vector<EdgeType> ListType;
private:
	std::vector<ListType> m_lists;
public:
	explicit AdjacencyList(int n = 0)
		: m_lists(n)
	{ }
	template <typename... Args>
	void add_edge(int u, Args&&... args){
		m_lists[u].emplace_back(args...);
	}
	const ListType &operator[](int u) const { return m_lists[u]; }
};
}
namespace lc {
struct Point {
	double x;
	double y;
	explicit Point(const double &x = 0.0, const double &y = 0.0) :
		x(x), y(y)
	{ }
	Point operator-(const Point &p) const { return Point(x - p.x, y - p.y); }
	double abs() const { return sqrt(x * x + y * y); }
	double norm() const { return x * x + y * y; }
	double arg() const { return atan2(y, x); }
};
inline double cross(const Point &a, const Point &b){
	return a.x * b.y - a.y * b.x;
}
inline double dot(const Point &a, const Point &b){
	return a.x * b.x + a.y * b.y;
}
}
namespace lc {
struct Circle {
	Point c;
	double r;
	explicit Circle(const Point &c = Point(), double r = 0.0) :
		c(c), r(r)
	{ }
	int contains(const Point &p) const {
		const double d2 = (p - c).norm(), r2 = r * r;
		if(d2 > r2){ return 0; }
		if(d2 < r2){ return 1; }
		return -1;
	}
};
}
namespace lc {
inline bool intersect(const Circle &a, const Circle &b){
	const double d = (a.c - b.c).abs();
	return d <= a.r + b.r && a.r + d >= b.r && b.r + d >= a.r;
}
}
namespace lc {
class Polygon {
private:
	std::vector<Point> m_points;
public:
	Polygon() : m_points() { }
	explicit Polygon(size_t s, const Point &p = Point())
		: m_points(s, p)
	{ }
	template <typename Iterator>
	explicit Polygon(Iterator begin, Iterator end)
		: m_points(begin, end)
	{ }
	explicit Polygon(std::initializer_list<Point> init)
		: m_points(init)
	{ }
	int size() const { return static_cast<int>(m_points.size()); }
	double area() const {
		double s = 0.0;
		for(int i = 0; i < size(); ++i){
			s += cross(m_points[i], m_points[(i + 1) % size()]);
		}
		return s * 0.5;
	}
	int contains(const Point &p) const {
		int result = -1;
		for(int i = 0; i < size(); ++i){
			Point a = m_points[i] - p;
			Point b = m_points[(i + 1) % size()] - p;
			if(a.y > b.y){ std::swap(a, b); }
			if(a.y <= 0.0 && b.y > 0.0 && cross(a, b) < 0.0){
				result = -result;
			}
			if(cross(a, b) == 0.0 && dot(a, b) <= 0.0){ return 0; }
		}
		return result;
	}
};
}
namespace lc {
template <class EdgeType>
std::vector<Polygon> extract_polygons(
	const std::vector<Point> &points, const AdjacencyList<EdgeType> &graph)
{
	const int n = points.size();
	std::vector<std::vector<int>> next_table(n, std::vector<int>(n, -1));
	for(int i = 0; i < n; ++i){
		const int m = graph[i].size();
		std::vector<std::tuple<double, int>> args(m);
		for(int j = 0; j < m; ++j){
			const int v = graph[i][j].to;
			args[j] = std::make_tuple((points[v] - points[i]).arg(), v);
		}
		std::sort(args.begin(), args.end());
		for(int j = 0; j < m; ++j){
			const int k = std::get<1>(args[(j + 1) % m]);
			next_table[i][k] = std::get<1>(args[j]);
		}
	}
	std::vector<std::vector<bool>> done(n, std::vector<bool>(n));
	std::vector<Polygon> result;
	for(int u = 0; u < n; ++u){
		for(const auto &e : graph[u]){
			const int v = e.to;
			if(done[u][v]){ continue; }
			int cur = v, prev = u;
			std::vector<Point> buffer;
			do {
				buffer.push_back(points[cur]);
				done[prev][cur] = true;
				const int next = next_table[cur][prev];
				prev = cur;
				cur = next;
			} while(cur != v);
			const Polygon poly(buffer.begin(), buffer.end());
			if(poly.area() > 0.0){
				result.emplace_back(poly);
			}
		}
	}
	return result;
}
}
using namespace std;
typedef lc::Edge Edge;
int main(){
	ios_base::sync_with_stdio(false);
	while(true){
		int n, m;
		cin >> n >> m;
		if(n == 0 && m == 0){ break; }
		vector<lc::Point> points(n);
		vector<lc::Circle> circles(n);
		for(int i = 0; i < n; ++i){
			double x, y, r;
			cin >> x >> y >> r;
			points[i] = lc::Point(x, y);
			circles[i] = lc::Circle(points[i], r);
		}
		lc::AdjacencyList<Edge> graph(n);
		for(int i = 0; i < n; ++i){
			for(int j = i + 1; j < n; ++j){
				if(lc::intersect(circles[i], circles[j])){
					graph.add_edge(i, j);
					graph.add_edge(j, i);
				}
			}
		}
		const vector<lc::Polygon> polygons =
			lc::extract_polygons(points, graph);
		const int k = polygons.size();
		for(int i = 0; i < m; ++i){
			if(i != 0){ cout << " "; }
			lc::Point a, b;
			cin >> a.x >> a.y >> b.x >> b.y;
			vector<bool> a_circle(n), b_circle(n);
			bool in_circle = false;
			for(int j = 0; j < n; ++j){
				a_circle[j] = circles[j].contains(a);
				b_circle[j] = circles[j].contains(b);
				if(a_circle[j] || b_circle[j]){ in_circle = true; }
			}
			if(in_circle){
				cout << (a_circle == b_circle ? "YES" : "NO");
				continue;
			}
			vector<bool> a_poly(k), b_poly(k);
			for(int j = 0; j < k; ++j){
				a_poly[j] = (polygons[j].contains(a) >= 0);
				b_poly[j] = (polygons[j].contains(b) >= 0);
			}
			cout << (a_poly == b_poly ? "YES" : "NO");
		}
		cout << endl;
	}
	return 0;
}

Measured memory_bytes: 1420