Problem: cf835_e
Difficulty: easy
Categories: bit, search
Time limit: 1000 ms, memory limit: 256 MB

E. The penguin's game

Pay attention: this problem is interactive.

Penguin Xoriy came up with a new game recently. He has *n* icicles numbered from 1 to *n*. Each icicle has a temperature — an integer from 1 to 109. Exactly two of these icicles are special: their temperature is *y*, while a temperature of all the others is *x* ≠ *y*. You have to find those special icicles. You can choose a non-empty subset of icicles and ask the penguin what is the bitwise exclusive OR (XOR) of the temperatures of the icicles in this subset. Note that you can't ask more than 19 questions.

You are to find the special icicles.

Input

The first line contains three integers *n*, *x*, *y* (2 ≤ *n* ≤ 1000, 1 ≤ *x*, *y* ≤ 109, *x* ≠ *y*) — the number of icicles, the temperature of non-special icicles and the temperature of the special icicles.

Output

To give your answer to the penguin you have to print character "!" (without quotes), then print two integers *p*1, *p*2 (*p*1 < *p*2) — the indexes of the special icicles in ascending order. Note that "!" and *p*1 should be separated by a space; the indexes should be separated by a space too. After you gave the answer your program should terminate immediately.

Interaction

To ask a question print character "?" (without quotes), an integer *c* (1 ≤ *c* ≤ *n*), and *c* distinct integers *p*1, *p*2,..., *p**c* (1 ≤ *p**i* ≤ *n*) — the indexes of icicles that you want to know about. Note that "?" and *c* should be separated by a space; the indexes should be separated by a space too.

After you asked the question, read a single integer — the answer.

Note that you can't ask more than 19 questions. If you ask more than 19 questions or at least one incorrect question, your solution will get "Wrong answer".

If at some moment your program reads  - 1 as an answer, it should immediately exit (for example, by calling exit(0)). You will get "Wrong answer" in this case, it means that you asked more than 19 questions, or asked an invalid question. If you ignore this, you can get other verdicts since your program will continue to read from a closed stream.

Your solution will get "Idleness Limit Exceeded", if you don't print anything or forget to flush the output, including for the final answer.

To flush you can use (just after printing):

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

Example

Input

```
4 2 1  
2  
1  
1
```

Output

```? 3 1 2 3? 1 1? 1 3! 1 3
```

Note

The answer for the first question is![](https://espresso.codeforces.com/b32d8d96beb0d2be8d8a600f458c8cf2e2e28c54.png).

The answer for the second and the third questions is 1, therefore, special icicles are indexes 1 and 3.

You can read more about bitwise XOR operation here: [link omitted].

Non-adaptive interactor (C++):





#include "testlib.h"
#include <bits/stdc++.h>

using namespace std;


static long long queries = 0;
static long long query_limit = 19; 
static const long long hard_cap = 20000; 


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());
}

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

    
    
    int n = inf.readInt(2, 1000, "n");
    long long x = inf.readLong(1LL, 1000000000LL, "x");
    long long y = inf.readLong(1LL, 1000000000LL, "y");
    
    
    if (x == y) {
        quitf(_fail, "Test case invalid: x (%lld) must not equal y (%lld)", x, y);
    }

    int p1 = inf.readInt(1, n, "p1");
    int p2 = inf.readInt(1, n, "p2");
    
    if (p1 == p2) {
        quitf(_fail, "Test case invalid: hidden indices p1 and p2 must be distinct");
    }
    
    if (p1 > p2) swap(p1, p2);

    
    cout << n << " " << x << " " << y << endl;
    
    
    log_metrics();

    
    string token;
    while (cin >> token) {
        if (token == "!") {
            
            int a1, a2;
            if (!(cin >> a1 >> a2)) {
                finish(_wa, "Failed to read answer indices after '!'");
            }

            
            if (a1 >= a2) {
                finish(_wa, "Answer indices must be distinct and in strictly ascending order");
            }

            if (a1 == p1 && a2 == p2) {
                finish(_ok, "Correct answer");
            } else {
                finish(_wa, format("Wrong answer: expected %d %d, found %d %d", p1, p2, a1, a2));
            }
            return 0;
        }

        
        
        
        int c = 0;
        if (token == "?") {
            if (!(cin >> c)) {
                finish(_wa, "Failed to read query size 'c' after '?'");
            }
        } else {
            
            try {
                size_t pos = 0;
                c = stoi(token, &pos);
                if (pos != token.size()) {
                    finish(_wa, "Invalid token encountered: " + token);
                }
            } catch (...) {
                finish(_wa, "Invalid token (not an integer): " + token);
            }
        }

        
        if (c < 1 || c > n) {
            finish(_wa, format("Query size %d out of range [1, %d]", c, n));
        }

        
        
        int special_in_query = 0;
        set<int> distinct_check;

        for (int i = 0; i < c; i++) {
            int idx;
            if (!(cin >> idx)) {
                finish(_wa, "Failed to read index for query");
            }
            if (idx < 1 || idx > n) {
                finish(_wa, format("Query index %d out of range [1, %d]", idx, n));
            }
            if (distinct_check.count(idx)) {
                finish(_wa, format("Duplicate index %d in query", idx));
            }
            distinct_check.insert(idx);

            if (idx == p1 || idx == p2) {
                special_in_query++;
            }
        }

        
        
        
        long long response = 0;
        if ((c - special_in_query) % 2 != 0) response ^= x;
        if (special_in_query % 2 != 0) response ^= y;

        
        queries++;
        log_metrics();

        
        
        if (queries > hard_cap) {
            finish(_pe, "Hard query limit exceeded");
        }
        
        
        cout << response << endl;
    }

    
    finish(_wa, "Stream ended without final answer '!'");
    return 0;
}


