Problem: cf1451_e1
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+2$ 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 << "\n";
        tout << "query_limit=" << query_limit << "\n";
        tout.flush();
    } catch (...) {
        
    }
}

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

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

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

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

    int n;
    try {
        n = inf.readInt();
    } catch (...) {
        finish(_pe, "Failed to read n from hidden input");
    }

    if (n < 4 || n > (1 << 16) || !isPowerOfTwo(n)) {
        
        query_limit = 0;
        log_metrics();
        finish(_pe, "Hidden input invalid: n out of bounds or not power of two");
    }

    vector<int> a(n);
    for (int i = 0; i < n; i++) {
        int v;
        try {
            v = inf.readInt();
        } catch (...) {
            finish(_pe, "Failed to read hidden array");
        }
        a[i] = v;
    }

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

    
    cout << n << endl;

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

    auto reply_and_flush = [&](long long x) {
        cout << x << endl;
    };

    string cmd;
    while (true) {
        if (!(cin >> cmd)) {
            finish(_wa, "Contestant terminated without providing final answer");
        }

        if (cmd == "!") {
            vector<long long> ans(n);
            for (int i = 0; i < n; i++) {
                if (!(cin >> ans[i])) {
                    finish(_pe, "Malformed final answer: expected n integers after '!'");
                }
            }
            for (int i = 0; i < n; i++) {
                if (ans[i] != a[i]) {
                    finish(_wa, "Wrong final array");
                }
            }
            finish(_ok, "OK");
        } else if (cmd == "AND" || cmd == "OR" || cmd == "XOR") {
            long long i, j;
            if (!(cin >> i >> j)) {
                reply_and_flush(-1);
                finish(_pe, "Malformed query: expected two indices");
            }

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

            int x;
            int ai = a[(int)i - 1];
            int aj = a[(int)j - 1];
            if (cmd == "AND") x = (ai & aj);
            else if (cmd == "OR") x = (ai | aj);
            else x = (ai ^ aj);

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

            reply_and_flush(x);
        } else {
            reply_and_flush(-1);
            finish(_pe, "Unknown command");
        }
    }
}


Adaptive interactor (C++):

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

static bool isPowerOfTwo(int n) {
    return n > 0 && (n & (n - 1)) == 0;
}

static int ilog2pow2(int n) {
    int k = 0;
    while ((1 << k) < n) k++;
    return k;
}

static int reverseBitsK(int x, int k) {
    int r = 0;
    for (int i = 0; i < k; i++) {
        r = (r << 1) | (x & 1);
        x >>= 1;
    }
    return r;
}

static vector<int> genPermutationShuffle(int n) {
    vector<int> a(n);
    iota(a.begin(), a.end(), 0);
    for (int i = n - 1; i >= 1; --i) {
        int j = rnd.next(0, i);
        swap(a[i], a[j]);
    }
    return a;
}

static vector<int> genPermutationStructured(int n) {
    int k = ilog2pow2(n);
    int mask = rnd.next(0, n - 1);
    vector<int> a(n);
    for (int i = 0; i < n; i++) {
        int v = reverseBitsK(i, k) ^ mask;
        a[i] = v;
    }
    return a;
}

static void ensureA1NotTooTrivial(vector<int>& a) {
    int n = (int)a.size();
    if (n <= 1) return;
    if (a[0] == 0) {
        for (int i = 1; i < n; i++) {
            if (a[i] != 0) {
                swap(a[0], a[i]);
                break;
            }
        }
    }
}

static vector<int> genDupXorNoZero(int n) {
    vector<int> a(n, 0);
    int a1 = rnd.next(0, n - 1);
    a[0] = a1;

    auto pickNotA1 = [&]() -> int {
        if (n == 1) return a1;
        int v = rnd.next(0, n - 2);
        if (v >= a1) v++;
        return v;
    };

    for (int i = 1; i < n; i++) a[i] = pickNotA1();

    
    int v1 = pickNotA1();
    int v2 = pickNotA1();
    while (v2 == v1) v2 = pickNotA1();

    int p = rnd.next(1, n - 1);
    int q = rnd.next(1, n - 1);
    while (q == p) q = rnd.next(1, n - 1);

    a[p] = v1;
    a[q] = v1;

    if (n >= 6) {
        int r = rnd.next(1, n - 1);
        while (r == p || r == q) r = rnd.next(1, n - 1);
        int s = rnd.next(1, n - 1);
        while (s == p || s == q || s == r) s = rnd.next(1, n - 1);
        a[r] = v2;
        a[s] = v2;
    }
    return a;
}

