#!/usr/bin/env python3

import sys
sys.setrecursionlimit(10**6)

from timeit import default_timer as timer
import math
# push_back insert lower_bound upper_bound erase 

SQRT_MULT = 3.0

class Uf:
    def __init__(self, n):
        self.p = [0]*n # p=element's parent
        self.r = [0]*n # r=rank
        for i in range(n):
            self.p[i]=i
        self.fake_p = dict()
    def clear_fake(self):
        self.fake_p.clear()
    # finds representant of a's set
    def find(self, a):
        if self.p[a]==a:
            return a
        else:
            self.p[a]=self.find(self.p[a])
            return self.p[a]
    def fake_find(self, a):
        a = self.find(a)
        if a in self.fake_p.keys():
            return self.fake_find(self.fake_p[a])
        else:
            return a
    # unifies sets of a and b
    def fake_uni(self, a, b):
        a = self.fake_find(a)
        b = self.fake_find(b)
        if a==b:
            return
        self.fake_p[b]=a
    def uni(self, a, b):
        # assert(self.fake_p.empty())
        a = self.find(a)
        b = self.find(b)
        if a==b:
            return
        if self.r[a]<self.r[b]:
            a, b = b, a
        self.p[b] = a
        self.r[a] += self.r[a]==self.r[b]
    # check if elements are in the same set
    def same(self, a, b):
        return self.fake_find(a) == self.fake_find(b)
#/unionfind

N = 0
M = 0
g = []
MXM = 100007
edges = [[0,0]]*MXM
v = []
inv = []

def check(cur_b, prev_b, bound):
    # start = timer()
    global N
    cur_e = v[prev_b]
    uf=Uf(N)
    sz=0
    for i in range(cur_b, cur_e):
        [a,b]=edges[i];
        uf.uni(a, b)
    # end = timer()
    # print('init:', end - start)
    # start = timer()
    for i in range(cur_e,M+1):
        [a,b]=edges[i]
        if uf.same(a, b):
            v[cur_b]=i
        for j in range(cur_b-1, prev_b, -1):
            [aa,bb]=edges[j]
            if uf.same(aa,bb) :
                break
            uf.fake_uni(aa,bb)
            v[j]=i
        uf.clear_fake()
        if uf.same(a, b):
            # end = timer()
            # print('end:', end - start)
            return
        uf.uni(a, b)
    v[cur_b]=M

def main():
    global v, inv
    global N, M
    [N,M]=list(map(int, input().split(' ')))
    g = []
    for i in range(N):
        g.append([])
    for i in range(M):
        [a,b]=list(map(int, input().split(' ')))
        a -= 1
        b -= 1
        edges[i]=[a,b]
        g[a].append(b)
        g[b].append(a)
    edges[M]=[0,0]
    Q = int(input())
    q = [[0,0]]*Q
    for i in range(Q):
        [a,b]=(list(map(int, input().split(' '))))
        q[i]=(a-1,b-1)
    for p in q:
        [a,b]=p
        a -= 1
        b -= 1

    v = [0]*M
    inv = [0]*M
    # bound = max(3,(math.ceil(SQRT_MULT * math.sqrt(M))))
    # bound = 200; # 20
    bound = 100; # 17

    idx=0
    last=0
    while idx<M:
        check(idx, last, bound)
        last=idx
        idx=max(idx+1, min(M,min(v[idx]-1,idx+bound)))
    for i in range(M-1):
        v[i+1]=max(v[i+1],v[i])
    idx=0
    for i in range(M):
        while(idx<v[i]):
            inv[idx]=i-1
            idx+=1

    lower = [0]*(M+1)
    for i in range(1,M+1):
        lower[i]=lower[i-1]+v[i-1]-(i-1)

    for p in q:
        [fir,sec]=p
        beg = fir
        end = max(beg, inv[sec]+1)
        rng = max(0,sec+1-end)
        res=lower[end] - lower[beg] + rng*(rng+1)//2
        # print(fir, "-", sec, "  b:", beg, ", e:", end, ", sum:", (lower[end]-lower[beg]), ", r:", rng, ", res:", res)
        print(res)

if __name__=='__main__':
    main()
