package main
import (
"bufio"
"io"
"os"
"sort"
"strconv"
)
const MOD int64 = 998244353
const MAXN = 400000
type FastScanner struct {
data []byte
idx int
}
func NewFastScanner() *FastScanner {
data, _ := io.ReadAll(os.Stdin)
return &FastScanner{data: data}
}
func (fs *FastScanner) NextInt() int {
n := len(fs.data)
for fs.idx < n && (fs.data[fs.idx] < '0' || fs.data[fs.idx] > '9') {
fs.idx++
}
val := 0
for fs.idx < n && fs.data[fs.idx] >= '0' && fs.data[fs.idx] <= '9' {
val = val*10 + int(fs.data[fs.idx]-'0')
fs.idx++
}
return val
}
type Trigger struct {
r int
b int
s int
}
var fact []int64
var ifact []int64
func modPow(a, e int64) int64 {
res := int64(1)
for e > 0 {
if e&1 == 1 {
res = res * a % MOD
}
a = a * a % MOD
e >>= 1
}
return res
}
func initComb() {
fact = make([]int64, MAXN+1)
ifact = make([]int64, MAXN+1)
fact[0] = 1
for i := 1; i <= MAXN; i++ {
fact[i] = fact[i-1] * int64(i) % MOD
}
ifact[MAXN] = modPow(fact[MAXN], MOD-2)
for i := MAXN; i >= 1; i-- {
ifact[i-1] = ifact[i] * int64(i) % MOD
}
}
func prob(R, B, r, b int) int64 {
if r < 0 || r > R || b < 0 || b > B {
return 0
}
dr := R - r
db := B - b
res := fact[dr+db]
res = res * ifact[dr] % MOD
res = res * ifact[db] % MOD
res = res * fact[r+b] % MOD
res = res * ifact[r] % MOD
res = res * ifact[b] % MOD
res = res * fact[R] % MOD
res = res * fact[B] % MOD
res = res * ifact[R+B] % MOD
return res
}
func main() {
initComb()
fs := NewFastScanner()
t := fs.NextInt()
out := bufio.NewWriterSize(os.Stdout, 1<<20)
defer out.Flush()
for ; t > 0; t-- {
n := fs.NextInt()
m := fs.NextInt()
k := fs.NextInt()
tr := make([]Trigger, k)
for i := 0; i < k; i++ {
r := fs.NextInt()
b := fs.NextInt()
tr[i] = Trigger{r: r, b: b, s: r + b}
}
sort.Slice(tr, func(i, j int) bool {
if tr[i].s != tr[j].s {
return tr[i].s > tr[j].s
}
return tr[i].r > tr[j].r
})
pMat := make([][]int64, k)
for i := 0; i < k; i++ {
pMat[i] = make([]int64, k)
}
pStart := make([]int64, k)
for i := 0; i < k; i++ {
pStart[i] = prob(n, m, tr[i].r, tr[i].b)
}
for i := 0; i < k; i++ {
R, B := tr[i].r, tr[i].b
for j := i + 1; j < k; j++ {
pMat[i][j] = prob(R, B, tr[j].r, tr[j].b)
}
}
J := make([]int64, k)
K := make([]int64, k)
q := make([]int64, k)
for u := k - 1; u >= 0; u-- {
sumQ := int64(0)
for i := u + 1; i < k; i++ {
x := pMat[u][i]
for j := u + 1; j < i; j++ {
if q[j] != 0 && pMat[j][i] != 0 {
x -= q[j] * pMat[j][i] % MOD
if x < 0 {
x += MOD
}
}
}
q[i] = x
sumQ += x
if sumQ >= MOD {
sumQ -= MOD
}
}
pnone := int64(1) - sumQ
if pnone < 0 {
pnone += MOD
}
R, B := tr[u].r, tr[u].b
Tu := int64(2*R+B) % MOD
ju := pnone
ku := pnone * Tu % MOD
for i := u + 1; i < k; i++ {
qi := q[i]
if qi == 0 {
continue
}
twoJi := 2 * J[i] % MOD
ju += qi * twoJi % MOD
if ju >= MOD {
ju -= MOD
}
delta := int64(2*(R-tr[i].r)+(B-tr[i].b)) % MOD
term := (twoJi*delta + K[i]) % MOD
ku += qi * term % MOD
if ku >= MOD {
ku -= MOD
}
}
J[u] = ju
K[u] = ku
}
sumQ := int64(0)
for i := 0; i < k; i++ {
x := pStart[i]
for j := 0; j < i; j++ {
if q[j] != 0 && pMat[j][i] != 0 {
x -= q[j] * pMat[j][i] % MOD
if x < 0 {
x += MOD
}
}
}
q[i] = x
sumQ += x
if sumQ >= MOD {
sumQ -= MOD
}
}
pnone := int64(1) - sumQ
if pnone < 0 {
pnone += MOD
}
ans := pnone * (int64(2*n+m) % MOD) % MOD
for i := 0; i < k; i++ {
qi := q[i]
if qi == 0 {
continue
}
delta := int64(2*(n-tr[i].r)+(m-tr[i].b)) % MOD
term := (2*J[i]%MOD*delta + K[i]) % MOD
ans += qi * term % MOD
if ans >= MOD {
ans -= MOD
}
}
out.WriteString(strconv.FormatInt(ans, 10))
out.WriteByte('\n')
}
}