Problem: cf2135_d1
Difficulty: medium
Categories: math
Time limit: 3000 ms, memory limit: 512 MB

This is the easy version of the problem. The difference between the versions is that in this version, there are no constraints on the sum of the lengths of the articles over all queries. 

This is an interactive problem.

The RiOI Team has recently developed a text editor named RiOI Editor. The editor works with exactly one integer parameter $W$ — the width of each line. It is known that $1 \leq W \leq 10^5$.

As you cannot understand the RiOI Language, from your point of view, words differ from each other only by their length. Hence, an article of length $n$ is defined as a sequence $a$ consisting of $n$ positive integers, where $a_i$ is the length of the $i$-th word in the article. The RiOI Editor displays the article $[a_1, a_2,\ldots, a_n]$ on screen as follows:

* If $\max(a_1, a_2, \ldots, a_n) > W$, the editor is unable to display the article;
* Otherwise, the editor is able to display the article by the following process:
  + Initially, $l = 1$, and $s = 0$. During the whole process, $l$ always denotes the current number of lines in the editor, and $s$ always denotes the sum of lengths of words in the last line;
  + Then, for each $1\le i\le n$:
    - If $s + a_i \leq W$, the word is inserted at the end of the current line. Thus, $l$ remains unchanged, and $s$ gets increased by $a_i$.
    - Otherwise, the word is inserted into a new line. Thus, $l$ becomes $l + 1$, and $s$ becomes $a_i$.
  + The number of lines needed to display the article is the final value of $l$.

You are very interested in the editor, so you decide to find out the value of $W$ by inputting some articles into the editor and observing the number of lines needed to display each article.

Formally, you can query the jury at most $2$ times. In each query, you input an article $[a_1, a_2, \ldots, a_n]$ ($1\leq n \leq 10^5$) to the editor, and the jury will respond to you with:

* The number of lines needed to display the article, if the editor is able to display it;
* $0$, if the editor is unable to display the article.

Input

Each test contains multiple test cases. The first line contains the number of test cases $t$ ($1 \le t \le 10$). The description of the test cases follows.

Interaction

For each test case, you can make up to $2$ queries to find out the value of $W$. It is guaranteed that $1\leq W\leq 10^5$.

To make a query, you should print a new line in the following format:

* $\texttt{? } n\texttt{ }a_1\texttt{ }a_2\texttt{ }\ldots\texttt{ }a_n$ ($1 \leq n, a_i \leq 10^5$) — the article you input to the editor.

At the end of each query, the jury will print an integer, as described in the statements.

To report that you have found the value of $W$, print a new line in the following format:

* $\texttt{! } W$ — the parameter of the editor.

Printing the answer does not count as one of the $2$ queries.

After that, proceed to process the next test case or terminate the program if it was the last test case.

After printing each query do not forget to output the end of line and flush$^{\text{∗}}$ the output. Otherwise, you will get Idleness limit exceeded verdict.

If, at any interaction step, you read $-1$ instead of valid data, your solution must exit immediately. This means that your solution will receive Wrong answer because of an invalid query or any other mistake. Failing to exit can result in an arbitrary verdict because your solution will continue to read from a closed stream.

The interactor in this problem is adaptive. It means that the value of $W$ may change during the interaction, but it is guaranteed that there is always at least one integer $W$ satisfying all the queries.

Example

Input

```
2

2

1

0
```

Output

```
? 5 1 9 4 6 1

? 2 10 10

! 20
? 1 2

! 1
```

Note

In the first test case:

* For the first query, the total length of the words is $1+9+4+6+1=21$, and the article is displayed in two lines, so $W<21$;
* For the second query, the total length of the words is $10+10=20$, and the article is displayed in one line, so $W\ge 20$.

Thus, we have determined $W = 20$.

In the second test case, the editor cannot display the article in the only query. Thus, $W < 2$, so it can only be $1$.

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 readToken(string& s) {
    return (cin >> s) ? true : false;
}

static bool parseLongLongStrict(const string& s, long long& out) {
    if (s.empty()) return false;
    int i = 0;
    bool neg = false;
    if (s[0] == '-') {
        neg = true;
        i = 1;
    }
    if (i >= (int)s.size()) return false;
    long long val = 0;
    for (; i < (int)s.size(); i++) {
        char c = s[i];
        if (c < '0' || c > '9') return false;
        int d = c - '0';
        if (val > (LLONG_MAX - d) / 10) return false;
        val = val * 10 + d;
    }
    out = neg ? -val : val;
    return true;
}