Adaptive interactor (C++):
#include "testlib.h"
#include <bits/stdc++.h>

using namespace std;


static long long queries = 0;

static long long query_limit = 19; 

static const long long HARD_CAP = 200000;



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());
}

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

    
    
    
    int n = inf.readInt();
    long long x = inf.readLong();
    long long y = inf.readLong();
    
    
    
    cout << n << " " << x << " " << y << endl;
    
    
    
    
    vector<pair<int, int>> candidates;
    long long num_pairs = (long long)n * (n - 1) / 2;
    candidates.reserve(num_pairs);
    for (int i = 1; i <= n; ++i) {
        for (int j = i + 1; j <= n; ++j) {
            candidates.push_back({i, j});
        }
    }
    
    
    log_metrics();

    
    while (true) {
        
        string type;
        if (!(cin >> type)) {
            finish(_pe, "Unexpected end of output");
        }

        if (type == "!") {
            
            int ans1, ans2;
            if (!(cin >> ans1 >> ans2)) {
                finish(_pe, "Invalid format for final answer");
            }
            if (ans1 > ans2) swap(ans1, ans2);

            
            
            
            
            bool found_ans = false;
            bool found_other = false;
            pair<int, int> counter_example = {-1, -1};
            
            for (const auto& p : candidates) {
                if (p.first == ans1 && p.second == ans2) {
                    found_ans = true;
                } else {
                    found_other = true;
                    counter_example = p;
                    
                    break;
                }
            }
            
            if (found_other) {
                
                finish(_wa, "found " + to_string(ans1) + " " + to_string(ans2) + 
                            ", expected " + to_string(counter_example.first) + " " + to_string(counter_example.second));
            } else if (found_ans) {
                
                finish(_ok, "Correct");
            } else {
                
                
                if (candidates.empty()) finish(_pe, "Internal error: feasible set is empty");
                counter_example = candidates[0];
                finish(_wa, "found " + to_string(ans1) + " " + to_string(ans2) + 
                            ", expected " + to_string(counter_example.first) + " " + to_string(counter_example.second));
            }
            return 0;

        } else if (type == "?") {
            
            queries++;
            
            if (queries % 5 == 0) log_metrics();
            
            
            if (queries > HARD_CAP) {
                finish(_pe, "Hard query limit exceeded");
            }

            int k;
            if (!(cin >> k)) finish(_pe, "Invalid format for query size");
            if (k < 1 || k > n) finish(_wa, "Query size out of range");

            vector<bool> in_query(n + 1, false);
            for (int i = 0; i < k; ++i) {
                int idx;
                cin >> idx; 
                if (idx < 1 || idx > n) finish(_wa, "Index out of range");
                if (in_query[idx]) finish(_wa, "Duplicate index in query");
                in_query[idx] = true;
            }

            
            vector<pair<int, int>> s_even, s_odd;
            s_even.reserve(candidates.size());
            s_odd.reserve(candidates.size());

            for (const auto& p : candidates) {
                int count = (in_query[p.first] ? 1 : 0) + (in_query[p.second] ? 1 : 0);
                
                
                
                
                
                
                
                
                if (count == 1) {
                    s_odd.push_back(p);
                } else {
                    
                    s_even.push_back(p);
                }
            }

            long long response;
            
            if (s_even.size() >= s_odd.size()) {
                candidates = move(s_even);
                
                if (k % 2 != 0) response = x;
                else response = 0;
            } else {
                candidates = move(s_odd);
                
                long long term_x = ((k - 1) % 2 != 0) ? x : 0;
                response = term_x ^ y;
            }

            if (candidates.empty()) {
                finish(_pe, "Internal error: feasible set became empty");
            }

            cout << response << endl;

        } else {
            finish(_pe, "Invalid query type");
        }
    }

    return 0;
}


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

