// May this submission get accepted!

#pragma GCC optimize ("O3")
#pragma GCC target ("tune=native")
#pragma GCC target ("avx")

#include <bits/stdc++.h>

// 汎用マクロ
#define ALL_OF(x) (x).begin(), (x).end()
#define REP(i,n) for (long long i=0, i##_len=(n); i<i##_len; i++)
#define RANGE(i,is,ie) for (long long i=(is), i##_end=(ie); i<=i##_end; i++)
#define DSRNG(i,is,ie) for (long long i=(is), i##_end=(ie); i>=i##_end; i--)
#define STEP(i, is, ie, step) for (long long i=(is), i##_end=(ie), i##_step = (step); i<=i##_end; i+=i##_step)
#define UNIQUE(v) do { sort((v).begin(), (v).end()); (v).erase(unique((v).begin(), (v).end()), (v).end()); } while (false)
template<class T> bool chmax(T &a, const T &b) { if (a < b) {a = b; return true;} return false; }
template<class T> bool chmin(T &a, const T &b) { if (a > b) {a = b; return true;} return false; }
#define INF 0x7FFFFFFF
#define LINF 0x7FFFFFFFFFFFFFFFLL
#define Yes(q) ((q) ? "Yes" : "No")
#define YES(q) ((q) ? "YES" : "NO")
#define Possible(q) ((q) ? "Possible" : "Impossible")
#define POSSIBLE(q) ((q) ? "POSSIBLE" : "IMPOSSIBLE")
#define DUMP(q) cerr << "[DEBUG] " #q ": " << (q) << " at " __FILE__ ":" << __LINE__ << endl
#define DUMPALL(q) do { cerr << "[DEBUG] " #q ": ["; REP(DUMPALL_ITR, (q).size()) { cerr << (q)[DUMPALL_ITR] << (DUMPALL_ITR == DUMPALL_ITR_len-1 ? "" : ", "); } cerr << "] at " __FILE__ ":" << __LINE__ << endl; } while (false)
template<class T> T gcd(T a, T b) { if (a < b) std::swap(a, b); while (b) std::swap(a %= b, b); return a; }
template<class T> T lcm(const T a, const T b) { return a / gcd(a, b) * b; }

// gcc拡張マクロ
#define popcount __builtin_popcount
#define popcountll __builtin_popcountll

// エイリアス
#define DANCE_ long
#define ROBOT_ unsigned
#define HUMAN_ signed
using  ll = DANCE_ HUMAN_ DANCE_;
using ull = DANCE_ ROBOT_ DANCE_;
using  ld = long double;
using namespace std;

// モジュール

string ask(vector<ll> &a) {
    string res;
    cout << "?";
    for (ll &ai : a) cout << " " << ai;
    cout << endl;
    cin >> res;
    if (res == "-1"s) exit(1);
    return res;
}

string ask_seq(ll n, ll i) {
    vector<ll> a(n);
    REP(j, n) a[j] = (i + j - 1) % (n * 2) + 1;
    return ask(a);
}

// 処理内容
int main() {
    
    ll n; cin >> n;

    if (n == 1) {
        cout << "? 1" << endl;
        string s; cin >> s;
        cout << (s[0] == 'R' ? "! RB" : "! BR") << endl;
        return 0;
    }
    
    string ans(n * 2, ' ');
    
    ll a = 1;   string ar = ask_seq(n, 1);
    ll b = n+1; string br = ar[0] == 'R' ? "Blue" : "Red";
    while (b - a > 1) {
        ll c = (b + a) / 2;
        string cr = ask_seq(n, c);
        (cr == ar ? a : b) = c;
    }
    ans[a-1]   = ar[0];
    ans[a+n-1] = br[0];

    vector<ll> eqset(n, -1);
    RANGE(i, b, b+n-2) eqset[i-b] = (i-1) % (n*2) + 1;
    
    RANGE(i, 0, n*2-1) {
        eqset.back() = -1;
        if (i == a-1 || i == a+n-1) continue;
        if (find(ALL_OF(eqset), i+1) == eqset.end()) {
            eqset.back() = i+1;
            ans[i] = ask(eqset)[0];
        }
    }

    vector<ll> reds, blues, neqset;
    eqset.back() = -1;
    RANGE(i, 1, n*2) {
        if (find(ALL_OF(eqset), i) >= eqset.end() - 1) {
            (ans[i-1] == 'R' ? reds : blues).push_back(i);
        }
    }
    REP(i, n/2) {
        neqset.push_back(reds[i]);
        neqset.push_back(blues[i]);
    }
    neqset.push_back(-1);
    DUMPALL(neqset);

    REP(j, n-1) {
        ll i = eqset[j];
        neqset.back() = i;
        ans[i-1] = ask(neqset)[0];
    }

    cout << "! " << ans << endl;
    
}

Measured memory_bytes: 724