Problem: cf1354_g
Difficulty: easy
Categories: search
Time limit: 2000 ms, memory limit: 256 MB

This is an interactive problem. Don't forget to flush output after printing queries using cout.flush() or fflush(stdout) in C++ or similar functions in other programming languages.

There are $n$ gift boxes in a row, numbered from $1$ to $n$ from left to right. It's known that exactly $k$ of them contain valuable gifts — other boxes contain just lucky stones. All boxes look the same and differ only in weight. All boxes with stones have the same weight and are strictly heavier than boxes with valuable items. But valuable gifts may be different, so the boxes with valuable items may have different weights.

You can ask no more than $50$ queries (printing an answer doesn't count). By each query you can compare total weights of two non-intersecting subsets of boxes $a_1, a_2, \dots, a_{k_a}$ and $b_1, b_2, \dots, b_{k_b}$. In return you'll get one of four results:

* FIRST, if subset $a_1, a_2, \dots, a_{k_a}$ is strictly heavier;
* SECOND, if subset $b_1, b_2, \dots, b_{k_b}$ is strictly heavier;
* EQUAL, if subsets have equal total weights;
* WASTED, if the query is incorrect or the limit of queries is exceeded.

Using such queries (or, maybe, intuition) find the box with a valuable gift with the minimum index.

Input

The input consists of several cases. In the beginning, you receive the integer $T$ ($1 \le T \le 500$) — the number of test cases.

At the beginning of each test case, you receive two integers $n$ and $k$ ($2 \le n \le 1000$, $1 \le k \le \frac{n}{2}$) — the number of boxes in a row and the number of boxes with valuable gifts.

It's guaranteed that the order of boxes is fixed beforehand and that the sum of $n$ in one test doesn't exceed $1000$.

Output

For each test case print the minimum index among all boxes with a valuable gift in the following format: "! $x$" where $x$ ($1 \le x \le n$) — the index of the box.

Interaction

Print each query in three lines. In the first line print the sizes of subset in the following format: "? $k_a$ $k_b$" where $k_a$ and $k_b$ ($1 \le k_a, k_b \le n$; $k_a + k_b \le n$) — the corresponding sizes.

In the second line print $k_a$ integers $a_1, a_2, \dots, a_{k_a}$ ($1 \le a_i \le n$; $a_i \neq a_j$ if $i \neq j$) — indexes of boxes in the first subset.

In the third line print $k_b$ integers $b_1, b_2, \dots, b_{k_b}$ ($1 \le b_i \le n$; $b_i \neq b_j$ if $i \neq j$) — indexes of boxes in the second subset.

The subsets shouldn't intersect, i. e. $a_i \neq b_j$ for all $i$ and $j$.

You'll receive one of four responses described above. In the case of WASTED stop your program to avoid getting random verdict instead of Wrong Answer.

Example

Input

```
2
2 1
-
-
-
FIRST
-
5 2
-
-
-
FIRST
-
-
-
SECOND
-
-
-
EQUAL
-
```

Output

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

Note

Additional separators "–" in the sample are used only to increase the readability of the sample. Don't print any unnecessary symbols or line breaks in your solution when you send it to the system.

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 readTokenFromContestant(string& s) {
    if (!(cin >> s)) return false;
    return true;
}

static long long readLLFromContestantOrDie(const string& what) {
    long long x;
    if (!(cin >> x)) finish(_pe, "Malformed or missing " + what);
    return x;
}

static void sendLine(const string& s) {
    cout << s << "\n";
    cout.flush();
}

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

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

    int T = inf.readInt(1, 500, "T");
    vector<int> n(T), k(T);
    vector<vector<long long>> w(T);
    vector<int> answer(T, -1);

    for (int tc = 0; tc < T; ++tc) {
        n[tc] = inf.readInt(2, 1000, "n");
        k[tc] = inf.readInt(1, n[tc] / 2, "k");

        w[tc].assign(n[tc] + 1, 0);
        long long mx = LLONG_MIN;
        for (int i = 1; i <= n[tc]; ++i) {
            w[tc][i] = inf.readLong(1LL, (long long)4e18, "weight");
            mx = max(mx, w[tc][i]);
        }

        int best = -1;
        for (int i = 1; i <= n[tc]; ++i) {
            if (w[tc][i] < mx) {
                best = i;
                break;
            }
        }
        if (best == -1) best = 1; 
        answer[tc] = best;
    }

    query_limit = 50LL * (long long)T;
    log_metrics(); 

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

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

    for (int tc = 0; tc < T; ++tc) {
        cout << n[tc] << " " << k[tc] << "\n";
        cout.flush();

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

            if (cmd == "?") {
                long long ka = readLLFromContestantOrDie("ka");
                long long kb = readLLFromContestantOrDie("kb");

                if (ka < 1 || kb < 1 || ka > n[tc] || kb > n[tc] || ka + kb > n[tc]) {
                    sendLine("WASTED");
                    finish(_pe, "Invalid subset sizes");
                }

                vector<int> A((size_t)ka), B((size_t)kb);
                vector<char> used((size_t)n[tc] + 1, 0);

                for (int i = 0; i < (int)ka; ++i) {
                    long long x = readLLFromContestantOrDie("a_i");
                    if (x < 1 || x > n[tc]) {
                        sendLine("WASTED");
                        finish(_pe, "Index out of range in A");
                    }
                    if (used[(int)x]) {
                        sendLine("WASTED");
                        finish(_pe, "Duplicate or intersecting index");
                    }
                    used[(int)x] = 1;
                    A[i] = (int)x;
                }

                for (int i = 0; i < (int)kb; ++i) {
                    long long x = readLLFromContestantOrDie("b_i");
                    if (x < 1 || x > n[tc]) {
                        sendLine("WASTED");
                        finish(_pe, "Index out of range in B");
                    }
                    if (used[(int)x]) {
                        sendLine("WASTED");
                        finish(_pe, "Duplicate or intersecting index");
                    }
                    used[(int)x] = 1;
                    B[i] = (int)x;
                }

                ++queries;
                if (queries > hard_cap) {
                    sendLine("WASTED");
                    finish(_pe, "Hard cap exceeded");
                }

                long long sumA = 0, sumB = 0;
                for (int x : A) sumA += w[tc][x];
                for (int x : B) sumB += w[tc][x];

                if (sumA > sumB) sendLine("FIRST");
                else if (sumB > sumA) sendLine("SECOND");
                else sendLine("EQUAL");
            } else if (cmd == "!") {
                long long x = readLLFromContestantOrDie("answer x");
                if (x < 1 || x > n[tc]) finish(_pe, "Answer out of range");
                if ((int)x != answer[tc]) finish(_wa, "Wrong answer for test case");
                break; 
            } else {
                finish(_pe, "Unknown command token");
            }
        }
    }

    finish(_ok, "OK");
    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 = 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 parseLL(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) {
        unsigned char c = (unsigned char)s[i];
        if (!isdigit(c)) return false;
        int d = s[i] - '0';
        if (val > (LLONG_MAX - d) / 10) return false;
        val = val * 10 + d;
    }
    out = neg ? -val : val;
    return true;
}

