Problem: cf1451_e2
Difficulty: easy
Categories: bit, math
Time limit: 4000 ms, memory limit: 256 MB

The only difference between the easy and hard versions is the constraints on the number of queries.

This is an interactive problem.

Ridbit has a hidden array $a$ of $n$ integers which he wants Ashish to guess. Note that $n$ is a power of two. Ashish is allowed to ask three different types of queries. They are of the form

* AND $i$ $j$: ask for the bitwise AND of elements $a_i$ and $a_j$ $(1 \leq i, j \le n$, $i \neq j)$
* OR $i$ $j$: ask for the bitwise OR of elements $a_i$ and $a_j$ $(1 \leq i, j \le n$, $i \neq j)$
* XOR $i$ $j$: ask for the bitwise XOR of elements $a_i$ and $a_j$ $(1 \leq i, j \le n$, $i \neq j)$

Can you help Ashish guess the elements of the array?

In this version, each element takes a value in the range $[0, n-1]$ (inclusive) and Ashish can ask no more than $n+1$ queries.

Input

The first line of input contains one integer $n$ $(4 \le n \le 2^{16})$ — the length of the array. It is guaranteed that $n$ is a power of two.

Interaction

To ask a query print a single line containing one of the following (without quotes)

* "AND i j"
* "OR i j"
* "XOR i j"

where $i$ and $j$ $(1 \leq i, j \le n$, $i \neq j)$ denote the indices being queried.

For each query, you will receive an integer $x$ whose value depends on the type of query. If the indices queried are invalid or you exceed the number of queries however, you will get $x = -1$. In this case, you should terminate the program immediately.

When you have guessed the elements of the array, print a single line "! " (without quotes), followed by $n$ space-separated integers  — the elements of the array.

Guessing the array does not count towards the number of queries asked.

The interactor is not adaptive. The array $a$ does not change with queries.

After printing a query do not forget to output the end of the line and flush the output. Otherwise, you will get Idleness limit exceeded. To do this, use:

* fflush(stdout) or cout.flush() in C++;
* System.out.flush() in Java;
* flush(output) in Pascal;
* stdout.flush() in Python;
* see the documentation for other languages.

Example

Input

```
4

0

2

3
```

Output

```
OR 1 2

OR 2 3

XOR 2 4! 0 0 2 3
```

Note

The array $a$ in the example is $[0, 0, 2, 3]$.

Non-adaptive interactor (C++):
#include "testlib.h"
#include <bits/stdc++.h>
using namespace std;

static long long queries = 0;
static long long query_limit = 0;

static void log_metrics() {
    try {
        tout << "queries=" << queries << endl;
        tout << "query_limit=" << query_limit << endl;
    } catch (...) {
        
    }
}

static void finish(TResult verdict, const string& msg) {
    log_metrics();
    quitf(verdict, "%s", msg.c_str());
}

static bool isPow2(int x) { return x >= 1 && (x & (x - 1)) == 0; }

static string toUpperStr(string s) {
    for (char &c : s) c = (char)toupper((unsigned char)c);
    return s;
}

int main(int argc, char** argv) {
    registerInteraction(argc, argv);
    atexit(log_metrics);

    int n = inf.readInt(4, 1 << 16, "n");
    if (!isPow2(n)) finish(_pe, "n is not a power of two in hidden input");

    vector<int> a(n + 1);
    for (int i = 1; i <= n; i++) {
        a[i] = inf.readInt(0, n - 1, ("a[" + to_string(i) + "]").c_str());
    }

    query_limit = (long long)n + 1;
    log_metrics(); 

    cout << n << endl; 
    cout.flush();

    long long hard_cap = max(200000LL, 10LL * query_limit);

    while (true) {
        string cmd;
        if (!(cin >> cmd)) {
            finish(_pe, "Unexpected EOF from contestant (no final answer)");
        }
        cmd = toUpperStr(cmd);

        if (cmd == "!") {
            vector<int> ans(n + 1);
            for (int i = 1; i <= n; i++) {
                long long x;
                if (!(cin >> x)) finish(_pe, "Could not read full answer array after '!'");
                if (x < 0 || x > n - 1) finish(_wa, "Answer element out of allowed range");
                ans[i] = (int)x;
            }
            for (int i = 1; i <= n; i++) {
                if (ans[i] != a[i]) finish(_wa, "Wrong array");
            }
            finish(_ok, "Correct");
        }

        if (cmd != "AND" && cmd != "OR" && cmd != "XOR") {
            cout << -1 << endl;
            cout.flush();
            finish(_pe, "Invalid command token");
        }

        long long i, j;
        if (!(cin >> i >> j)) {
            finish(_pe, "Could not read query indices");
        }

        if (i < 1 || i > n || j < 1 || j > n || i == j) {
            cout << -1 << endl;
            cout.flush();
            finish(_pe, "Invalid query indices");
        }

        int ai = a[(int)i], aj = a[(int)j];
        int res = 0;
        if (cmd == "AND") res = (ai & aj);
        else if (cmd == "OR") res = (ai | aj);
        else res = (ai ^ aj);

        queries++;
        if (queries > hard_cap) {
            finish(_pe, "Hard cap exceeded (possible infinite loop)");
        }

        cout << res << endl;
        cout.flush();
    }
}


