/** author: shobonvip created: 2026.04.19 09:21:56 **/ #include using namespace std; //* ATCODER #include using namespace atcoder; typedef modint998244353 mint; //*/ /* BOOST MULTIPRECISION #include using namespace boost::multiprecision; //*/ typedef long long ll; #define rep(i, s, n) for (int i = (int)(s); i < (int)(n); i++) #define rrep(i, s, n) for (int i = (int)(n)-1; i >= (int)(s); i--) #define all(v) v.begin(), v.end() template bool chmin(T &a, const T &b) { if (a <= b) return false; a = b; return true; } template bool chmax(T &a, const T &b) { if (a >= b) return false; a = b; return true; } template T max(vector &a){ assert(!a.empty()); T ret = a[0]; for (int i=0; i<(int)a.size(); i++) chmax(ret, a[i]); return ret; } template T min(vector &a){ assert(!a.empty()); T ret = a[0]; for (int i=0; i<(int)a.size(); i++) chmin(ret, a[i]); return ret; } template T sum(vector &a){ T ret = 0; for (int i=0; i<(int)a.size(); i++) ret += a[i]; return ret; } int op(int a, int b) { return a + b; } int e() { return 0; } const ll INF = 2e18; void solve() { int n; ll k; cin >> n >> k; vector a(n - 1); rep(i,0,n - 1) { cin >> a[i]; } vector daihyo(n, -1); iota(all(daihyo), 0); segtree seg(vector(n,1)); int xt; auto f = [&](int z) -> bool { return z < xt; }; vector l(2*n-1,-1),r(2*n-1,-1); rep(i,0,n-1) { xt = a[i]; int x = seg.max_right(0, f); xt = 1; int y = seg.max_right(x + 1, f); l[n+i] = daihyo[x]; r[n+i] = daihyo[y]; daihyo[x] = n+i; daihyo[y] = -1; seg.set(x, 1); seg.set(y, 0); } vector> dp(2*n-1,vector(3)); auto dfs = [&](auto self, int i) -> void { if (l[i]==-1) { fill(all(dp[i]),1LL); return; } self(self, l[i]); self(self, r[i]); // (R,P) dp[i][0] += min((__int128)INF, (__int128)dp[l[i]][1] * dp[r[i]][0]); dp[i][0] += min((__int128)INF, (__int128)dp[l[i]][0] * dp[r[i]][1]); chmin(dp[i][0], INF); // (S,R) dp[i][1] += min((__int128)INF, (__int128)dp[l[i]][2] * dp[r[i]][1]); dp[i][1] += min((__int128)INF, (__int128)dp[l[i]][1] * dp[r[i]][2]); chmin(dp[i][1], INF); // (P,S) dp[i][2] += min((__int128)INF, (__int128)dp[l[i]][0] * dp[r[i]][2]); dp[i][2] += min((__int128)INF, (__int128)dp[l[i]][2] * dp[r[i]][0]); chmin(dp[i][2], INF); }; dfs(dfs,2*n-2); // 辞書順... P,R,S k--; vector> t1(3), t2(3); t1[0] = pair(0,1); t1[1] = pair(1,2); t1[2] = pair(0,2); t2[0] = pair(1,0); t2[1] = pair(2,1); t2[2] = pair(2,0); vector ans(2*n-1); auto dfs2 = [&](auto self, int x, ll r0, ll r1, ll r2, ll k) -> ll { if (x < n) { if (r0 > k) { ans[x] = 0; return 0; } else if (r0 + r1 > k) { ans[x] = 1; return r0; } else { ans[x] = 2; return r0 + r1; } } //cout << x << ' ' << r0 << ' ' << r1 << ' ' << r2 << ' ' << k << endl; // 0 が来たら r0 加算、1 が来たら r1 加算、2 が来たら r2 加算 // のルールで、k 番目の値を求めたい。 ll lft = k / min((__int128)INF, (__int128)dp[r[x]][t1[0].second]); // まず左側は、対応する右側の数だけ乗算させられる。 ll nl0 = min(INF, r0 + r2); ll nl1 = min(INF, r0 + r1); ll nl2 = min(INF, r1 + r2); // 0 には r0 回, 1 には r1 回対応する // もし出来上がったのが 1 だったら ? // 右側が 2 だったら r1 加算、 0 だったら r0 加算。 // k はどうなる ? // g がバッファーとなる. ll g = self(self, l[x], nl0, nl1, nl2, lft); ll rgt = k - g * dp[r[x]][t1[0].second]; ll t; if (ans[l[x]] == 0) { t = self(self, r[x], 0, r0, r2, rgt); } else if (ans[l[x]] == 1) { t = self(self, r[x], r0, 0, r1, rgt); } else { t = self(self, r[x], r2, r1, 0, rgt); } if (ans[l[x]] + ans[r[x]] == 1) ans[x] = 0; if (ans[l[x]] + ans[r[x]] == 2) ans[x] = 2; if (ans[l[x]] + ans[r[x]] == 3) ans[x] = 1; return g * dp[r[x]][t1[0].second] + t; }; // R,P,S for (int d:{1,0,2}) { int x = 2*n-2; if (dp[x][d] <= k) { cout << -1 << '\n'; continue; } dfs2(dfs2,x,int(d==0),int(d==1),int(d==2),k); rep(i,0,n) { char c = (ans[i] == 0 ? 'P' : (ans[i] == 1 ? 'R' : 'S')); cout << c; } cout << '\n'; } } int main(){ ios_base::sync_with_stdio(false); cin.tie(NULL); int t; cin >> t; while (t--) solve(); }