#include <bits/stdc++.h>
using namespace std;
const int SIZE = 100000 + 1;
int tree[SIZE * 4];
const int INF = 2e9;
struct square {
  int up, down, left, right;
  int num;
};
vector<int> xxr[SIZE];
vector<int> yyr[SIZE];
vector<int> xxs[SIZE];
vector<int> yys[SIZE];
vector<square> sq;
void update(int v, int tl, int tr, int pos, int val) {
  if (tl == tr) {
    tree[v] = val;
    return;
  }
  int tm = (tl + tr) / 2;
  if (pos <= tm)
    update(v * 2, tl, tm, pos, val);
  else
    update(v * 2 + 1, tm + 1, tr, pos, val);
  tree[v] = min(tree[v * 2], tree[v * 2 + 1]);
}
int get(int v, int tl, int tr, int l, int r) {
  if (l > r) return INF;
  if (tl == l && tr == r) return tree[v];
  int tm = (tl + tr) / 2;
  return min(get(v * 2, tl, tm, l, min(tm, r)),
             get(v * 2 + 1, tm + 1, tr, max(tm + 1, l), r));
}
int main() {
  ios::sync_with_stdio(false);
  int n, m, k, q;
  cin >> n >> m >> k >> q;
  for (int i = 0; i < k; ++i) {
    int x, y;
    cin >> x >> y;
    xxr[x].push_back(y);
    yyr[y].push_back(x);
  }
  vector<char> ans(q, 2);
  for (int i = 0; i < q; ++i) {
    square a;
    cin >> a.left >> a.down >> a.right >> a.up;
    a.num = i;
    sq.push_back(a);
    xxs[a.right].push_back(i);
    yys[a.up].push_back(i);
  }
  for (int i = 1; i < SIZE; ++i) {
    for (int a : xxr[i]) update(1, 0, SIZE - 1, a, i);
    for (int j = 0; j < xxs[i].size(); ++j) {
      square cur = sq[xxs[i][j]];
      int left = get(1, 0, SIZE - 1, cur.down, cur.up);
      if (left < cur.left) ans[cur.num]--;
    }
  }
  memset(tree, 0, sizeof tree);
  for (int i = 1; i < SIZE; ++i) {
    for (int a : yyr[i]) update(1, 0, SIZE - 1, a, i);
    for (int j = 0; j < yys[i].size(); ++j) {
      square cur = sq[yys[i][j]];
      int down = get(1, 0, SIZE - 1, cur.left, cur.right);
      if (down < cur.down) ans[cur.num]--;
    }
  }
  for (int i = 0; i < q; ++i)
    if (ans[i] != 0)
      cout << "YES\n";
    else
      cout << "NO\n";
  return 0;
}
