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()
}