#include <bits/stdc++.h>
using namespace std;
template <typename T>
T gcd(T first, T second) {
  while (second > 0) {
    first %= second;
    swap(first, second);
  }
  return first;
}
template <class _T>
inline _T sqr(const _T &first) {
  return first * first;
}
template <class _T>
inline string tostr(const _T &a) {
  ostringstream os("");
  os << a;
  return os.str();
}
const long double PI = 3.1415926535897932384626433832795L;
template <typename T>
inline void input(T &a) {
  static int c;
  a = 0;
  while (!isdigit(c = getchar()) && c != '-') {
  }
  char neg = 0;
  if (c == '-') {
    neg = 1;
    c = getchar();
  }
  while (isdigit(c)) {
    a = 10 * a + c - '0';
    c = getchar();
  }
  if (neg) a = -a;
}
template <typename T = int>
inline T nxt() {
  T res;
  input(res);
  return res;
}
inline string next12345() {
  static int c;
  string res;
  while (isspace(c = getchar())) {
  }
  while (!isspace(c)) {
    res = res + (char)c;
    c = getchar();
  }
  return res;
}
const int MAXMEM = 1e8;
char buf[MAXMEM];
char *cur = buf;
void *operator new(size_t n) {
  char *res = cur;
  cur += n;
  assert(cur - buf <= MAXMEM);
  return res;
}
void operator delete(void *first) {}
struct node {
  int value;
  node *l, *r;
  node(int value) : value(value), l(0), r(0) {}
  node(node *l, node *r) : l(l), r(r) { value = min(l->value, r->value); }
};
int get(node *v, int tl, int tr, int l, int r) {
  if (l > r) {
    return INT_MAX;
  }
  if (tl == l && tr == r) {
    return v->value;
  }
  int tm = (tl + tr) / 2;
  return min(get(v->l, tl, tm, l, min(r, tm)),
             get(v->r, tm + 1, tr, max(tm + 1, l), r));
}
node *update(node *v, int tl, int tr, int pos, int value) {
  if (tl == tr) {
    return new node(value);
  }
  int tm = (tl + tr) / 2;
  if (pos <= tm) {
    return new node(update(v->l, tl, tm, pos, value), v->r);
  } else {
    return new node(v->l, update(v->r, tm + 1, tr, pos, value));
  }
}
node *init(int tl, int tr) {
  if (tl == tr) {
    return new node(INT_MIN);
  }
  int tm = (tl + tr) / 2;
  return new node(init(tl, tm), init(tm + 1, tr));
}
int main() {
  int n = nxt(), m = nxt(), k = nxt(), q = nxt();
  pair<int, int> a[k];
  for (int i = 0; i < k; ++i) {
    a[i].first = nxt();
    a[i].second = nxt();
  }
  node *byX[n + 1];
  byX[0] = init(1, m);
  node *byY[m + 1];
  byY[0] = init(1, n);
  sort(a, a + k,
       [&](pair<int, int> u, pair<int, int> v) { return u.first < v.first; });
  for (int i = 1, j = 0; i <= n; ++i) {
    byX[i] = byX[i - 1];
    while (j < k && a[j].first == i) {
      byX[i] = update(byX[i], 1, m, a[j++].second, i);
    }
  }
  sort(a, a + k,
       [&](pair<int, int> u, pair<int, int> v) { return u.second < v.second; });
  for (int i = 1, j = 0; i <= m; ++i) {
    byY[i] = byY[i - 1];
    while (j < k && a[j].second == i) {
      byY[i] = update(byY[i], 1, n, a[j++].first, i);
    }
  }
  while (q--) {
    int x12345 = nxt(), y12345 = nxt();
    int x2 = nxt(), y2 = nxt();
    char ok = false;
    ok |= get(byX[x2], 1, m, y12345, y2) >= x12345;
    ok |= get(byY[y2], 1, n, x12345, x2) >= y12345;
    puts(ok ? "YES" : "NO");
  }
  return 0;
}
