```go
package main
import (
"bufio"
"fmt"
"os"
)
func abs(x int) int {
if x < 0 {
return -x
}
return x
}
const MOD = 1000000007
const MAX = 1000005
var (
parent = make([]int, MAX)
vCount = make([]int, MAX)
eCount = make([]int, MAX)
hasLoop = make([]bool, MAX)
active = make([]bool, MAX)
)
func Find(i int) int {
root := i
for parent[root] != root {
root = parent[root]
}
curr := i
for curr != root {
nxt := parent[curr]
parent[curr] = root
curr = nxt
}
return root
}
func AddEdge(u, v int) {
active[u] = true
active[v] = true
rootU := Find(u)
rootV := Find(v)
if rootU != rootV {
parent[rootU] = rootV
vCount[rootV] += vCount[rootU]
eCount[rootV] += eCount[rootU] + 1
hasLoop[rootV] = hasLoop[rootV] || hasLoop[rootU]
} else {
eCount[rootU]++
if u == v {
hasLoop[rootU] = true
}
}
}
func nextInt(reader *bufio.Reader) int {
res := 0
for {
c, err := reader.ReadByte()
if err != nil {
return 0
}
if c >= '0' && c <= '9' {
res = int(c - '0')
break
}
}
for {
c, err := reader.ReadByte()
if err != nil || c < '0' || c > '9' {
break
}
res = res*10 + int(c - '0')
}
return res
}
func main() {
reader := bufio.NewReader(os.Stdin)
writer := bufio.NewWriter(os.Stdout)
defer writer.Flush()
t := nextInt(reader)
for tc := 0; tc < t; tc++ {
n := nextInt(reader)
m := nextInt(reader)
k := nextInt(reader)
sz := n * m
for i := 0; i < sz; i++ {
parent[i] = i
vCount[i] = 1
eCount[i] = 0
hasLoop[i] = false
active[i] = false
}
prevX := nextInt(reader)
prevY := nextInt(reader)
possible := true
for i := 0; i < k; i++ {
currX := nextInt(reader)
currY := nextInt(reader)
if !possible {
prevX, prevY = currX, currY
continue
}
dx := abs(prevX - currX)
dy := abs(prevY - currY)
if dx+dy != 2 {
possible = false
} else {
if dx == 1 && dy == 1 {
u := (prevX-1)*m + (currY - 1)
v := (currX-1)*m + (prevY - 1)
AddEdge(u, v)
} else if dx == 2 {
midX := (prevX + currX) / 2
u := (midX-1)*m + (prevY - 1)
AddEdge(u, u)
} else if dy == 2 {
midY := (prevY + currY) / 2
u := (prevX-1)*m + (midY - 1)
AddEdge(u, u)
}
}
prevX, prevY = currX, currY
}
if !possible {
fmt.Fprintln(writer, 0)
continue
}
ans := int64(1)
for i := 0; i < sz; i++ {
if active[i] && parent[i] == i {
V := vCount[i]
E := eCount[i]
if E > V {
ans = 0
break
} else if E == V {
if hasLoop[i] {
ans = (ans * 1) % MOD
} else {
ans = (ans * 2) % MOD
}
} else if E == V-1 {
ans = (ans * int64(V)) % MOD
}
}
}
fmt.Fprintln(writer, ans)
}
}
```