Problem: cf1286_c1
Difficulty: medium
Categories: data structures, math
Time limit: 1000 ms, memory limit: 256 MB

This problem is different with hard version only by constraints on total answers length

It is an interactive problem

Venya joined a tour to the madhouse, in which orderlies play with patients the following game. Orderlies pick a string $s$ of length $n$, consisting only of lowercase English letters. The player can ask two types of queries:

* ? l r – ask to list all substrings of $s[l..r]$. Substrings will be returned in random order, and in every substring, all characters will be randomly shuffled.
* ! s – guess the string picked by the orderlies. This query can be asked exactly once, after that the game will finish. If the string is guessed correctly, the player wins, otherwise he loses.

The player can ask no more than $3$ queries of the first type.

To make it easier for the orderlies, there is an additional limitation: the total number of returned substrings in all queries of the first type must not exceed $(n+1)^2$.

Venya asked you to write a program, which will guess the string by interacting with the orderlies' program and acting by the game's rules.

Your program should immediately terminate after guessing the string using a query of the second type. In case your program guessed the string incorrectly, or it violated the game rules, it will receive verdict Wrong answer.

Note that in every test case the string is fixed beforehand and will not change during the game, which means that the interactor is not adaptive.

Input

First line contains number $n$ ($1 \le n \le 100$) — the length of the picked string.

Interaction

You start the interaction by reading the number $n$.

To ask a query about a substring from $l$ to $r$ inclusively ($1 \le l \le r \le n$), you should output

? l r

on a separate line. After this, all substrings of $s[l..r]$ will be returned in random order, each substring exactly once. In every returned substring all characters will be randomly shuffled.

In the case, if you ask an incorrect query, ask more than $3$ queries of the first type or there will be more than $(n+1)^2$ substrings returned in total, you will receive verdict Wrong answer.

To guess the string $s$, you should output

! s

on a separate line.

After printing each query, do not forget to flush the output. Otherwise, you will get Idleness limit exceeded. To flush the output, you can 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.

If you received - (dash) as an answer to any query, you need to terminate your program with exit code 0 (for example, by calling exit(0)). This means that there was an error in the interaction protocol. If you don't terminate with exit code 0, you can receive any unsuccessful verdict.

Example

Input

```
4

a
aa
a

cb
b
c

c
```

Output

```
? 1 2

? 3 4

? 4 4

! aabc
```

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 long long total_returned = 0;
static long long hard_cap_queries = 0;
static long long hard_cap_returned = 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 uint64_t fnv1a64(const string& s) {
    uint64_t h = 1469598103934665603ULL;
    for (unsigned char c : s) {
        h ^= (uint64_t)c;
        h *= 1099511628211ULL;
    }
    return h;
}

static uint64_t splitmix64_next(uint64_t& x) {
    x += 0x9e3779b97f4a7c15ULL;
    uint64_t z = x;
    z = (z ^ (z >> 30)) * 0xbf58476d1ce4e5b9ULL;
    z = (z ^ (z >> 27)) * 0x94d049bb133111ebULL;
    return z ^ (z >> 31);
}

static uint64_t mix64(uint64_t x) {
    x += 0x9e3779b97f4a7c15ULL;
    x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9ULL;
    x = (x ^ (x >> 27)) * 0x94d049bb133111ebULL;
    return x ^ (x >> 31);
}

static string shuffle_chars_deterministic(string t, uint64_t seed) {
    
    for (int i = (int)t.size() - 1; i > 0; --i) {
        uint64_t r = splitmix64_next(seed);
        int j = (int)(r % (uint64_t)(i + 1));
        swap(t[i], t[j]);
    }
    return t;
}

