```go
package main
import (
"bufio"
"fmt"
"os"
"sort"
"strconv"
)
type State struct {
s1, s2, s3 int
}
var K int
var stateToIndex = make(map[State]int)
var indexToState []State
func multiplyMatrices(A, B [][]int) [][]int {
res := make([][]int, K)
for i := 0; i < K; i++ {
res[i] = make([]int, K)
row := make([]uint64, K)
for k := 0; k < K; k++ {
ak := uint64(A[i][k])
if ak == 0 {
continue
}
bk := B[k]
for j := 0; j < K; j++ {
row[j] += ak * uint64(bk[j])
if row[j] >= 17000000000000000000 {
row[j] %= 998244353
}
}
}
for j := 0; j < K; j++ {
res[i][j] = int(row[j] % 998244353)
}
}
return res
}
func multiplyVectorMatrix(V []int, M [][]int) []int {
res := make([]uint64, K)
for i := 0; i < K; i++ {
vi := uint64(V[i])
if vi == 0 {
continue
}
mi := M[i]
for j := 0; j < K; j++ {
res[j] += vi * uint64(mi[j])
if res[j] >= 17000000000000000000 {
res[j] %= 998244353
}
}
}
finalRes := make([]int, K)
for j := 0; j < K; j++ {
finalRes[j] = int(res[j] % 998244353)
}
return finalRes
}
func main() {
scanner := bufio.NewScanner(os.Stdin)
scanner.Split(bufio.ScanWords)
buf := make([]byte, 1024*1024)
scanner.Buffer(buf, 10*1024*1024)
scanInt := func() int {
scanner.Scan()
res, _ := strconv.Atoi(scanner.Text())
return res
}
if !scanner.Scan() {
return
}
n, _ := strconv.Atoi(scanner.Text())
a := make([]int, n+1)
for i := 1; i <= n; i++ {
a[i] = scanInt()
}
m := scanInt()
type Cell struct {
y, c int
}
stripCells := make([][]Cell, n+1)
for i := 0; i < m; i++ {
x := scanInt()
y := scanInt()
c := scanInt()
stripCells[x] = append(stripCells[x], Cell{y, c - 1})
}
f := make([][]int, 3)
for i := 0; i < 3; i++ {
f[i] = make([]int, 3)
for j := 0; j < 3; j++ {
f[i][j] = scanInt()
}
}
q := []State{{4, 4, 4}}
stateToIndex[State{4, 4, 4}] = 0
indexToState = append(indexToState, State{4, 4, 4})
K = 1
for i := 0; i < len(q); i++ {
u := q[i]
for c := 0; c < 3; c++ {
set := make([]bool, 5)
if f[c][0] == 1 && u.s1 != 4 {
set[u.s1] = true
}
if f[c][1] == 1 && u.s2 != 4 {
set[u.s2] = true
}
if f[c][2] == 1 && u.s3 != 4 {
set[u.s3] = true
}
s_new := 0
for set[s_new] {
s_new++
}
v := State{s_new, u.s1, u.s2}
if _, exists := stateToIndex[v]; !exists {
stateToIndex[v] = K
indexToState = append(indexToState, v)
q = append(q, v)
K++
}
}
}
M_c := make([][][]int, 3)
for c := 0; c < 3; c++ {
M_c[c] = make([][]int, K)
for i := 0; i < K; i++ {
M_c[c][i] = make([]int, K)
}
}
M_unc := make([][]int, K)
for i := 0; i < K; i++ {
M_unc[i] = make([]int, K)
}
for i := 0; i < K; i++ {
u := indexToState[i]
for c := 0; c < 3; c++ {
set := make([]bool, 5)
if f[c][0] == 1 && u.s1 != 4 {
set[u.s1] = true
}
if f[c][1] == 1 && u.s2 != 4 {
set[u.s2] = true
}
if f[c][2] == 1 && u.s3 != 4 {
set[u.s3] = true
}
s_new := 0
for set[s_new] {
s_new++
}
v := State{s_new, u.s1, u.s2}
j := stateToIndex[v]
M_c[c][i][j] = 1
M_unc[i][j]++
}
}
P := make([][][]int, 30)
P[0] = M_unc
for b := 1; b < 30; b++ {
P[b] = multiplyMatrices(P[b-1], P[b-1])
}
R := []int{1, 1, 1, 1}
uncoloredMemo := make(map[int][]int)
for i := 1; i <= n; i++ {
cells := stripCells[i]
if len(cells) == 0 {
if cachedQ, ok := uncoloredMemo[a[i]]; ok {
for j := 0; j < 4; j++ {
R[j] = int((int64(R[j]) * int64(cachedQ[j])) % 998244353)
}
continue
}
}
sort.Slice(cells, func(j, k int) bool {
return cells[j].y < cells[k].y
})
V := make([]int, K)
V[0] = 1
curr := 0
for _, cell := range cells {
d := cell.y - curr - 1
if d > 0 {
for b := 0; b < 30; b++ {
if (d>>b)&1 == 1 {
V = multiplyVectorMatrix(V, P[b])
}
}
}
V = multiplyVectorMatrix(V, M_c[cell.c])
curr = cell.y
}
d := a[i] - curr
if d > 0 {
for b := 0; b < 30; b++ {
if (d>>b)&1 == 1 {
V = multiplyVectorMatrix(V, P[b])
}
}
}
poly := make([]int, 4)
for j := 0; j < K; j++ {
u := indexToState[j]
if u.s1 >= 0 && u.s1 <= 3 {
poly[u.s1] = (poly[u.s1] + V[j]) % 998244353
}
}
Q := make([]int, 4)
p0, p1, p2, p3 := int64(poly[0]), int64(poly[1]), int64(poly[2]), int64(poly[3])
Q[0] = int((p0 + p1 + p2 + p3) % 998244353)
Q[1] = int((p0 - p1 + p2 - p3) % 998244353)
Q[2] = int((p0 + p1 - p2 - p3) % 998244353)
Q[3] = int((p0 - p1 - p2 + p3) % 998244353)
for j := 0; j < 4; j++ {
if Q[j] < 0 {
Q[j] += 998244353
}
}
if len(cells) == 0 {
uncoloredMemo[a[i]] = Q
}
for j := 0; j < 4; j++ {
R[j] = int((int64(R[j]) * int64(Q[j])) % 998244353)
}
}
ans := (R[0] + R[1] + R[2] + R[3]) % 998244353
ans = int((int64(ans) * 748683265) % 998244353)
fmt.Println(ans)
}
```