#include <bits/stdc++.h>
using namespace std;
const int M_LIM = 300000;
const int M_INF = 2000000000;
const int M_MOD = 1000000007;
const int M_MOD_B = 1000000009;
const int M_P = 31;
struct point {
  int x, y;
};
bool operator<(const point &a, const point &b) {
  return a.y < b.y || (a.y == b.y && a.x < b.x);
}
struct rect {
  point p1, p2;
  int k;
};
bool operator<(const rect &a, const rect &b) { return a.p2 < b.p2; }
struct tree_node {
  int l, r, ans;
};
int n, m, k, q;
point pts[M_LIM];
rect rects[M_LIM];
bool ans[M_LIM] = {false};
tree_node tree[2 * M_LIM] = {0};
void build_tree(int v, int l, int r) {
  tree[v].ans = 0;
  tree[v].l = l;
  tree[v].r = r;
  if (l != r) {
    build_tree(2 * v + 1, l, (l + r) / 2);
    build_tree(2 * v + 2, (l + r) / 2 + 1, r);
  }
}
void push(int v, int p, int k) {
  if (tree[v].l == p && tree[v].r == p) {
    tree[v].ans = k;
    return;
  }
  if (tree[2 * v + 1].r < p)
    push(2 * v + 2, p, k);
  else
    push(2 * v + 1, p, k);
  tree[v].ans = min(tree[2 * v + 1].ans, tree[2 * v + 2].ans);
}
int find_ans(int v, int l, int r) {
  if (tree[v].l == l && tree[v].r == r) return tree[v].ans;
  int m = tree[2 * v + 1].r;
  if (m < l)
    return find_ans(2 * v + 2, l, r);
  else if (m >= r)
    return find_ans(2 * v + 1, l, r);
  else
    return min(find_ans(2 * v + 1, l, m), find_ans(2 * v + 2, m + 1, r));
}
void fill_ans() {
  int ptr = 0;
  int tree_size = 1;
  while (tree_size < n) tree_size *= 2;
  build_tree(0, 1, tree_size);
  for (int i = 0; i < k; i++) {
    while (ptr < q && rects[ptr].p2 < pts[i]) {
      if (find_ans(0, rects[ptr].p1.x, rects[ptr].p2.x) >= rects[ptr].p1.y)
        ans[rects[ptr].k] = true;
      ptr++;
    }
    push(0, pts[i].x, pts[i].y);
  }
  while (ptr < q) {
    if (find_ans(0, rects[ptr].p1.x, rects[ptr].p2.x) >= rects[ptr].p1.y)
      ans[rects[ptr].k] = true;
    ptr++;
  }
}
int main() {
  cin >> n >> m >> k >> q;
  for (int i = 0; i < k; i++) cin >> pts[i].x >> pts[i].y;
  for (int i = 0; i < q; i++) {
    cin >> rects[i].p1.x >> rects[i].p1.y >> rects[i].p2.x >> rects[i].p2.y;
    rects[i].k = i;
  }
  sort(pts, pts + k);
  sort(rects, rects + q);
  fill_ans();
  swap(n, m);
  for (int i = 0; i < k; i++) swap(pts[i].x, pts[i].y);
  for (int i = 0; i < q; i++) {
    swap(rects[i].p1.x, rects[i].p1.y);
    swap(rects[i].p2.x, rects[i].p2.y);
  }
  sort(pts, pts + k);
  sort(rects, rects + q);
  fill_ans();
  for (int i = 0; i < q; i++)
    if (ans[i])
      cout << "YES" << endl;
    else
      cout << "NO" << endl;
  return 0;
}
