```go
package main
import (
"bufio"
"fmt"
"os"
)
const (
ShapeR = 0
ShapeP = 1
ShapeS = 2
)
var combineTable [8][8]int
var beatsTable [3][8]bool
func initTables() {
beats := func(s1, s2 int) bool {
if s1 == s2 {
return true
}
if s1 == ShapeR && s2 == ShapeS {
return true
}
if s1 == ShapeP && s2 == ShapeR {
return true
}
if s1 == ShapeS && s2 == ShapeP {
return true
}
return false
}
for s := 0; s < 3; s++ {
beatsTable[s][0] = true
for m := 1; m < 8; m++ {
canWin := false
for b := 0; b < 3; b++ {
if (m & (1 << b)) != 0 {
if beats(s, b) {
canWin = true
break
}
}
}
beatsTable[s][m] = canWin
}
}
for m1 := 0; m1 < 8; m1++ {
for m2 := 0; m2 < 8; m2++ {
if m1 == 0 {
combineTable[m1][m2] = m2
continue
}
if m2 == 0 {
combineTable[m1][m2] = m1
continue
}
res := 0
for b1 := 0; b1 < 3; b1++ {
if (m1 & (1 << b1)) != 0 {
for b2 := 0; b2 < 3; b2++ {
if (m2 & (1 << b2)) != 0 {
if beats(b1, b2) {
res |= (1 << b1)
}
if beats(b2, b1) {
res |= (1 << b2)
}
}
}
}
}
combineTable[m1][m2] = res
}
}
}
const P = 262144
var treeMask []int8
var treeCnt []int32
var limit int
func updateNode(u int, lChild, rChild int) {
if lChild >= limit {
// Left is empty, so right is empty too (complete tree property relative to filling)
// Or if not, logic implies u takes from R?
// In our filling, if L is empty, R is also empty or outside range.
// Actually, simpler: if lChild >= limit, u is effectively empty/padding.
treeMask[u] = 0
uOff := u * 192
end := uOff + 192
for i := uOff; i < end; i++ {
treeCnt[i] = 0
}
return
}
if rChild >= limit {
// Right is empty. u is copy of Left.
treeMask[u] = treeMask[lChild]
uOff := u * 192
lOff := lChild * 192
copy(treeCnt[uOff:uOff+192], treeCnt[lOff:lOff+192])
return
}
lm := int(treeMask[lChild])
rm := int(treeMask[rChild])
treeMask[u] = int8(combineTable[lm][rm])
uOff := u * 192
lOff := lChild * 192
rOff := rChild * 192
var permL [8]int
var permR [8]int
for i := 0; i < 8; i++ {
permL[i] = combineTable[i][lm] // eR is irrelevant for L? No, this is for R child. permL maps eL for R child.
// Correct logic:
// For R child players: effective left is combine(eL, L.mask).
// Here permL[i] = combine(i, lm). Correct.
permR[i] = combineTable[rm][i] // For L child players: effective right is combine(R.mask, eR).
// Here permR[i] = combine(rm, i). Correct.
}
idx := uOff
for s := 0; s < 3; s++ {
lBase := lOff + (s << 6)
rBase := rOff + (s << 6)
for eL := 0; eL < 8; eL++ {
lRowBase := lBase + (eL << 3)
rRowBase := rBase + (permL[eL] << 3)
for eR := 0; eR < 8; eR++ {
// u[s][eL][eR] = L[s][eL][permR[eR]] + R[s][permL[eL]][eR]
treeCnt[idx] = treeCnt[lRowBase+permR[eR]] + treeCnt[rRowBase+eR]
idx++
}
}
}
}
func buildLeaf(u int, shape int) {
treeMask[u] = int8(1 << shape)
uOff := u * 192
idx := uOff
for s := 0; s < 3; s++ {
if s != shape {
end := idx + 64
for idx < end {
treeCnt[idx] = 0
idx++
}
} else {
for eL := 0; eL < 8; eL++ {
validL := beatsTable[s][eL]
for eR := 0; eR < 8; eR++ {
if validL && beatsTable[s][eR] {
treeCnt[idx] = 1
} else {
treeCnt[idx] = 0
}
idx++
}
}
}
}
}
func main() {
reader := bufio.NewReaderSize(os.Stdin, 1024*1024)
writer := bufio.NewWriter(os.Stdout)
defer writer.Flush()
initTables()
var n, q int
line1, _ := reader.ReadString('\n')
scanLine(line1, &n, &q)
line2, _ := reader.ReadString('\n')
limit = P + n
treeMask = make([]int8, limit+5)
treeCnt = make([]int32, (limit+5)*192)
for i := 0; i < n; i++ {
char := line2[i]
shape := 0
if char == 'P' {
shape = ShapeP
} else if char == 'S' {
shape = ShapeS
}
buildLeaf(P+i, shape)
}
for i := P - 1; i > 0; i-- {
updateNode(i, 2*i, 2*i+1)
}
printAns(writer)
for k := 0; k < q; k++ {
line, _ := reader.ReadString('\n')
var p int
var c byte
pos := 0
for pos < len(line) && (line[pos] < '0' || line[pos] > '9') {
pos++
}
for pos < len(line) && line[pos] >= '0' && line[pos] <= '9' {
p = p*10 + int(line[pos]-'0')
pos++
}
for pos < len(line) && line[pos] == ' ' {
pos++
}
c = line[pos]
shape := ShapeR
if c == 'P' {
shape = ShapeP
} else if c == 'S' {
shape = ShapeS
}
idx := P + p - 1
buildLeaf(idx, shape)
for idx > 1 {
idx /= 2
updateNode(idx, 2*idx, 2*idx+1)
}
printAns(writer)
}
}
func printAns(w *bufio.Writer) {
// Root is 1. Offsets for s=0,1,2 with eL=0, eR=0.
// 1*192 + s*64 + 0 + 0
ans := treeCnt[192] + treeCnt[256] + treeCnt[320]
fmt.Fprintf(w, "%d ", ans)
}
func scanLine(s string, args ...*int) {
idx := 0
for _, target := range args {
for idx < len(s) && s[idx] <= ' ' {
idx++
}
val := 0
for idx < len(s) && s[idx] >= '0' && s[idx] <= '9' {
val = val*10 + int(s[idx]-'0')
idx++
}
*target = val
}
}
```