using namespace std;

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

    
    string mode = opt<string>("mode", "non");
    int n = opt<int>("n", -1);
    long long x = opt<long long>("x", -1);
    long long y = opt<long long>("y", -1);

    
    int seed_val = atoi(argv[1]);

    
    if (n == -1) {
        if (seed_val == 1) n = 2;
        else if (seed_val == 2) n = 3;
        else if (seed_val == 3) n = 1000; 
        else n = rnd.next(2, 1000);
    }

    
    if (x == -1) {
        
        if (rnd.next(5) == 0) x = rnd.next(1, 100);
        else x = rnd.next(1, 1000000000);
    }

    
    if (y == -1) {
        int t = rnd.next(10);
        if (t < 3) {
            
            
            bool found = false;
            for (int k = 0; k < 10; ++k) {
                int bit = rnd.next(0, 29);
                long long cand = x ^ (1LL << bit);
                if (cand >= 1 && cand <= 1000000000LL) {
                    y = cand;
                    found = true;
                    break;
                }
            }
            if (!found) {
                do { y = rnd.next(1, 1000000000); } while (y == x);
            }
        } else {
            
            do { y = rnd.next(1, 1000000000); } while (y == x);
        }
    }

    
    if (x == y) {
        if (y < 1000000000) y++; else y--;
    }

    
    cout << n << " " << x << " " << y << endl;

    
    if (mode == "non") {
        
        int p1, p2;

        if (n == 2) {
            
            p1 = 1; p2 = 2;
        } else {
            
            bool fixed = false;
            
            
            if (seed_val == 2 && n == 3) { p1 = 1; p2 = 3; fixed = true; }
            if (seed_val == 3 && n == 1000) { p1 = 1; p2 = 1000; fixed = true; }

            if (!fixed) {
                int type = rnd.next(100);
                if (type < 15) { 
                    
                    p1 = rnd.next(1, n - 1);
                    p2 = p1 + 1;
                } else if (type < 30) { 
                    
                    p1 = 1; p2 = n;
                } else if (type < 60) {
                    
                    bool found = false;
                    for (int k = 0; k < 20; ++k) {
                        p1 = rnd.next(1, n);
                        int bit = rnd.next(0, 9); 
                        int cand = p1 ^ (1 << bit);
                        if (cand >= 1 && cand <= n && cand != p1) {
                            p2 = cand;
                            found = true;
                            break;
                        }
                    }
                    if (!found) {
                        
                        p1 = rnd.next(1, n);
                        do { p2 = rnd.next(1, n); } while (p1 == p2);
                    }
                } else {
                    
                    p1 = rnd.next(1, n);
                    do { p2 = rnd.next(1, n); } while (p1 == p2);
                }
            }
        }

        if (p1 > p2) swap(p1, p2);
        cout << p1 << " " << p2 << endl;
    }
    

    return 0;
}