Problem: cf1776_c
Difficulty: medium
Categories: game, greedy, data structures
Time limit: 2000 ms, memory limit: 256 MB

Alessia and Bernardo are discovering the world of competitive programming through the books of their university library.

The library consists of $m$ sections numbered from $1$ to $m$. Each section contains only books dedicated to a particular subject and different sections correspond to different subjects. In order to prevent the students from wandering in the library, the university has established a system of passes. Each pass has a length $y$ associated to it and allows access to an interval of $y$ consecutive sections in the library. During a visit, the student must choose exactly one book from one of these sections and leave the library. Each pass can be used only once.

At the moment Alessia and Bernardo have $n$ passes of lengths $x_1, \, x_2, \, \dots, \, x_n$. They have different opinions on the best way to improve: Alessia thinks that it is important to study many different topics, while Bernardo believes that it is important to study deeply at least one topic. So, Alessia wants to use the $n$ passes to get $n$ books on distinct topics, while Bernardo would like to get at least two books on the same topic.

They have reached the following agreement: for each of the following $n$ days, Alessia will choose a pass of length $y$ among those which are still available and an interval of $y$ sections in the library, and Bernardo will go into the library and will take exactly one book from one of those sections.

Can Bernardo manage to get at least two books on the same subject, or will Alessia be able to avoid it?

You should decide whether you want to be Alessia or Bernardo, and you have to fulfill the goal of your chosen character. The judge will impersonate the other character. Note that, even if at some moment Bernardo has already taken two books on the same subject, the interaction should go on until the end of the $n$ days.

Input

The first line contains two integers $n$ and $m$ ($1 \le n \le 100$, $n \le m \le 5000$) — the number of passes and the number of sections.

The second line contains $n$ integers $x_1, \, x_2, \, \dots, \, x_n$ ($1 \le x_i \le m$) — the lengths of the passes available.

Interaction

First, you should print a line containing either the string $\texttt{Alessia}$ or the string $\texttt{Bernardo}$ — the character that you want to impersonate.

Then, for each of the $n$ turns:

* If you are taking the role of Alessia, print a single line consisting of two integers $y$ and $a$ ($1 \le a \le m - y + 1$) — you are choosing a pass of length $y$ and the interval of sections $[a, a + y - 1]$. Note that at least one pass of length $y$ must still be available. After this, read a single integer $b$ ($a \le b \le a + y - 1$) — the subject of the book selected by Bernardo.
* If you are taking the role of Bernardo, read two integers $y$ and $a$ ($1 \le a \le m - y + 1$) — the length of the pass chosen by Alessia and the index of the first section of the interval. It is guaranteed that there is at least one pass of length $y$ available. Then, print a line consisting of a single integer $b$ ($a \le b \le a + y - 1$) — the subject from which you choose to take a book.

If one of your interactions is malformed, the interactor terminates immediately and your program receives the verdict $\texttt{WRONG-ANSWER}$. Otherwise, you will receive the verdict according to the game's criteria described above.

After printing a line do not forget to end the line and flush the output. Otherwise, you will get the verdict $\texttt{TIMELIMIT}$. To flush the output, use:

* $\texttt{fflush(stdout)}$ in C;
* $\texttt{fflush(stdout)}$, $\texttt{cout <}\texttt{< flush}$ or $\texttt{cout.flush()}$ in C++;
* $\texttt{System.out.flush()}$ in Java and Kotlin;
* $\texttt{sys.stdout.flush()}$ in Python.

Examples

Input

```
5 14
3 7 2 3 10
```

Output

```
-
```

Input

```
4 10
4 1 6 4
```

Output

```
-
```

Note

In the first sample, it can be shown that Alessia can accomplish her goal. An example of interaction (after reading the input) follows:

 \begin{array}{|c|c|c|} \hline \textbf{Contestant} & \textbf{Judge} & \textbf{Explanation} \\ \hline \texttt{Alessia} & & \text{The program will act as Alessia} \\ \hline 3 \quad 11 & & \text{Choose $y = 3$ and $a = 11$} \\ \hline & 13 & \text{Judge selects $b = 13$} \\ \hline 10 \quad 2 & & \text{Choose $y = 10$ and $a = 2$} \\ \hline & 9 & \text{Judge selects $b = 9$} \\ \hline 7 \quad 1 & & \text{Choose $y = 7$ and $a = 1$} \\ \hline & 4 & \text{Judge selects $b = 4$} \\ \hline 2 \quad 10 & & \text{Choose $y = 2$ and $a = 10$} \\ \hline & 10 & \text{Judge selects $b = 10$} \\ \hline 3 \quad 6 & & \text{Choose $y = 3$ and $a = 6$} \\ \hline & 7 & \text{Judge selects $b = 7$} \\ \hline \end{array} 