static bool readToken(string& tok) {
    if (!(cin >> tok)) return false;
    return true;
}

static bool readLong(long long& x) {
    string tok;
    if (!readToken(tok)) return false;
    return parseLL(tok, x);
}

static vector<string> splitWS(const string& line) {
    vector<string> t;
    string cur;
    for (char ch : line) {
        if (isspace((unsigned char)ch)) {
            if (!cur.empty()) {
                t.push_back(cur);
                cur.clear();
            }
        } else {
            cur.push_back(ch);
        }
    }
    if (!cur.empty()) t.push_back(cur);
    return t;
}

static bool isNonEmptyLine(const string& s) {
    for (char c : s) if (!isspace((unsigned char)c)) return true;
    return false;
}

static string readNextNonEmptyInfLine() {
    while (!inf.eof()) {
        string line = inf.readLine();
        if (isNonEmptyLine(line)) return line;
    }
    return "";
}

struct AdaptiveCase {
    int n = 0, k = 0;
    long long stoneW = 0;
    long long giftW = 0;
    long long D = 0;
    vector<int> feasibleL; 
};

static int giftCountInWindow(const vector<int>& pref, int L, int k) {
    int R = L + k - 1;
    return pref[R] - pref[L - 1];
}

static void outputToContestant(const string& s) {
    cout << s << "\n";
    cout.flush();
}

