#include <bits/stdc++.h>
using namespace std;
const int MAXN = 3e5 + 10;
struct Query {
  int l, r;
  int id;
  void read(int i) {
    id = i;
    scanf("%d%d", &l, &r);
    --l;
    --r;
  }
};
struct Edge {
  int a, b;
  int id;
  void read(int i) {
    id = i;
    scanf("%d%d", &a, &b);
    --a;
    --b;
  }
  int to(int v) const {
    assert(v == a || v == b);
    return (a ^ b) ^ v;
  }
};
int n, m;
vector<Edge> g[MAXN];
vector<Query> qs;
vector<Edge> es;
bool read() {
  if (scanf("%d%d", &n, &m) < 2) {
    return 0;
  }
  for (int i = 0; i < int(n); ++i) {
    g[i].clear();
  }
  es.resize(m);
  for (int i = 0; i < int(m); ++i) {
    es[i].read(i);
  }
  for (const auto& e : es) {
    g[e.a].push_back(e);
    g[e.b].push_back(e);
  }
  int q;
  scanf("%d", &q);
  qs.resize(q);
  for (int i = 0; i < int(q); ++i) {
    qs[i].read(i);
  }
  return 1;
}
void dfs(int v, int prev_________________, vector<int>& st, vector<int>& col,
         vector<vector<int>>& cycles) {
  col[v] = 1;
  st.push_back(v);
  for (const auto& e : g[v]) {
    int to = e.to(v);
    if (to == prev_________________) {
      continue;
    }
    if (col[to] == 1) {
      vector<int> cycle;
      for (int i = ((int)(st).size()) - 1; i >= 0 && st[i] != to; --i) {
        cycle.push_back(st[i]);
      }
      cycle.push_back(to);
      cycles.push_back(cycle);
    } else if (col[to] == 0) {
      dfs(to, v, st, col, cycles);
    }
  }
  assert(st.back() == v);
  st.pop_back();
  col[v] = 2;
}
struct FenwTree {
  vector<long long> t;
  FenwTree(int n = 0) { t.assign(n, 0); }
  long long get(int r) {
    long long ans = 0;
    for (int i = r; i >= 0; i &= i + 1, --i) {
      ans += t[i];
    }
    return ans;
  }
  long long get(int l, int r) { return get(r) - get(l - 1); }
  void upd(int pos, long long val) {
    for (int i = pos; i < ((int)(t).size()); i |= i + 1) {
      t[i] += val;
    }
  }
};
void solve() {
  vector<vector<int>> cycles;
  vector<int> col(n, 0);
  vector<int> st;
  for (int v = 0; v < int(n); ++v) {
    if (col[v] == 0) {
      dfs(v, -1, st, col, cycles);
    }
  }
  vector<int> cnt_cycle(((int)(cycles).size()));
  vector<int> id_cycle(n, -1);
  for (int i = 0; i < int(((int)(cycles).size())); ++i) {
    for (int v : cycles[i]) {
      id_cycle[v] = i;
    }
  }
  {
    ;
    ;
    for (const auto& cycle : cycles) {
      for (const auto& v : cycle) {
        ;
        ;
      };
      ;
    };
    ;
  }
  vector<int> next_________________(n);
  int r = 0;
  for (int l = 0; l < int(n); ++l) {
    while (r < n) {
      const int c = id_cycle[r];
      if (c == -1) {
        ++r;
        continue;
      }
      if (cnt_cycle[c] + 1 == ((int)(cycles[c]).size())) {
        break;
      }
      ++cnt_cycle[c];
      ++r;
    }
    next_________________[l] = r - 1;
    {
      const int c = id_cycle[l];
      if (c != -1) {
        assert(cnt_cycle[c] > 0);
        --cnt_cycle[c];
      }
    }
  }
  {
    ;
    ;
    for (int v = 0; v < int(n); ++v) {
      ;
      ;
    };
    ;
  }
  vector<long long> ans(((int)(qs).size()), 0);
  vector<vector<int>> who_next(n);
  for (int i = 0; i < int(n); ++i) {
    who_next[next_________________[i]].push_back(i);
  }
  vector<vector<Query>> who_qs_r(n);
  for (const auto& q : qs) {
    who_qs_r[q.r].push_back(q);
  }
  {
    FenwTree T(n);
    for (int r = 0; r < int(n); ++r) {
      for (int i : who_next[r]) {
        T.upd(i, r - i + 1);
      }
      for (const auto& q : who_qs_r[r]) {
        ans[q.id] += T.get(q.l, q.r);
      }
    }
  }
  {
    FenwTree sum(n);
    FenwTree cnt(n);
    for (int r = int(n) - 1; r >= 0; --r) {
      for (const auto& q : who_qs_r[r]) {
        long long cur = -sum.get(q.l, q.r);
        cur += (r + 1) * cnt.get(q.l, q.r);
        ans[q.id] += cur;
      }
      for (int i : who_next[r]) {
        sum.upd(i, i);
        cnt.upd(i, +1);
      }
    }
  }
  for (int i = 0; i < int(((int)(qs).size())); ++i) {
    printf("%lld\n", ans[i]);
  }
}
int main() {
  while (read()) {
    solve();
  }
  return 0;
}
