#include using namespace std; #include #include using namespace __gnu_pbds; template using ordered_set = tree, rb_tree_tag, tree_order_statistics_node_update>; template using ordered_map = tree, rb_tree_tag, tree_order_statistics_node_update>; typedef long long ll; typedef long double ld; typedef pair pii; typedef pair pll; typedef vector vi; typedef vector vll; #define FOR(i,j,k,in) for(int i=(j); i < (k);i+=in) #define FORD(i,j,k,in) for(int i=(j); i >=(k);i-=in) #define REP(i,b) FOR(i,0,b,1) #define REPD(i,b) FORD(i,b,0,1) #define pb push_back #define mp make_pair #define ff first #define ss second #define all(x) begin(x), end(x) #define MANY_TESTS int tcase; cin >> tcase; while(tcase--) const double EPS = 1e-9; const int MOD = 1e9+7; const ll INFF = 1e18; const int INF = 1e9; const ld PI = acos((ld)-1); const vi dy = {1, 0, -1, 0, -1, 1, 1, -1}; const vi dx = {0, 1, 0, -1, -1, 1, -1, 1}; void DBG(){cout << "]" << endl;} template void DBG(const T& head, const U... args){ cout << head << "; "; DBG(args...); } #define dbg(...) cout << "Line(" << __LINE__ << ") -> [" << #__VA_ARGS__ << "]: [", DBG(__VA_ARGS__); #define chk() cout << "Check at line(" << __LINE__ << ") hit." << endl; template ostream& operator<<(ostream& out, const array &v){out << "["; REP(i, U) out << v[i] << ", "; out << "]"; return out;} template ostream& operator<<(ostream& out, const pair &par) {out << "[" << par.first << ";" << par.second << "]"; return out;} template ostream& operator<<(ostream& out, const set &cont) { out << "{"; for( const auto &x:cont) out << x << ", "; out << "}"; return out; } template ostream& operator<<(ostream& out, const map &cont) {out << "{"; for( const auto &x:cont) out << x << ", "; out << "}"; return out; } template ostream& operator<<(ostream& out, const vector &v){ out << "["; REP(i, v.size()) out << v[i] << ", "; out << "]"; return out;} template istream& operator>>(istream& in, vector &v){ for(auto &x : v) in >> x; return in; } mt19937 rng(chrono::steady_clock::now().time_since_epoch().count()); // https://github.com/kth-competitive-programming/kactl/blob/main/content/graph/LinkCutTree.h struct Node { // Splay tree. Root's pp contains tree's parent. Node *p = 0, *pp = 0, *c[2]; bool flip = 0; Node() { c[0] = c[1] = 0; fix(); } void fix() { if (c[0]) c[0]->p = this; if (c[1]) c[1]->p = this; // (+ update sum of subtree elements etc. if wanted) } void pushFlip() { if (!flip) return; flip = 0; swap(c[0], c[1]); if (c[0]) c[0]->flip ^= 1; if (c[1]) c[1]->flip ^= 1; } int up() { return p ? p->c[1] == this : -1; } void rot(int i, int b) { int h = i ^ b; Node *x = c[i], *y = b == 2 ? x : x->c[h], *z = b ? y : x; if ((y->p = p)) p->c[up()] = y; c[i] = z->c[i ^ 1]; if (b < 2) { x->c[h] = y->c[h ^ 1]; z->c[h ^ 1] = b ? x : this; } y->c[i ^ 1] = b ? this : x; fix(); x->fix(); y->fix(); if (p) p->fix(); swap(pp, y->pp); } void splay() { /// Splay this up to the root. Always finishes without flip set. for (pushFlip(); p; ) { if (p->p) p->p->pushFlip(); p->pushFlip(); pushFlip(); int c1 = up(), c2 = p->up(); if (c2 == -1) p->rot(c1, 2); else p->p->rot(c2, c1 != c2); } } Node* first() { /// Return the min element of the subtree rooted at this, splayed to the top. pushFlip(); return c[0] ? c[0]->first() : (splay(), this); } }; struct LinkCut { vector node; LinkCut(int N) : node(N) {} void link(int u, int v) { // add an edge (u, v) assert(!connected(u, v)); makeRoot(&node[u]); node[u].pp = &node[v]; } void cut(int u, int v) { // remove an edge (u, v) Node *x = &node[u], *top = &node[v]; makeRoot(top); x->splay(); assert(top == (x->pp ?: x->c[0])); if (x->pp) x->pp = 0; else { x->c[0] = top->p = 0; x->fix(); } } bool connected(int u, int v) { // are u, v in the same tree? Node* nu = access(&node[u])->first(); return nu == access(&node[v])->first(); } void makeRoot(Node* u) { /// Move u to root of represented tree. access(u); u->splay(); if(u->c[0]) { u->c[0]->p = 0; u->c[0]->flip ^= 1; u->c[0]->pp = u; u->c[0] = 0; u->fix(); } } Node* access(Node* u) { /// Move u to root aux tree. Return the root of the root aux tree. u->splay(); while (Node* pp = u->pp) { pp->splay(); u->pp = 0; if (pp->c[1]) { pp->c[1]->p = 0; pp->c[1]->pp = pp; } pp->c[1] = u; pp->fix(); u = pp; } return u; } }; int main(){ ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL); int n, m; cin >> n >> m; vector> edges; REP(i, m){ int u, v; cin >> u >> v; u--; v--; edges.pb({u, v}); } LinkCut lc(n); int pp = 0; vector r(m); REP(i, m){ while(pp < m && !lc.connected(edges[pp][0], edges[pp][1])){ lc.link(edges[pp][0], edges[pp][1]); pp++; } lc.cut(edges[i][0], edges[i][1]); r[i] = pp - 1; } vector ps(m + 1, 0); FOR(i, 1, m + 1, 1){ ps[i] += ps[i - 1]; ps[i] += (r[i - 1] - i + 2); } int q; cin >> q; REP(i, q){ int s, t; cin >> s >> t; s--; ll ans = 0; int id = lower_bound(all(r), t) - r.begin(); id = max(id, s); if(id < t){ ll diff = t - id; ll su = (diff * (diff + 1)) / 2; ans += su; } ans += ps[id] - ps[s]; cout << ans << "\n"; } return 0; }