static void outputToContestantIntPair(int a, int b) {
    cout << a << " " << b << "\n";
    cout.flush();
}

static void outputWastedAndDie(const string& msg) {
    outputToContestant("WASTED");
    finish(_pe, msg);
}

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

    int T = inf.readInt();
    if (T < 1 || T > 500) finish(_pe, "bad T in input");
    query_limit = 50LL * T;
    log_metrics(); 

    outputToContestant(to_string(T));

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

    for (int tc = 1; tc <= T; ++tc) {
        int n = inf.readInt();
        int k = inf.readInt();
        if (n < 2 || n > 1000) finish(_pe, "bad n in input");
        if (k < 1 || k > n / 2) finish(_pe, "bad k in input");

        
        (void)inf.readLine();
        string line1 = readNextNonEmptyInfLine();
        if (line1.empty()) finish(_pe, "unexpected EOF while reading case payload");

        vector<string> tok1 = splitWS(line1);

        bool fixed_mode = false;
        vector<long long> weights(n + 1, 0);
        AdaptiveCase ac;
        ac.n = n;
        ac.k = k;

        if ((int)tok1.size() == 1) {
            
            long long stoneW_in = 0;
            if (!parseLL(tok1[0], stoneW_in)) finish(_pe, "bad stoneW token");
            string line2 = readNextNonEmptyInfLine();
            if (line2.empty()) finish(_pe, "unexpected EOF while reading gmin/gmax");
            vector<string> tok2 = splitWS(line2);
            if ((int)tok2.size() != 2) finish(_pe, "bad gmin/gmax line");

            long long gmin_in = 0, gmax_in = 0;
            if (!parseLL(tok2[0], gmin_in) || !parseLL(tok2[1], gmax_in)) finish(_pe, "bad gmin/gmax tokens");

            long long stoneW = max(2LL, stoneW_in);
            long long gmin = max(1LL, gmin_in);
            long long gmax = max(gmin, gmax_in);

            if (gmax >= stoneW) {
                stoneW = gmax + 1;
            }
            long long giftW = min(gmin, stoneW - 1);
            if (giftW < 1) giftW = 1;
            if (giftW >= stoneW) giftW = stoneW - 1;
            if (giftW < 1) stoneW = max(stoneW, 2LL), giftW = 1;

            ac.stoneW = stoneW;
            ac.giftW = giftW;
            ac.D = ac.stoneW - ac.giftW;
            if (ac.D <= 0) {
                ac.stoneW = max(ac.stoneW, ac.giftW + 1);
                ac.D = ac.stoneW - ac.giftW;
                if (ac.D <= 0) finish(_pe, "failed to ensure stoneW>giftW");
            }

            int maxL = n - k + 1;
            ac.feasibleL.resize(maxL);
            iota(ac.feasibleL.begin(), ac.feasibleL.end(), 1);
        } else if ((int)tok1.size() == n) {
            
            fixed_mode = true;
            for (int i = 1; i <= n; ++i) {
                long long wi = 0;
                if (!parseLL(tok1[i - 1], wi)) finish(_pe, "bad weight token");
                weights[i] = wi;
            }
        } else {
            finish(_pe, "cannot detect input mode (line token count mismatch)");
        }

        
        outputToContestantIntPair(n, k);

        
        int fixed_answer = -1;
        if (fixed_mode) {
            long long stoneW = *max_element(weights.begin() + 1, weights.end());
            fixed_answer = n + 1;
            int giftCount = 0;
            for (int i = 1; i <= n; ++i) {
                if (weights[i] < stoneW) {
                    fixed_answer = min(fixed_answer, i);
                    giftCount++;
                }
            }
            if (fixed_answer == n + 1) finish(_pe, "fixed mode: no gifts detected");
            
            if (giftCount != k) {
                
            }
        }

        while (true) {
            string cmd;
            if (!readToken(cmd)) finish(_pe, "unexpected EOF from contestant");

            if (cmd == "?") {
                long long ka_ll = 0, kb_ll = 0;
                if (!readLong(ka_ll) || !readLong(kb_ll)) outputWastedAndDie("bad query sizes");
                if (ka_ll < 1 || kb_ll < 1 || ka_ll > n || kb_ll > n) outputWastedAndDie("query sizes out of range");
                if (ka_ll + kb_ll > n) outputWastedAndDie("query subsets intersect by size");
                int ka = (int)ka_ll, kb = (int)kb_ll;

                queries++;
                if (queries > hard_cap) outputWastedAndDie("too many queries (hard cap)");

                vector<int> used(n + 1, 0);
                vector<int> A;
                vector<int> B;
                A.reserve(ka);
                B.reserve(kb);

                for (int i = 0; i < ka; ++i) {
                    long long idx_ll = 0;
                    if (!readLong(idx_ll)) outputWastedAndDie("bad A index token");
                    if (idx_ll < 1 || idx_ll > n) outputWastedAndDie("A index out of range");
                    int idx = (int)idx_ll;
                    if (used[idx]) outputWastedAndDie("duplicate index in A");
                    used[idx] = 1;
                    A.push_back(idx);
                }
                for (int i = 0; i < kb; ++i) {
                    long long idx_ll = 0;
                    if (!readLong(idx_ll)) outputWastedAndDie("bad B index token");
                    if (idx_ll < 1 || idx_ll > n) outputWastedAndDie("B index out of range");
                    int idx = (int)idx_ll;
                    if (used[idx]) outputWastedAndDie("intersection or duplicate index in B");
                    used[idx] = 1;
                    B.push_back(idx);
                }

                if (fixed_mode) {
                    __int128 sumA = 0, sumB = 0;
                    for (int idx : A) sumA += (__int128)weights[idx];
                    for (int idx : B) sumB += (__int128)weights[idx];

                    if (sumA > sumB) outputToContestant("FIRST");
                    else if (sumA < sumB) outputToContestant("SECOND");
                    else outputToContestant("EQUAL");
                    continue;
                }

                
                vector<int> markA(n + 1, 0), markB(n + 1, 0);
                for (int idx : A) markA[idx] = 1;
                for (int idx : B) markB[idx] = 1;

                vector<int> prefA(n + 1, 0), prefB(n + 1, 0);
                for (int i = 1; i <= n; ++i) {
                    prefA[i] = prefA[i - 1] + markA[i];
                    prefB[i] = prefB[i - 1] + markB[i];
                }

                vector<int> groupFirst, groupSecond, groupEqual;
                groupFirst.reserve(ac.feasibleL.size());
                groupSecond.reserve(ac.feasibleL.size());
                groupEqual.reserve(ac.feasibleL.size());

                for (int L : ac.feasibleL) {
                    int gA = giftCountInWindow(prefA, L, k);
                    int gB = giftCountInWindow(prefB, L, k);
                    long long sumA = ac.stoneW * (long long)ka - ac.D * (long long)gA;
                    long long sumB = ac.stoneW * (long long)kb - ac.D * (long long)gB;
                    if (sumA > sumB) groupFirst.push_back(L);
                    else if (sumA < sumB) groupSecond.push_back(L);
                    else groupEqual.push_back(L);
                }

                auto span = [&](const vector<int>& v) -> int {
                    if (v.empty()) return -1;
                    int mn = v[0], mx = v[0];
                    for (int x : v) mn = min(mn, x), mx = max(mx, x);
                    return mx - mn;
                };

                struct Choice {
                    string word;
                    vector<int>* group;
                    int sz;
                    int sp;
                    int pr; 
                };

                vector<Choice> choices;
                choices.push_back({"EQUAL", &groupEqual, (int)groupEqual.size(), span(groupEqual), 3});
                choices.push_back({"FIRST", &groupFirst, (int)groupFirst.size(), span(groupFirst), 2});
                choices.push_back({"SECOND", &groupSecond, (int)groupSecond.size(), span(groupSecond), 1});

                Choice best = {"", nullptr, -1, -1, -1};
                for (auto& c : choices) {
                    if (c.sz == 0) continue;
                    if (c.sz > best.sz) best = c;
                    else if (c.sz == best.sz) {
                        if (c.sp > best.sp) best = c;
                        else if (c.sp == best.sp) {
                            if (c.pr > best.pr) best = c;
                            else if (c.pr == best.pr) {
                                
                                if (c.word < best.word) best = c;
                            }
                        }
                    }
                }

                if (best.group == nullptr) {
                    
                    outputWastedAndDie("internal: empty partition");
                }

                outputToContestant(best.word);
                ac.feasibleL.swap(*best.group);
                continue;
            }

            if (cmd == "!") {
                long long x_ll = 0;
                if (!readLong(x_ll)) finish(_pe, "bad final answer token");
                if (x_ll < 1 || x_ll > n) finish(_wa, "final answer out of range");
                int x = (int)x_ll;

                if (fixed_mode) {
                    if (x != fixed_answer) finish(_wa, "wrong answer (fixed mode)");
                } else {
                    bool okForAll = true;
                    for (int L : ac.feasibleL) {
                        if (L != x) {
                            okForAll = false;
                            break;
                        }
                    }
                    if (!okForAll) finish(_wa, "wrong answer (not forced by interaction)");
                }
                break; 
            }

            finish(_pe, "unknown command from contestant");
        }
    }

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


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

