#include <cstdio>
#include <iostream>
#include <vector>
#include <algorithm>
#include <string>
#include <cstring>
#include <set>
#include <map>
#include <cmath>

using namespace std;

const int N = 3005;

int col[N];
int par[N];
int rang[N];
int res[N][N];
int gp[N][N];

int getRoot(int v) {
    if (par[v] == v) return v;
    return getRoot(par[v]);
}

void unite(int a, int b) {
    a = getRoot(a), b = getRoot(b);
    if (a == b) return;
    if (rang[a] < rang[b]) swap(a, b);
    par[b] = a;
    rang[a] += (rang[a] == rang[b]);
}

int ask(int lb, int rb) {
    if (res[lb][rb] != 0) return res[lb][rb];
    cout << "? " << lb << ' ' << rb << endl; cout.flush();
    cin >> res[lb][rb];
    gp[lb][rb] = rb - lb + 1 - res[lb][rb];
    return res[lb][rb];
}

int main() {
    int n;
    cin >> n;
    for (int i = 1; i <= n; ++i) {
        par[i] = i;
        res[i][i] = 1;
    }
    ask(1, n);
    for (int r = 2; r <= n; ++r) {
        /*ask(1, r - 1);
        ask(1, r);
        if (!(gp[1][r] - gp[1][r - 1])) continue;*/
        ask(r - 1, r);
        if (gp[r - 1][r]) {
            unite(r - 1, r);
            continue;
        }
        int lg = 1, rg = r;
        while (rg - lg > 1) {
            int mg = (lg + rg) >> 1;
            if (mg == r) {
                rg = mg;
                continue;
            }
            ask(mg, r);
            ask(mg, r - 1);
            int gg = gp[mg][r] - gp[mg][r - 1];
            if (gg > 0) lg = mg;
            else rg = mg;
        }
        unite(lg, r);
    }

    set<int> was;
    map<int, int> cd;
    int cc = 0;
    for (int i = 1; i <= n; ++i) {
        int cr = getRoot(i);
        if (was.find(cr) == was.end()) {
            cd[cr] = ++cc;
            was.insert(cr);
        }
    }
    int ans = ask(1, n);
    cout << "Ready!" << endl;
    cout << ans << endl;
    for (int i = 1; i <= n; ++i) cout << cd[getRoot(i)] << ' ';
    cout << endl; cout.flush();
    return 0;
}