// Type.
typedef int Label;
typedef double Weight;
struct Vertex {Label label; double x, y;};
struct Edge {Label from, to; Weight weight;};
// Library.
#include<iostream>
#include<cassert>
#include<algorithm>
#include<cmath>
#include<map>
#include<queue>
#include<vector>
// Class.
template<typename Vertex, typename Edge>
class PlaneGraph {
public:
  void insert(const Vertex& v);
  void insert(Edge e);
  const std::vector<std::vector<Edge>> dualgraph(const Weight& weight = Weight()) const;
private:
  const std::vector<Edge> dualgraph_color(std::map<Label, std::map<Label, Label>>& color, const Label& c, const Edge& e, const std::map<Label, std::vector<Edge>>& edge) const;
  std::map<Label, Vertex> V;
  std::map<Label, std::vector<Edge>> E;
};
// Implement.
template<typename Vertex, typename Edge>
void PlaneGraph<Vertex, Edge>::insert(const Vertex& v) {
  V[v.label] = v;
}
template<typename Vertex, typename Edge>
void PlaneGraph<Vertex, Edge>::insert(Edge e) {
  assert(V.find(e.from) != std::end(V));
  assert(V.find(e.to) != std::end(V));
  E[e.from].push_back(e);
  std::swap(e.from, e.to);
  E[e.from].push_back(e);
}
template<typename Vertex, typename Edge>
const std::vector<std::vector<Edge>> PlaneGraph<Vertex, Edge>::dualgraph(const Weight& weight) const {
  // Sort edges counterclockwise.
  auto edge = E;
  for(auto& list: edge) if(!list.second.empty()) {
    std::sort(std::begin(list.second), std::end(list.second), [&](const Edge& lhs, const Edge& rhs) {
      double l = std::atan2(V.at(lhs.to).y - V.at(lhs.from).y, V.at(lhs.to).x - V.at(lhs.from).x);
      double r = std::atan2(V.at(rhs.to).y - V.at(rhs.from).y, V.at(rhs.to).x - V.at(rhs.from).x);
      return l < r;
    });
    list.second.push_back(list.second.front());
  }
  // Color edges.
  std::vector<std::vector<Edge>> result;
  std::map<Label, std::map<Label, Label>> color;
  Label c = Label();
  for(const auto& list: edge) for(const auto& e: list.second) if(!color[e.from].count(e.to)) {
    auto add = dualgraph_color(color, c++, e, edge);
//     if(add.size() < 3) continue;
    result.push_back(add);
  }
  return result;
}
template<typename Vertex, typename Edge>
const std::vector<Edge> PlaneGraph<Vertex, Edge>::dualgraph_color(std::map<Label, std::map<Label, Label>>& color, const Label& c, const Edge& e, const std::map<Label, std::vector<Edge>>& edge) const {
  std::vector<Edge> result = {e};
  color[e.from][e.to] = c;
  for(auto it = edge.at(e.to).rbegin(); it != edge.at(e.to).rend(); ++it) if(it->to == e.from) {
    ++it;
    if(!color[it->from].count(it->to)) {
      auto add = dualgraph_color(color, c, *it, edge);
      result.insert(std::end(result), std::begin(add), std::end(add));
    }
    break;
  }
  return result;
}
////////////////////////////////////////
// Union-Find.
#include<unordered_map>
#include<utility>
template<typename T>
class UnionFind {
public:
  void unite(const T& a, const T& b) {
    T x = find(a), y = find(b);
    if(rank_[x] < rank_[y]) std::swap(x, y);
    parent_[y] = x;
    if(rank_[x] == rank_[y]) rank_[x] += 1;
  }
  const T find(const T& x) {
    if(!parent_.count(x)) {
      rank_[x] = 1;
      return parent_[x] = x;
    }
    return (parent_[x] == x) ? x : (parent_[x] = find(parent_[x]));
  }
private:
  std::unordered_map<T, T> parent_;
  std::unordered_map<T, int> rank_;
};
////////////////////////////////////////
// Geometry.
struct Point {double x, y;};
struct Circle {double x, y, r;};
double distance(const Point& lhs, const Point& rhs) {
  return std::hypot(lhs.x - rhs.x, lhs.y - rhs.y);
}
bool include(const Circle& c, const Point& p) {
  return distance({c.x, c.y}, p) <= c.r;
}
bool intersect(const Circle& lhs, const Circle& rhs) {
  double d = distance({lhs.x, lhs.y}, {rhs.x, rhs.y});
  if(d + std::min(lhs.r, rhs.r) < std::max(lhs.r, rhs.r)) return false;
  return d <= lhs.r + rhs.r;
}
double norm(const Point& p) {return p.x * p.x + p.y * p.y;}
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;}
// 3??????????????¢???
const double INF = 1e9;
const double EPS = 1e-9;                // |EPS|???????????°???0??¨????????±???
enum POSITION {ONLINE_FRONT = -2, CLOCKWISE, ON_SEGMENT, COUNTER_CLOCKWISE, ONLINE_BACK};
POSITION ccw(const Point& a, const Point& b, const Point& p) {
  Point v1 = b;
  Point v2 = p;
  v1.x -= a.x; v1.y -= a.y;
  v2.x -= a.x; v2.y -= a.y;
  if(cross(v1, v2) >= EPS) return COUNTER_CLOCKWISE;
  if(cross(v1, v2) <= -EPS) return CLOCKWISE;
  if(dot(v1, v2) <= -EPS) return ONLINE_BACK;
  if(norm(v1) < norm(v2)) return ONLINE_FRONT;
  return ON_SEGMENT;
}
// bool intersect(const Point& s1i, const Point& s1t, const Point& s2i) {
//   Point s2t = {INF, s2i.y};
//   return ccw(s1i, s1t, s2i) * ccw(s1i, s1t, s2t) <= 0
//       && ccw(s2i, s2t, s1i) * ccw(s2i, s2t, s1t) <= 0;
// }
bool include(const std::vector<Circle>& circle, const std::vector<Edge>& edge, const Point& p) {
  bool in = false;
  for(const auto& e: edge) {
    Point a = {circle[e.from].x, circle[e.from].y};
    Point b = {circle[e.to].x, circle[e.to].y};
    a.x -= p.x; a.y -= p.y;
    b.x -= p.x; b.y -= p.y;
    if(a.y > b.y) std::swap(a, b);
    if(a.y <= 0 && 0 < b.y && cross(a, b) < 0) in = !in;
    if(std::abs(cross(a, b)) <= EPS && dot(a, b) <= EPS) return true;
  }
  return in;
}
////////////////////////////////////////
#include<bits/stdc++.h>
using namespace std;
struct Query {double sx, sy, gx, gy;};
bool check(const vector<Circle>& circle, vector<vector<Edge>>& cycle, const Query& q) {
  Point P({q.sx, q.sy}), Q({q.gx, q.gy});
  for(const auto& c: circle) if(include(c, P) != include(c, Q)) return false;
  for(const auto& list: cycle) {
    bool in = false;
    for(const auto& e: list) if(include(circle[e.from], P) || include(circle[e.from], Q)) in = true;
    if(in) continue;
    if(include(circle, list, P) != include(circle, list, Q)) return false;
  }
  return true;
}
int main() {
  int n, m;
  while(cin >> n >> m, n | m) {
    vector<Circle> circle(n);
    for(auto& c: circle) cin >> c.x >> c.y >> c.r;
    vector<Query> query(m);
    for(auto& q: query) cin >> q.sx >> q.sy >> q.gx >> q.gy;

    vector<Edge> E;
    UnionFind<int> uf;
    for(int i = 0; i < n; ++i) for(int j = i + 1; j < n; ++j) if(intersect(circle[i], circle[j])) {
      uf.unite(i, j);
      E.push_back({i, j, 1});
    }
    map<int, PlaneGraph<Vertex, Edge>> chain;
    for(int i = 0; i < n; ++i) chain[uf.find(i)].insert(Vertex{i, circle[i].x, circle[i].y});
    for(const auto& e: E) chain[uf.find(e.from)].insert(Edge({e.from, e.to, 1}));
    vector<vector<Edge>> cycle;
    for(const auto& c: chain) {
      auto add = c.second.dualgraph();
      cycle.insert(begin(cycle), begin(add), end(add));
    }

    for(int i = 0; i < m; ++i) cout << (i ? " " : "") << (check(circle, cycle, query[i]) ? "YES" : "NO");
    cout << endl;
  }
}

Measured memory_bytes: 1496