static long long clampLL(long long x, long long lo, long long hi) {
    if (x < lo) return lo;
    if (x > hi) return hi;
    return x;
}

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

static void fisherYatesShuffle(vector<int>& a) {
    for (int i = (int)a.size() - 1; i > 0; --i) {
        int j = rnd.next(0, i);
        swap(a[i], a[j]);
    }
}

static vector<int> buildGiftIndices(int n, int k, int& leftmost, int pattern) {
    vector<int> isGift(n + 1, 0);
    vector<int> gifts;
    gifts.reserve(k);

    auto addGift = [&](int idx) {
        if (idx < 1 || idx > n) return;
        if (!isGift[idx]) {
            isGift[idx] = 1;
            gifts.push_back(idx);
        }
    };

    if (pattern == 2) {
        int start = n - k + 1;
        leftmost = start;
        for (int i = start; i <= n; ++i) addGift(i);
        return gifts;
    }

    addGift(leftmost);

    if (pattern == 1) {
        for (int i = leftmost + 1; i <= n && (int)gifts.size() < k; i += 2) addGift(i);
        for (int i = leftmost + 2; i <= n && (int)gifts.size() < k; i += 2) addGift(i);
    }

    if ((int)gifts.size() < k) {
        vector<int> cand;
        cand.reserve(n);
        for (int i = leftmost + 1; i <= n; ++i) if (!isGift[i]) cand.push_back(i);
        fisherYatesShuffle(cand);
        for (int i = 0; i < (int)cand.size() && (int)gifts.size() < k; ++i) addGift(cand[i]);
    }

    if ((int)gifts.size() < k) {
        for (int i = 1; i <= n && (int)gifts.size() < k; ++i) addGift(i);
    }

    sort(gifts.begin(), gifts.end());
    return gifts;
}

