```go
package main
import (
"bufio"
"fmt"
"os"
"strconv"
)
const MOD = 1000000007
var sc *bufio.Scanner
func init() {
sc = bufio.NewScanner(os.Stdin)
sc.Split(bufio.ScanWords)
sc.Buffer(make([]byte, 0, 1024*1024), 1024*1024)
}
func readInt() int {
sc.Scan()
x, _ := strconv.Atoi(sc.Text())
return x
}
func abs(x int) int {
if x < 0 {
return -x
}
return x
}
func solve() int {
n := readInt()
m := readInt()
k := readInt()
total := n * m
oddX := make([]int, k+1)
oddY := make([]int, k+1)
isOdd := make([]bool, total)
for i := 0; i <= k; i++ {
x := readInt()
y := readInt()
oddX[i] = x
oddY[i] = y
id := (x-1)*m + (y-1)
isOdd[id] = true
}
setSize := make([]int, k)
setElem := make([][2]int, k)
cellSets := make([][]int, total)
for i := 0; i < k; i++ {
x1, y1 := oddX[i], oddY[i]
x2, y2 := oddX[i+1], oddY[i+1]
dist := abs(x1-x2) + abs(y1-y2)
if dist != 2 {
return 0
}
var cand [][2]int
if x1 == x2 {
cand = append(cand, [2]int{x1, (y1 + y2) / 2})
} else if y1 == y2 {
cand = append(cand, [2]int{(x1 + x2) / 2, y1})
} else {
cand = append(cand, [2]int{x1, y2}, [2]int{x2, y1})
}
var valid []int
for _, c := range cand {
cx, cy := c[0], c[1]
if cx >= 1 && cx <= n && cy >= 1 && cy <= m {
id := (cx-1)*m + (cy-1)
if !isOdd[id] {
valid = append(valid, id)
}
}
}
if len(valid) == 0 {
return 0
}
setSize[i] = len(valid)
setElem[i][0] = valid[0]
if len(valid) == 2 {
setElem[i][1] = valid[1]
}
for _, v := range valid {
cellSets[v] = append(cellSets[v], i)
}
}
assigned := make([]bool, total)
queue := make([]int, 0, k)
for i := 0; i < k; i++ {
if setSize[i] == 1 {
queue = append(queue, i)
}
}
for len(queue) > 0 {
i := queue[0]
queue = queue[1:]
if setSize[i] == -1 {
continue
}
if setSize[i] != 1 {
continue
}
c := setElem[i][0]
if assigned[c] {
return 0
}
assigned[c] = true
setSize[i] = -1
for _, j := range cellSets[c] {
if setSize[j] <= 0 {
continue
}
if setElem[j][0] == c {
if setSize[j] == 2 {
setElem[j][0] = setElem[j][1]
setSize[j] = 1
queue = append(queue, j)
} else {
return 0
}
} else if setSize[j] == 2 && setElem[j][1] == c {
setSize[j] = 1
queue = append(queue, j)
}
}
}
visited := make([]bool, total)
ways := 1
for i := 0; i < k; i++ {
if setSize[i] != 2 {
continue
}
u := setElem[i][0]
if !visited[u] {
vCount := 0
eCount := 0
stack := []int{u}
visited[u] = true
for len(stack) > 0 {
curr := stack[len(stack)-1]
stack = stack[:len(stack)-1]
vCount++
for _, j := range cellSets[curr] {
if setSize[j] == 2 {
eCount++
other := setElem[j][0]
if other == curr {
other = setElem[j][1]
}
if !visited[other] {
visited[other] = true
stack = append(stack, other)
}
}
}
}
eCount /= 2
if eCount > vCount {
return 0
} else if eCount == vCount {
ways = (ways * 2) % MOD
} else if eCount == vCount-1 {
ways = (ways * vCount) % MOD
} else {
return 0
}
}
}
return ways
}
func main() {
t := readInt()
for i := 0; i < t; i++ {
fmt.Println(solve())
}
}
```