static long long readIntFromCinOrDie(const string& what) {
    string tok;
    if (!readToken(tok)) {
        cout << -1 << endl;
        finish(_pe, "Unexpected EOF while reading " + what);
    }
    long long x = 0;
    if (!parseLongLongStrict(tok, x)) {
        cout << -1 << endl;
        finish(_pe, "Non-integer token while reading " + what);
    }
    return x;
}

static int computeLinesOrZero(const vector<int>& a, int W) {
    int mx = 0;
    for (int x : a) mx = max(mx, x);
    if (mx > W) return 0;
    int lines = 1;
    int s = 0;
    for (int x : a) {
        if (s + x <= W) {
            s += x;
        } else {
            lines++;
            s = x;
        }
    }
    return lines;
}

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

    int t = inf.readInt(1, 10, "t");
    vector<int> hiddenW(t + 1);
    for (int i = 1; i <= t; i++) {
        hiddenW[i] = inf.readInt(1, 100000, "W");
    }

    query_limit = 2LL * t;
    log_metrics(); 

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

    cout << t << endl;

    for (int tc = 1; tc <= t; tc++) {
        int W = hiddenW[tc];
        bool done = false;

        while (!done) {
            if (queries > hard_cap) {
                cout << -1 << endl;
                finish(_pe, "Hard cap exceeded");
            }

            string cmd;
            if (!readToken(cmd)) {
                cout << -1 << endl;
                finish(_pe, "Unexpected EOF: contestant terminated early");
            }

            if (cmd == "?") {
                long long nll = readIntFromCinOrDie("n");
                if (nll < 1 || nll > 100000) {
                    cout << -1 << endl;
                    finish(_wa, "Invalid query: n out of range");
                }
                int n = (int)nll;
                vector<int> a;
                a.reserve(n);
                for (int i = 0; i < n; i++) {
                    long long xll = readIntFromCinOrDie("a_i");
                    if (xll < 1 || xll > 100000) {
                        cout << -1 << endl;
                        finish(_wa, "Invalid query: a_i out of range");
                    }
                    a.push_back((int)xll);
                }

                int ans = computeLinesOrZero(a, W);
                queries++;

                cout << ans << endl;

            } else if (cmd == "!") {
                long long guess = readIntFromCinOrDie("W");
                if (guess < 1 || guess > 100000) {
                    cout << -1 << endl;
                    finish(_wa, "Invalid answer: W out of range");
                }
                if ((int)guess != W) {
                    cout << -1 << endl;
                    finish(_wa, "Wrong answer");
                }
                done = true;

            } else {
                cout << -1 << endl;
                finish(_pe, "Unknown command token");
            }
        }
    }

    finish(_ok, "OK");
}


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 string trimCopy(const string& s) {
    size_t i = 0, j = s.size();
    while (i < j && isspace((unsigned char)s[i])) i++;
    while (j > i && isspace((unsigned char)s[j - 1])) j--;
    return s.substr(i, j - i);
}

static bool readTokenFromContestant(string& tok) {
    return (cin >> tok) ? true : false;
}

static bool parseLLStrict(const string& s, long long& out) {
    if (s.empty()) return false;
    int i = 0;
    bool neg = false;
    if (s[0] == '-') {
        neg = true;
        i = 1;
        if ((int)s.size() == 1) return false;
    }
    long long val = 0;
    for (; i < (int)s.size(); i++) {
        char c = s[i];
        if (c < '0' || c > '9') return false;
        int d = c - '0';
        if (val > (LLONG_MAX - d) / 10) return false;
        val = val * 10 + d;
    }
    out = neg ? -val : val;
    return true;
}

static vector<int> parseIntsFromLine(const string& line) {
    vector<int> v;
    stringstream ss(line);
    long long x;
    while (ss >> x) v.push_back((int)x);
    return v;
}

struct QueryEval {
    int maxA = 0;
    vector<int> a;
    vector<int> memo; 
    int maxW = 100000;

    explicit QueryEval(vector<int> arr, int maxW_) : a(std::move(arr)), maxW(maxW_) {
        maxA = 0;
        for (int x : a) maxA = max(maxA, x);
        memo.assign(maxW + 1, -2);
    }

    int linesForW(int W) {
        int lines = 1;
        int s = 0;
        for (int x : a) {
            if (s + x <= W) s += x;
            else {
                lines++;
                s = x;
            }
        }
        return lines;
    }

    int response(int W) {
        if (W < maxA) return 0;
        int& m = memo[W];
        if (m != -2) return m;
        m = linesForW(W);
        return m;
    }

    int linesOnly(int W) {
        
        int& m = memo[W];
        if (m != -2) return m;
        m = linesForW(W);
        return m;
    }
};