static vector<long long> buildWeights(int n, const vector<int>& gifts, long long stoneW, long long gmin, long long gmax, bool nearStone, bool uniqueRandom) {
    vector<long long> w(n + 1, stoneW);
    int k = (int)gifts.size();

    gmax = min(gmax, stoneW - 1);
    if (gmax < gmin) gmax = gmin;

    if (nearStone) {
        for (int i = 0; i < k; ++i) {
            long long gw = stoneW - 1 - i;
            if (gw < 1) gw = 1;
            w[gifts[i]] = gw;
        }
        return w;
    }

    long long range = gmax - gmin + 1;
    if (!uniqueRandom || range <= k + 5) {
        long long start = gmin;
        if (start + (k - 1) > gmax) start = max(gmin, gmax - (k - 1));
        for (int i = 0; i < k; ++i) w[gifts[i]] = start + i;
        return w;
    }

    unordered_set<long long> used;
    used.reserve((size_t)k * 2 + 1);
    int idx = 0;
    int guard = 0;
    while (idx < k) {
        if (++guard > 2000000) {
            long long start = gmin;
            if (start + (k - 1) > gmax) start = max(gmin, gmax - (k - 1));
            for (int i = 0; i < k; ++i) w[gifts[i]] = start + i;
            return w;
        }
        long long gw = rnd.next((long long)gmin, (long long)gmax);
        if (used.insert(gw).second) {
            w[gifts[idx]] = gw;
            ++idx;
        }
    }
    return w;
}

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

    int seed = 0;
    if (argc >= 2) seed = atoi(argv[1]);

    string mode = opt<string>("mode", "non");

    int nOpt = opt<int>("n", 1000);
    long long stoneWOpt = opt<long long>("stone", 1000000000LL);
    long long gminOpt = opt<long long>("gmin", 1LL);
    long long gmaxOpt = opt<long long>("gmax", stoneWOpt - 1);

    int n = clampInt(nOpt, 2, 1000);
    int kOpt = opt<int>("k", -1);
    int k = (kOpt == -1 ? n / 2 : clampInt(kOpt, 1, n / 2));

    long long stoneW = max(2LL, stoneWOpt);
    long long gmin = max(1LL, gminOpt);
    long long gmax = min(gmaxOpt, stoneW - 1);
    if (gmax < gmin) gmax = gmin;

    int leftmost = 1;
    int pattern = 0;
    bool nearStone = false;
    bool uniqueRandom = true;

    if (seed == 1) {
        n = 2; k = 1;
        leftmost = 2;
        pattern = 0;
        nearStone = false;
        uniqueRandom = false;
    } else if (seed == 2) {
        n = 1000; k = 500;
        leftmost = n - k + 1;
        pattern = 2;
        nearStone = false;
        uniqueRandom = true;
    } else if (seed == 3) {
        n = 8; k = 4;
        leftmost = 2;
        pattern = 1;
        nearStone = true;
        uniqueRandom = false;
    } else {
        n = clampInt(n, 2, 1000);
        k = clampInt(k, 1, n / 2);

        int maxLeft = n - k + 1;
        int lo = max(1, maxLeft - 60);
        int hi = maxLeft;
        leftmost = rnd.next(lo, hi);

        pattern = rnd.next(0, 2);
        if (pattern == 2) leftmost = maxLeft;

        nearStone = (rnd.next(0, 9) == 0);
        uniqueRandom = true;

        if (opt<int>("nearStone", -1) != -1) nearStone = (opt<int>("nearStone", 0) != 0);
        if (opt<int>("pattern", -1) != -1) pattern = clampInt(opt<int>("pattern", 0), 0, 2);
    }

    if (k > n / 2) k = n / 2;
    if (k < 1) k = 1;
    int maxLeft = n - k + 1;
    leftmost = clampInt(leftmost, 1, maxLeft);

    if (mode != "non" && mode != "adp") mode = "non";

    cout << 1 << "\n";
    cout << n << " " << k << "\n";

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

    vector<int> gifts = buildGiftIndices(n, k, leftmost, pattern);

    vector<long long> w;
    if (seed == 1) {
        stoneW = 10;
        gmin = 1; gmax = 1;
        w.assign(n + 1, stoneW);
        w[2] = 1;
    } else if (seed == 3) {
        stoneW = max(stoneW, 1000000000LL);
        w = buildWeights(n, gifts, stoneW, 1LL, stoneW - 1, true, false);
    } else {
        w = buildWeights(n, gifts, stoneW, gmin, gmax, nearStone, uniqueRandom);
    }

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