12 12
5 1
5 11
1 11
8 11
8 9
5 12
6 9
7 11
9 3
9 10
4 12
10 2
78
1 1
1 2
1 3
1 4
1 5
1 6
1 7
1 8
1 9
1 10
1 11
1 12
2 2
2 3
2 4
2 5
2 6
2 7
2 8
2 9
2 10
2 11
2 12
3 3
3 4
3 5
3 6
3 7
3 8
3 9
3 10
3 11
3 12
4 4
4 5
4 6
4 7
4 8
4 9
4 10
4 11
4 12
5 5
5 6
5 7
5 8
5 9
5 10
5 11
5 12
6 6
6 7
6 8
6 9
6 10
6 11
6 12
7 7
7 8
7 9
7 10
7 11
7 12
8 8
8 9
8 10
8 11
8 12
9 9
9 10
9 11
9 12
10 10
10 11
10 12
11 11
11 12
12 12

1
3
6
10
15
21
28
36
45
55
65
76
1
3
6
10
15
21
28
36
45
55
66
1
3
6
10
15
21
28
36
45
55
1
3
6
10
15
21
28
36
45
1
3
6
10
15
21
28
36
1
3
6
10
15
21
28
1
3
6
10
15
21
1
3
6
10
15
1
3
6
10
1
3
6
1
3
1

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.*;

/**
 * @author Don Li
 */
public class BipartiteSegments {
    
    int N = (int) 3e5 + 10;
    
    int n, m;
    int[][] G;
    
    int timer = 0;
    int[] enter = new int[N], low = new int[N];
    int sz = 0;
    boolean[] in_stack = new boolean[N];
    int[] stack = new int[N];
    
    int[] mx;
    
    void solve() {
        n = in.nextInt(); m = in.nextInt();
        int[] fr = new int[m], to = new int[m];
        for (int i = 0; i < m; i++) {
            fr[i] = in.nextInt() - 1;
            to[i] = in.nextInt() - 1;
        }
        G = build_graph(n, fr, to);
        
        mx = new int[n];
        Arrays.fill(mx, n);
        
        for (int i = 0; i < n; i++) {
            if (enter[i] == 0) {
                dfs(i, -1);
            }
        }
        
        for (int i = n - 2; i >= 0; i--) mx[i] = Math.min(mx[i], mx[i + 1]);
        
        long[] sum = new long[n + 1];
        sum[0] = 0;
        for (int i = 0; i < n; i++) sum[i + 1] = sum[i] + (mx[i] - i);
        
        int Q = in.nextInt();
        while (Q-- > 0) {
            int l = in.nextInt() - 1, r = in.nextInt();
            int p = upperBound(mx, r);
            if (p >= r) {
                out.println(sum[r] - sum[l]);
                continue;
            }
            if (p < l) {
                out.println((long) (r - l) * (r - l + 1) / 2);
                continue;
            }
            long ans = 0;
            ans += sum[p] - sum[l];
            ans += (long) (r - p) * (r - p + 1) / 2;
            out.println(ans);
        }
    }
    
    int upperBound(int[] a, int k) {
        int lb = -1, ub = a.length;
        while (ub - lb > 1) {
            int m = (lb + ub) >> 1;
            if (a[m] > k) ub = m;
            else lb = m;
        }
        return ub;
    }
    
    void dfs(int u, int p) {
        low[u] = enter[u] = ++timer;
        in_stack[u] = true;
        stack[sz++] = u;
        
        for (int v : G[u]) {
            if (v != p) {
                if (enter[v] == 0) {
                    dfs(v, u);
                    low[u] = Math.min(low[u], low[v]);
                } else if (in_stack[v]) {
                    low[u] = Math.min(low[u], enter[v]);
                }
            }
        }
        
        if (low[u] == enter[u]) {
            List<Integer> cycle = new ArrayList<>();
            int v;
            do {
                v = stack[--sz];
                in_stack[v] = false;
                cycle.add(v);
            } while (v != u);
            Collections.sort(cycle);
            if (cycle.size() > 1) mx[cycle.get(0)] = cycle.get(cycle.size() - 1);
        }
    }
    
    int[][] build_graph(int n, int[] from, int[] to) {
        int[][] G = new int[n][];
        int[] cnt = new int[n];
        for (int i = 0; i < from.length; i++) {
            cnt[from[i]]++;
            cnt[to[i]]++;
        }
        for (int i = 0; i < n; i++) G[i] = new int[cnt[i]];
        for (int i = 0; i < from.length; i++) {
            G[from[i]][--cnt[from[i]]] = to[i];
            G[to[i]][--cnt[to[i]]] = from[i];
        }
        return G;
    }
    
    public static void main(String[] args) {
        in = new FastScanner(new BufferedReader(new InputStreamReader(System.in)));
        out = new PrintWriter(System.out);
        new BipartiteSegments().solve();
        out.close();
    }
    
    static FastScanner in;
    static PrintWriter out;
    
    static class FastScanner {
        BufferedReader in;
        StringTokenizer st;
        
        public FastScanner(BufferedReader in) {
            this.in = in;
        }
        
        public String nextToken() {
            while (st == null || !st.hasMoreTokens()) {
                try {
                    st = new StringTokenizer(in.readLine());
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            return st.nextToken();
        }
        
        public int nextInt() {
            return Integer.parseInt(nextToken());
        }
        
        public long nextLong() {
            return Long.parseLong(nextToken());
        }
        
        public double nextDouble() {
            return Double.parseDouble(nextToken());
        }
    }
}
