#include <bits/stdc++.h>
using namespace std;
const int INF = 0x3f3f3f3f;
const long long LINF = 0x3f3f3f3f3f3f3f3fll;
const long double pi = acos(-1);
const int MOD = 1e9 + 7;
const int N = 300050;
const int NN = N * 20;
int root[N], tr[NN], L[NN], R[NN], cnt = 1;
void build(int node, int b, int e) {
  tr[node] = INF;
  if (b == e) return;
  L[node] = cnt++;
  R[node] = cnt++;
  int mid = (b + e) / 2;
  if (b == e) return;
  build(L[node], b, mid);
  build(R[node], mid + 1, e);
}
int update(int node, int b, int e, int p, int val) {
  int idx = cnt++;
  tr[idx] = tr[node];
  L[idx] = L[node];
  R[idx] = R[node];
  if (b == e) {
    tr[idx] = min(tr[node], val);
  } else {
    int mid = (b + e) / 2;
    if (p <= mid)
      L[idx] = update(L[node], b, mid, p, val);
    else
      R[idx] = update(R[node], mid + 1, e, p, val);
    tr[idx] = max(tr[L[idx]], tr[R[idx]]);
  }
  return idx;
}
int query(int node, int b, int e, int i, int j) {
  if (b > j or i > e) return 0;
  if (i <= b and e <= j) {
    return tr[node];
  }
  int mid = (b + e) / 2;
  return max(query(L[node], b, mid, i, j), query(R[node], mid + 1, e, i, j));
}
vector<tuple<int, int, int>> v;
int n, m, k;
int main() {
  scanf("%d %d %d", &n, &m, &k);
  for (int i = 0; i < k; i++) {
    int l, r, p;
    scanf("%d %d %d", &l, &r, &p);
    v.push_back({l, r, p});
  }
  build(0, 1, n);
  sort(v.begin(), v.end());
  for (int i = k - 1; i >= 0; i--) {
    root[i] = update(root[i + 1], 1, n, get<2>(v[i]), get<1>(v[i]));
  }
  while (m--) {
    int a, b, x, y;
    scanf("%d %d", &a, &b);
    scanf("%d %d", &x, &y);
    tuple<int, int, int> cara = {x, -1, -1};
    int i = upper_bound(v.begin(), v.end(), cara) - v.begin();
    int c = query(root[i], 1, n, a, b);
    if (c <= y)
      puts("yes");
    else
      puts("no");
    fflush(stdout);
  }
  return 0;
}