The program of the contestant wins because all the books chosen by Bernardo pertain to different topics. The actions performed by the contestant and the judge in this example of interaction may be non-optimal.

In the second sample, it can be shown that Bernardo can manage to fulfil his goal. An example of interaction (after reading the input) follows:

 \begin{array}{|c|c|c|} \hline \textbf{Contestant} & \textbf{Judge} & \textbf{Explanation} \\ \hline \texttt{Bernardo} & & \text{The program will act as Bernardo} \\ \hline & 4 \quad 1 & \text{Judge chooses $y = 4$ and $a = 1$} \\ \hline 4 & & \text{Select $b = 4$} \\ \hline & 1 \quad 10 & \text{Judge chooses $y = 1$ and $a = 10$} \\ \hline 10 & & \text{Select $b = 10$} \\ \hline & 6 \quad 3 & \text{Judge chooses $y = 6$ and $a = 3$} \\ \hline 4 & & \text{Select $b = 4$} \\ \hline & 4 \quad 5 & \text{Judge chooses $y = 4$ and $a = 5$} \\ \hline 8 & & \text{Select $b = 8$} \\ \hline \end{array} 

The program of the contestant wins because Bernardo has selected two books on topic number $4$. The actions performed by the contestant and the judge in this example of interaction may be non-optimal.

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

using namespace std;




















static int queries = 0;
static int 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());
}

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

    
    int n = inf.readInt(1, 100, "n");
    int m = inf.readInt(n, 5000, "m");
    
    
    multiset<int> available_passes;
    vector<int> x(n);
    for (int i = 0; i < n; i++) {
        x[i] = inf.readInt(1, m, "x_i");
        available_passes.insert(x[i]);
    }

    
    query_limit = n;

    
    cout << n << " " << m << endl;
    for (int i = 0; i < n; i++) {
        cout << x[i] << (i == n - 1 ? "" : " ");
    }
    cout << endl; 

    
    string role_token;
    if (!(cin >> role_token)) {
        finish(_wa, "No role provided");
    }
    
    bool contestant_is_alessia = false;
    if (role_token == "Alessia") {
        contestant_is_alessia = true;
    } else if (role_token == "Bernardo") {
        contestant_is_alessia = false;
    } else {
        finish(_wa, "Invalid role: " + role_token + " (expected Alessia or Bernardo)");
    }

    
    vector<bool> book_taken(m + 1, false);
    bool duplicate_found = false;

    
    for (int turn = 0; turn < n; turn++) {
        
        log_metrics();

        if (contestant_is_alessia) {
            
            
            

            string s;
            if (!(cin >> s)) finish(_pe, "Unexpected EOF reading 'y'");
            if (s == "?") cin >> s; 

            int y = 0, a = 0;
            try { y = stoi(s); } catch(...) { finish(_pe, "Invalid format for 'y'"); }

            if (!(cin >> s)) finish(_pe, "Unexpected EOF reading 'a'");
            try { a = stoi(s); } catch(...) { finish(_pe, "Invalid format for 'a'"); }

            
            auto it = available_passes.find(y);
            if (it == available_passes.end()) {
                finish(_wa, "Pass length " + to_string(y) + " is not available");
            }
            available_passes.erase(it);

            
            if (a < 1 || a + y - 1 > m) {
                finish(_wa, "Interval [" + to_string(a) + ", " + to_string(a + y - 1) + 
                            "] out of bounds [1, " + to_string(m) + "]");
            }

            
            int b = -1;
            for (int k = 0; k < y; k++) {
                int current_book = a + k;
                if (book_taken[current_book]) {
                    b = current_book;
                    break; 
                }
            }
            
            
            if (b == -1) {
                b = a;
            }

            
            if (book_taken[b]) duplicate_found = true;
            book_taken[b] = true;

            
            cout << b << endl;

        } else {
            
            
            

            
            
            
            
            
            vector<pair<int, int>> gaps;
            int start = -1;
            for (int i = 1; i <= m; i++) {
                if (!book_taken[i]) {
                    if (start == -1) start = i;
                } else {
                    if (start != -1) {
                        gaps.push_back({start, i - 1});
                        start = -1;
                    }
                }
            }
            if (start != -1) {
                gaps.push_back({start, m});
            }

            int choose_y = -1;
            int choose_a = -1;

            
            
            for (auto rit = available_passes.rbegin(); rit != available_passes.rend(); ++rit) {
                int p = *rit;
                int best_gap_idx = -1;
                int min_gap_len = 1000000;

                
                for (int g = 0; g < (int)gaps.size(); g++) {
                    int gap_len = gaps[g].second - gaps[g].first + 1;
                    if (gap_len >= p) {
                        if (gap_len < min_gap_len) {
                            min_gap_len = gap_len;
                            best_gap_idx = g;
                        }
                    }
                }

                if (best_gap_idx != -1) {
                    choose_y = p;
                    choose_a = gaps[best_gap_idx].first; 
                    break;
                }
            }

            
            if (choose_y == -1) {
                choose_y = *available_passes.begin();
                choose_a = 1;
                
                if (choose_a + choose_y - 1 > m) {
                    choose_a = m - choose_y + 1;
                }
            }

            
            available_passes.erase(available_passes.find(choose_y));

            
            cout << choose_y << " " << choose_a << endl;

            
            string s;
            if (!(cin >> s)) finish(_pe, "Unexpected EOF reading 'b'");
            if (s == "?" || s == "!") cin >> s; 

            int b = 0;
            try { b = stoi(s); } catch(...) { finish(_pe, "Invalid format for 'b'"); }

            
            if (b < choose_a || b > choose_a + choose_y - 1) {
                finish(_wa, "Book " + to_string(b) + " is not in interval [" + 
                            to_string(choose_a) + ", " + to_string(choose_a + choose_y - 1) + "]");
            }

            
            if (book_taken[b]) duplicate_found = true;
            book_taken[b] = true;
        }

        queries++;
    }

    log_metrics();

    
    if (contestant_is_alessia) {
        
        if (duplicate_found) {
            finish(_wa, "Bernardo (Judge) managed to take a duplicate book.");
        } else {
            finish(_ok, "Alessia (Contestant) successfully avoided duplicates.");
        }
    } else {
        
        if (duplicate_found) {
            finish(_ok, "Bernardo (Contestant) successfully took a duplicate book.");
        } else {
            finish(_wa, "Bernardo (Contestant) failed to take a duplicate book.");
        }
    }

    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;


