← Home
package main

import (
	"bufio"
	"io"
	"os"
	"strconv"
)

const MOD int64 = 1000000007

type Frame struct {
	v  int
	pe int
	ei int
}

func main() {
	data, _ := io.ReadAll(os.Stdin)
	p := 0
	nextInt := func() int {
		for p < len(data) && (data[p] == ' ' || data[p] == '\n' || data[p] == '\r' || data[p] == '\t') {
			p++
		}
		sign := 1
		if data[p] == '-' {
			sign = -1
			p++
		}
		val := 0
		for p < len(data) && data[p] >= '0' && data[p] <= '9' {
			val = val*10 + int(data[p]-'0')
			p++
		}
		return val * sign
	}

	n := nextInt()
	m := nextInt()

	head := make([]int, n+1)
	for i := 1; i <= n; i++ {
		head[i] = -1
	}
	to := make([]int, 2*m)
	next := make([]int, 2*m)
	eu := make([]int, m)
	ev := make([]int, m)

	edgePtr := 0
	for i := 0; i < m; i++ {
		u := nextInt()
		v := nextInt()
		eu[i] = u
		ev[i] = v

		to[edgePtr] = v
		next[edgePtr] = head[u]
		head[u] = edgePtr
		edgePtr++

		to[edgePtr] = u
		next[edgePtr] = head[v]
		head[v] = edgePtr
		edgePtr++
	}

	tin := make([]int, n+1)
	low := make([]int, n+1)
	bridge := make([]bool, m)
	timer := 1
	stack := make([]Frame, 0, n)

	for s := 1; s <= n; s++ {
		if tin[s] != 0 {
			continue
		}
		tin[s] = timer
		low[s] = timer
		timer++
		stack = append(stack, Frame{v: s, pe: -1, ei: head[s]})

		for len(stack) > 0 {
			topi := len(stack) - 1
			v := stack[topi].v
			pe := stack[topi].pe
			ei := stack[topi].ei

			if ei != -1 {
				stack[topi].ei = next[ei]
				if pe != -1 && ei == (pe^1) {
					continue
				}
				u := to[ei]
				if tin[u] == 0 {
					tin[u] = timer
					low[u] = timer
					timer++
					stack = append(stack, Frame{v: u, pe: ei, ei: head[u]})
				} else {
					if tin[u] < low[v] {
						low[v] = tin[u]
					}
				}
			} else {
				stack = stack[:topi]
				if pe != -1 {
					parent := to[pe^1]
					if low[v] < low[parent] {
						low[parent] = low[v]
					}
					if low[v] > tin[parent] {
						bridge[pe>>1] = true
					}
				}
			}
		}
	}

	compOf := make([]int, n+1)
	isCycleComp := make([]bool, 1)
	compCnt := 0
	queue := make([]int, 0, n)

	for v := 1; v <= n; v++ {
		if compOf[v] != 0 {
			continue
		}
		hasNonBridge := false
		for e := head[v]; e != -1; e = next[e] {
			if !bridge[e>>1] {
				hasNonBridge = true
				break
			}
		}

		compCnt++
		isCycleComp = append(isCycleComp, hasNonBridge)

		if hasNonBridge {
			queue = queue[:0]
			queue = append(queue, v)
			compOf[v] = compCnt
			for qi := 0; qi < len(queue); qi++ {
				x := queue[qi]
				for e := head[x]; e != -1; e = next[e] {
					if bridge[e>>1] {
						continue
					}
					y := to[e]
					if compOf[y] == 0 {
						compOf[y] = compCnt
						queue = append(queue, y)
					}
				}
			}
		} else {
			compOf[v] = compCnt
		}
	}

	tHead := make([]int, compCnt+1)
	for i := 1; i <= compCnt; i++ {
		tHead[i] = -1
	}
	tTo := make([]int, 0, 2*compCnt)
	tNext := make([]int, 0, 2*compCnt)

	addTreeEdge := func(u, v int) {
		tTo = append(tTo, v)
		tNext = append(tNext, tHead[u])
		tHead[u] = len(tTo) - 1
	}

	for i := 0; i < m; i++ {
		cu := compOf[eu[i]]
		cv := compOf[ev[i]]
		if cu != cv {
			addTreeEdge(cu, cv)
			addTreeEdge(cv, cu)
		}
	}

	K := 0
	for (1 << K) <= compCnt {
		K++
	}
	up := make([][]int, K)
	for i := 0; i < K; i++ {
		up[i] = make([]int, compCnt+1)
	}
	depth := make([]int, compCnt+1)
	pref := make([]int, compCnt+1)
	seen := make([]bool, compCnt+1)

	queue = queue[:0]
	root := 1
	seen[root] = true
	queue = append(queue, root)
	if isCycleComp[root] {
		pref[root] = 1
	}

	for qi := 0; qi < len(queue); qi++ {
		v := queue[qi]
		for e := tHead[v]; e != -1; e = tNext[e] {
			u := tTo[e]
			if seen[u] {
				continue
			}
			seen[u] = true
			depth[u] = depth[v] + 1
			up[0][u] = v
			pref[u] = pref[v]
			if isCycleComp[u] {
				pref[u]++
			}
			queue = append(queue, u)
		}
	}

	for j := 1; j < K; j++ {
		prev := up[j-1]
		cur := up[j]
		for v := 1; v <= compCnt; v++ {
			cur[v] = prev[prev[v]]
		}
	}

	lca := func(a, b int) int {
		if depth[a] < depth[b] {
			a, b = b, a
		}
		diff := depth[a] - depth[b]
		bit := 0
		for diff > 0 {
			if diff&1 == 1 {
				a = up[bit][a]
			}
			diff >>= 1
			bit++
		}
		if a == b {
			return a
		}
		for j := K - 1; j >= 0; j-- {
			if up[j][a] != up[j][b] {
				a = up[j][a]
				b = up[j][b]
			}
		}
		return up[0][a]
	}

	pow2 := make([]int64, compCnt+1)
	pow2[0] = 1
	for i := 1; i <= compCnt; i++ {
		pow2[i] = (pow2[i-1] * 2) % MOD
	}

	k := nextInt()
	out := bufio.NewWriterSize(os.Stdout, 1<<20)
	for i := 0; i < k; i++ {
		x := nextInt()
		y := nextInt()
		a := compOf[x]
		b := compOf[y]
		c := lca(a, b)
		cnt := pref[a] + pref[b] - 2*pref[c]
		if isCycleComp[c] {
			cnt++
		}
		out.WriteString(strconv.FormatInt(pow2[cnt], 10))
		out.WriteByte('\n')
	}
	out.Flush()
}