#include #define fi first #define se second #define rep(i,s,n) for (int i = (s); i < (n); ++i) #define rrep(i,g,n) for (int i = (n)-1; i >= (g); --i) #define all(a) a.begin(),a.end() #define rall(a) a.rbegin(),a.rend() #define len(x) (int)(x).size() #define dup(x,y) (((x)+(y)-1)/(y)) #define pb push_back #define eb emplace_back #define Field(T) vector> using namespace std; using ll = long long; using ull = unsigned long long; template using pq = priority_queue,greater>; using P = pair; templatebool chmax(T&a,T b){if(abool chmin(T&a,T b){if(b struct ModInt { int x; ModInt() : x(0) {} ModInt(int64_t y) : x(y >= 0 ? y % mod : (mod - (-y) % mod) % mod) {} ModInt &operator+=(const ModInt &p) { if((x += p.x) >= mod) x -= mod; return *this; } ModInt &operator-=(const ModInt &p) { if((x += mod - p.x) >= mod) x -= mod; return *this; } ModInt &operator*=(const ModInt &p) { x = (int) (1LL * x * p.x % mod); return *this; } ModInt &operator/=(const ModInt &p) { *this *= p.inverse(); return *this; } ModInt operator-() const { return ModInt(-x); } ModInt operator+(const ModInt &p) const { return ModInt(*this) += p; } ModInt operator-(const ModInt &p) const { return ModInt(*this) -= p; } ModInt operator*(const ModInt &p) const { return ModInt(*this) *= p; } ModInt operator/(const ModInt &p) const { return ModInt(*this) /= p; } bool operator==(const ModInt &p) const { return x == p.x; } bool operator!=(const ModInt &p) const { return x != p.x; } ModInt inverse() const { assert(x); int a = x, b = mod, u = 1, v = 0, t; while(b > 0) { t = a / b; swap(a -= t * b, b); swap(u -= t * v, v); } return ModInt(u); } ModInt pow(int64_t n) const { ModInt ret(1), mul(x); while(n > 0) { if(n & 1) ret *= mul; mul *= mul; n >>= 1; } return ret; } friend ostream &operator<<(ostream &os, const ModInt &p) { return os << p.x; } friend istream &operator>>(istream &is, ModInt &a) { int64_t t; is >> t; a = ModInt< mod >(t); return (is); } static int get_mod() { return mod; } }; template< typename T > struct Combination { private: int n_; vector fac, inv, finv; void extend(int l) { while(n_ <= l) { fac.emplace_back(fac.back() * T(n_)); inv.emplace_back(-inv[T::get_mod()%n_] * (T::get_mod()/n_)); finv.emplace_back(finv.back() * inv[n_]); ++n_; } } public: Combination() : n_(2), fac({T(1),T(1)}), inv({T(0),T(1)}), finv({T(1),T(1)}) {} // n! T fact(int n) { extend(n); return fac[n]; } // (n!)^{-1} T ifact(int n) { extend(n); return finv[n]; } T inverse(int n) { extend(n); return inv[n]; } // nCk T com(int n, int k) { if (n < 0 || k < 0 || n < k) return 0; extend(n); return fac[n] * finv[k] * finv[n-k]; } // nPk T perm(int n, int k) { if (n < 0 || k < 0 || n < k) return 0; extend(n); return fac[n] * finv[n-k]; } // nCk を Lucas の定理を用いて計算する。最悪 O(mod) であることに注意。 T com_lucas(long long n, long long k) { if (n < 0 || k < 0 || n < k) return 0; T ret = 1; const int p = T::get_mod(); while(n > 0 || k > 0) { ret *= com(n % p, k % p); n /= p, k /= p; } return ret; } }; template struct SegTree { public: SegTree() : SegTree(0) {} SegTree(int n) : SegTree(vector(n, e())) {} SegTree(int n, S v) : SegTree(vector(n, v)) {} SegTree(const vector& v) : _n(int(v.size())){ lg = 0; while ((1U << lg) < (unsigned int)(_n)) lg++; sz = 1 << lg; d = vector(2 * sz, e()); for (int i = 0; i < _n; ++i) d[sz + i] = v[i]; for (int i = sz-1; i >= 1; --i) { update(i); } } void set(int p, S x) { assert(0 <= p && p < _n); p += sz; d[p] = x; for (int i = 1; i <= lg; ++i) update(p >> i); } S get(int p) { assert(0 <= p && p < _n); return d[p+sz]; } S prod(int l, int r) { assert(0 <= l && l <= r && r <= _n); S sml = e(), smr = e(); l += sz, r += sz; while(l < r) { if (l & 1) sml = op(sml, d[l++]); if (r & 1) smr = op(d[--r], smr); l >>= 1, r >>= 1; } return op(sml, smr); } S all_prod() { return d[1]; } using F = function; // max_{r \in [l, n]} f(prod(l, r)) == true int max_right(int l, const F &f) { assert(0 <= l && l <= _n); assert(f(e())); if (l == _n) return _n; l += sz; S v = e(); do { while(l % 2 == 0) l >>= 1; if (!f(op(v, d[l]))) { while(l < sz) { l *= 2; if (f(op(v, d[l]))) { v = op(v, d[l]); ++l; } } return l - sz; } v = op(v, d[l]); ++l; } while((l & -l) != l); return _n; } // min_{l \in [0, r]} f(prod(l, r)) == true int min_left(int r, const F &f) { assert(0 <= r && r <= _n); assert(f(e())); if (r == 0) return 0; r += sz; S v = e(); do { --r; while(r > 0 && (r % 2)) r >>= 1; if (!f(op(d[r], v))) { while(r < sz) { r = r*2+1; if (f(op(d[r], v))) { v = op(d[r], v); --r; } } return r+1-sz; } v = op(d[r], v); } while((r & -r) != r); return 0; } private: int _n, sz, lg; vector d; void update(int k) {d[k] = op(d[2*k], d[2*k+1]);} }; using mint = ModInt<998244353>; mint op(mint a, mint b) { return a*b; } mint e() { return 1; } int main() { Combination com; int n, q; string s; cin >> n >> q >> s; SegTree seg(n); set st; st.emplace(0); rep(i,0,n-1) { if (s[i] != s[i+1]) { st.emplace(i+1); } } function f = [&](int n) { if (n%2 == 1) return mint(0); return com.com(n, n/2)*com.inverse((n/2)+1); }; auto itr = st.begin(); while(next(itr) != st.end()) { int x = *next(itr); seg.set(x, f(x-*(itr))); itr = next(itr); } while(q--) { int t; cin >> t; if (t == 1) { int i; cin >> i; --i; if (i > 0 && s[i-1] != s[i]) { seg.set(i, 1); st.erase(i); auto itr = st.lower_bound(i); if (itr != st.end()) { seg.set(*itr, f((*itr)-(*prev(itr)))); } } if (i+1 < n && s[i] != s[i+1]) { seg.set(i+1, 1); st.erase(i+1); auto itr = st.lower_bound(i+1); if (itr != st.end()) { seg.set(*itr, f((*itr)-(*prev(itr)))); } } s[i] = (s[i] == 'Y' ? 'N' : 'Y'); if (i > 0 && s[i-1] != s[i]) { st.emplace(i); auto itr = st.lower_bound(i); if (itr != st.begin()) { seg.set(*itr, f((*itr)-(*prev(itr)))); } else { seg.set(*itr, f(*itr)); } if (next(itr) != st.end()) { seg.set(*next(itr), f((*next(itr))-(*itr))); } } if (i+1 < n && s[i] != s[i+1]) { st.emplace(i+1); auto itr = st.lower_bound(i+1); if (itr != st.begin()) { seg.set(*itr, f((*itr)-(*prev(itr)))); } else { seg.set(*itr, f(*itr)); } if (next(itr) != st.end()) { seg.set(*next(itr), f((*next(itr))-(*itr))); } } } else { int k; cin >> k; mint ans = seg.all_prod(); // cout << ans << endl; int c = n-(st.empty() ? 0 : *(prev(st.end()))); // cout << "c = " << c << endl; k -= (n-c)/2; if (k < 0) { cout << 0 << endl; continue; } if (s.back() == 'Y') k = c-k; if (k-(c-k) < 0) { cout << 0 << endl; continue; } ans *= (com.com(c,k)-com.com(c,k+1)); cout << ans << endl; } // cout << s << endl; // rep(i,0,n) cout << seg.get(i) << " "; // cout << endl; } return 0; }