#include <bits/stdc++.h>
using namespace std;
const int INF = INT_MAX;
const signed long long int LINF = LLONG_MAX;
const double EPS = 1e-9;
const int MOD = 1000000007;
const int MAXN = 100001;
const int ALPH = 26;
const int DALPH = 52;
struct Node {
  int l, r, m;
  int minValue;
  Node *lson, *rson;
  Node(const int &al, const int &ar)
      : l(al),
        r(ar),
        m((al + ar) / 2),
        minValue(-1),
        lson(nullptr),
        rson(nullptr) {
    if (l == r) {
      return;
    }
    lson = new Node(l, m);
    rson = new Node(m + 1, r);
  }
  ~Node() {
    if (lson) {
      delete lson;
      delete rson;
    }
  }
  void set(const int &index, const int &value) {
    if (l == r) {
      minValue = value;
      return;
    }
    if (index < m + 1) {
      lson->set(index, value);
    } else {
      rson->set(index, value);
    }
    minValue = min(lson->minValue, rson->minValue);
  }
  int getMin(const int &al, const int &ar) {
    if (ar < l || r < al) {
      return INF;
    }
    if (al <= l && r <= ar) {
      return minValue;
    }
    return min(lson->getMin(al, ar), rson->getMin(al, ar));
  }
};
struct pt {
  int x, y;
  pt() {}
  pt(const int &ax, const int &ay) : x(ax), y(ay) {}
  void read() { scanf("%d %d", &x, &y); }
};
bool operator<(const pt &p1, const pt &p2) { return p1.x < p2.x; }
struct query {
  int id;
  pt p1, p2;
  bool ans;
  query() {}
  query(const int &aId, const pt &aP1, const pt &aP2)
      : id(aId), p1(aP1), p2(aP2), ans(false) {}
};
bool operator<(const query &q1, const query &q2) { return q1.p2.x < q2.p2.x; }
bool cmpid(const query &q1, const query &q2) { return q1.id < q2.id; }
int n, m, k, q;
vector<pt> rook;
vector<query> qList;
void solve() {
  sort((rook).begin(), (rook).end());
  sort((qList).begin(), (qList).end());
  Node *tree = new Node(1, m);
  int rptr = 0, qptr = 0;
  while (qptr < q) {
    while (rptr < k && rook[rptr].x <= qList[qptr].p2.x) {
      tree->set(rook[rptr].y, rook[rptr].x);
      ++rptr;
    }
    if (tree->getMin(qList[qptr].p1.y, qList[qptr].p2.y) >= qList[qptr].p1.x) {
      qList[qptr].ans = true;
    }
    ++qptr;
  }
  delete tree;
}
int main() {
  scanf("%d %d %d %d", &n, &m, &k, &q);
  rook.resize(k);
  for (int i = 0; i < k; ++i) {
    rook[i].read();
  }
  qList.resize(q);
  for (int i = 0; i < q; ++i) {
    pt p1, p2;
    p1.read();
    p2.read();
    qList[i] = query(i, p1, p2);
  }
  solve();
  for (int i = 0; i < k; ++i) {
    swap(rook[i].x, rook[i].y);
  }
  for (int i = 0; i < q; ++i) {
    swap(qList[i].p1.x, qList[i].p1.y);
    swap(qList[i].p2.x, qList[i].p2.y);
  }
  swap(n, m);
  solve();
  sort((qList).begin(), (qList).end(), cmpid);
  for (int i = 0; i < q; ++i) {
    if (qList[i].ans) {
      puts("YES");
    } else {
      puts("NO");
    }
  }
}
