Problem: cf1746_e2
Difficulty: medium
Categories: game, search
Time limit: 1000 ms, memory limit: 256 MB

The only difference between this problem and the hard version is the maximum number of questions.

This is an interactive problem.

There is a hidden integer $1 \le x \le n$ which you have to find. In order to find it you can ask at most $\mathbf{53}$ questions.

In each question you can choose a non-empty integer set $S$ and ask if $x$ belongs to $S$ or not, after each question, if $x$ belongs to $S$, you'll receive "YES", otherwise "NO".

But the problem is that not all answers are necessarily true (some of them are joking), it's just guaranteed that for each two consecutive questions, at least one of them is answered correctly.

Additionally to the questions, you can make at most $2$ guesses for the answer $x$. Each time you make a guess, if you guess $x$ correctly, you receive ":)" and your program should terminate, otherwise you'll receive ":(".

As a part of the joking, we will not fix the value of $x$ in the beginning. Instead, it can change throughout the interaction as long as all the previous responses are valid as described above.

Note that your answer guesses are always answered correctly. If you ask a question before and after a guess, at least one of these two questions is answered correctly, as normal.

Input

The only line of the input contains a single integer $n$ ($1 \le n \le 10^5$), the maximum possible value of $x$.

Interaction

For each question, if you want to ask about a set $S$, first print the character '?', then print the size of $S$ and then print the elements of $S$ one by one. Each element should be an integer between $1$ and $n$, the elements must be distinct. After each question, read a string "YES" or "NO", as explained in the statement. You can make at most $53$ such questions.

If you want to guess for $x$, first print the character '!' and then print your guess. After each guess, read ":)" or ":(". If you guess $x$ correctly, the answer is ":)" and your program should terminate immediately, otherwise you'll receive ":(". You can make at most $2$ such guesses.

After printing a query do not forget to output end of 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 documentation for other languages.

Example

Input

```
6  
  
NO  
  
:(  
  
NO  
  
:)
```

Output

```
? 5 1 2 5 4 3  
  
! 6  
  
? 4 1 2 3 4  
  
! 5
```

Note

If the answer of the first question were correct, then $x$ would have been equal to $6$, but as we can see in the first guess, $6$ is not the answer.

So the answer of the first question is joking. As we know, the answer of at least one of our two questions is correct, since the answer of the first question was joking, the answer of the second question should be correct.

So we will understand that $x$ is not equal to $1, 2, 3$ or $4$, and we also knew that $x$ is not equal to $6$ either. Hence $x$ should be equal to $5$.

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


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


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(1, 100000, "n");
    int x = inf.readInt(1, n, "x");

    
    cout << n << endl;

    
    log_metrics();

    
    string token;
    long long interactions = 0;
    const long long HARD_CAP = 200000; 
    int guesses = 0;

    while (true) {
        if (interactions++ > HARD_CAP) {
            finish(_pe, "Interaction hard cap exceeded");
        }

        
        if (!(cin >> token)) {
            
            finish(_wa, "Unexpected EOF (did not find answer)");
        }

        if (token == "?") {
            if (queries >= query_limit) {
                finish(_wa, "Query limit exceeded");
            }

            int k;
            if (!(cin >> k)) {
                finish(_wa, "Expected set size after '?'");
            }
            if (k < 1 || k > n) {
                finish(_wa, format("Invalid set size: %d", k));
            }

            vector<char> seen(n + 1, 0);
            bool has_x = false;
            for (int i = 0; i < k; i++) {
                int val;
                if (!(cin >> val)) {
                    finish(_wa, "Expected set element");
                }
                if (val < 1 || val > n) {
                    finish(_wa, "Set element out of range");
                }
                if (seen[val]) {
                    finish(_wa, "Duplicate element in set");
                }
                seen[val] = 1;
                if (val == x) has_x = true;
            }

            cout << (has_x ? "YES" : "NO") << endl;
            queries++;
            if (queries % 10 == 0) log_metrics();
            continue;
        }

        if (token == "!") {
            
            int guess;
            if (!(cin >> guess)) {
                finish(_wa, "Expected integer guess after '!'");
            }
            guesses++;
            if (guesses > 2) {
                finish(_wa, "Too many guesses");
            }

            if (guess == x) {
                cout << ":)" << endl;
                finish(_ok, "Guessed correctly");
            } else {
                cout << ":(" << endl;
            }
            continue;
        }

        finish(_wa, "Unknown query type");
    }

    return 0;
}


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













enum State {
    VALID = 0,
    WARNING = 1,
    ELIMINATED = 2
};

int n;
vector<State> states;
int alive_count = 0; 


long long queries = 0;     
const int QUERY_LIMIT = 53;
int guesses = 0;           
const int GUESS_LIMIT = 2;


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


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





