package main
import (
"io"
"os"
"strconv"
)
type DSU struct {
p []int
sz []int
}
func newDSU(n int) DSU {
p := make([]int, n+1)
sz := make([]int, n+1)
for i := 1; i <= n; i++ {
p[i] = i
sz[i] = 1
}
return DSU{p: p, sz: sz}
}
func (d *DSU) Find(x int) int {
for d.p[x] != x {
d.p[x] = d.p[d.p[x]]
x = d.p[x]
}
return x
}
func (d *DSU) Union(a, b int) {
ra := d.Find(a)
rb := d.Find(b)
if ra == rb {
return
}
if d.sz[ra] < d.sz[rb] {
ra, rb = rb, ra
}
d.p[rb] = ra
d.sz[ra] += d.sz[rb]
}
func main() {
data, _ := io.ReadAll(os.Stdin)
idx := 0
nextInt := func() int {
for idx < len(data) && (data[idx] < '0' || data[idx] > '9') {
idx++
}
val := 0
for idx < len(data) && data[idx] >= '0' && data[idx] <= '9' {
val = val*10 + int(data[idx]-'0')
idx++
}
return val
}
n := nextInt()
m := nextInt()
dsus := make([]DSU, 30)
for i := 0; i < 30; i++ {
dsus[i] = newDSU(n)
}
incidentMask := make([]int, n+1)
hasEvenIncident := make([]bool, n+1)
for i := 0; i < m; i++ {
a := nextInt()
b := nextInt()
w := nextInt()
incidentMask[a] |= w
incidentMask[b] |= w
if w&1 == 0 {
hasEvenIncident[a] = true
hasEvenIncident[b] = true
}
for bit := 0; bit < 30; bit++ {
if (w>>bit)&1 == 1 {
dsus[bit].Union(a, b)
}
}
}
goodComp := make([][]bool, 30)
for bit := 1; bit < 30; bit++ {
goodComp[bit] = make([]bool, n+1)
}
for v := 1; v <= n; v++ {
if !hasEvenIncident[v] {
continue
}
mask := incidentMask[v]
for bit := 1; bit < 30; bit++ {
if (mask>>bit)&1 == 1 {
root := dsus[bit].Find(v)
goodComp[bit][root] = true
}
}
}
good := make([]bool, n+1)
for v := 1; v <= n; v++ {
for bit := 1; bit < 30; bit++ {
if goodComp[bit][dsus[bit].Find(v)] {
good[v] = true
break
}
}
}
q := nextInt()
out := make([]byte, 0, q*2)
for ; q > 0; q-- {
u := nextInt()
v := nextInt()
ans := 2
for bit := 0; bit < 30; bit++ {
if dsus[bit].Find(u) == dsus[bit].Find(v) {
ans = 0
break
}
}
if ans != 0 && good[u] {
ans = 1
}
out = strconv.AppendInt(out, int64(ans), 10)
out = append(out, '\n')
}
os.Stdout.Write(out)
}