#ifndef ONLINE_JUDGE #define _GLIBCXX_DEBUG #endif #include #include #include using namespace std; using namespace __gnu_pbds; using lint = long long; using loub = long double; template using vec = vector; template using deq = deque; template using priq = priority_queue; template using prig = priority_queue, greater>; template using uset = gp_hash_table; template using umap = gp_hash_table; template using iset = tree, rb_tree_tag, tree_order_statistics_node_update>; template using imap = tree, rb_tree_tag, tree_order_statistics_node_update>; #define fst first #define snd second #define REP1(i, r) for (lint i = 0; i < (r); i++) #define REP2(i, l, r) for (lint i = (l); i < (r); i++) #define REP3(i, l, r, d) for (lint i = (l); (d) > 0 ? i < (r) : i > (r); i += (d)) #define SELECT_REP(_0, _1, _2, _3, REP_NAME, ...) REP_NAME #define rep(...) SELECT_REP(__VA_ARGS__, REP3, REP2, REP1)(__VA_ARGS__) #define all(v) v.begin(), v.end() #define rall(v) v.rbegin(), v.rend() #define part(v, l, r) v.begin() + (l), v.begin() + (r) #define rpart(v, l, r) make_reverse_iterator(v.begin() + (r)), make_reverse_iterator(v.begin() + (l)) template void vecin(vec &v, lint l, lint r) { rep(i, l, r) cin >> v[i]; } template void vecin(vec &v) { vecin(v, 0, v.size()); }; template void vecho(vec &v, lint l, lint r) { rep(i, l, r) cout << (i > l ? " " : "") << v[i]; cout << endl; } template void vecho(vec &v) { vecho(v, 0, v.size()); } template void echo(const T &val) { cout << val << endl; } template void echo(const T &val, const Ts &...vals) { cout << val << " "; echo(vals...); } template int chmin(T &a, const T &b) { if (a <= b) return a == b; a = b; return 2; } template int chmax(T &a, const T &b) { if (a >= b) return a == b; a = b; return 2; } template T sq(T x) { return x * x; } template T cb(T x) { return x * x * x; } const int INF = 2'000'000'001; const lint LINF = 2'000'000'000'000'000'001; void solve(); void test(); int main() { ios::sync_with_stdio(false); cin.tie(nullptr); cout << fixed << setprecision(15); int T = 1; // cin >> T; rep(i, T) { solve(); // test(); } } struct mod_calc { lint MOD = 998244353; vec FACT; vec FINV; mod_calc(lint mod) { MOD = mod; } lint pow(lint b, lint e) { lint ret = 1; while (e > 0) { if (e & 1) ret = ret * b % MOD; e >>= 1; b = b * b % MOD; } return ret; } lint inv(lint n) { return pow(n, MOD - 2); } void init_facts(lint MAX) { FACT.resize(MAX+1); FINV.resize(MAX+1); FACT[0] = 1; rep(i, 1, MAX+1) FACT[i] = i * FACT[i-1] % MOD; FINV[MAX] = inv(FACT[MAX]); rep(i, MAX, 0, -1) FINV[i-1] = i * FINV[i] % MOD; } lint fact(lint n) { return n >= 0 ? FACT[n] : 0; } lint finv(lint n) { return n >= 0 ? FINV[n] : 0; } lint bic(lint n, lint r) { return fact(n) * finv(r) % MOD * finv(n-r) % MOD; } }; void solve() { lint N; string S; cin >> N >> S; mod_calc mc(998244353); mc.init_facts(N); lint K = count(all(S), 'A') + count(all(S), 'B'); echo(mc.bic(N, K)); }