pair<int, int> simulate(const vector<bool>& in_set, bool ans_yes) {
    int next_alive = 0;
    int next_valid = 0;
    
    for (int i = 1; i <= n; i++) {
        if (states[i] == ELIMINATED) continue;
        
        bool inS = in_set[i];
        State current = states[i];
        State next_st = ELIMINATED;
        
        if (ans_yes) { 
            
            if (inS) {
                
                next_st = VALID;
            } else {
                
                if (current == VALID) next_st = WARNING;
                else next_st = ELIMINATED;
            }
        } else { 
            
            if (inS) {
                
                if (current == VALID) next_st = WARNING;
                else next_st = ELIMINATED;
            } else {
                
                next_st = VALID;
            }
        }
        
        if (next_st != ELIMINATED) {
            next_alive++;
            if (next_st == VALID) next_valid++;
        }
    }
    return {next_alive, next_valid};
}


void apply_transition(const vector<bool>& in_set, bool ans_yes) {
    alive_count = 0;
    for (int i = 1; i <= n; i++) {
        if (states[i] == ELIMINATED) continue;
        
        bool inS = in_set[i];
        State current = states[i];
        State next_st = ELIMINATED;
        
        if (ans_yes) {
            if (inS) next_st = VALID;
            else {
                if (current == VALID) next_st = WARNING;
                else next_st = ELIMINATED;
            }
        } else {
            if (inS) {
                if (current == VALID) next_st = WARNING;
                else next_st = ELIMINATED;
            } else {
                next_st = VALID;
            }
        }
        
        states[i] = next_st;
        if (next_st != ELIMINATED) alive_count++;
    }
}

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

    
    
    
    n = inf.readInt();
    
    
    log_metrics();

    
    cout << n << endl;

    
    states.assign(n + 1, VALID);
    alive_count = n;

    
    int operations = 0;
    const int HARD_CAP = 400; 

    
    vector<bool> in_set(n + 1, false);

    while (true) {
        operations++;
        if (operations > HARD_CAP) {
            finish(_pe, "Too many operations (hard cap)");
        }

        string type;
        if (!(cin >> type)) {
            
            finish(_wa, "Solution exited without correct guess");
        }

        if (type == "?") {
            queries++;
            
            if (queries % 10 == 0) log_metrics();

            int k;
            if (!(cin >> k)) finish(_wa, "Expected set size");
            if (k < 1 || k > n) finish(_wa, "Invalid set size");

            vector<int> elements;
            elements.reserve(k);
            for (int i = 0; i < k; i++) {
                int val;
                if (!(cin >> val)) finish(_wa, "Expected element");
                if (val < 1 || val > n) finish(_wa, "Element out of range");
                elements.push_back(val);
            }

            
            for (int x : elements) {
                if (in_set[x]) finish(_wa, "Duplicate element in query set");
                in_set[x] = true;
            }

            
            
            pair<int, int> res_yes = simulate(in_set, true);
            pair<int, int> res_no = simulate(in_set, false);

            bool say_yes = false;
            
            if (res_yes.first > res_no.first) {
                say_yes = true;
            } else if (res_no.first > res_yes.first) {
                say_yes = false;
            } else {
                
                if (res_yes.second >= res_no.second) {
                    say_yes = true;
                } else {
                    say_yes = false;
                }
            }

            
            apply_transition(in_set, say_yes);
            cout << (say_yes ? "YES" : "NO") << endl;

            
            for (int x : elements) in_set[x] = false;

        } else if (type == "!") {
            guesses++;
            if (guesses > GUESS_LIMIT) finish(_pe, "Too many guesses");

            int guess_val;
            if (!(cin >> guess_val)) finish(_wa, "Expected guess value");
            
            
            bool possible = (guess_val >= 1 && guess_val <= n && states[guess_val] != ELIMINATED);

            if (!possible) {
                
                cout << ":(" << endl;
            } else {
                
                
                
                if (alive_count > 1) {
                    cout << ":(" << endl;
                    states[guess_val] = ELIMINATED;
                    alive_count--;
                } else {
                    cout << ":)" << endl;
                    finish(_ok, "Guessed correctly");
                }
            }
        } else {
            finish(_wa, "Unknown 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);

    
    if (n == -1) {
        long long seedVal = 0;
        
        if (argc > 1) {
            try {
                seedVal = stoll(argv[1]);
            } catch (...) {
                seedVal = 0; 
            }
        }

        
        if (seedVal == 1) n = 100000;       
        else if (seedVal == 2) n = 1;       
        else if (seedVal == 3) n = 2;       
        else if (seedVal == 4) n = 3;       
        else if (seedVal == 5) n = 4;       
        else if (seedVal == 6) n = 10;      
        else if (seedVal == 7) n = 100;     
        else {
            
            
            
            if (rnd.next(10) == 0) {
                n = rnd.next(1, 100);
            } else {
                n = rnd.next(100, 100000);
            }
        }
    }

    
    if (mode == "non") {
        
        
        int x = rnd.next(1, n);
        println(n, x);
    } else if (mode == "adp") {
        
        
        println(n);
    } else {
        quitf(_fail, "Unknown mode: %s", mode.c_str());
    }

    return 0;
}