import java.io.*;
import java.util.*;

/**
 * Created by roi on 07.04.2016.
 */
public class Task6 {

    void solve(IO io) {
        int n = io.n();
        ans = new int[n];
        ans[0] = 1;

        int max = 1;
        for (i = 1; i < n; i++) {
            int left = 0;
            int right = i;
            while (right - left > 1) {
                int j = left + (right - left) / 2;

                int res = safeAsk(io, j, i);
                int cnt = safeAsk(io, j, i - 1);
                if (res != cnt) {
                    right = j;
                } else {
                    left = j;
                }
            }

            if (safeAsk(io, left, i - 1) == safeAsk(io, left, i)) {
                ans[i] = ans[left];
            }
            if (ans[i] == 0) {
                ans[i] = ++max;
            }
        }

        if (max != io.safeAsk(0, n - 1)) throw new AssertionError();

        io.finish(ans, max);
    }

    int i;
    int[] ans;

    int safeAsk(IO io, int i, int j) {
        if (j < this.i -1) {
            HashSet<Integer> kek = new HashSet<>();
            for (int k = i; k <= j; k++) {
                kek.add(ans[k]);
            }
            return kek.size();
        }
        return io.safeAsk(i, j);
    }


    public static void main(String[] args) {
        Task6 solver = new Task6();
        if (System.getProperty("os.name").contains("Windows")) {
            solver.solve(new DebugIO());
        } else {
            solver.solve(new RealIO());
        }
    }

    abstract static class IO {
        int reqCnt = 0;

        abstract int n();

        abstract int ask(int i, int j);

        abstract void finish(int[] ans, int cnt);

        int[][] cache = new int[3001][3001];

        boolean hasCached(int i, int j) {
            return cache[i][j] != 0;
        }

        int safeAsk(int i, int j) {
            if (i == j) return 1;
            if (cache[i][j] == 0) {
                cache[i][j] = ask(i, j);
            }
            return cache[i][j];
        }

        int safeAsk_(int i, int j) {
            reqCnt--;
            return safeAsk(i, j);
        }
    }


    static class DebugIO extends IO {
        DebugIO() {
            try {
                BufferedReader in = new BufferedReader(new FileReader("decode.txt"));
                String[] ss = in.readLine().split(" ");
                seq = new int[ss.length];
                for (int i = 0; i < ss.length; i++) {
                    seq[i] = Integer.parseInt(ss[i]);
                }
            } catch (IOException e) {
                e.printStackTrace();
                seq = new int[0];
            }
        }

        int[] seq;

        @Override
        int n() {
            return seq.length;
        }

        @Override
        int ask(int i, int j) {
            reqCnt++;
//            System.err.println(i + " " + j);
            HashSet<Integer> set = new HashSet<>();
            for (int k = i; k <= j; k++) {
                set.add(seq[k]);
            }
            return set.size();
        }

        @Override
        void finish(int[] ans, int cnt) {
            System.err.println(reqCnt + " requests");
            if (Arrays.equals(ans, seq)) {
                System.err.println("OK");
            } else {
                System.err.println("wtf?");
                System.err.println(Arrays.toString(ans));
            }
        }
    }


    static class RealIO extends IO {

        public int ask(int i, int j) {
            reqCnt++;
//            if (reqCnt > 35500) {
//                throw new AssertionError();
//            }
            System.out.println("? " + (i + 1) + " " + (j + 1));
            return nextInt();
        }

        public void finish(int[] ans, int cnt) {
            StringBuilder builder = new StringBuilder("Ready!\n");
            builder.append(cnt).append('\n');
            for (int i : ans) builder.append(i).append(' ');
            System.out.println(builder);
        }

        int _n;

        public int n() {
            return _n;
        }

        BufferedReader in;
        StringTokenizer tok;


        RealIO() {
            in = new BufferedReader(new InputStreamReader(System.in));
            _n = nextInt();
        }

        String nextToken() {
            if (tok == null || !tok.hasMoreTokens()) {
                try {
                    tok = new StringTokenizer(in.readLine());
                } catch (IOException e) {
                    e.printStackTrace();
                    return null;
                }
            }
            return tok.nextToken();
        }

        int nextInt() {
            return Integer.parseInt(nextToken());
        }
    }

}