Adaptive interactor (C++):

Test generator (C++):
#include "testlib.h"
#include <bits/stdc++.h>
using namespace std;

static bool isPow2(int x) { return x >= 1 && (x & (x - 1)) == 0; }

static int clampPow2InRange(int n) {
    n = max(n, 4);
    n = min(n, 1 << 16);
    if (isPow2(n)) return n;
    int p = 1;
    while (p < n) p <<= 1;
    int lower = p >> 1;
    if (lower >= 4 && (n - lower) <= (p - n)) n = lower;
    else n = p;
    n = min(n, 1 << 16);
    if (n < 4) n = 4;
    return n;
}

static vector<int> permAffine(int n, bool forceNonZeroFirst) {
    int mask = n - 1;
    int mul = rnd.next(1, n - 1) | 1; 
    int add;
    if (forceNonZeroFirst && n > 1) add = rnd.next(1, n - 1);
    else add = rnd.next(0, n - 1);
    vector<int> a(n);
    for (int i = 0; i < n; i++) {
        long long v = 1LL * mul * i + add;
        a[i] = int(v & mask);
    }
    return a;
}

static vector<int> permGrayXor(int n, bool forceNonZeroFirst) {
    int c;
    if (forceNonZeroFirst && n > 1) c = rnd.next(1, n - 1);
    else c = rnd.next(0, n - 1);
    vector<int> a(n);
    for (int i = 0; i < n; i++) {
        int g = i ^ (i >> 1);
        a[i] = g ^ c;
    }
    return a;
}

static vector<int> permShuffled(int n, bool forceNonZeroFirst) {
    vector<int> p(n);
    iota(p.begin(), p.end(), 0);
    for (int i = n - 1; i >= 1; --i) {
        int j = rnd.next(0, i);
        swap(p[i], p[j]);
    }
    if (forceNonZeroFirst && n > 1) {
        int want = rnd.next(1, n - 1);
        int pos = 0;
        for (int i = 0; i < n; i++) if (p[i] == want) { pos = i; break; }
        swap(p[0], p[pos]);
    }
    return p;
}

int main(int argc, char** argv) {
    registerGen(argc, argv, 1);

    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    string mode = opt<string>("mode", "non"); 
    int seed = (argc >= 2 ? atoi(argv[1]) : 1);

    int n = 0;
    vector<int> a;

    auto outputNon = [&](int nn, const vector<int>& aa) {
        cout << nn << "\n";
        for (int i = 0; i < nn; i++) {
            if (i) cout << ' ';
            cout << aa[i];
        }
        cout << "\n";
    };

    
    if (seed == 1) {
        n = 4;
        a = {0, 0, 0, 0}; 
    } else if (seed == 2) {
        n = 4;
        a = {2, 3, 1, 0}; 
    } else if (seed == 3) {
        n = 8;
        a = {3, 0, 5, 5, 1, 2, 4, 6}; 
    } else {
        int exp = opt<int>("exp", -1);
        int nOpt = opt<int>("n", 1 << 16);
        if (exp != -1) {
            exp = max(exp, 2);
            exp = min(exp, 16);
            n = 1 << exp;
        } else {
            n = clampPow2InRange(nOpt);
        }

        string kind = opt<string>("kind", "auto");     
        string permType = opt<string>("perm", "auto"); 
        bool forceNonZeroFirst = opt<int>("nonzero_first", 1) != 0;

        if (kind == "auto") {
            
            if (seed % 17 == 0) kind = "const";
            else if (seed % 11 == 0) kind = "dups"; 
            else if (seed % 7 == 0) kind = "dups";
            else kind = "perm";
        }

        auto genPerm = [&]() -> vector<int> {
            string t = permType;
            if (t == "auto") {
                if (seed % 6 == 0) t = "gray";
                else if (seed % 2 == 0) t = "affine";
                else t = "shuf";
            }
            if (t == "affine") return permAffine(n, forceNonZeroFirst);
            if (t == "gray") return permGrayXor(n, forceNonZeroFirst);
            return permShuffled(n, forceNonZeroFirst);
        };

        if (kind == "perm") {
            a = genPerm();
        } else if (kind == "const") {
            int v = rnd.next(0, n - 1);
            a.assign(n, v);
        } else { 
            a = genPerm();

            
            int i = rnd.next(1, n - 1);
            int j = rnd.next(1, n - 1);
            while (j == i) j = rnd.next(1, n - 1);
            a[j] = a[i];

            
            bool addX0 = (seed % 11 == 0);
            if (addX0 && n >= 4) {
                int k = rnd.next(1, n - 1);
                while (k == i || k == j) k = rnd.next(1, n - 1);
                a[k] = a[0];
            }
        }
    }

    if (mode == "adp") {
        
        cout << n << "\n";
        return 0;
    }

    
    outputNon(n, a);
    return 0;
}