#include <bits/stdc++.h>
using namespace std;
inline int read() {
  int x = 0, f = 1;
  char ch = getchar();
  while (ch < '0' || ch > '9') {
    if (ch == '-') f = -1;
    ch = getchar();
  }
  while (ch >= '0' && ch <= '9') x = x * 10 + ch - '0', ch = getchar();
  return x * f;
}
int n, K, m, tr[100010 + 500010][2], val[100010 + 500010], fa[100010 + 500010],
    minn[100010 + 500010], ans[100010], cc[100010], st[100010];
bool tag[100010 + 500010];
struct Edge {
  int u, v;
} edge[500010];
inline bool cmp(Edge a, Edge b) { return a.v < b.v; }
struct Q {
  int l, r, id;
  friend bool operator<(Q a, Q b) { return a.r < b.r; }
} que[100010];
namespace SGT {
int a[100005];
void add(int x, int v) {
  while (x <= n) a[x] += v, x += x & -x;
}
int query(int x) {
  int ret = 0;
  while (x) ret += a[x], x -= x & -x;
  return ret;
}
}  // namespace SGT
namespace LCT {
int fa[600005], tr[600005][2], minn[600005], st[600005], tag[600005];
bool nroot(int x) { return tr[fa[x]][0] == x || tr[fa[x]][1] == x; }
int getson(int x) { return tr[fa[x]][1] == x; }
void pushup(int x) {
  minn[x] = x;
  if (val[minn[tr[x][0]]] < val[minn[x]]) minn[x] = minn[tr[x][0]];
  if (val[minn[tr[x][1]]] < val[minn[x]]) minn[x] = minn[tr[x][1]];
}
void pushdown(int x) {
  if (tag[x]) {
    swap(tr[x][0], tr[x][1]);
    if (tr[x][0]) tag[tr[x][0]] ^= 1;
    if (tr[x][1]) tag[tr[x][1]] ^= 1;
    tag[x] = 0;
  }
}
void rotate(int x) {
  int y = fa[x], z = fa[y], b = getson(x), c = getson(y), a = tr[x][!b];
  if (nroot(y)) tr[z][c] = x;
  fa[x] = z, tr[x][!b] = y, fa[y] = x, tr[y][b] = a;
  if (a) fa[a] = y;
  pushup(y), pushup(x);
}
void splay(int x) {
  int top = 0;
  st[++top] = x;
  for (int i = x; nroot(i); i = fa[i]) st[++top] = fa[i];
  while (top) pushdown(st[top--]);
  while (nroot(x)) {
    int y = fa[x];
    if (nroot(y))
      if (getson(x) == getson(y))
        rotate(y);
      else
        rotate(x);
    rotate(x);
  }
}
void access(int x) {
  for (int y = 0; x; x = fa[y = x]) splay(x), tr[x][1] = y, pushup(x);
}
int findroot(int x) {
  access(x), splay(x);
  while (tr[x][0]) x = tr[x][0];
  return x;
}
void makeroot(int x) { access(x), splay(x), tag[x] ^= 1; }
void split(int x, int y) { makeroot(x), access(y), splay(y); }
void link(int x, int y) { split(x, y), fa[x] = y, pushup(y); }
void cut(int x, int y) { split(x, y), fa[x] = tr[y][0] = 0; }
void insert(int x) {
  int u = edge[x].u, v = edge[x].v;
  if (findroot(u) != findroot(v)) {
    link(u, n + x), link(n + x, v), SGT::add(n - u + 1, 1);
    return;
  }
  split(u, v);
  int w = minn[v];
  if (val[w] >= val[x + n]) return;
  cut(w, edge[w - n].u), cut(w, edge[w - n].v), SGT::add(n - val[w] + 1, -1),
      link(u, n + x), link(n + x, v), SGT::add(n - u + 1, 1);
}
}  // namespace LCT
int main() {
  n = read();
  K = read();
  m = read();
  val[0] = 0x7f7f7f7f;
  for (int i = 1; i <= m; ++i) {
    edge[i].u = read();
    edge[i].v = read();
    if (edge[i].u > edge[i].v) swap(edge[i].u, edge[i].v);
  }
  sort(edge + 1, edge + m + 1, cmp);
  int q = read();
  for (int i = 1; i <= m; ++i) val[i + n] = edge[i].u;
  for (int i = 1; i <= n; ++i) val[i] = 0x7f7f7f7f;
  for (int i = 1; i <= q; ++i)
    que[i].l = read(), que[i].r = read(), que[i].id = i;
  sort(que + 1, que + q + 1);
  int pos = 1;
  for (int i = 1; i <= q; ++i) {
    while (pos <= m && edge[pos].v <= que[i].r) LCT::insert(pos), ++pos;
    ans[que[i].id] = que[i].r - que[i].l + 1 - SGT::query(n - que[i].l + 1);
  }
  for (int i = 1; i <= q; ++i) printf("%d\n", ans[i]);
  return 0;
}
