#include <bits/stdc++.h>
using namespace std;
void read(char& a) {
  do scanf("%c", &a);
  while (isspace(a));
}
void write(const char& a) { printf("%c", a); }
char BUF[1234560];
void read(string& a) {
  scanf("%s", BUF);
  a = string(BUF);
}
void write(const string& a) { printf("%s", a.c_str()); }
void read(int& a) { scanf("%d", &a); }
void write(const int& a) { printf("%d", a); }
void read(long long& a) { scanf("%I64d", &a); }
void write(const long long& a) { printf("%I64d", a); }
void read(double& a) { scanf("%lf", &a); }
void write(const double& a) { printf("%lf", a); }
void read(long double& a) { scanf("%Lf", &a); }
void write(const long double& a) { printf("%Lf", a); }
void read(pair<int, int>& a) { scanf("%d%d", &a.first, &a.second); }
void write(const pair<int, int>& a) { printf("%d %d", a.first, a.second); }
template <template <typename T, typename A = allocator<T>> class C, class T>
void read(C<T>& a) {
  int sz = a.size();
  for (int i = 0; i < sz; ++i) read(a[i]);
}
template <template <typename T, typename A = allocator<T>> class C, class T>
void write(const C<T>& a) {
  int sz = a.size();
  if (sz != 0) write(a[0]);
  for (int i = 1; i < sz; ++i) {
    write(' ');
    write(a[i]);
  }
}
template <typename T1, typename T2>
void read(T1& t1, T2& t2) {
  read(t1);
  read(t2);
}
template <typename T1, typename T2>
void write(const T1& t1, const T2& t2) {
  write(t1);
  write(' ');
  write(t2);
}
template <typename T1, typename T2, typename T3>
void read(T1& t1, T2& t2, T3& t3) {
  read(t1);
  read(t2);
  read(t3);
}
template <typename T1, typename T2, typename T3>
void write(const T1& t1, const T2& t2, const T3& t3) {
  write(t1);
  write(' ');
  write(t2);
  write(' ');
  write(t3);
}
template <template <typename T, typename A = allocator<T>> class C, class T>
void sort(C<T>& a) {
  sort((a).begin(), (a).end());
}
template <typename T>
int sz(const T& a) {
  return int(a.size());
}
int min(vector<int>& t, int v, int tl, int tr, int l, int r) {
  if (l > r) return 1234567890;
  if (l == tl && r == tr) return t[v];
  int tm = (tl + tr) / 2;
  return min(min(t, v * 2, tl, tm, l, min(r, tm)),
             min(t, v * 2 + 1, tm + 1, tr, max(l, tm + 1), r));
}
void update(vector<int>& t, int v, int tl, int tr, int pos, int new_val) {
  if (tl == tr)
    t[v] = new_val;
  else {
    int tm = (tl + tr) / 2;
    if (pos <= tm)
      update(t, v * 2, tl, tm, pos, new_val);
    else
      update(t, v * 2 + 1, tm + 1, tr, pos, new_val);
    t[v] = min(t[v * 2], t[v * 2 + 1]);
  }
}
int main() {
  int n;
  read(n);
  ++n;
  int m;
  read(m);
  ++m;
  int k;
  read(k);
  int q;
  read(q);
  vector<pair<int, int>> a(k);
  read(a);
  vector<pair<pair<int, int>, pair<int, int>>> rect(q);
  for (auto i = ((0)); i < decltype(i)((q)); ++i)
    read(rect[i].first, rect[i].second);
  vector<string> ans(q, "NO");
  for (int t = 0; t < 2; ++t) {
    set<pair<pair<int, int>, int>> ev;
    for (auto i = ((0)); i < decltype(i)((k)); ++i)
      ev.insert({{a[i].second, 0}, i});
    for (auto i = ((0)); i < decltype(i)((q)); ++i)
      ev.insert({{rect[i].second.second, 1}, i});
    vector<int> tree(4 * n);
    while (!ev.empty()) {
      auto c = *ev.begin();
      ev.erase(ev.begin());
      if (c.first.second == 0) {
        update(tree, 1, 0, n - 1, a[c.second].first, c.first.first);
      } else {
        if (min(tree, 1, 0, n - 1, rect[c.second].first.first,
                rect[c.second].second.first) >= rect[c.second].first.second)
          ans[c.second] = "YES";
      }
    }
    for (auto i = ((0)); i < decltype(i)((k)); ++i)
      swap(a[i].first, a[i].second);
    for (auto i = ((0)); i < decltype(i)((q)); ++i) {
      swap(rect[i].first.first, rect[i].first.second);
      swap(rect[i].second.first, rect[i].second.second);
    }
    swap(n, m);
  }
  for (auto i = ((0)); i < decltype(i)((q)); ++i) write(ans[i]), write('\n');
}