void log_metrics() {
    try {
        if (query_limit == 0) query_limit = 1; 
        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());
}


string readToken() {
    string s;
    if (!(cin >> s)) finish(_wa, "Unexpected EOF reading token");
    return s;
}


int readInt() {
    string s;
    if (!(cin >> s)) finish(_wa, "Unexpected EOF reading int");
    try {
        size_t pos;
        int val = stoi(s, &pos);
        if (pos != s.size()) finish(_wa, "Malformed integer");
        return val;
    } catch (...) {
        finish(_wa, "Malformed integer");
    }
    return 0;
}

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

    
    int n = inf.readInt();
    int m = inf.readInt();
    vector<int> x(n);
    multiset<int> available_passes;
    for (int i = 0; i < n; i++) {
        x[i] = inf.readInt();
        available_passes.insert(x[i]);
    }

    query_limit = n; 

    
    cout << n << " " << m << endl;
    for (int i = 0; i < n; i++) {
        cout << x[i] << (i == n - 1 ? "" : " ");
    }
    cout << endl;

    
    string chosen_role = readToken();
    if (chosen_role != "Alessia" && chosen_role != "Bernardo") {
        finish(_wa, "Invalid role: " + chosen_role);
    }

    set<int> used_points;
    bool collision_occurred = false;

    if (chosen_role == "Alessia") {
        
        
        
        
        
        for (int turn = 1; turn <= n; turn++) {
            queries = turn;
            log_metrics(); 

            int y = readInt();
            int a = readInt();

            
            auto it = available_passes.find(y);
            if (it == available_passes.end()) {
                finish(_wa, "Used unavailable pass length " + to_string(y));
            }
            available_passes.erase(it);

            
            if (a < 1 || a + y - 1 > m) {
                finish(_wa, "Interval out of bounds: [" + to_string(a) + ", " + to_string(a + y - 1) + "]");
            }

            int L = a;
            int R = a + y - 1;
            int pick = -1;

            
            for (int u : used_points) {
                if (u >= L && u <= R) {
                    pick = u;
                    collision_occurred = true;
                    break; 
                }
            }

            if (pick == -1) {
                
                
                
                int gap_start = 0;
                int gap_end = m + 1;
                
                auto it_up = used_points.upper_bound(R);
                if (it_up != used_points.end()) gap_end = *it_up;
                
                auto it_low = used_points.lower_bound(L);
                if (it_low != used_points.begin()) {
                    gap_start = *prev(it_low);
                }

                
                double target = (gap_start + gap_end) / 2.0;
                double best_dist = 1e18;
                pick = L;

                
                for (int candidate = L; candidate <= R; candidate++) {
                    double dist = abs(candidate - target);
                    if (dist < best_dist) {
                        best_dist = dist;
                        pick = candidate;
                    }
                }
            }

            cout << pick << endl;
            used_points.insert(pick);
        }

        
        if (collision_occurred) {
            finish(_wa, "Bernardo managed to get at least two books on the same subject");
        } else {
            if ((int)used_points.size() == n)
                finish(_ok, "Alessia wins (all distinct)");
            else
                finish(_wa, "Size mismatch logic error");
        }

    } else {
        
        
        
        vector<int> sorted_passes = x;
        sort(sorted_passes.rbegin(), sorted_passes.rend());

        for (int turn = 1; turn <= n; turn++) {
            queries = turn;
            log_metrics();

            int y = sorted_passes[turn - 1];
            
            
            vector<pair<int, int>> gaps;
            int last_u = 0;
            for (int u : used_points) {
                if (u > last_u + 1) {
                    gaps.push_back({last_u + 1, u - 1});
                }
                last_u = u;
            }
            if (m > last_u) {
                gaps.push_back({last_u + 1, m});
            }

            
            int best_gap_idx = -1;
            int max_len = -1;
            for (int i = 0; i < (int)gaps.size(); i++) {
                int len = gaps[i].second - gaps[i].first + 1;
                if (len >= y) {
                    if (len > max_len) {
                        max_len = len;
                        best_gap_idx = i;
                    }
                }
            }

            int a;
            if (best_gap_idx != -1) {
                
                a = gaps[best_gap_idx].first;
            } else {
                
                a = 1; 
                
                if (a + y - 1 > m) a = m - y + 1; 
            }

            cout << y << " " << a << endl;

            int b = readInt();
            
            
            if (b < a || b > a + y - 1) {
                finish(_wa, "Bernardo chose b outside interval");
            }

            if (used_points.count(b)) {
                collision_occurred = true;
            }
            used_points.insert(b);
        }

        
        if (collision_occurred) {
            finish(_ok, "Bernardo wins (managed collision)");
        } else {
            finish(_wa, "Alessia prevented collision");
        }
    }

    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, m;
    vector<int> x;

    if (mode == "adp") {
        
        
        int type = rnd.next(1, 6);
        
        if (type == 1) {
            
            
            n = rnd.next(50, 100);
            m = rnd.next(n, 3 * n);
            x.resize(n);
            for (int i = 0; i < n; i++) 
                x[i] = rnd.next(1, max(1, m / 2));
        } else if (type == 2) {
            
            
            n = rnd.next(20, 50);
            m = rnd.next(n * 2, 2000);
            x.resize(n);
            for (int i = 0; i < n; i++) 
                x[i] = rnd.next(m / 2, m);
        } else if (type == 3) {
            
            n = rnd.next(30, 80);
            m = rnd.next(n * 5, 5000);
            x.resize(n);
            for (int i = 0; i < n; i++) {
                if (rnd.next(2)) x[i] = rnd.next(1, 3);
                else x[i] = rnd.next(m / 3, m);
            }
        } else if (type == 4) {
            
            n = rnd.next(10, 100);
            m = rnd.next(n, 5000);
            int val = rnd.next(1, m);
            x.assign(n, val);
        } else if (type == 5) {
             
             n = rnd.next(20, 100);
             m = rnd.next(n * 2, 5000);
             x.resize(n);
             int limit = max(1, (int)sqrt(m));
             for(int i=0; i < n; i++) x[i] = rnd.next(limit, m);
        } else {
            
            n = rnd.next(80, 100);
            m = rnd.next(n, 5000);
            x.resize(n);
            for (int i = 0; i < n; i++) x[i] = rnd.next(1, m);
        }
    } else {
        
        
        int type = rnd.next(1, 7);

        if (type == 1) { 
            n = rnd.next(1, 5);
            m = rnd.next(n, 20);
        } else if (type == 2) { 
            n = rnd.next(5, 15);
            m = rnd.next(n, 50);
        } else if (type == 3) { 
            n = 100;
            m = 5000;
        } else if (type == 4) { 
            n = 100;
            m = 100;
        } else if (type == 5) { 
            n = rnd.next(10, 100);
            m = rnd.next(n, 5000);
            x.assign(n, 1);
        } else if (type == 6) { 
            n = rnd.next(10, 100);
            m = rnd.next(n, 5000);
            x.assign(n, m);
        } else { 
            n = rnd.next(10, 100);
            m = rnd.next(n, 5000);
        }

        if (x.empty()) {
            x.resize(n);
            for (int i = 0; i < n; i++) x[i] = rnd.next(1, m);
        }
    }

    
    if (m < n) m = n; 
    for (int i = 0; i < n; i++) {
        if (x[i] < 1) x[i] = 1;
        if (x[i] > m) x[i] = m;
    }
    
    
    shuffle(x.begin(), x.end());

    
    println(n, m);
    println(x);

    return 0;
}