← Home
```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)
}
```