struct Plateau {
    int y = 0;
    int L = 1, R = 0; 
};

static Plateau plateauForCandidate(QueryEval& ev, int curL, int curR, int Wc) {
    Plateau p;
    p.y = ev.response(Wc);

    if (p.y == 0) {
        p.L = curL;
        p.R = min(curR, ev.maxA - 1);
        return p;
    }

    int low = max(curL, ev.maxA);
    int high = curR;
    if (low > high) {
        p.L = 1;
        p.R = 0;
        return p;
    }

    
    int y = p.y;
    int lo = low, hi = Wc;
    while (lo < hi) {
        int mid = (lo + hi) / 2;
        int val = ev.linesOnly(mid);
        if (val <= y) hi = mid;
        else lo = mid + 1;
    }
    int left = lo;

    
    lo = Wc;
    hi = high;
    while (lo < hi) {
        int mid = (lo + hi + 1) / 2;
        int val = ev.linesOnly(mid);
        if (val >= y) lo = mid;
        else hi = mid - 1;
    }
    int right = lo;

    p.L = left;
    p.R = right;
    return p;
}

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

    const int MAXW = 100000;

    int t = inf.readInt();
    query_limit = 2LL * t;
    log_metrics(); 

    cout << t << "\n";
    cout.flush();

    
    if (!inf.eof()) (void)inf.readLine();

    vector<pair<int,int>> initial(t, {1, MAXW});
    for (int tc = 0; tc < t; tc++) {
        string line;
        while (true) {
            if (inf.eof()) finish(_pe, "unexpected EOF in hidden input");
            line = inf.readLine();
            if (!trimCopy(line).empty()) break;
        }
        auto nums = parseIntsFromLine(line);
        if ((int)nums.size() == 1) {
            int W = nums[0];
            if (W < 1 || W > MAXW) finish(_pe, "hidden W out of range");
            initial[tc] = {W, W};
        } else if ((int)nums.size() == 2) {
            int L = nums[0], R = nums[1];
            if (L < 1 || L > MAXW || R < 1 || R > MAXW) finish(_pe, "hidden interval out of range");
            if (L > R) swap(L, R);
            initial[tc] = {L, R};
        } else {
            finish(_pe, "hidden input line must have 1 or 2 integers");
        }
    }

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

    for (int tc = 0; tc < t; tc++) {
        int curL = initial[tc].first;
        int curR = initial[tc].second;

        while (true) {
            string tok;
            if (!readTokenFromContestant(tok)) finish(_pe, "EOF from contestant");

            if (tok == "?") {
                string sn;
                if (!readTokenFromContestant(sn)) finish(_pe, "missing n");
                long long nll;
                if (!parseLLStrict(sn, nll)) finish(_pe, "invalid n token");
                if (nll < 1 || nll > 100000) finish(_pe, "n out of range");
                int n = (int)nll;

                vector<int> a;
                a.reserve(n);
                for (int i = 0; i < n; i++) {
                    string sa;
                    if (!readTokenFromContestant(sa)) finish(_pe, "missing ai");
                    long long xll;
                    if (!parseLLStrict(sa, xll)) finish(_pe, "invalid ai token");
                    if (xll < 1 || xll > 100000) finish(_pe, "ai out of range");
                    a.push_back((int)xll);
                }

                queries++;
                if (queries > hard_cap) finish(_pe, "too many queries (hard cap)");

                QueryEval ev(std::move(a), MAXW);

                vector<int> candidates;
                candidates.push_back(curL);
                candidates.push_back(curR);
                candidates.push_back((curL + curR) / 2);

                if (curL <= ev.maxA - 1 && ev.maxA - 1 <= curR) candidates.push_back(ev.maxA - 1);
                if (curL <= ev.maxA && ev.maxA <= curR) candidates.push_back(ev.maxA);

                sort(candidates.begin(), candidates.end());
                candidates.erase(unique(candidates.begin(), candidates.end()), candidates.end());

                Plateau best;
                long long bestSize = -1;
                int bestL = -1, bestR = -1, bestY = -1;

                for (int Wc : candidates) {
                    if (Wc < curL || Wc > curR) continue;
                    Plateau p = plateauForCandidate(ev, curL, curR, Wc);
                    if (p.L > p.R) continue;
                    long long sz = 1LL * p.R - p.L + 1;
                    
                    if (sz > bestSize ||
                        (sz == bestSize && (p.L > bestL ||
                                            (p.L == bestL && (p.R > bestR ||
                                                              (p.R == bestR && p.y > bestY)))))) {
                        bestSize = sz;
                        bestL = p.L;
                        bestR = p.R;
                        bestY = p.y;
                        best = p;
                    }
                }

                
                if (bestSize < 0) {
                    best.y = ev.response(curL);
                    best.L = curL;
                    best.R = curR;
                }

                curL = best.L;
                curR = best.R;

                cout << best.y << "\n";
                cout.flush();
            } else if (tok == "!") {
                string sW;
                if (!readTokenFromContestant(sW)) finish(_pe, "missing final W");
                long long Wll;
                if (!parseLLStrict(sW, Wll)) finish(_pe, "invalid final W token");
                if (Wll < 1 || Wll > MAXW) finish(_wa, "final W out of range");
                int Wans = (int)Wll;

                if (Wans < curL || Wans > curR) finish(_wa, "final W not consistent");
                if (curL != curR) finish(_wa, "W not uniquely determined");
                
                break;
            } else {
                finish(_pe, "invalid command token (expected ? or !)");
            }
        }
    }

    finish(_ok, "ok");
    return 0;
}


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

