package main
import (
"bufio"
"fmt"
"os"
)
const MOD = 998244353
var fact [200005]int64
var invFact [200005]int64
var pow2 [200005]int64
var invPow2 [200005]int64
var inv2 int64
func power(base, exp int64) int64 {
res := int64(1)
base %= MOD
for exp > 0 {
if exp%2 == 1 {
res = (res * base) % MOD
}
base = (base * base) % MOD
exp /= 2
}
return res
}
func modInverse(n int64) int64 {
return power(n, MOD-2)
}
func precompute() {
fact[0] = 1
invFact[0] = 1
for i := 1; i <= 200000; i++ {
fact[i] = (fact[i-1] * int64(i)) % MOD
}
invFact[200000] = power(fact[200000], MOD-2)
for i := 199999; i >= 1; i-- {
invFact[i] = (invFact[i+1] * int64(i+1)) % MOD
}
pow2[0] = 1
for i := 1; i <= 200000; i++ {
pow2[i] = (pow2[i-1] * 2) % MOD
}
inv2 = modInverse(2)
invPow2[0] = 1
for i := 1; i <= 200000; i++ {
invPow2[i] = (invPow2[i-1] * inv2) % MOD
}
}
func nCr(n, r int) int64 {
if r < 0 || r > n {
return 0
}
return fact[n] * invFact[r] % MOD * invFact[n-r] % MOD
}
var curr_N int = 1
var curr_K int = 0
var curr_B int64 = 1
func get_B(N, K int) int64 {
if K < 0 {
return 0
}
if K >= N {
return pow2[N]
}
for curr_K > K {
curr_B = (curr_B - nCr(curr_N, curr_K) + MOD) % MOD
curr_K--
}
for curr_N < N {
curr_B = (2*curr_B%MOD - nCr(curr_N, curr_K) + MOD) % MOD
curr_N++
}
for curr_N > N {
curr_N--
curr_B = (curr_B + nCr(curr_N, curr_K)) % MOD * inv2 % MOD
}
for curr_K < K {
curr_K++
curr_B = (curr_B + nCr(curr_N, curr_K)) % MOD
}
return curr_B
}
func main() {
precompute()
reader := bufio.NewReader(os.Stdin)
writer := bufio.NewWriter(os.Stdout)
defer writer.Flush()
var n, m int
if _, err := fmt.Fscan(reader, &n, &m); err != nil {
return
}
var sStr string
fmt.Fscan(reader, &sStr)
s := []byte(sStr)
b_odd, w_odd, b_even, w_even, q := 0, 0, 0, 0, 0
for i := 0; i < n; i++ {
if s[i] == 'b' {
if i%2 == 0 {
b_odd++
} else {
b_even++
}
} else if s[i] == 'w' {
if i%2 == 0 {
w_odd++
} else {
w_even++
}
} else {
q++
}
}
printExpected := func() {
Z := b_odd + w_even
C := Z - n/2
var V_half int64
if q < 3 {
V_half = 0
for k := 0; k <= q; k++ {
if (k%2+2)%2 == (C%2+2)%2 {
val := int64(k + C)
if val < 0 {
val = -val
}
V_half = (V_half + nCr(q, k)*(val/2)) % MOD
}
}
} else {
C_mod := (int64(C)%MOD + MOD) % MOD
S1_half := (2*C_mod + int64(q)) % MOD * pow2[q-3] % MOD
R := -C
var C_term int64 = 0
if R > 0 {
term1 := int64(R) % MOD * get_B(q-1, R-2) % MOD
term2 := int64(q) % MOD * get_B(q-2, R-3) % MOD
C_term = (term1 - term2 + MOD) % MOD
}
V_half = (S1_half + C_term) % MOD
}
ans := V_half * invPow2[q-1] % MOD
fmt.Fprintln(writer, ans)
}
printExpected()
for i := 0; i < m; i++ {
var pos int
var charStr string
fmt.Fscan(reader, &pos, &charStr)
pos--
oldChar := s[pos]
newChar := charStr[0]
if oldChar == 'b' {
if pos%2 == 0 {
b_odd--
} else {
b_even--
}
} else if oldChar == 'w' {
if pos%2 == 0 {
w_odd--
} else {
w_even--
}
} else {
q--
}
if newChar == 'b' {
if pos%2 == 0 {
b_odd++
} else {
b_even++
}
} else if newChar == 'w' {
if pos%2 == 0 {
w_odd++
} else {
w_even++
}
} else {
q++
}
s[pos] = newChar
printExpected()
}
}