#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];   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);     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);       sort(e + 1, e + m + 1, cmpx);       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;   }