#include <bits/stdc++.h>
using namespace std;
const int INF = int(2e9);
class segment_tree {
 private:
  vector<int> ST;
  vector<set<int> > A;
  int n;
  void build(int node, int l, int r) {
    if (l == r - 1) {
      ST[node] = *A[l].begin();
      return;
    }
    int leftChild = node << 1;
    int rightChild = leftChild | 1;
    int mid = (l + r) >> 1;
    build(leftChild, l, mid);
    build(rightChild, mid, r);
    ST[node] = max(ST[leftChild], ST[rightChild]);
  }
  int range_query(int L, int R, int node, int l, int r) {
    if (l >= R || r <= L) return -INF;
    int leftChild = node << 1;
    int rightChild = leftChild | 1;
    if (L <= l && r <= R) return ST[node];
    int mid = (l + r) >> 1;
    int leftAns = range_query(L, R, leftChild, l, mid);
    int rightAns = range_query(L, R, rightChild, mid, r);
    return max(leftAns, rightAns);
  }
  void point_update(int pos, int node, int l, int r) {
    if (r <= pos || l > pos) return;
    if (l == r - 1 && l == pos) {
      A[l].erase(A[l].begin());
      ST[node] = *A[l].begin();
      return;
    }
    int leftChild = node << 1;
    int rightChild = leftChild | 1;
    int mid = (l + r) >> 1;
    point_update(pos, leftChild, l, mid);
    point_update(pos, rightChild, mid, r);
    ST[node] = max(ST[leftChild], ST[rightChild]);
  }

 public:
  segment_tree() {
    ST.clear();
    A.clear();
    n = 0;
  }
  segment_tree(vector<pair<int, int> >& R, int m) {
    n = m + 1;
    A = vector<set<int> >(m + 1);
    for (int i = 0; i < n; i++) A[i].insert(INF);
    for (int i = 0; i < (int)(R.size()); i++) A[R[i].second].insert(R[i].first);
    ST = vector<int>(4 * n, 0);
    build(1, 0, n);
  }
  int query(int L, int R) { return range_query(L, R, 1, 0, n); }
  void point_update(int pos) { point_update(pos, 1, 0, n); }
};
const int N = (2e5) + 10;
int n, m, k, q;
vector<pair<int, int> > R;
vector<pair<pair<pair<int, int>, pair<int, int> >, int> > Q;
bool ans[N];
void checkX() {
  segment_tree second(R, m);
  sort(R.begin(), R.end());
  sort(Q.begin(), Q.end());
  for (int i = 0, j = 0; i < q; i++) {
    int x1 = Q[i].first.first.first, y1 = Q[i].first.first.second;
    int x2 = Q[i].first.second.first, y2 = Q[i].first.second.second;
    int pos = Q[i].second;
    while (R[j].first < x1 && j < (int)(R.size())) {
      second.point_update(R[j].second);
      j++;
    }
    int mx = second.query(y1, y2 + 1);
    if (mx <= x2) ans[pos] |= true;
  }
}
void rotateBoard() {
  swap(n, m);
  for (int i = 0; i < (int)(R.size()); i++) swap(R[i].first, R[i].second);
  for (int i = 0; i < q; i++) {
    swap(Q[i].first.first.first, Q[i].first.first.second);
    swap(Q[i].first.second.first, Q[i].first.second.second);
  }
}
int main() {
  scanf("%d", &n);
  scanf("%d", &m);
  scanf("%d", &k);
  scanf("%d", &q);
  R = vector<pair<int, int> >(k);
  for (int i = 0; i < k; i++)
    scanf("%d", &R[i].first), scanf("%d", &R[i].second);
  Q = vector<pair<pair<pair<int, int>, pair<int, int> >, int> >(q);
  for (int i = 0; i < q; i++) {
    scanf("%d", &Q[i].first.first.first);
    scanf("%d", &Q[i].first.first.second);
    scanf("%d", &Q[i].first.second.first);
    scanf("%d", &Q[i].first.second.second);
    Q[i].second = i;
    ans[i] = false;
  }
  checkX();
  rotateBoard();
  checkX();
  for (int i = 0; i < q; i++) printf("%s\n", ans[i] ? "YES" : "NO");
  return 0;
}
