#include using namespace atcoder; using mint = modint998244353; const long long MOD = 998244353; // using mint = modint1000000007; // const long long MOD = 1000000007; // using mint = modint;//mint::set_mod(MOD); #include #define rep(i, a, b) for (ll i = (ll)(a); i < (ll)(b); i++) #define repeq(i, a, b) for (ll i = (ll)(a); i <= (ll)(b); i++) #define repreq(i, a, b) for (ll i = (ll)(a); i >= (ll)(b); i--) #define endl '\n' // fflush(stdout); #define cYes cout << "Yes" << endl #define cNo cout << "No" << endl #define sortr(v) sort(v, greater<>()) #define pb push_back #define pob pop_back #define mp make_pair #define mt make_tuple #define FI first #define SE second #define ALL(v) (v).begin(), (v).end() #define INFLL 3000000000000000100LL #define INF 1000000100 #define PI acos(-1.0L) #define TAU (PI * 2.0L) using namespace std; typedef long long ll; typedef pair Pll; typedef tuple Tlll; typedef vector Vi; typedef vector VVi; typedef vector Vl; typedef vector VVl; typedef vector VVVl; typedef vector VTlll; typedef vector Vm; typedef vector VVm; typedef vector Vs; typedef vector Vd; typedef vector Vc; typedef vector Vb; typedef vector VPll; typedef priority_queue PQl; typedef priority_queue, greater> PQlr; /* inout */ ostream &operator<<(ostream &os, mint const &m) { os << m.val(); return os; } istream &operator>>(istream &is, mint &m) { long long n; is >> n, m = n; return is; } template ostream &operator<<(ostream &os, const vector &v) { int n = v.size(); rep(i, 0, n) { os << v[i] << " \n"[i == n - 1]; } return os; } template ostream &operator<<(ostream &os, const vector> &v) { int n = v.size(); rep(i, 0, n) os << v[i]; return os; } template ostream &operator<<(ostream &os, pair const &p) { os << p.first << ' ' << p.second; return os; } template ostream &operator<<(ostream &os, const map &mp) { for (auto &[key, val] : mp) { os << key << ':' << val << '\n'; } return os; } template ostream &operator<<(ostream &os, const set &st) { auto itr = st.begin(); for (int i = 0; i < (int)st.size(); i++) { os << *itr << (i + 1 != (int)st.size() ? ' ' : '\n'); itr++; } return os; } template ostream &operator<<(ostream &os, multiset &st) { auto itr = st.begin(); for (int i = 0; i < (int)st.size(); i++) { os << *itr << (i + 1 != (int)st.size() ? ' ' : '\n'); itr++; } return os; } template ostream &operator<<(ostream &os, queue q) { while (q.size()) { os << q.front(); q.pop(); os << " \n"[q.empty()]; } return os; } template ostream &operator<<(ostream &os, stack st) { vector v; while (st.size()) { v.push_back(st.top()); st.pop(); } reverse(ALL(v)); os << v; return os; } template ostream &operator<<(ostream &os, priority_queue pq) { vector v; while (pq.size()) { v.push_back(pq.top()); pq.pop(); } os << v; return os; } template istream &operator>>(istream &is, vector &v) { for (T &in : v) is >> in; return is; } template istream &operator>>(istream &is, pair &p) { is >> p.first >> p.second; return is; } /* useful */ template int SMALLER(vector &a, T x) { return lower_bound(a.begin(), a.end(), x) - a.begin(); } template int orSMALLER(vector &a, T x) { return upper_bound(a.begin(), a.end(), x) - a.begin(); } template int BIGGER(vector &a, T x) { return a.size() - orSMALLER(a, x); } template int orBIGGER(vector &a, T x) { return a.size() - SMALLER(a, x); } template int COUNT(vector &a, T x) { return upper_bound(ALL(a), x) - lower_bound(ALL(a), x); } template bool chmax(T &a, S b) { if (a < b) { a = b; return 1; } return 0; } template bool chmin(T &a, S b) { if (a > b) { a = b; return 1; } return 0; } template void press(T &v) { v.erase(unique(ALL(v)), v.end()); } template vector zip(vector b) { pair p[b.size() + 10]; int a = b.size(); vector l(a); for (int i = 0; i < a; i++) p[i] = mp(b[i], i); sort(p, p + a); int w = 0; for (int i = 0; i < a; i++) { if (i && p[i].first != p[i - 1].first) w++; l[p[i].second] = w; } return l; } template vector vis(vector &v) { vector S(v.size() + 1); rep(i, 1, S.size()) S[i] += v[i - 1] + S[i - 1]; return S; } ll dem(ll a, ll b) { return ((a + b - 1) / (b)); } ll dtoll(double d, int g) { return round(d * pow(10, g)); } const double EPS = 1e-10; void init() { cin.tie(0); cout.tie(0); ios::sync_with_stdio(0); cout << fixed << setprecision(12); } // do {} while (next_permutation(ALL(vec))); /********************************** START **********************************/ void sol(); int main() { init(); int q = 1; // cin >> q; while (q--) sol(); return 0; } /********************************** SOLVE **********************************/ template struct FormalPowerSeries : vector { using vector::vector; using vector::operator=; using F = FormalPowerSeries; FormalPowerSeries() {} F operator-() const { F res(*this); for (auto &e : res) e = -e; return res; } F &operator*=(const T &g) { for (auto &e : *this) e *= g; return *this; } F &operator/=(const T &g) { assert(g != T(0)); *this *= g.inv(); return *this; } F &operator+=(const F &g) { int n = (*this).size(), m = g.size(); (*this).resize(max(n, m)); for (int i = 0; i < max(n, m); i++) { (*this)[i] += g[i]; } return *this; } F &operator-=(const F &g) { int n = (*this).size(), m = g.size(); for (int i = 0; i < min(n, m); i++) { (*this)[i] -= g[i]; } return *this; } F &operator<<=(const int d) { int n = (*this).size(); (*this).insert((*this).begin(), d, 0); (*this).resize(n); return *this; } F &operator>>=(const int d) { int n = (*this).size(); (*this).erase((*this).begin(), (*this).begin() + min(n, d)); (*this).resize(n); return *this; } F inv(int d = -1) const { int n = (*this).size(); assert(n != 0 && (*this)[0] != 0); if (d == -1) d = n; assert(d > 0); F res{(*this)[0].inv()}; while (res.size() < d) { int m = size(res); F f(begin(*this), begin(*this) + min(n, 2 * m)); F r(res); f.resize(2 * m), internal::butterfly(f); r.resize(2 * m), internal::butterfly(r); for (int i = 0; i < 2 * m; i++) { f[i] *= r[i]; } internal::butterfly_inv(f); f.erase(f.begin(), f.begin() + m); f.resize(2 * m), internal::butterfly(f); for (int i = 0; i < 2 * m; i++) { f[i] *= r[i]; } internal::butterfly_inv(f); T iz = T(2 * m).inv(); iz *= -iz; for (int i = 0; i < m; i++) { f[i] *= iz; } res.insert(res.end(), f.begin(), f.begin() + m); } return {res.begin(), res.begin() + d}; } // // fast: FMT-friendly modulus only // F &operator*=(const F &g) { // *this = convolution(*this, g); // while ((*this).size() > 1 && (*this).back() == T(0)) // (*this).pop_back(); return *this; // } // F &operator/=(const F &g) { // int n = (*this).size(); // *this = convolution(*this, g.inv(n)); // (*this).resize(n); // return *this; // } // naive F &operator*=(const F &g) { int n = (*this).size(), m = g.size(); F ret; ret.resize(n + m); rep(i, 0, n + m) ret[i] = 0; for (int i = 0; i < n; i++) { for (int j = 0; j < m; j++) { ret[i + j] += (*this)[i] * g[j]; } } *this = ret; return *this; } F &operator/=(const F &g) { assert(g[0] != T(0)); T ig0 = g[0].inv(); int n = (*this).size(), m = g.size(); for (int i = 0; i < n; i++) { for (int j = 1; j < min(i + 1, m); j++) { (*this)[i] -= (*this)[i - j] * g[j]; } (*this)[i] *= ig0; } return *this; } // sparse F &operator*=(vector> g) { int n = (*this).size(); auto [d, c] = g.front(); if (d == 0) g.erase(g.begin()); else c = 0; for (int i = n - 1; i >= 0; i--) { (*this)[i] *= c; for (auto &[j, b] : g) { if (j > i) break; (*this)[i] += (*this)[i - j] * b; } } return *this; } F &operator/=(vector> g) { int n = (*this).size(); auto [d, c] = g.front(); assert(d == 0 && c != T(0)); T ic = c.inv(); g.erase(g.begin()); for (int i = 0; i < n; i++) { for (auto &[j, b] : g) { if (j > i) break; (*this)[i] -= (*this)[i - j] * b; } (*this)[i] *= ic; } return *this; } // multiply and divide (1 + cz^d) void multiply(const int d, const T c) { int n = (*this).size(); if (c == T(1)) for (int i = n - d - 1; i >= 0; i--) (*this)[i + d] += (*this)[i]; else if (c == T(-1)) for (int i = n - d - 1; i >= 0; i--) (*this)[i + d] -= (*this)[i]; else for (int i = n - d - 1; i >= 0; i--) (*this)[i + d] += (*this)[i] * c; } void divide(const int d, const T c) { int n = (*this).size(); if (c == T(1)) for (int i = 0; i < n - d; i++) (*this)[i + d] -= (*this)[i]; else if (c == T(-1)) for (int i = 0; i < n - d; i++) (*this)[i + d] += (*this)[i]; else for (int i = 0; i < n - d; i++) (*this)[i + d] -= (*this)[i] * c; } T eval(const T &a) const { T x(1), res(0); for (auto e : *this) res += e * x, x *= a; return res; } F operator*(const T &g) const { return F(*this) *= g; } F operator/(const T &g) const { return F(*this) /= g; } F operator+(const F &g) const { return F(*this) += g; } F operator-(const F &g) const { return F(*this) -= g; } F operator<<(const int d) const { return F(*this) <<= d; } F operator>>(const int d) const { return F(*this) >>= d; } F operator*(const F &g) const { return F(*this) *= g; } F operator/(const F &g) const { return F(*this) /= g; } F operator*(vector> g) const { return F(*this) *= g; } F operator/(vector> g) const { return F(*this) /= g; } }; template struct Matrix { vector> A; Matrix() {} Matrix(size_t n, size_t m) : A(n, std::vector(m, zero())) {} Matrix(size_t n) : A(n, std::vector(n, zero())){}; T zero() { return (T()); } size_t height() const { return (A.size()); } size_t width() const { return (A[0].size()); } inline const vector &operator[](int k) const { return (A.at(k)); } inline vector &operator[](int k) { return (A.at(k)); } static Matrix I(size_t n) { Matrix mat(n); for (int i = 0; i < n; i++) mat[i][i] = 1; return (mat); } Matrix &operator+=(const Matrix &B) { size_t n = height(), m = width(); assert(n == B.height() && m == B.width()); for (int i = 0; i < n; i++) for (int j = 0; j < m; j++) (*this)[i][j] += B[i][j]; return (*this); } Matrix &operator-=(const Matrix &B) { size_t n = height(), m = width(); assert(n == B.height() && m == B.width()); for (int i = 0; i < n; i++) for (int j = 0; j < m; j++) (*this)[i][j] -= B[i][j]; return (*this); } Matrix &operator*=(const Matrix &B) { size_t n = height(), m = B.width(), p = width(); assert(p == B.height()); vector> C(n, vector(m, zero())); for (int i = 0; i < n; i++) { for (int j = 0; j < m; j++) { // cerr << "今からかけるよ!" << endl; // cerr << (*this)[i][j] << "x"; // cerr << B[i][j] << "="; for (int k = 0; k < p; k++) { if ((*this)[i][k] == zero()) continue; if (B[k][j] == zero()) continue; C[i][j] += (*this)[i][k] * B[k][j]; } // cerr << C[i][j] << endl; } } A.swap(C); return (*this); } Matrix &operator^=(long long k) { Matrix B = Matrix::I(height()); while (k > 0) { if (k & 1) B *= *this; *this *= *this; k >>= 1LL; } A.swap(B.A); return (*this); } Matrix operator+(const Matrix &B) const { return (Matrix(*this) += B); } Matrix operator-(const Matrix &B) const { return (Matrix(*this) -= B); } Matrix operator*(const Matrix &B) const { return (Matrix(*this) *= B); } Matrix operator^(const long long k) const { return (Matrix(*this) ^= k); } friend ostream &operator<<(ostream &os, Matrix &p) { size_t n = p.height(), m = p.width(); for (int i = 0; i < n; i++) { for (int j = 0; j < m; j++) { os << p[i][j] << (j + 1 == m ? "\n" : " "); } } return (os); } T determinant() { // O(n^3) Matrix B(*this); assert(width() == height()); T ret = 1; for (int i = 0; i < width(); i++) { int idx = -1; for (int j = i; j < width(); j++) { if (B[j][i] != 0) idx = j; } if (idx == -1) return (0); if (i != idx) { ret *= -1; swap(B[i], B[idx]); } ret *= B[i][i]; T vv = B[i][i]; for (int j = 0; j < width(); j++) { B[i][j] /= vv; } for (int j = i + 1; j < width(); j++) { T a = B[j][i]; for (int k = 0; k < width(); k++) { B[j][k] -= B[i][k] * a; } } } return (ret); } }; using mint = modint998244353; using fps = FormalPowerSeries; using sfps = vector>; void sol() { int n; string s; cin >> n >> s; int nn = n; set nibe; rep(i, 0, 40) { nibe.insert(1LL << i); } while (!nibe.count(n)) { n++; s += 'E'; } vector> dp(n * 2, Matrix(2, 2)); // fps型の0と1とxを定義 fps zero = {0}, one = {1}, x = {0, 1}; rep(i, 0, n) { // R に[[1,x],[0,1]]の行列を // B に[[1,0],[x,1]]の行列を // E に[[1,0],[0,1]]の行列を入れる if (s[i] == 'R') { dp[i + n][0][0] = one; dp[i + n][0][1] = x; dp[i + n][1][0] = zero; dp[i + n][1][1] = one; } else if (s[i] == 'B') { dp[i + n][0][0] = one; dp[i + n][0][1] = zero; dp[i + n][1][0] = x; dp[i + n][1][1] = one; } else { dp[i + n][0][0] = one; dp[i + n][0][1] = zero; dp[i + n][1][0] = zero; dp[i + n][1][1] = one; } } repreq(i, n - 1, 1) { dp[i] = dp[i * 2] * dp[i * 2 + 1]; } // rep(i, 1, dp.size()) { // cerr << i << endl; // rep(j, 0, 2) { // rep(k, 0, 2) { // cerr << j << ' ' << k << ' ' << dp[i][j][k] << endl; // } // } // } fps ans = dp[1][0][0] + dp[1][0][1] + dp[1][1][0] + dp[1][1][1]; repeq(i, 1, nn) { if (i < ans.size()) cout << ans[i] << endl; else cout << 0 << endl; } // cout << ans; // fps p = {2, 3}, q = {2, 5}; // cout << p * q << endl; }