static bool is_lowercase_word(const string& s) {
    for (char c : s) if (c < 'a' || c > 'z') return false;
    return true;
}

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

    try {
        int n = inf.readInt(1, 100, "n");
        string hidden = inf.readToken();
        if ((int)hidden.size() != n) finish(_fail, "Hidden input: string length mismatch");
        if (!is_lowercase_word(hidden)) finish(_fail, "Hidden input: string is not lowercase");

        query_limit = 3;
        hard_cap_queries = max(200000LL, 10LL * query_limit);
        long long substr_budget = 1LL * (n + 1) * (n + 1);
        hard_cap_returned = max(200000LL, 10LL * substr_budget);

        
        log_metrics();

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

        uint64_t global_seed = fnv1a64(hidden) ^ mix64((uint64_t)n) ^ 0x243f6a8885a308d3ULL;

        while (true) {
            string cmd;
            if (!(cin >> cmd)) {
                finish(_pe, "Unexpected EOF from contestant (no final answer)");
            }

            if (cmd == "?") {
                long long l, r;
                if (!(cin >> l >> r)) {
                    cout << "-\n";
                    cout.flush();
                    finish(_pe, "Malformed query: expected '? l r'");
                }

                queries++;
                if (queries > hard_cap_queries) {
                    cout << "-\n";
                    cout.flush();
                    finish(_pe, "Hard cap exceeded: too many queries");
                }

                if (l < 1 || r < 1 || l > r || r > n) {
                    cout << "-\n";
                    cout.flush();
                    finish(_pe, "Query out of bounds");
                }

                int L = (int)l - 1;
                int R = (int)r - 1;
                int k = R - L + 1;
                long long cnt = 1LL * k * (k + 1) / 2;
                total_returned += cnt;
                if (total_returned > hard_cap_returned) {
                    cout << "-\n";
                    cout.flush();
                    finish(_pe, "Hard cap exceeded: too many substrings returned");
                }

                vector<pair<uint64_t, pair<int,int>>> pos;
                pos.reserve((size_t)cnt);
                for (int i = L; i <= R; ++i) {
                    for (int j = i; j <= R; ++j) {
                        uint64_t key = mix64(global_seed ^ (uint64_t)(i + 1) * 0x9e3779b97f4a7c15ULL ^
                                             (uint64_t)(j + 1) * 0xbf58476d1ce4e5b9ULL);
                        pos.push_back({key, {i, j}});
                    }
                }
                stable_sort(pos.begin(), pos.end(), [](const auto& a, const auto& b) {
                    if (a.first != b.first) return a.first < b.first;
                    if (a.second.first != b.second.first) return a.second.first < b.second.first;
                    return a.second.second < b.second.second;
                });

                for (const auto& it : pos) {
                    int i = it.second.first, j = it.second.second;
                    string t = hidden.substr(i, j - i + 1);
                    uint64_t seed = global_seed ^ (uint64_t)(i + 1) * 0x94d049bb133111ebULL ^
                                    (uint64_t)(j + 1) * 0xbf58476d1ce4e5b9ULL ^
                                    (uint64_t)t.size() * 0x9e3779b97f4a7c15ULL ^
                                    it.first;
                    t = shuffle_chars_deterministic(std::move(t), seed);
                    cout << t << "\n";
                }
                cout.flush();
            } else if (cmd == "!") {
                string guess;
                if (!(cin >> guess)) {
                    finish(_pe, "Malformed answer: expected '! s'");
                }
                if ((int)guess.size() != n) {
                    finish(_wa, "Wrong answer");
                }
                if (!is_lowercase_word(guess)) {
                    finish(_pe, "Answer contains non-lowercase letters");
                }
                if (guess == hidden) finish(_ok, "OK");
                finish(_wa, "Wrong answer");
            } else {
                cout << "-\n";
                cout.flush();
                finish(_pe, "Unknown command");
            }
        }
    } catch (const std::exception& e) {
        log_metrics();
        quitf(_fail, "Interactor exception: %s", e.what());
    } catch (...) {
        log_metrics();
        quitf(_fail, "Interactor exception");
    }
}


Adaptive interactor (C++):

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

static string make_non_instance(int n, long long seedHint, int alphabet) {
    auto clampAlpha = [&](int x) { return max(1, min(26, x)); };
    alphabet = clampAlpha(alphabet);
    n = max(1, min(100, n));

    auto randChar = [&]() -> char {
        return char('a' + rnd.next(0, alphabet - 1));
    };

    if (seedHint == 1) {
        return string(1, 'a');
    }
    if (seedHint == 2) {
        return string(n, 'a');
    }
    if (seedHint == 3) {
        string s;
        s.reserve(n);
        for (int i = 0; i < n; i++) s.push_back((i % 2 == 0) ? 'a' : 'b');
        if (n >= 3) {
            s[0] = 'c';
            s[n - 1] = 'c';
            s[n / 2] = 'c';
        }
        return s;
    }

    int scheme = rnd.next(1, 4);
    string s;
    s.reserve(n);

    if (scheme == 1) {
        for (int i = 0; i < n; i++) s.push_back(randChar());
        return s;
    }

    if (scheme == 2) {
        vector<char> base;
        base.reserve(alphabet);
        for (int i = 0; i < alphabet; i++) base.push_back(char('a' + i));

        int pos = 0;
        while (pos < n) {
            int shift = rnd.next(0, alphabet - 1);
            for (int i = 0; i < alphabet && pos < n; i++, pos++) {
                char c = base[(i + shift) % alphabet];
                if (rnd.next(1, 10) == 1) c = randChar();
                s.push_back(c);
            }
        }
        return s;
    }

    if (scheme == 3) {
        for (int i = 0; i < n; i++) {
            int v = (i % alphabet);
            s.push_back(char('a' + v));
        }
        int swaps = max(1, n / 3);
        for (int t = 0; t < swaps; t++) {
            int i = rnd.next(0, n - 1);
            int j = rnd.next(0, n - 1);
            swap(s[i], s[j]);
        }
        for (int t = 0; t < max(1, n / 10); t++) {
            int i = rnd.next(0, n - 1);
            s[i] = randChar();
        }
        return s;
    }

    
    {
        int pos = 0;
        while (pos < n) {
            int remaining = n - pos;
            int len = rnd.next(1, min(remaining, 15));
            char c;
            if (rnd.next(1, 4) == 1) c = char('a' + (pos % alphabet));
            else c = randChar();
            for (int i = 0; i < len; i++) s.push_back(c);
            pos += len;
        }
        for (int t = 0; t < max(1, n / 12); t++) {
            int i = rnd.next(0, n - 1);
            s[i] = randChar();
        }
        return s;
    }
}

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

    string mode = opt<string>("mode", "non");
    int nOpt = opt<int>("n", 100);
    int alphabet = opt<int>("alphabet", 26);

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

    if (mode == "adp") {
        int n = max(1, min(100, nOpt));
        if (seedHint >= 1 && seedHint <= 3) {
            if (seedHint == 1) n = 1;
            else n = 100;
        } else {
            if (nOpt == 100) n = rnd.next(80, 100);
        }
        cout << n << "\n";
        return 0;
    }

    if (mode != "non") {
        
        mode = "non";
    }

    int n = max(1, min(100, nOpt));
    if (seedHint >= 1 && seedHint <= 3) {
        if (seedHint == 1) n = 1;
        else n = 100;
    } else {
        if (nOpt == 100) n = rnd.next(80, 100);
    }

    string s = make_non_instance(n, seedHint, alphabet);
    n = (int)s.size();

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