// Subtasks:
// 1: AC
// 2: AC
// 3: AC
// 4: AC 68

#include <iostream>
#include <map>
#include <cassert>
#include <random>

using namespace std;
typedef long long ll;
#define all(x) x.begin(), x.end()
#define sz(x) (int)(x).size()
// mt19937 mt(time(0));
mt19937 mt(1338);

map<pair<ll, ll>, bool> mem;
bool ask(ll u, ll v) {
    if (u > v) return !ask(v, u);
    if (mem.count({u, v})) return mem[{u, v}];
    cout << "? " << u+1 << " " << v+1 << endl;
    char r;
    cin >> r;
    return mem[{u, v}] = r == '>';
}

void solve(ll n) {
    mem.clear();

    // initialize length 2 paths
    vector<vector<ll>> paths;
    for (ll i = 0; i < n/2; i++) {
        if (ask(2*i, 2*i+1)) paths.push_back({2*i, 2*i+1});
        else paths.push_back({2*i+1, 2*i});
    }
    if (n & 1) paths.push_back({n-1});

    auto split_random_path = [&]() {
        ll i;
        do i = mt() % sz(paths);
        while (sz(paths[i]) < 2);
        ll k = 1 + mt() % (sz(paths[i]) - 1);
        paths.emplace_back(paths[i].begin() + k, paths[i].end());
        paths[i].erase(paths[i].begin() + k, paths[i].end());
    };

    ll bad_iterations = 0;
    merge_paths:
    while (sz(paths) > 1) {
        ll i = mt() % sz(paths);
        ll j = mt() % sz(paths);
        if (i == j) continue;
        if (ask(paths[i].back(), paths[j][0])) {
            paths[i].insert(paths[i].end(), all(paths[j]));
            paths.erase(paths.begin() + j);
        }
        // EDITED: For small n, don't split too often
        else if (++bad_iterations % max(n, 10ll) == 0) {
            split_random_path();
        }
    }
    if (!ask(paths[0].back(), paths[0][0])) {
        split_random_path();
        goto merge_paths;
    }

    // verify correctness
    for (ll i = 0; i+1 < n; i++) {
        assert(ask(paths[0][i], paths[0][i+1]));
    }
    assert(ask(paths[0].back(), paths[0][0]));

    cout << "! ";
    for (ll i = 0; i < n; i++) {
        cout << paths[0][i]+1 << " ";
    }
    cout << endl;
}

const int N = 505;
bool adj[N][N];

int main() {
    ll n, t;
    cin >> n >> t;

    if (n < 40) {
        for (int i = 0; i < n; ++i) {
            for (int j = 1; j <= n/2; ++j) {
                int k = (i+j) % n;
                adj[i][k] = 1;
                adj[k][i] = 0;
            }
        }
    } else {
        for (int i = 0; i < n; ++i) {
            for (int j = 1; j <= n/2; ++j) {
                int k = (i+j) % n;
                adj[i][k] = mt() % 2;
                adj[k][i] = adj[i][k] ^ 1;
            }
        }
    }

    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < n; ++j) {
            cout << adj[i][j];
        }
        cout << endl;
    }

    for (int ti = 0; ti < t; ++ti) solve(n);
}
