#include namespace { #pragma GCC diagnostic ignored "-Wunused-function" #include #pragma GCC diagnostic warning "-Wunused-function" using namespace std; using namespace atcoder; #define rep(i,n) for(int i = 0; i < (int)(n); i++) #define rrep(i,n) for(int i = (int)(n) - 1; i >= 0; i--) #define all(x) begin(x), end(x) #define rall(x) rbegin(x), rend(x) template bool chmax(T& a, const T& b) { if (a < b) { a = b; return true; } else return false; } template bool chmin(T& a, const T& b) { if (b < a) { a = b; return true; } else return false; } using ll = long long; using P = pair; using VI = vector; using VVI = vector; using VL = vector; using VVL = vector; using mint = modint998244353; constexpr int FACT_SIZE = 1000000; mint Fact[FACT_SIZE + 1]; mint iFact[FACT_SIZE + 1]; const auto fact_init = [] { Fact[0] = mint::raw(1); for(int i = 1; i <= FACT_SIZE; ++i) { Fact[i] = Fact[i-1] * i; } iFact[FACT_SIZE] = Fact[FACT_SIZE].inv(); for(int i = FACT_SIZE; i; --i) { iFact[i-1] = iFact[i] * i; } return false; }(); mint comb(int n, int k) { if (k == 0) return mint::raw(1); assert(n >= 0 && k >= 0); if (k > n) return mint::raw(0); return Fact[n] * iFact[n - k] * iFact[k]; } mint icomb(int n, int k) { return iFact[n] * Fact[n - k] * Fact[k]; } mint fact(int n) {return Fact[n];} mint perm(int n, int k) { assert(0 <= n); return Fact[n] * iFact[n - k]; } mint cat(int d) { mint ans = comb(2*d, d); if (d) ans -= comb(2*d, d-1); return ans; } } int main() { ios::sync_with_stdio(false); cin.tie(0); int n, q; cin >> n >> q; string s; cin >> s; set cuts{0}; for (int i = 1; i < n; i++) if (s[i-1] != s[i]) cuts.emplace(i); mint ans = 1; int odds = 0; auto add = [&](int d) { if (d % 2 == 0) ans *= cat(d/2); else odds++; }; auto rmv = [&](int d) { if (d % 2 == 0) ans /= cat(d/2); else odds--; }; for (auto it1 = cuts.begin(), it2 = next(it1); it2 != cuts.end(); it1 = it2++) { add(*it2 - *it1); } auto flip = [&](int i) { if (s[i-1] == s[i]) { auto it = cuts.insert(i).first; auto pit = prev(it), nit = next(it); if (nit != cuts.end()) rmv(*nit - *pit), add(*nit - *it); add(*it - *pit); } else { auto it = cuts.find(i); auto pit = prev(it), nit = next(it); rmv(*it - *pit); if (nit != cuts.end()) rmv(*nit - *it), add(*nit - *pit); cuts.erase(it); } }; rep(_, q) { int op; cin >> op; if (op == 1) { int i; cin >> i; i--; if (i) flip(i); if (i+1 < n) flip(i+1); s[i] ^= 'N' ^ 'Y'; } else { int k; cin >> k; int last = *cuts.rbegin(); if (odds) { cout << 0 << '\n'; continue; } int vlast = k - (n - k); // add+sub = n-last // add-sub = vlast int add = (n - last + vlast) / 2; int sub = (n - last - vlast) / 2; if (add < 0 || sub < 0) { cout << 0 << '\n'; continue; } mint res; if (s[last] == 'N') { if (vlast >= 0) { mint mul = comb(add + sub, sub); if (sub) mul -= comb(add + sub, sub - 1); res = ans * mul; } } else { if (vlast <= 0) { mint mul = comb(add + sub, add); if (add) mul -= comb(add + sub, add - 1); res = ans * mul; } } cout << res.val() << '\n'; } } }