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