static vector<int> genHasZeroXor(int n) {
    vector<int> a(n, 0);
    int a1 = rnd.next(0, n - 1);
    a[0] = a1;
    for (int i = 1; i < n; i++) a[i] = rnd.next(0, n - 1);
    int pos = rnd.next(1, n - 1);
    a[pos] = a1; 
    
    if (n >= 8) {
        int v = rnd.next(0, n - 1);
        for (int t = 0; t < min(12, n - 1); t++) {
            int idx = rnd.next(1, n - 1);
            a[idx] = v;
        }
        a[pos] = a1;
    }
    return a;
}

static vector<int> genRandomArray(int n) {
    vector<int> a(n);
    for (int i = 0; i < n; i++) a[i] = rnd.next(0, n - 1);
    return a;
}

static int chooseN(long long seed, int nOpt, int minExp, int maxExp) {
    if (nOpt != -1) {
        ensuref(4 <= nOpt && nOpt <= (1 << 16), "n out of bounds");
        ensuref(isPowerOfTwo(nOpt), "n must be a power of two");
        return nOpt;
    }
    if (seed == 1) return 4;
    if (seed == 2) return 8;
    if (seed == 3) return (1 << 16);

    int e;
    int roll = rnd.next(1, 100);
    if (roll <= 82) e = maxExp;
    else e = rnd.next(minExp, maxExp);
    return 1 << e;
}

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

    long long seed = 0;
    if (argc >= 2) seed = atoll(argv[1]);

    string mode = opt<string>("mode", "non");
    int nOpt = opt<int>("n", -1);
    int minExp = opt<int>("minExp", 2);   
    int maxExp = opt<int>("maxExp", 16);  
    string pattern = opt<string>("pattern", "auto"); 

    ensuref(2 <= minExp && minExp <= maxExp && maxExp <= 16, "invalid exp range");

    int n = chooseN(seed, nOpt, minExp, maxExp);

    if (mode == "adp") {
        cout << n << "\n";
        return 0;
    }
    ensuref(mode == "non", "unknown mode: %s", mode.c_str());

    vector<int> a;

    if (seed == 1) {
        
        n = 4;
        a = {2, 0, 3, 1};
    } else if (seed == 2) {
        
        n = 8;
        a = {6, 1, 1, 2, 3, 4, 5, 0};
    } else if (seed == 3) {
        
        n = (1 << 16);
        a.resize(n);
        int mask = 43690; 
        for (int i = 0; i < n; i++) a[i] = (i ^ mask);
        ensureA1NotTooTrivial(a);
    } else {
        
        string use = pattern;
        if (use == "auto") {
            int r = rnd.next(1, 100);
            if (n >= 1024) {
                if (r <= 74) use = "perm";
                else if (r <= 86) use = "dup";
                else if (r <= 94) use = "dup0";
                else use = "rand";
            } else {
                if (r <= 50) use = "perm";
                else if (r <= 70) use = "dup";
                else if (r <= 85) use = "dup0";
                else use = "rand";
            }
        }

        if (use == "perm") {
            if (rnd.next(0, 1) == 0) a = genPermutationShuffle(n);
            else a = genPermutationStructured(n);
            ensureA1NotTooTrivial(a);
        } else if (use == "perm_struct") {
            a = genPermutationStructured(n);
            ensureA1NotTooTrivial(a);
        } else if (use == "dup0") {
            a = genHasZeroXor(n);
        } else if (use == "dup") {
            a = genDupXorNoZero(n);
        } else if (use == "rand") {
            a = genRandomArray(n);
        } else {
            ensuref(false, "unknown pattern: %s", use.c_str());
        }
    }

    ensuref((int)a.size() == n, "internal: array size mismatch");
    for (int i = 0; i < n; i++) {
        ensuref(0 <= a[i] && a[i] <= n - 1, "a[%d]=%d out of range [0,%d]", i, a[i], n - 1);
    }

    cout << n << "\n";
    for (int i = 0; i < n; i++) {
        if (i) cout << ' ';
        cout << a[i];
    }
    cout << "\n";
    return 0;
}