#pragma GCC optimize("Ofast", "unroll-loops", "no-stack-protector")

#include <bits/stdc++.h>

using namespace std;

#define all(a) (a).begin(), (a).end()
#define sz(a) (int)(a).size()

using ll = long long;
using ld = double;
using pii = pair<int, int>;
using uint = unsigned int;
using ull = unsigned long long;

mt19937 rnd(chrono::steady_clock::now().time_since_epoch().count());
default_random_engine generator;

void solve();

int main() {
#ifdef LOCAL
    // freopen("input.txt", "r", stdin);
    // freopen("output.txt", "w", stdout);  
#endif 
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    cout << setprecision(16) << fixed;
    cerr << setprecision(16) << fixed;

    int tests = 1;
    // cin >> tests;

    for (int test = 1; test <= tests; ++test) {
        // cout << "Case #" << test << ": ";
        solve();
    }

#ifdef LOCAL
    cerr << "Time: " << double(clock()) / CLOCKS_PER_SEC << endl;
#endif
}

// -----------------------------------------------------------------

// int m;

// int f(int x) {
//     int pw = 1;
//     int y = 0;
//     while (x > 0) {
//         y += (x % 3 == 0 ? 0 : 3 - x % 3) * pw;
//         x /= 3;
//         pw *= 3;
//     }
//     return y;
// }

// int g(int x) {
//     return (x + 1) % m;
// }

// vector<int> f(const vector<int> &p) {
//     vector<int> q;
//     for (int x : p) {
//         q.push_back(f(x));
//     }
//     return q;
// }

// vector<int> g(const vector<int> &p) {
//     vector<int> q;
//     for (int x : p) {
//         q.push_back(g(x));
//     }
//     return q;
// }

void solve() {
    int n;
    cin >> n;

    int m = 1;
    for (int i = 0; i < n; ++i) {
        m *= 3;
    }

    string s;
    cin >> s;

    vector<int> res(m);

    vector<int> pos(sz(s), 0);

    for (int k = 1, t = 1; k <= n; ++k, t *= 3) {
        vector<int> p(3 * t);
        for (int i = 0; i < 3 * t; ++i) {
            p[i] = i / t;
        }

        // for (int i = 0; i < 3 * t; ++i) {
        //     cerr << p[i] << " ";
        // }
        // cerr << endl;


        vector<int> last(3 * t, 0);
        int cnt = 0;

        for (int i = 0; i < sz(s); ++i) {
            int new_pos = -1;

            for (int x = 0; x < 3; ++x) {
                int ps = pos[i] + x * t;
                if ((cnt - last[ps]) & 1) {
                    p[ps] = (3 - p[ps]) % 3;
                }
                last[ps] = cnt;

                if (p[ps] == 2) {
                    new_pos = ps;
                }
            }

            if (s[i] == 'S') {
                ++cnt;
            } else {
                for (int x = 0; x < 3; ++x) {
                    int ps = pos[i] + x * t;
                    // if ((cnt - last[ps]) & 1) {
                    //     p[ps] = (3 - p[ps]) % 3;
                    // }
                    // last[ps] = cnt;
                    p[ps] = (p[ps] + 1) % 3; 
                }
            }

            assert(new_pos != -1);
            pos[i] = new_pos;
        }

        for (int i = 0; i < 3 * t; ++i) {
            if ((cnt - last[i]) & 1) {
                p[i] = (3 - p[i]) % 3;
            }
        }

        for (int i = 0; i < m; ++i) {
            res[i] += t * p[i % (3 * t)];
        }
    }

    for (int x : res) {
        cout << x << " ";
    }
    cout << endl;






    // int n;
    // cin >> n;

    // m = 1;
    // for (int i = 0; i < n; ++i) {
    //     m *= 3;
    // }

    // set<vector<int>> used;

    // vector<int> p(m);

    // iota(all(p), 0);

    // used.insert(p);

    // queue<vector<int>> que;
    // que.push(p);


    // // string s;
    // // cin >> s;

    // // for (int i = 0; i < sz(s); ++i) {
    // //     if (s[i] == 'S') {
    // //         p = f(p);
    // //     } else {
    // //         p = g(p);
    // //     }
    // // } 

    // // for (int x : p) {
    // //     cerr << x << " ";
    // // }
    // // cerr << endl;

    // while (!que.empty()) {
    //     vector<int> q = que.front();
    //     que.pop();
    //     vector<int> r;

    //     r = f(q);
    //     if (!used.count(r)) {
    //         used.insert(r);
    //         que.push(r);
    //     }

    //     r = g(q);
    //     if (!used.count(r)) {
    //         used.insert(r);
    //         que.push(r);
    //     }
    // }

    // set<pii> setik;

    // for (auto p : used) {
    //     setik.insert({p[0], p[1]});
    //     // for (int i = 0; i < m; ++i) {
    //     //     // q[p[i]] = i;
    //     //     cout << p[i] << " ";
    //     // }

    //     // for (int x : q) {
    //     //     cerr << x << " ";
    //     // }
    //     // cout << endl;
    // }

    // for (auto [x, y] : setik) {
    //     cerr << x << " " << y << endl;
    // }

    // cout << sz(used) << endl;

}   


Measured memory_bytes: 10500