#include <bits/stdc++.h>
using namespace std;
const int OO = 1e9;
const double EPS = 1e-9;
template <class T>
void _db(const char* dbStr, T e) {
  cout << dbStr << " = " << e << endl;
}
template <class T, class... L>
void _db(const char* dbStr, T e, L... r) {
  while (*dbStr != ',') cout << *dbStr++;
  cout << " = " << e << ',';
  _db(dbStr + 1, r...);
}
template <class S, class T>
ostream& operator<<(ostream& o, const map<S, T>& v) {
  o << "[";
  int i = 0;
  for (const pair<S, T>& pr : v)
    o << (!i++ ? "" : ", ") << "{" << pr.first << " : " << pr.second << "}";
  return o << "]";
}
template <template <class, class...> class S, class T, class... L>
ostream& operator<<(ostream& o, const S<T, L...>& v) {
  o << "[";
  int i = 0;
  for (const auto& e : v) o << (!i++ ? "" : ", ") << e;
  return o << "]";
}
template <class S, class T>
ostream& operator<<(ostream& o, const pair<S, T>& pr) {
  return o << "(" << pr.first << ", " << pr.second << ")";
}
ostream& operator<<(ostream& o, const string& s) {
  for (const char& c : s) o << c;
  return o;
}
template <class T>
using V = vector<T>;
template <class T>
using VV = V<V<T>>;
template <class T>
using VVV = VV<V<T>>;
using ll = long long;
using pii = pair<int, int>;
using vi = V<int>;
using vii = V<pii>;
using vvi = VV<int>;
using mii = map<int, int>;
using umii = unordered_map<int, int>;
using si = set<int>;
using usi = unordered_set<int>;
int n, m, k, q;
vvi adj;
vi in, owned;
struct LCA {
  int n, LOGN;
  vi lvl, par, subTr;
  vvi P;
  LCA(int _n, int root) {
    n = _n;
    LOGN = log2(n) + 1;
    lvl.assign(n + 1, 0);
    subTr.assign(n + 1, 1);
    par.assign(n + 1, -1);
    P.assign(n + 1, vi(LOGN, -1));
    dfs(root, 0, -1);
    for (int i = 1; i <= n; ++i) {
      P[i][0] = par[i];
    }
    for (int j = 1; (1 << j) <= n; ++j)
      for (int i = 1; i <= n; ++i)
        if (P[i][j - 1] != -1) {
          P[i][j] = P[P[i][j - 1]][j - 1];
        }
  }
  void dfs(int u, int level, int parent) {
    lvl[u] = level, par[u] = parent;
    for (auto& v : adj[u])
      if (v != parent) dfs(v, level + 1, u), subTr[u] += subTr[v];
  }
  int query(int u, int v) {
    if (lvl[u] < lvl[v]) swap(u, v);
    int log = 1;
    while ((1 << log) <= lvl[u]) ++log;
    --log;
    for (int i = log; i >= 0; --i)
      if (lvl[u] - (1 << i) >= lvl[v]) u = P[u][i];
    if (u == v) return u;
    for (int i = log; i >= 0; --i)
      if (P[u][i] != -1 && P[u][i] != P[v][i]) u = P[u][i], v = P[v][i];
    return par[u];
  }
};
int main() {
  ios::sync_with_stdio(false);
  cout.precision(10);
  cin.tie(0);
  cin >> n >> m >> k >> q;
  adj.assign(n + 1, vi());
  in.assign(n + 1, 0);
  owned.assign(m + 1, 0);
  for (int i = 1; i <= k; ++i) {
    int a, b;
    cin >> a >> b;
    if (owned[b]) adj[owned[b]].push_back(a), ++in[a];
    owned[b] = a;
  }
  for (int i = 1; i <= n; ++i) {
    if (!in[i]) adj[0].push_back(i);
  }
  true;
  LCA lca(n, 0);
  for (int i = 1; i <= q; ++i) {
    int x, y;
    cin >> x >> y;
    int z = owned[y];
    if (!z)
      cout << "0\n";
    else {
      int w = lca.query(x, z);
      true;
      if (w == x)
        cout << lca.subTr[x] << '\n';
      else
        cout << "0\n";
    }
  }
  return 0;
}
