#include <bits/stdc++.h>
using namespace std;
int n, m, k, q, i, j, x, y, g, z, tree[400005], ans[200005];
pair<int, int> a[200005];
struct que {
  int x, x1, y, y1, id;
} b[200005];
bool cmp(que u, que v) { return u.y1 < v.y1; }
void update(int l, int r, int ind) {
  if (l == r) {
    tree[ind] = y;
    return;
  }
  int mid = (l + r) / 2;
  if (x <= mid)
    update(l, mid, ind * 2);
  else
    update(mid + 1, r, ind * 2 + 1);
  tree[ind] = min(tree[ind * 2], tree[ind * 2 + 1]);
}
void query(int l, int r, int ind) {
  if (x <= l && r <= y) {
    g = min(g, tree[ind]);
    return;
  }
  int mid = (l + r) / 2;
  if (x <= mid) query(l, mid, ind * 2);
  if (y > mid) query(mid + 1, r, ind * 2 + 1);
}
int main() {
  scanf("%d%d%d%d", &n, &m, &k, &q);
  for (i = 0; i < k; i++) scanf("%d%d", &a[i].second, &a[i].first);
  for (i = 0; i < q; i++) {
    scanf("%d%d%d%d", &b[i].x, &b[i].y, &b[i].x1, &b[i].y1);
    b[i].id = i;
  }
  sort(a, a + k);
  sort(b, b + q, cmp);
  memset(tree, 0, sizeof(tree));
  int p = 0;
  for (i = 0; i < q; i++) {
    while (a[p].first <= b[i].y1 && p < k) {
      x = a[p].second;
      y = a[p].first;
      update(1, n, 1);
      p++;
    }
    g = 1000000005;
    x = b[i].x;
    y = b[i].x1;
    query(1, n, 1);
    bool flag = 0;
    if (g >= b[i].y)
      flag = 1;
    else
      flag = 0;
    ans[b[i].id] = flag;
  }
  memset(tree, 0, sizeof(tree));
  for (i = 0; i < k; i++) swap(a[i].first, a[i].second);
  for (i = 0; i < q; i++) {
    swap(b[i].x, b[i].y);
    swap(b[i].x1, b[i].y1);
  }
  sort(a, a + k);
  sort(b, b + q, cmp);
  p = 0;
  for (i = 0; i < q; i++) {
    while (a[p].first <= b[i].y1 && p < k) {
      x = a[p].second;
      y = a[p].first;
      update(1, m, 1);
      p++;
    }
    g = 1000000005;
    x = b[i].x;
    y = b[i].x1;
    query(1, m, 1);
    bool flag = 0;
    if (g >= b[i].y)
      flag = 1;
    else
      flag = 0;
    ans[b[i].id] |= flag;
  }
  for (i = 0; i < q; i++) {
    if (ans[i])
      printf("YES\n");
    else
      printf("NO\n");
  }
}
