#include using namespace std; typedef long long ll; typedef double lf; typedef long double Lf; typedef pair pii; typedef pair pll; #define TRACE(x) cerr << #x << " " << x << endl #define FOR(i, a, b) for (int i = (a); i < int(b); i++) #define REP(i, n) FOR(i, 0, n) #define all(x) (x).begin(), (x).end() #define _ << " " << #define fi first #define sec second #define mp make_pair #define pb push_back struct UF { vector p; vector rank; stack c; stack c2; void init(int n) { p.resize(n + 5); rank.resize(n + 5); REP(i, n + 1) p[i] = i; } int f(int x) { if (p[x] == x) return x; return f(p[x]); } bool spoji(int x, int y) { x = f(x); y = f(y); if (x == y) { c2.push({p.size() - 1, 0}); c.push({p.size() - 1, 0}); return false; } if (rank[x] > rank[y]) swap(x, y); c2.push({y, rank[y]}); c.push({x, p[x]}); p[x] = y; if (rank[x] == rank[y]) rank[y] ++; return true; } void odspoji() { assert(c.size() >= 0); auto par = c.top(); auto par2 = c2.top(); rank[par.first] = par.second; p[par.first] = par.second; c.pop(); c2.pop(); } } uf; const int MAXN = 1e6 + 5; int sol[MAXN]; int a[MAXN], b[MAXN]; void solve(int from, int to, int lo, int hi) { if (to <= from) return; if (lo == hi) { FOR(i, from, to) sol[i] = lo; return; } int mi = (lo + hi) >> 1; if (from >= mi) { solve(from, to, mi+1, hi); return; } int stage1 = 0; bool uspjeh = true; FOR(i, max(to, lo), mi + 1) { uspjeh &= uf.spoji(a[i], b[i]); stage1 ++; } if (!uspjeh) { REP(i, stage1) uf.odspoji(); solve(from, to, lo, mi); return; } int stage2 = 0; int pocni = min(to - 1, mi); //cout << from _ to _ lo _ hi _ pocni _ uf.c.size() << endl; assert(pocni >= from); do { stage2 ++; bool uspio = uf.spoji(a[pocni], b[pocni]); if (!uspio) { break; } pocni --; } while (pocni >= from); REP(i, stage2) uf.odspoji(); solve(pocni + 1, to, mi+1, hi); REP(i, stage1) uf.odspoji(); FOR(i, pocni + 1, min(to, lo)) uf.spoji(a[i], b[i]); solve(from, pocni + 1, lo, mi); FOR(i, pocni + 1, min(to, lo)) uf.odspoji(); } ll pref[MAXN]; int main() { int n, m; cin >> n >> m; ios_base::sync_with_stdio(false); cin.tie(0); REP(i, m) { cin >> a[i] >> b[i]; } uf.init(n); solve(0, m, 0, m); pref[0] = sol[0]; FOR(i, 1, m) pref[i] = pref[i - 1] + sol[i] - i; int q; cin >> q; while(q--) { int s, t; cin >> s >> t; s --; t --; int lo = s, hi = t + 1; while (lo < hi) { int mi = (lo + hi) >> 1; if (sol[mi] <= t) lo = mi + 1; else hi = mi; } int cnt = t - hi + 1; ll sol = (ll) cnt * (cnt + 1) / 2; if (lo) sol += pref[lo - 1]; if (s) sol -= pref[s - 1]; cout << sol << endl; } return 0; }