static int clampInt(int x, int lo, int hi) {
    if (x < lo) return lo;
    if (x > hi) return hi;
    return x;
}

static int pickStructuredW(int maxW) {
    
    int mode = rnd.next(0, 99);
    if (mode < 25) {
        return rnd.next(1, min(maxW, 100));
    } else if (mode < 50) {
        int lo = max(1, maxW - 100);
        return rnd.next(lo, maxW);
    } else if (mode < 80) {
        int kMax = 0;
        while ((1 << (kMax + 1)) <= maxW) kMax++;
        int k = rnd.next(0, kMax);
        int base = 1 << k;
        int delta = rnd.next(-1, 1);
        int w = base + delta;
        return clampInt(w, 1, maxW);
    } else {
        return rnd.next(1, maxW);
    }
}

static pair<int,int> pickInterval(int maxW) {
    int mode = rnd.next(0, 99);
    if (mode < 60) {
        return {1, maxW}; 
    } else if (mode < 75) {
        int len = rnd.next(maxW / 2, maxW);
        int L = rnd.next(1, maxW - len + 1);
        return {L, L + len - 1};
    } else if (mode < 90) {
        int len = rnd.next(1, min(maxW, 50));
        int side = rnd.next(0, 1);
        if (side == 0) return {1, len};
        return {maxW - len + 1, maxW};
    } else {
        int mid = rnd.next(1, maxW);
        int rad = rnd.next(0, min(maxW, 2000));
        int L = max(1, mid - rad);
        int R = min(maxW, mid + rad);
        if (L > R) swap(L, R);
        return {L, R};
    }
}

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

    string mode = opt<string>("mode", "non");
    int maxW = opt<int>("maxw", 100000);
    maxW = clampInt(maxW, 1, 100000);

    
    cout << 1 << "\n";

    long long seed = 1;
    if (argc >= 2) {
        
        
        
        try {
            seed = stoll(string(argv[1]));
        } catch (...) {
            seed = 4; 
        }
    }

    if (mode == "non") {
        int W;
        if (seed == 1) W = 1;
        else if (seed == 2) W = maxW;
        else if (seed == 3) W = clampInt(50000, 1, maxW);
        else W = pickStructuredW(maxW);

        int forcedW = opt<int>("W", -1);
        if (forcedW != -1) W = clampInt(forcedW, 1, maxW);

        cout << W << "\n";
        return 0;
    }

    if (mode == "adp") {
        int L, R;
        if (seed == 1) { L = 1; R = 1; }
        else if (seed == 2) { L = maxW; R = maxW; }
        else if (seed == 3) { L = 1; R = maxW; }
        else {
            auto iv = pickInterval(maxW);
            L = iv.first;
            R = iv.second;
        }

        int forcedL = opt<int>("L", -1);
        int forcedR = opt<int>("R", -1);
        if (forcedL != -1 || forcedR != -1) {
            if (forcedL == -1) forcedL = 1;
            if (forcedR == -1) forcedR = maxW;
            forcedL = clampInt(forcedL, 1, maxW);
            forcedR = clampInt(forcedR, 1, maxW);
            if (forcedL > forcedR) swap(forcedL, forcedR);
            L = forcedL;
            R = forcedR;
        }

        cout << L << " " << R << "\n";
        return 0;
    }

    
    int W = pickStructuredW(maxW);
    int forcedW = opt<int>("W", -1);
    if (forcedW != -1) W = clampInt(forcedW, 1, maxW);
    cout << W << "\n";
    return 0;
}