#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
const int INF = 1e9 + 7;
struct segTree {
  int val, lazy;
} tree[3 * N];
segTree merge(segTree a, segTree b) {
  segTree ret;
  ret.val = min(a.val, b.val);
  return ret;
}
void push(int node, int a, int b) {
  if (a != b) {
  }
  tree[node].lazy = 0;
  return;
}
void update(int node, int a, int b, int i, int j, int val) {
  int mid = (a + b) / 2;
  if (a > b || a > j || b < i || i > j) return;
  if (a >= i && b <= j) {
    tree[node].val = val;
    return;
  }
  update(2 * node, a, mid, i, j, val);
  update(2 * node + 1, mid + 1, b, i, j, val);
  tree[node] = merge(tree[2 * node], tree[2 * node + 1]);
}
void updatep(int node, int l, int r, int i, int val) {
  if (l == r) {
    tree[node].val = val;
    return;
  }
  int mid = (l + r) / 2;
  if (i <= mid)
    updatep(2 * node, l, mid, i, val);
  else
    updatep(2 * node + 1, mid + 1, r, i, val);
  tree[node] = merge(tree[2 * node], tree[2 * node + 1]);
  return;
}
segTree query(int node, int a, int b, int i, int j) {
  if (i <= a && j >= b) return tree[node];
  int mid = (a + b) / 2;
  if (j <= mid)
    return query(2 * node, a, mid, i, j);
  else if (i > mid) {
    return query(2 * node + 1, mid + 1, b, i, j);
  } else {
    return merge(query(2 * node, a, mid, i, j),
                 query(2 * node + 1, mid + 1, b, i, j));
  }
}
vector<pair<pair<int, int>, pair<int, int> > > qx[N], qy[N];
vector<int> posx[N], posy[N];
int ans[2 * N];
int main() {
  ios::sync_with_stdio(false);
  cin.tie(nullptr);
  int n, m, k, q;
  cin >> n >> m >> k >> q;
  for (int i = (0); i < (k); i++) {
    int x, y;
    cin >> x >> y;
    --x;
    --y;
    posx[x].push_back(y);
    posy[y].push_back(x);
  }
  for (int i = (0); i < (q); i++) {
    int x1, x2, y1, y2;
    cin >> x1 >> y1 >> x2 >> y2;
    --x1;
    --y1;
    --x2;
    --y2;
    qx[y2].push_back(make_pair(make_pair(x1, x2), make_pair(y1, i)));
    qy[x2].push_back(make_pair(make_pair(y1, y2), make_pair(x1, i)));
  }
  for (int i = (0); i < (3 * N); i++) tree[i].val = -1;
  for (int i = (0); i < (m); i++) {
    for (int j = (0); j < (posy[i].size()); j++) {
      updatep(1, 0, n - 1, posy[i][j], i);
    }
    for (int j = (0); j < (qx[i].size()); j++) {
      int x1 = qx[i][j].first.first, x2 = qx[i][j].first.second,
          y1 = qx[i][j].second.first;
      if (query(1, 0, n - 1, x1, x2).val >= y1) {
        ans[qx[i][j].second.second] = 1;
      }
    }
  }
  for (int i = (0); i < (3 * N); i++) tree[i].val = -1;
  for (int i = (0); i < (n); i++) {
    for (int j = (0); j < (posx[i].size()); j++) {
      updatep(1, 0, m - 1, posx[i][j], i);
    }
    for (int j = (0); j < (qy[i].size()); j++) {
      int y1 = qy[i][j].first.first, y2 = qy[i][j].first.second,
          x1 = qy[i][j].second.first;
      if (query(1, 0, m - 1, y1, y2).val >= x1) {
        ans[qy[i][j].second.second] = 1;
      }
    }
  }
  for (int i = (0); i < (q); i++) {
    if (ans[i])
      cout << "YES\n";
    else
      cout << "NO\n";
  }
  return 0;
}
