#include <bits/stdc++.h>
using namespace std;
template <class S, class T>
ostream& operator<<(ostream& o, const pair<S, T>& p) {
  return o << "(" << p.first << "," << p.second << ")";
}
template <class T>
ostream& operator<<(ostream& o, const vector<T>& vc) {
  o << "sz = " << vc.size() << endl << "[";
  for (const T& v : vc) o << v << ",";
  o << "]";
  return o;
}
struct unionfind {
  int par[6];
  void init(int N) {
    for (int i = 0; i < (int)(N); i++) par[i] = i;
  }
  int find(int x) {
    if (par[x] == x) return x;
    return par[x] = find(par[x]);
  }
  bool same(int x, int y) { return find(x) == find(y); }
  void unite(int x, int y) {
    x = find(x), y = find(y);
    if (x == y) return;
    if (x > y) swap(x, y);
    par[y] = x;
  }
  friend ostream& operator<<(ostream& o, const unionfind& d) {
    o << "[";
    for (int i = 0; i < (int)(5); i++) o << d.par[i] << " ";
    o << "]";
    return o;
  }
};
struct Bell {
  vector<unionfind> UFs;
  int N;
  map<vector<int>, int> VI2id;
  queue<int> que;
  vector<int> UF2VI(unionfind UF) {
    vector<int> vi(N);
    for (int i = 0; i < (int)(N); i++) vi[i] = UF.find(i);
    return vi;
  }
  int add(unionfind UF) {
    vector<int> vi = UF2VI(UF);
    int id = UFs.size();
    VI2id[vi] = id;
    UFs.push_back(UF);
    que.push(id);
    return id;
  }
  int UF2id(unionfind UF) {
    vector<int> vi = UF2VI(UF);
    if (VI2id.count(vi)) return VI2id[vi];
    return -1;
  }
  void bfs() {
    while (!que.empty()) {
      int id = que.front();
      que.pop();
      vector<int> roots;
      for (int i = 0; i < (int)(N); i++)
        if (UFs[id].find(i) == i) roots.push_back(i);
      int K = roots.size();
      for (int i = 0; i < (int)(K); i++)
        for (int j = 0; j < (int)(i); j++) {
          unionfind UF = UFs[id];
          UF.unite(roots[i], roots[j]);
          int nid;
          if ((nid = UF2id(UF)) == -1) {
            nid = add(UF);
          }
        }
    }
  }
  int init(int N_) {
    N = N_;
    unionfind UF;
    UF.init(N);
    add(UF);
    bfs();
    return UFs.size();
  }
} bell;
const int MN = 100100;
const int B = 52;
int nxt[B][32], cost[B][32];
int bt[MN];
int lastsz[B];
const int p2 = 1 << 17;
int segnxt[1 << 18][B], segsum[1 << 18][B];
void precalc(int N) {
  bell.init(5);
  for (int id = 0; id < (int)(B); id++) {
    for (int b = 0; b < (int)(32); b++) {
      unionfind uf_prev = bell.UFs[id];
      unionfind uf;
      uf.init(6);
      for (int v = 0; v < (int)(5); v++) uf.unite(v, uf_prev.find(v));
      for (int v = 0; v < (int)(5); v++)
        if ((b >> (4 - v)) & 1) uf.unite(v, 5);
      unionfind uf_nxt;
      uf_nxt.init(5);
      for (int i = 0; i < (int)(5); i++)
        for (int j = 0; j < (int)(5); j++)
          if (uf.same(i + 1, j + 1)) uf_nxt.unite(i, j);
      int nxtid = bell.UF2id(uf_nxt);
      assert(nxtid != -1);
      nxt[id][b] = nxtid;
      cost[id][b] = 1;
      for (int v = 1; v <= (int)(5); v++)
        if (uf.same(0, v)) cost[id][b] = 0;
    }
  }
  for (int id = 0; id < (int)(B); id++) {
    unionfind uf = bell.UFs[id];
    for (int i = 0; i < (int)(5); i++)
      if (uf.find(i) == i) lastsz[id]++;
  }
  for (int i = 0; i < (int)(N - 1); i++) {
    for (int j = 0; j < (int)(B); j++) {
      segnxt[i + p2][j] = nxt[j][bt[i + 1]];
      segsum[i + p2][j] = cost[j][bt[i + 1]];
    }
  }
  for (int i = p2 - 1; i > 0; i--) {
    for (int j = 0; j < (int)(B); j++) {
      segnxt[i][j] = segnxt[i * 2 + 1][segnxt[i * 2][j]];
      segsum[i][j] = segsum[i * 2][j] + segsum[i * 2 + 1][segnxt[i * 2][j]];
    }
  }
}
int now_glb;
int sum_glb;
void calc(int a, int b, int l = 0, int r = p2, int k = 1) {
  if (b <= l || r <= a) return;
  if (a <= l && r <= b) {
    sum_glb += segsum[k][now_glb];
    now_glb = segnxt[k][now_glb];
    return;
  }
  calc(a, b, l, (l + r) / 2, k * 2);
  calc(a, b, (l + r) / 2, r, k * 2 + 1);
}
void query(int a, int b, int& now, int& sum) {
  now_glb = now;
  sum_glb = sum;
  calc(a, b);
  now = now_glb;
  sum = sum_glb;
  sum += lastsz[now];
}
int main() {
  int N, K, M, Q;
  cin >> N >> K >> M;
  for (int i = 0; i < (int)(M); i++) {
    int a, b;
    scanf("%d%d", &a, &b);
    a--, b--;
    if (a > b) swap(a, b);
    bt[b] |= (1 << (b - a - 1));
  }
  precalc(N);
  cin >> Q;
  for (int t = 0; t < (int)(Q); t++) {
    int l, r;
    scanf("%d%d", &l, &r);
    l--;
    int nowid = B - 1, csum = 0;
    if (r - l <= 5) {
      for (int x = l + 1; x < r; x++) {
        int btmask = (1 << (x - l)) - 1;
        int b = bt[x] & btmask;
        csum += cost[nowid][b];
        nowid = nxt[nowid][b];
      }
      assert(csum == 0);
      csum += lastsz[nowid];
      printf("%d\n", csum);
      continue;
    }
    for (int x = l + 1; x < l + 5; x++) {
      int btmask = (1 << (x - l)) - 1;
      int b = bt[x] & btmask;
      csum += cost[nowid][b];
      nowid = nxt[nowid][b];
    }
    int i = l + 4;
    query(i, r - 1, nowid, csum);
    printf("%d\n", csum);
  }
}
