#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
struct node {
  int x, y, id;
  void scan() {
    scanf("%d%d", &x, &y);
    if (x > y) swap(x, y);
  }
} e[N * 5], q[N], tmp[N], ee[N * 5];
struct opt {
  int x, y, sz, f;
  long long ans;
} op[N * 5];
int T;
int ext;
int cnt, now, tot, n, m, qu, bs, l, r, top, pos;
int ed[N], in[N], sz[N], father[N];
vector<node> v[N], g[N];
long long ret[N], ans;
bool cmpx(const node &a, const node &b) { return a.x < b.x; }
bool cmpy(const node &a, const node &b) { return a.y < b.y; }
int calc(int x) {
  int l = 1, r = m;
  if (e[1].x >= x) return 1;
  if (e[m].x < x) return m + 1;
  while (l + 1 < r) {
    int mid = (l + r) >> 1;
    if (e[mid].x >= x)
      r = mid;
    else
      l = mid + 1;
  }
  if (e[l].x >= x)
    return l;
  else
    return r;
}
int getfather(int x) { return father[x] == x ? x : getfather(father[x]); }
void solve(int x, int y) {
  int fx = getfather(x), fy = getfather(y);
  if (fx == fy) return;
  if (sz[fx] < sz[fy]) swap(fx, fy);
  ++top;
  op[top].x = fx;
  op[top].y = fy;
  op[top].sz = sz[fx];
  op[top].f = father[fy];
  op[top].ans = ans;
  father[fy] = fx;
  ans++;
  sz[fx] += sz[fy];
}
void undo() {
  for (int i(top); i >= (1); --i) {
    int fx = op[i].x, fy = op[i].y;
    father[fy] = op[i].f;
    ans = op[i].ans;
    sz[fx] = op[i].sz;
  }
}
int main() {
  scanf("%d%d", &n, &ext);
  scanf("%d", &m);
  for (int i(1); i <= (m); ++i) e[i].scan();
  scanf("%d", &qu);
  for (int i(1); i <= (qu); ++i) q[i].scan(), q[i].id = i;
  sort(e + 1, e + m + 1, cmpx);
  for (int i(1); i <= (m); ++i) ee[i] = e[i];
  memset(in, 0, sizeof in);
  for (int i(1); i <= (m); ++i) ++in[e[i].x];
  bs = (int)floor(sqrt((double)(2 * m) * (double)(log(n) / 0.4)));
  tot = 0;
  now = 0;
  memset(ed, 0, sizeof ed);
  for (int i(1); i <= (n); ++i) {
    now += in[i];
    if (now >= bs) {
      ++tot;
      ed[tot] = i;
      now = 0;
    }
  }
  if (ed[tot] != n) {
    ++tot;
    ed[tot] = n;
  }
  for (int i(1); i <= (tot); ++i) {
    l = ed[i - 1] + 1, r = ed[i];
    v[i].clear();
    g[i].clear();
    for (int j(1); j <= (m); ++j)
      if (e[j].x >= l && e[j].x <= r) v[i].push_back(e[j]);
    for (int j(1); j <= (qu); ++j)
      if (q[j].x >= l && q[j].y <= r) g[i].push_back(q[j]);
  }
  for (int et(1); et <= (tot); ++et) {
    l = ed[et - 1] + 1, r = ed[et];
    cnt = 0;
    for (int i(1); i <= (qu); ++i)
      if (q[i].x >= l && q[i].x <= r && q[i].y > r) {
        tmp[++cnt] = q[i];
      }
    sort(tmp + 1, tmp + cnt + 1, cmpy);
    for (int i(1); i <= (m); ++i) e[i] = ee[i];
    pos = calc(r + 1);
    sort(e + pos, e + m + 1, cmpy);
    for (int i(1); i <= (n); ++i) father[i] = i, sz[i] = 1;
    ans = 0;
    for (int j = pos, k = 1; k <= cnt; ++k) {
      while (e[j].y <= tmp[k].y && j <= m) {
        solve(e[j].x, e[j].y);
        ++j;
      }
      top = 0;
      for (auto edge : v[et]) {
        if (tmp[k].x <= edge.x && edge.y <= tmp[k].y) {
          solve(edge.x, edge.y);
        }
      }
      ret[tmp[k].id] = tmp[k].y - tmp[k].x + 1 - ans;
      undo();
    }
    for (int i(1); i <= (n); ++i) father[i] = i, sz[i] = 1;
    ans = 0;
    for (auto query : g[et]) {
      top = 0;
      for (auto edge : v[et]) {
        if (query.x <= edge.x && edge.y <= query.y) {
          solve(edge.x, edge.y);
        }
      }
      ret[query.id] = query.y - query.x + 1 - ans;
      undo();
    }
  }
  for (int i(1); i <= (qu); ++i) printf("%lld\n", ret[i]);
  return 0;
}
