One of the most remarkable landmarks in Egypt is the Great Sphinx of Giza, a statue depicting a mythical creature with the head of a human, the body of a lion, and the wings of an eagle. Sphinxes were regarded as guardians in Egyptian and Greek mythologies.Probably the most famous sphinx is the one who guarded the Greek city of Thebes. According to myths,when Oedipus tried to enter the city, the sphinx gave him the following riddle: “Which creature has one voice, but has four feet in the morning,two feet in the afternoon, and three feet at night?" As you might have heard, Oedipus correctly answered,“Man — who crawls on all fours as a baby, then walks on two feet as an adult, and then uses a walking stick in old age."

In this problem, you meet a different sphinx who gives you a somewhat reversed riddle: “How many legs do an axex,a basilisk, and a centaur have?” While you recognize these as creatures from Egyptian and Greek mythology，you have no clue how many legs each has (except that it is a nonnegative integer). The sphinx sternly instructs you to not touch anything so you are unable to search for the answer on your phone.

However, the sphinx allows you to ask her five questions. In each question you can ask the sphinx how many legs some number of these creatures have in total. For instance, you could ask, “How many legs do three basilisks and one axex have in total?” or “How many legs do five centaurs have?” Seems easy enough,you think, but then you remember that sphinxes are tricky creatures: one of the sphinx's five answers might be an outright lie, and you do not know which one.

![](images/70bb1228c86ed7c8a26393a2cc782f0605d76f83447f9ee3fbfd3b8472bd2c9f.jpg)
Oedipus and the Sphinx by Gustave Moreau,1864,public domain

Write a program to talk to the sphinx,ask the five questions,and solve the riddle.

# Interaction

There are exactly five rounds of questions. In each question round, you must first write a line containing three space-separated integers $a , b$ ,and $c \left( 0 \leq a , b , c \leq 1 0 \right)$ , representing the question “How many legs do $a$ axex, $b$ basilisks, and $c$ centaurs have in total?” After the question is asked, an input line containing a single integer $r$ $0 \leq r \leq 1 0 ^ { 5 }$ ） is available on standard input, giving the sphinx's answer to your question.

After the five rounds of questions, output a line containing three space-separated nonnegative integers $\ell _ { a } , \ell _ { b }$ ,and $\ell _ { c }$ , indicating the number of legs of an axex,a basilisk,and a centaur, respectively.

# Read

# Sample Interaction 1

Write

	111

12

	111

13

	501

24

	100

4

	110

8

	444

Read

# Sample Interaction 2

Write

444

2023

	100

0

	010

42

	001

2024

	000

0

	042 2024

#include "testlib.h"
#include <bits/stdc++.h>

using namespace std;

static long long queries = 0;
static long long query_limit = 5;

static long long La, Lb, Lc;
static int lie_idx;

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);

    string mode = inf.readToken();
    if (mode != "fixed") {
        finish(_fail, "Interactor input mismatch: expected 'fixed' mode.");
    }
    La = inf.readLong();
    Lb = inf.readLong();
    Lc = inf.readLong();
    lie_idx = inf.readInt();

    int hard_cap = 50;

    while (true) {

        if (cin.eof()) {
            finish(_pe, "Unexpected end of input (expected query or answer)");
        }

        string token;
        cin >> token;

        if (cin.fail()) {
            if (cin.eof()) finish(_pe, "Unexpected end of input");
            finish(_pe, "Failed to read token");
        }

        bool is_answer = false;
        bool is_query = false;
        long long a = -1, b = -1, c = -1;

        if (token == "!") {
            is_answer = true;
            if (!(cin >> a >> b >> c)) finish(_pe, "Expected 3 integers after '!'");
        } else if (token == "?") {
            is_query = true;
            if (!(cin >> a >> b >> c)) finish(_pe, "Expected 3 integers after '?'");
        } else {

            try {
                size_t idx;
                a = stoll(token, &idx);
                if (idx != token.size()) finish(_pe, "Invalid token (expected integer, '?', or '!')");
            } catch (...) {
                finish(_pe, "Invalid token format");
            }
            if (!(cin >> b >> c)) finish(_pe, "Expected 3 integers");

            if (queries < 5) {
                is_query = true;
            } else {
                is_answer = true;
            }
        }

        if (is_answer) {
            if (a == La && b == Lb && c == Lc) {
                finish(_ok, "Correct answer");
            } else {
                string msg = "Wrong answer. Expected: " + to_string(La) + " " + to_string(Lb) + " " + to_string(Lc)
                           + ", Found: " + to_string(a) + " " + to_string(b) + " " + to_string(c);
                finish(_wa, msg);
            }
        } else {

            if (queries >= 5) {
                finish(_wa, "Too many queries used (limit is 5)");
            }

            if (a < 0 || a > 10 || b < 0 || b > 10 || c < 0 || c > 10) {
                finish(_pe, "Query coefficients must be between 0 and 10");
            }

            long long response = a * La + b * Lb + c * Lc;

            if (queries + 1 == lie_idx) {

                if (response == 0) response = 1;
                else response = response - 1;
            }

            cout << response << endl;
            queries++;

            log_metrics();

            if (queries > hard_cap) {
                finish(_pe, "Hard query limit exceeded (infinite loop)");
            }
        }
    }

    return 0;
}

#include "testlib.h"
#include <vector>
#include <string>
#include <iostream>
#include <algorithm>
#include <random>

using namespace std;

static long long queries_count = 0;
static long long query_limit = 5;

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

    }
}

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

struct Candidate {
    int a, b, c;
    int errors;
};

vector<Candidate> pool;
struct History {
    int a, b, c;
    long long r;
};
vector<History> history_log;

bool adaptive_mode = false;
int fix_a, fix_b, fix_c;
int fix_lie_idx;

long long eval_query(int a, int b, int c, int la, int lb, int lc) {
    return 1LL * a * la + 1LL * b * lb + 1LL * c * lc;
}

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

    string mode_str = inf.readToken();
    if (mode_str == "fixed") {
        adaptive_mode = false;
        fix_a = inf.readInt();
        fix_b = inf.readInt();
        fix_c = inf.readInt();
        fix_lie_idx = inf.readInt();
    } else {
        adaptive_mode = true;
        int seed = inf.readInt();
        rnd.setSeed(seed);

        auto add = [&](int a, int b, int c) {
            pool.push_back({a, b, c, 0});
        };

        add(0, 0, 0);

        vector<int> corners = {0, 1, 2, 3, 5, 10, 100, 1000, 10000, 20000};
        for(int x : corners) for(int y : corners) for(int z : corners) add(x,y,z);

        while(pool.size() < 60000) {
            int t = rnd.next(3);
            if(t == 0) {

                add(rnd.next(0, 20), rnd.next(0, 20), rnd.next(0, 20));
            } else if (t == 1) {

                add(rnd.next(0, 500), rnd.next(0, 500), rnd.next(0, 500));
            } else {

                add(rnd.next(0, 20000), rnd.next(0, 20000), rnd.next(0, 20000));
            }
        }
    }

    for (int round = 1; round <= 5; round++) {

        if (cin.eof()) finish(_pe, "Unexpected EOF in query loop");

        int qa, qb, qc;
        if (!(cin >> qa >> qb >> qc)) finish(_pe, "Invalid query format");

        if (qa < 0 || qa > 10 || qb < 0 || qb > 10 || qc < 0 || qc > 10) {
            finish(_pe, "Coefficients must be in range [0, 10]");
        }

        queries_count++;

        if (queries_count == 1) log_metrics();

        long long reply = 0;

        if (!adaptive_mode) {

            long long val = eval_query(qa, qb, qc, fix_a, fix_b, fix_c);
            if (round == fix_lie_idx) {
                reply = val + 1;
            } else {
                reply = val;
            }
        } else {

            static vector<pair<long long, int>> votes;
            votes.clear();
            if (votes.capacity() < pool.size()) votes.reserve(pool.size());

            for(int i=0; i<(int)pool.size(); ++i) {
                votes.push_back({eval_query(qa, qb, qc, pool[i].a, pool[i].b, pool[i].c), i});
            }
            sort(votes.begin(), votes.end());

            long long best_r = 0;
            pair<int, int> best_score = {-1, -1};

            if (!votes.empty()) {
                int n = votes.size();
                for(int i=0; i<n; ) {
                    int j = i;
                    long long current_val = votes[i].first;
                    int count_err1 = 0;
                    int count_err0 = 0;

                    while(j < n && votes[j].first == current_val) {
                        int idx = votes[j].second;
                        if (pool[idx].errors == 1) count_err1++;
                        if (pool[idx].errors == 0) count_err0++;
                        j++;
                    }

                    if (make_pair(count_err1, count_err0) > best_score) {
                        best_score = {count_err1, count_err0};
                        best_r = current_val;
                    }
                    i = j;
                }
            }

            reply = best_r;

            int w = 0;
            for(int k=0; k<(int)pool.size(); ++k) {
                long long v = eval_query(qa, qb, qc, pool[k].a, pool[k].b, pool[k].c);
                int cost = (v != reply ? 1 : 0);
                pool[k].errors += cost;
                if (pool[k].errors <= 1) {
                    pool[w++] = pool[k];
                }
            }
            pool.resize(w);
        }

        cout << reply << endl;
        history_log.push_back({qa, qb, qc, reply});
    }

    int la, lb, lc;
    if (!(cin >> la >> lb >> lc)) finish(_pe, "Expected final answer (3 integers)");

    int mismatches = 0;
    for(const auto& h : history_log) {
        if (eval_query(h.a, h.b, h.c, la, lb, lc) != h.r) {
            mismatches++;
        }
    }

    if (mismatches > 1) {
        finish(_wa, "Final answer is inconsistent with query history (more than 1 mismatch)");
    }

    if (adaptive_mode) {

        for(const auto& c : pool) {

            if (c.a != la || c.b != lb || c.c != lc) {
                finish(_wa, "Solution is not unique; another valid configuration exists");
            }
        }
    } else {

        if (la != fix_a || lb != fix_b || lc != fix_c) {
            finish(_wa, "Incorrect answer for fixed test case");
        }
    }

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

#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");

    if (mode == "non") {

        cout << "fixed" << endl;

        int sum_limit = 10000;

        int la, lb, lc;

        int type = rnd.next(100);

        if (type < 5) {

            la = 0; lb = 0; lc = 0;
        } else if (type < 10) {

            la = 3333; lb = 3333; lc = 3333;
        } else if (type < 20) {

            int val = rnd.next(0, sum_limit);
            int who = rnd.next(3);
            la = (who == 0 ? val : 0);
            lb = (who == 1 ? val : 0);
            lc = (who == 2 ? val : 0);
        } else if (type < 30) {

            int s = rnd.next(0, sum_limit);
            auto p = rnd.partition(2, (long long)s);
            int who = rnd.next(3);
            if (who == 0) { la = 0; lb = (int)p[0]; lc = (int)p[1]; }
            else if (who == 1) { la = (int)p[0]; lb = 0; lc = (int)p[1]; }
            else { la = (int)p[0]; lb = (int)p[1]; lc = 0; }
        } else {

            int s = rnd.next(0, sum_limit);
            auto p = rnd.partition(3, (long long)s);

            shuffle(p.begin(), p.end());
            la = (int)p[0];
            lb = (int)p[1];
            lc = (int)p[2];
        }

        cout << la << " " << lb << " " << lc << endl;

        int lie_idx;
        if (rnd.next(20) == 0) {
            lie_idx = 0;
        } else {
            lie_idx = rnd.next(1, 5);
        }
        cout << lie_idx << endl;

    } else if (mode == "adp") {

        cout << "adaptive" << endl;

        cout << rnd.next(1, 2000000000) << endl;

    } else {
        quitf(_fail, "Unknown mode: %s", mode.c_str());
    }

    return 0;
}


You are given a bipartite graph with $n_1$ vertices in the first part, $n_2$ vertices in the second part, and $m$ edges. The maximum matching in this graph is the maximum possible (by size) subset of edges of this graph such that no vertex is incident to more than one chosen edge.

You have to process two types of queries to this graph:

* $1$ — remove the minimum possible number of vertices from this graph so that the size of the maximum matching gets reduced exactly by $1$, and print the vertices that you have removed. Then, find any maximum matching in this graph and print the sum of indices of edges belonging to this matching;
* $2$ — query of this type will be asked only after a query of type $1$. As the answer to this query, you have to print the edges forming the maximum matching you have chosen in the previous query.

Note that you should solve the problem in online mode. It means that you can't read the whole input at once. You can read each query only after writing the answer for the last query. Use functions fflush in C++ and BufferedWriter.flush in Java languages after each writing in your program.

Input

The first line contains four integers $n_1$, $n_2$, $m$ and $q$ ($1 \le n_1, n_2 \le 2 \cdot 10^5$; $1 \le m \le \min(n_1 \cdot n_2, 2 \cdot 10^5)$; $1 \le q \le 2 \cdot 10^5$).

Then $m$ lines follow. The $i$-th of them contains two integers $x_i$ and $y_i$ ($1 \le x_i \le n_1$; $1 \le y_i \le n_2$) meaning that the $i$-th edge connects the vertex $x_i$ in the first part and the vertex $y_i$ in the second part. There are no pairs of vertices that are connected by more than one edge.

Then $q$ lines follow. The $i$-th of them contains one integer, $1$ or $2$, denoting the $i$-th query. Additional constraints on queries:

* the number of queries of type $1$ won't exceed the size of the maximum matching in the initial graph;
* the number of queries of type $2$ won't exceed $3$;
* each query of type $2$ is preceded by a query of type $1$;
* your solution is allowed to read the $i$-th query only after printing the answer for the $(i-1)$-th query and flushing the output.

Output

For a query of type $1$, print the answer in three lines as follows:

* the first line should contain the number of vertices you remove;
* the second line should contain the indices of vertices you remove, as follows: if you remove the vertex $x$ from the left part, print $x$; if you remove the vertex $y$ from the right part, print $-y$ (negative index);
* the third line should contain the sum of indices of edges in some maximum matching in the resulting graph. The edges are numbered from $1$ to $m$.

For a query of type $2$, print the answer in two lines as follows:

* the first line should contain the size of the maximum matching;
* the second line should contain the indices of the edges belonging to the maximum matching. Note that the sum of these indices should be equal to the number you printed at the end of the previous query of type $1$;

After printing the answer to a query, don't forget to flush the output.

Example

Input

```
3 4 4 4
2 2
1 3
2 1
3 4
1
2
1
2
```

Output

```
1
-4
3
===
2
1 2
===
1
2
2
===
1
2
```

Note

In this problem, you may receive the verdict "Idleness Limit Exceeded" since it is in online mode. If it happens, it means that either the output format is wrong, or you don't meet some constraint of the problem. You may treat this verdict as "Wrong Answer".

For your convenience, the output for queries in the example is separated by the line ===. Don't print this line in your program, it is done only to make sure that it's easy to distinguish between answers for different queries in the statement.

#include "testlib.h"
#include <bits/stdc++.h>
using namespace std;

struct Edge {
    int to;
    int rev;
    int flow;
    int cap;
};

vector<vector<Edge>> adj;
vector<int> level;
vector<int> ptr;

void add_edge(int from, int to, int cap) {
    adj[from].push_back({to, (int)adj[to].size(), 0, cap});
    adj[to].push_back({from, (int)adj[from].size() - 1, 0, 0});
}

bool bfs(int s, int t) {
    fill(level.begin(), level.end(), -1);
    level[s] = 0;
    queue<int> q;
    q.push(s);
    while (!q.empty()) {
        int v = q.front();
        q.pop();
        for (auto& edge : adj[v]) {
            if (edge.cap - edge.flow > 0 && level[edge.to] == -1) {
                level[edge.to] = level[v] + 1;
                q.push(edge.to);
            }
        }
    }
    return level[t] != -1;
}

int dfs(int v, int t, int pushed) {
    if (pushed == 0) return 0;
    if (v == t) return pushed;
    for (int& cid = ptr[v]; cid < adj[v].size(); ++cid) {
        auto& edge = adj[v][cid];
        int tr = edge.to;
        if (level[v] + 1 != level[tr] || edge.cap - edge.flow == 0) continue;
        int push = dfs(tr, t, min(pushed, edge.cap - edge.flow));
        if (push == 0) continue;
        edge.flow += push;
        adj[tr][edge.rev].flow -= push;
        return push;
    }
    return 0;
}

int dinic(int s, int t) {
    int flow = 0;
    while (bfs(s, t)) {
        fill(ptr.begin(), ptr.end(), 0);
        while (int pushed = dfs(s, t, 1e9)) {
            flow += pushed;
        }
    }
    return flow;
}

int n1, n2, m, q;
vector<pair<int, int>> edges;
vector<bool> is_removed;
vector<bool> in_mvc;
vector<int> D;
vector<vector<int>> g_adj;

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());
}

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

    n1 = inf.readInt();
    n2 = inf.readInt();
    m = inf.readInt();
    q = inf.readInt();

    cout << n1 << " " << n2 << " " << m << " " << q << endl;

    edges.resize(m + 1);
    g_adj.resize(n1 + n2 + 1);

    int S = 0, T = n1 + n2 + 1;
    adj.resize(T + 1);
    level.resize(T + 1);
    ptr.resize(T + 1);

    for (int i = 1; i <= n1; i++) add_edge(S, i, 1);
    for (int i = 1; i <= n2; i++) add_edge(n1 + i, T, 1);

    for (int i = 1; i <= m; i++) {
        int u = inf.readInt();
        int v = inf.readInt();
        edges[i] = {u, v};

        cout << u << " " << v << endl;

        add_edge(u, n1 + v, 1);
        g_adj[u].push_back(n1 + v);
        g_adj[n1 + v].push_back(u);
    }
    cout.flush();

    vector<int> query_types(q);
    for (int i = 0; i < q; i++) {
        query_types[i] = inf.readInt();
    }

    int max_matching = dinic(S, T);
    query_limit = max_matching;
    log_metrics();

    vector<bool> reachable(T + 1, false);
    queue<int> Q;
    Q.push(S);
    reachable[S] = true;

    while(!Q.empty()){
        int u = Q.front(); Q.pop();
        for(auto& e : adj[u]){
            if(e.cap - e.flow > 0 && !reachable[e.to]){
                reachable[e.to] = true;
                Q.push(e.to);
            }
        }
    }

    in_mvc.assign(n1 + n2 + 1, false);
    is_removed.assign(n1 + n2 + 1, false);

    int mvc_size = 0;
    for(int i=1; i<=n1; ++i) {
        if(!reachable[i]) { in_mvc[i] = true; mvc_size++; }
    }
    for(int i=1; i<=n2; ++i) {
        if(reachable[n1 + i]) { in_mvc[n1 + i] = true; mvc_size++; }
    }

    if(mvc_size != max_matching) {

    }

    D.assign(n1 + n2 + 1, 0);
    for(int i=1; i<=n1+n2; ++i) {
        if(in_mvc[i]) {
            for(int neighbor : g_adj[i]) {
                if(!in_mvc[neighbor]) {
                    D[i]++;
                }
            }
        }
    }

    int current_matching_size = max_matching;

    for (int k = 0; k < q; k++) {

        if (k % 50 == 0) log_metrics();

        int type = query_types[k];
        cout << type << endl;

        if (type == 1) {
            queries++;

            string line1;

            while(line1.empty()) {
                if(!(cin >> line1)) finish(_wa, "Unexpected EOF reading answer to type 1");
            }

            if (line1[0] == '!') finish(_wa, "Unexpected answer format (received '!')");

            int count = 0;
            try { count = stoi(line1); } catch(...) { finish(_wa, "Invalid integer for count"); }

            if (count != 1) finish(_wa, "Count of removed vertices must be 1");

            int idx = 0;
            if(!(cin >> idx)) finish(_wa, "Unexpected EOF reading vertex index");

            int u = 0;
            if (idx > 0) {
                u = idx;
                if (u < 1 || u > n1) finish(_wa, "Vertex index out of bounds");
            } else if (idx < 0) {
                u = n1 + (-idx);
                if (u <= n1 || u > n1 + n2) finish(_wa, "Vertex index out of bounds");
            } else {
                finish(_wa, "Vertex index cannot be 0");
            }

            long long reported_sum;
            if(!(cin >> reported_sum)) finish(_wa, "Unexpected EOF reading sum");

            if (is_removed[u]) finish(_wa, "Vertex already removed");

            if (in_mvc[u]) {

                in_mvc[u] = false;
                is_removed[u] = true;
                current_matching_size--;

            } else {

                int swap_v = -1;
                for (int v : g_adj[u]) {
                    if (!is_removed[v] && in_mvc[v]) {
                        if (D[v] == 1) {
                            swap_v = v;
                            break;
                        }
                    }
                }

                if (swap_v == -1) {
                    finish(_wa, "Removing this vertex does not reduce max matching size");
                }

                for (int z : g_adj[u]) {
                    if (!is_removed[z] && in_mvc[z]) {
                        D[z]--;
                    }
                }

                for (int z : g_adj[swap_v]) {
                    if (!is_removed[z] && in_mvc[z]) {
                        D[z]++;
                    }
                }

                in_mvc[swap_v] = false;
                is_removed[u] = true;
                current_matching_size--;
            }

        } else {

            int size_claimed;
            if(!(cin >> size_claimed)) finish(_wa, "Unexpected EOF reading size");

            if (size_claimed != current_matching_size) {
                finish(_wa, "Incorrect max matching size reported");
            }

            vector<int> edges_indices(size_claimed);
            vector<bool> v_covered(n1 + n2 + 1, false);

            for(int i=0; i<size_claimed; ++i) {
                if(!(cin >> edges_indices[i])) finish(_wa, "Unexpected EOF reading edge indices");

                int eid = edges_indices[i];
                if(eid < 1 || eid > m) finish(_wa, "Invalid edge index");

                int eu = edges[eid].first;
                int ev = n1 + edges[eid].second;

                if(is_removed[eu] || is_removed[ev]) finish(_wa, "Matching uses removed vertex");
                if(v_covered[eu] || v_covered[ev]) finish(_wa, "Not a matching (vertex shared)");

                v_covered[eu] = true;
                v_covered[ev] = true;
            }

        }
    }

    finish(_ok, "Passed all queries");
    return 0;
}

#include "testlib.h"
#include <bits/stdc++.h>

using namespace std;

static long long queries_cnt = 0;
static long long query_limit = 0;

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

    }
}

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

const int MAXN = 400005;
const int INF = 1e9;

struct Edge {
    int u, v, id;
};
vector<Edge> edges;

struct FlowEdge {
    int to;
    int rev;
    int cap;
    int flow;
    int id;
};

vector<FlowEdge> adj[MAXN];
int level[MAXN];
int ptr[MAXN];
int S, T;
int n1, n2, m, q;

void add_flow_edge(int from, int to, int cap, int id = -1) {
    FlowEdge a = {to, (int)adj[to].size(), cap, 0, id};
    FlowEdge b = {from, (int)adj[from].size(), 0, 0, -1};
    adj[from].push_back(a);
    adj[to].push_back(b);
}

bool bfs() {
    fill(level, level + T + 1, -1);
    level[S] = 0;
    queue<int> q_bfs;
    q_bfs.push(S);
    while (!q_bfs.empty()) {
        int v = q_bfs.front();
        q_bfs.pop();
        for (const auto& edge : adj[v]) {
            if (edge.cap - edge.flow > 0 && level[edge.to] == -1) {
                level[edge.to] = level[v] + 1;
                q_bfs.push(edge.to);
            }
        }
    }
    return level[T] != -1;
}

int dfs(int v, int pushed) {
    if (pushed == 0) return 0;
    if (v == T) return pushed;
    for (int& cid = ptr[v]; cid < (int)adj[v].size(); ++cid) {
        auto& edge = adj[v][cid];
        int tr = edge.to;
        if (level[v] + 1 != level[tr] || edge.cap - edge.flow == 0) continue;
        int push = dfs(tr, min(pushed, edge.cap - edge.flow));
        if (push == 0) continue;
        edge.flow += push;
        adj[tr][edge.rev].flow -= push;
        return push;
    }
    return 0;
}

int dinic() {
    int flow = 0;
    while (bfs()) {
        fill(ptr, ptr + T + 1, 0);
        while (int pushed = dfs(S, INF)) {
            flow += pushed;
        }
    }
    return flow;
}

set<int> initial_MVC;

int current_match[MAXN];

vector<pair<int, int>> adj_simple[MAXN];
set<int> removed_vertices;
long long last_type1_sum = -1;

void build_mvc_and_match() {

    fill(current_match, current_match + T + 1, 0);
    for (int u = 1; u <= n1; ++u) {
        for (const auto& e : adj[u]) {
            if (e.to > n1 && e.to <= n1 + n2 && e.flow == 1) {
                current_match[u] = e.to;
                current_match[e.to] = u;
                break;
            }
        }
    }

    vector<bool> reachable(T + 1, false);
    queue<int> q_bfs;

    for (int u = 1; u <= n1; ++u) {
        if (current_match[u] == 0) {
            reachable[u] = true;
            q_bfs.push(u);
        }
    }

    while(!q_bfs.empty()) {
        int u = q_bfs.front(); q_bfs.pop();

        for (const auto& e : adj[u]) {

            if (e.cap - e.flow > 0) {
                if (e.to >= 1 && e.to <= n1 + n2 && !reachable[e.to]) {
                    reachable[e.to] = true;
                    q_bfs.push(e.to);
                }
            }
        }
    }

    for (int u = 1; u <= n1; ++u) {
        if (!reachable[u]) initial_MVC.insert(u);
    }
    for (int v = n1 + 1; v <= n1 + n2; ++v) {
        if (reachable[v]) initial_MVC.insert(v);
    }
}

bool vis[MAXN];
bool find_aug_path_bfs(int start_node, bool start_is_left) {

    fill(vis, vis + n1 + n2 + 1, false);
    queue<int> q_aug;

    q_aug.push(start_node);
    vis[start_node] = true;

    while(!q_aug.empty()) {
        int u = q_aug.front(); q_aug.pop();

        for (auto& edge : adj_simple[u]) {
            int v = edge.first;
            if (removed_vertices.count(v)) continue;

            int next_u = current_match[v];
            if (next_u == 0) return true;

            if (!vis[next_u]) {
                vis[next_u] = true;
                q_aug.push(next_u);
            }
        }
    }
    return false;
}

int main(int argc, char** argv) {

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

    registerInteraction(argc, argv);
    atexit(log_metrics);

    n1 = inf.readInt();
    n2 = inf.readInt();
    m = inf.readInt();
    q = inf.readInt();

    for (int i = 1; i <= m; ++i) {
        int u = inf.readInt();
        int v = inf.readInt();
        edges.push_back({u, v, i});

        adj_simple[u].push_back({n1 + v, i});
        adj_simple[n1 + v].push_back({u, i});

        add_flow_edge(u, n1 + v, 1, i);
    }

    S = 0; T = n1 + n2 + 1;
    for (int i = 1; i <= n1; ++i) add_flow_edge(S, i, 1);
    for (int i = 1; i <= n2; ++i) add_flow_edge(n1 + i, T, 1);

    vector<int> query_types(q);
    for (int i = 0; i < q; ++i) {
        query_types[i] = inf.readInt();
    }
    query_limit = q;

    dinic();
    build_mvc_and_match();

    cout << n1 << " " << n2 << " " << m << " " << q << endl;
    for (const auto& e : edges) {
        cout << e.u << " " << e.v << endl;
    }
    cout.flush();

    for (int k = 0; k < q; ++k) {
        int type = query_types[k];
        cout << type << endl;

        if (type == 1) {
            queries_cnt++;

            int cnt;
            if (!(cin >> cnt)) finish(_wa, "Unexpected EOF reading query 1 answer (count)");
            if (cnt != 1) finish(_wa, "Must remove exactly 1 vertex");

            int v_idx;
            if (!(cin >> v_idx)) finish(_wa, "Unexpected EOF reading query 1 answer (vertex)");

            int v_abs = abs(v_idx);
            int v_real = -1;
            if (v_idx > 0) {
                if (v_idx > n1) finish(_wa, "Vertex index out of range");
                v_real = v_idx;
            } else if (v_idx < 0) {
                if (v_abs > n2) finish(_wa, "Vertex index out of range");
                v_real = n1 + v_abs;
            } else {
                finish(_wa, "Vertex index cannot be 0");
            }

            if (removed_vertices.count(v_real)) finish(_wa, "Vertex already removed");

            long long s;
            if (!(cin >> s)) finish(_wa, "Unexpected EOF reading query 1 answer (sum)");
            last_type1_sum = s;

            if (current_match[v_real] != 0) {

                int partner = current_match[v_real];
                current_match[v_real] = 0;
                current_match[partner] = 0;
                removed_vertices.insert(v_real);
            } else {

                removed_vertices.insert(v_real);
                finish(_wa, "Removing vertex did not decrease max matching size (vertex was unmatched)");
            }

        } else if (type == 2) {

            int k_ans;
            if (!(cin >> k_ans)) finish(_wa, "Unexpected EOF reading query 2 answer");

            vector<int> edge_indices(k_ans);
            long long sum_indices = 0;
            set<int> used_nodes;

            for(int i=0; i<k_ans; ++i) {
                if (!(cin >> edge_indices[i])) finish(_wa, "Unexpected EOF reading edges");
                if (edge_indices[i] < 1 || edge_indices[i] > m) finish(_wa, "Edge index out of range");

                sum_indices += edge_indices[i];
                Edge& e = edges[edge_indices[i]-1];

                int u = e.u;
                int v = n1 + e.v;

                if (removed_vertices.count(u) || removed_vertices.count(v)) {
                    finish(_wa, "Edge incident to removed vertex");
                }
                if (used_nodes.count(u) || used_nodes.count(v)) {
                    finish(_wa, "Invalid matching (overlapping edges)");
                }
                used_nodes.insert(u);
                used_nodes.insert(v);
            }

            if (sum_indices != last_type1_sum) {
                finish(_wa, "Sum of edge indices mismatch with previous query 1");
            }

            int current_size = 0;
            for(int i=1; i<=n1; ++i) if(current_match[i] != 0) current_size++;

            if (k_ans != current_size) {

                finish(_wa, "Matching size not maximum");
            }

        } else {
            finish(_wa, "Internal error: unknown query type");
        }
    }

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

#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");

    long long seed_val = 0;
    if (argc > 1) seed_val = atoll(argv[1]);

    int n1, n2, m;

    if (seed_val > 0 && seed_val <= 3) {

        if (seed_val == 1) {
            n1 = 1; n2 = 1; m = 1;
        } else if (seed_val == 2) {
            n1 = 2; n2 = 3; m = 6;
        } else {
            n1 = 5; n2 = 5; m = 4;
        }
    } else {

        n1 = rnd.next(100, 200000);
        n2 = rnd.next(100, 200000);
        long long max_m = min((long long)n1 * n2, 200000LL);

        if (rnd.next(5) == 0) m = (int)max_m;
        else m = rnd.next(1, (int)max_m);
    }

    int limit_K = min({n1, n2, m});
    int K = rnd.next(1, limit_K);

    if (mode == "adp" || rnd.next(3) == 0) {
        K = rnd.next(limit_K / 2 + (limit_K % 2), limit_K);
        if (K == 0) K = 1;
    }

    vector<pair<int,int>> edges;
    set<pair<int,int>> edge_set;

    vector<int> p1(n1), p2(n2);
    iota(p1.begin(), p1.end(), 1);
    iota(p2.begin(), p2.end(), 1);
    shuffle(p1.begin(), p1.end());
    shuffle(p2.begin(), p2.end());

    for(int i=0; i<K; ++i) {
        edges.push_back({p1[i], p2[i]});
        edge_set.insert({p1[i], p2[i]});
    }

    while((int)edges.size() < m) {
        int u = rnd.next(1, n1);
        int v = rnd.next(1, n2);
        if (edge_set.find({u, v}) == edge_set.end()) {
            edge_set.insert({u, v});
            edges.push_back({u, v});
        }
    }

    shuffle(edges.begin(), edges.end());

    int num_t1 = rnd.next(1, K);

    int num_t2 = rnd.next(0, 3);

    vector<int> t1_indices(num_t1);
    iota(t1_indices.begin(), t1_indices.end(), 0);
    shuffle(t1_indices.begin(), t1_indices.end());

    vector<bool> follow(num_t1, false);
    for(int i=0; i<min(num_t1, num_t2); ++i) {
        follow[t1_indices[i]] = true;
    }

    vector<int> queries;
    for(int i=0; i<num_t1; ++i) {
        queries.push_back(1);
        if(follow[i]) queries.push_back(2);
    }

    println(n1, n2, m, (int)queries.size());
    for(const auto& e : edges) {
        println(e.first, e.second);
    }
    for(int q : queries) {
        println(q);
    }

    return 0;
}


D. Mahmoud and Ehab and the binary string

Mahmoud and Ehab are in the fourth stage now.

Dr. Evil has a hidden binary string of length *n*. He guarantees that there is at least one '0' symbol and at least one '1' symbol in it. Now he wants Mahmoud and Ehab to find a position of any '0' symbol and any '1' symbol. In order to do this, Mahmoud and Ehab can ask Dr. Evil up to 15 questions. They tell Dr. Evil some binary string of length *n*, and Dr. Evil tells the Hamming distance between these two strings. Hamming distance between 2 binary strings of the same length is the number of positions in which they have different symbols. You can find the definition of Hamming distance in the notes section below.

Help Mahmoud and Ehab find these two positions.

You will get Wrong Answer verdict if

* Your queries doesn't satisfy interaction protocol described below.
* You ask strictly more than 15 questions and your program terminated after exceeding queries limit. Please note, that you can do up to 15 ask queries and one answer query.
* Your final answer is not correct.

You will get Idleness Limit Exceeded if you don't print anything or if you forget to flush the output, including for the final answer (more info about flushing output below).

If you exceed the maximum number of queries, You should terminate with 0, In this case you'll get Wrong Answer, If you don't terminate you may receive any verdict because you'll be reading from a closed stream.

Input

The first line of input will contain a single integer *n* (2 ≤ *n* ≤ 1000) — the length of the hidden binary string.

Output

To print the final answer, print "! pos0 pos1" (without quotes), where *pos*0 and *pos*1 are positions of some '0' and some '1' in the string (the string is 1-indexed). Don't forget to flush the output after printing the answer!

Interaction

To ask a question use the format "? s" (without quotes), where *s* is a query string. Don't forget to flush the output after printing a query!

After each query you can read a single integer from standard input — the Hamming distance between the hidden string and the query string.

To flush the output you can use:-

* fflush(stdout) in C++;
* System.out.flush() in Java;
* stdout.flush() in Python;
* flush(output) in Pascal;
* See the documentation for other languages.

Example

Input

```
3
2
1
3
2
1
0
```

Output

```? 000? 001? 010? 011? 100? 101! 2 1
```

Note

Hamming distance definition: [link omitted]

In the first test case the hidden binary string is 101, The first query is 000, so the Hamming distance is 2. In the second query the hidden string is still 101 and query is 001, so the Hamming distance is 1.

After some queries you find that symbol at position 2 is '0' and symbol at position 1 is '1', so you print "! 2 1".

#include "testlib.h"
#include <bits/stdc++.h>
using namespace std;

static long long queries = 0;
static long long query_limit = 15;

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

    }
}

template <typename... Args>
void finish(TResult verdict, const char* fmt, Args... args) {
    log_metrics();
    quitf(verdict, fmt, args...);
}

int main(int argc, char** argv) {

    registerInteraction(argc, argv);

    atexit(log_metrics);

    int n = inf.readInt(2, 1000, "n");
    string hidden_s = inf.readToken("[01]+", "hidden_s");

    if ((int)hidden_s.length() != n) {
        finish(_fail, "Hidden string length (%d) does not match n (%d)", (int)hidden_s.length(), n);
    }
    bool has0 = false, has1 = false;
    for (char c : hidden_s) {
        if (c == '0') has0 = true;
        if (c == '1') has1 = true;
    }
    if (!has0 || !has1) {
        finish(_fail, "Hidden string must contain at least one '0' and one '1'");
    }

    cout << n << endl;

    log_metrics();

    int hard_cap = 300;

    while (true) {

        if (queries > hard_cap) {
            finish(_pe, "Hard query limit exceeded (%d)", hard_cap);
        }

        string token;
        if (!(cin >> token)) {

            finish(_wa, "Unexpected EOF: expected query ('?') or answer ('!')");
        }

        if (token == "!") {

            int p0, p1;
            if (!(cin >> p0 >> p1)) {
                finish(_wa, "Unexpected EOF reading answer positions");
            }

            if (p0 < 1 || p0 > n || p1 < 1 || p1 > n) {
                finish(_wa, "Answer positions %d %d out of range [1, %d]", p0, p1, n);
            }

            char c0 = hidden_s[p0 - 1];
            char c1 = hidden_s[p1 - 1];

            if (c0 != '0') {
                finish(_wa, "Position %d is '%c', expected '0'", p0, c0);
            }
            if (c1 != '1') {
                finish(_wa, "Position %d is '%c', expected '1'", p1, c1);
            }

            finish(_ok, "Correct! Found 0 at %d, 1 at %d", p0, p1);
        } else {

            string qs;
            if (token == "?") {

                if (!(cin >> qs)) {
                    finish(_wa, "Unexpected EOF reading query string after '?'");
                }
            } else {

                qs = token;
            }

            if ((int)qs.length() != n) {
                finish(_wa, "Query string length %d, expected %d", (int)qs.length(), n);
            }

            int dist = 0;
            for (int i = 0; i < n; i++) {
                if (qs[i] != '0' && qs[i] != '1') {
                    finish(_wa, "Query string contains invalid character '%c'", qs[i]);
                }
                if (qs[i] != hidden_s[i]) {
                    dist++;
                }
            }

            queries++;

            if (queries % 5 == 0) log_metrics();

            cout << dist << endl;
        }
    }

    return 0;
}

#include "testlib.h"
#include <bits/stdc++.h>

using namespace std;

static long long queries = 0;
static const long long query_limit = 15;

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 string make_hidden_string(int n, uint64_t seed) {
    mt19937 rng((uint32_t)(seed ^ (seed >> 32)));
    string s(n, '0');
    for (int i = 0; i < n; i++) s[i] = (rng() & 1) ? '1' : '0';
    bool has0 = false, has1 = false;
    for (char ch : s) {
        has0 |= (ch == '0');
        has1 |= (ch == '1');
    }
    if (!has0) s[0] = '0';
    if (!has1) s[n - 1] = '1';
    if (n == 1) s[0] = '0';
    return s;
}

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

    int n = inf.readInt(2, 1000, "n");
    string hidden_s;
    if (!inf.seekEof()) hidden_s = inf.readToken();
    if (hidden_s.empty()) {
        uint64_t seed = (uint64_t)hash<string>{}(string(argv[1]));
        seed ^= (uint64_t)n * 0x9e3779b97f4a7c15ULL;
        hidden_s = make_hidden_string(n, seed);
    }

    if ((int)hidden_s.size() != n) finish(_fail, "Hidden string length mismatch");
    bool has0 = false, has1 = false;
    for (char ch : hidden_s) {
        if (ch != '0' && ch != '1') finish(_fail, "Hidden string has invalid character");
        has0 |= (ch == '0');
        has1 |= (ch == '1');
    }
    if (!has0 || !has1) finish(_fail, "Hidden string must contain at least one 0 and one 1");

    cout << n << endl;
    cout.flush();
    log_metrics();

    const int hard_cap = 300;
    while (true) {
        if (queries > hard_cap) finish(_pe, "Hard query limit exceeded");

        string token;
        if (!(cin >> token)) {
            finish(_wa, "Unexpected EOF: expected query ('?') or answer ('!')");
        }

        if (token == "!") {
            int p0, p1;
            if (!(cin >> p0 >> p1)) finish(_wa, "Malformed answer");
            if (p0 < 1 || p0 > n || p1 < 1 || p1 > n) finish(_wa, "Answer indices out of range");
            if (hidden_s[p0 - 1] != '0') finish(_wa, "Wrong 0 position");
            if (hidden_s[p1 - 1] != '1') finish(_wa, "Wrong 1 position");
            finish(_ok, "OK");
        }

        string qs;
        if (token == "?") {
            if (!(cin >> qs)) finish(_wa, "Malformed query");
        } else {
            qs = token;
        }

        if ((int)qs.size() != n) finish(_wa, "Query length mismatch");
        int dist = 0;
        for (int i = 0; i < n; i++) {
            if (qs[i] != '0' && qs[i] != '1') finish(_wa, "Query has invalid character");
            if (qs[i] != hidden_s[i]) dist++;
        }
        queries++;
        if ((queries % 5) == 0) log_metrics();
        cout << dist << endl;
        cout.flush();
    }
}

#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 seed_val = atoi(argv[1]);

    int n;

    if (seed_val == 1) n = 2;
    else if (seed_val == 2) n = 3;
    else if (seed_val == 3) n = 1000;
    else if (seed_val == 4) n = 1000;
    else {

        if (rnd.next(5) == 0) n = rnd.next(2, 20);
        else n = rnd.next(900, 1000);
    }

    if (mode == "adp") {
        cout << n << endl;
        return 0;
    }

    string s = "";

    if (seed_val == 1) {
        s = "01";
    } else if (seed_val == 2) {
        s = "100";
    } else if (seed_val == 3) {

        s = string(n, '1');
        s[rnd.next(n)] = '0';
    } else if (seed_val == 4) {

        s = string(n, '0');
        s[rnd.next(n)] = '1';
    } else {

        int type = rnd.next(1, 5);
        if (type == 1) {

            for (int i = 0; i < n; i++)
                s += (rnd.next(2) ? '1' : '0');
        } else if (type == 2) {

            int k = rnd.next(1, max(1, n / 15));
            s = string(n, '1');
            for (int i = 0; i < k; i++) s[i] = '0';
            shuffle(s.begin(), s.end());
        } else if (type == 3) {

            int k = rnd.next(1, max(1, n / 15));
            s = string(n, '0');
            for (int i = 0; i < k; i++) s[i] = '1';
            shuffle(s.begin(), s.end());
        } else if (type == 4) {

            s = string(n, '0');
            for (int i = 0; i < n / 2; i++) s[i] = '1';
            shuffle(s.begin(), s.end());
        } else {

            char cur = rnd.next(2) ? '1' : '0';
            while (s.length() < n) {
                int len = rnd.next(1, max(1, (int)(n - s.length())));
                s += string(len, cur);
                cur = (cur == '1' ? '0' : '1');
            }
        }
    }

    bool has0 = false;
    for (char c : s) if (c == '0') has0 = true;
    if (!has0) s[rnd.next(n)] = '0';

    bool has1 = false;
    for (char c : s) if (c == '1') has1 = true;
    if (!has1) {

        s[rnd.next(n)] = '1';
    }

    cout << n << endl;
    cout << s << endl;

    return 0;
}


### Problem Statement

This is an **interactive task**, where your and the judge's programs interact via Standard Input and Output.

You and the judge will follow the procedure below.
The procedure consists of phases $1$ and $2$; phase $1$ is immediately followed by phase $2$.

(Phase $1$)

* The judge decides an integer $N$ between $1$ and $10^9$ (inclusive), which is hidden.
* You print an integer $M$ between $1$ and $110$ (inclusive).
* You also print an integer sequence $A=(A_1,A_2,\ldots,A_M)$ of length $M$ such that $1 \leq A_i \leq M$ for all $i = 1, 2, \ldots, M$.

(Phase $2$)

* The judge gives you an integer sequence $B=(B_1,B_2,\ldots,B_M)$ of length $M$. Here, $B_i = f^N(i)$. $f(i)$ is defined by $f(i)=A_i$ for all integers $i$ between $1$ and $M$ (inclusive), and $f^N(i)$ is the integer resulting from replacing $i$ with $f(i)$ $N$ times.
* Based on the given $B$, you identify the integer $N$ that the judge has decided, and print $N$.

After the procedure above, terminate the program immediately to be judged correct.

### Constraints

* $N$ is an integer between $1$ and $10^9$ (inclusive).

### Input and Output

This is an interactive task, where your and the judge's programs interact via Standard Input and Output.

(Phase $1$)

* First, print an integer $M$ between $1$ and $110$ (inclusive). It must be followed by a newline.

```
$M$
```

* Then, print a sequence $A=(A_1,A_2,\ldots,A_M)$ of length $M$ consisting of integers between $1$ and $M$ (inclusive), with spaces in between. It must be followed by a newline.

```
$A_1$ $A_2$ $\ldots$ $A_M$
```

(Phase $2$)

* First, an integer sequence $B=(B_1,B_2,\ldots,B_M)$ of length $M$ is given from the input.

```
$B_1$ $B_2$ $\ldots$ $B_M$
```

* Find the integer $N$ and print it. It must be followed by a newline.

```
$N$
```

If you print something illegal, the judge prints `-1`. In that case, your submission is already considered incorrect. Since the judge program terminates at this point, it is desirable that your program terminates too.

### Notes

* **After each output, add a newline and then flush Standard Output. Otherwise, you may get a TLE verdict.**
* **If an invalid output is printed during the interaction, or if the program terminates halfway, the verdict will be indeterminate.**
* After you print the answer (or you receive `-1`), immediately terminate the program normally. Otherwise, the verdict will be indeterminate.
* Note that an excessive newline is also considered an invalid input.

### Sample Interaction

The following is a sample interaction with $N = 2$.

| Input | Output | Description |
| --- | --- | --- |
|  |  | The judge has decided that $N=2$. $N$ is hidden: it is not given as an input. |
|  | `4` | You print $M$. |
|  | `2 3 4 4` | You print $A=(2,3,4,4)$. |
|
| `3 4 4 4` |  | $f^2(1)=3,f^2(2)=4,f^2(3)=4$, and $f^2(4)=4$, so the judge gives $B=(3,4,4,4)$ to your program. |
|  | `2` | Based on $B$, you have identified that $N=2$. Print $N$ and terminate the program normally. |
|

#include "testlib.h"
#include <bits/stdc++.h>
using namespace std;

static long long queries = 0;
static long long query_limit = 1;

static int N_hidden;

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 void invalid_move(const string& reason) {
    cout << "-1" << endl;
    finish(_pe, "Invalid output: " + reason);
}

static bool parse_long(const string& s, long long& out) {
    if (s.empty()) return false;
    try {
        size_t idx;
        out = stoll(s, &idx);
        return idx == s.size();
    } catch (...) {
        return false;
    }
}

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

    N_hidden = inf.readInt(1, 1000000000, "N");

    string token;
    if (!(cin >> token)) {
        finish(_pe, "Empty output from solution");
    }

    bool interaction_phase = true;
    long long M_long = 0;

    if (token == "!") {

        interaction_phase = false;
    } else {
        if (token == "?") {

            if (!(cin >> token)) finish(_pe, "Expected M after '?'");
        }

        if (!parse_long(token, M_long)) {
            invalid_move("M is not a valid integer");
        }
    }

    if (interaction_phase) {

        if (M_long < 1 || M_long > 110) {
            invalid_move(format("M (%lld) out of range [1, 110]", M_long));
        }
        int M = (int)M_long;

        vector<int> A(M + 1);
        for (int i = 1; i <= M; ++i) {
            string t;
            if (!(cin >> t)) invalid_move(format("Expected A[%d]", i));

            long long val;
            if (!parse_long(t, val)) invalid_move(format("A[%d] not an integer", i));
            if (val < 1 || val > M) invalid_move(format("A[%d]=%lld out of range [1, %d]", i, val, M));
            A[i] = (int)val;
        }

        queries++;
        log_metrics();

        static int up[32][120];

        for (int i = 1; i <= M; ++i) up[0][i] = A[i];

        for (int k = 1; k < 31; ++k) {
            for (int i = 1; i <= M; ++i) {
                up[k][i] = up[k-1][up[k-1][i]];
            }
        }

        vector<int> B(M + 1);
        for (int i = 1; i <= M; ++i) {
            int curr = i;
            int tempN = N_hidden;
            for (int k = 0; k < 31; ++k) {
                if ((tempN >> k) & 1) {
                    curr = up[k][curr];
                }
            }
            B[i] = curr;
        }

        for (int i = 1; i <= M; ++i) {
            cout << B[i] << (i == M ? "" : " ");
        }
        cout << endl;

        if (!(cin >> token)) finish(_pe, "No final answer provided");
        if (token == "!") {
            if (!(cin >> token)) finish(_pe, "No final answer after '!'");
        }
    } else {

        if (!(cin >> token)) finish(_pe, "No final answer after '!'");
    }

    long long ans;
    if (!parse_long(token, ans)) {
        finish(_pe, "Final answer is not a valid integer");
    }

    if (ans == N_hidden) {
        finish(_ok, format("Correct! N=%d", N_hidden));
    } else {
        finish(_wa, format("Wrong Answer. Expected N=%d, found %lld", N_hidden, ans));
    }

    return 0;
}

#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");

    long long seed_val = -1;
    if (argc > 1) {
        string s = argv[1];
        if (!s.empty() && all_of(s.begin(), s.end(), ::isdigit) && s.size() < 19) {
            try {
                seed_val = stoll(s);
            } catch (...) {
                seed_val = -1;
            }
        }
    }

    int n;

    if (seed_val == 1) {
        n = 1;
    } else if (seed_val == 2) {
        n = 1000000000;
    } else if (seed_val == 3) {
        n = 1000000000 - 1;
    } else if (seed_val == 4) {
        n = 2;
    } else if (seed_val == 5) {
        n = 3;
    } else {

        n = rnd.next(1, 1000000000);
    }

    cout << n << endl;

    return 0;
}


This is an interactive problem.

You are given an integer $n$ and an $n\times n$ grid of numbers $G$. The grid of numbers contains each number from $1$ to $n^2$ exactly once.

Let's define a snake of length $l$ as a deque $[(x_1,y_1), (x_2,y_2), \ldots, (x_l,y_l)]$, where $(x_1,y_1)$ is the head of the snake, and $(x_l,y_l)$ is the tail. At second $1$, $x_1=x_2=\ldots = x_l=1$ and $y_i=i$ for all $1 \leq i \leq l$. In other words, the snake is entirely located in the first row, with the head at $(1,1)$ and the rest of the snake to the right of the head.

Each subsequent second, the snake moves down or right in the grid. Formally, the tail $(x_l,y_l)$ is removed, and either $(x_1+1,y_1)$ or $(x_1,y_1+1)$ is added as the new head. The first move of the snake is always downwards. It can be shown that the snake will never intersect itself under these restrictions. The snake will move exactly $2n-2$ times, never moving outside the grid. At second $2n-1$, the head reaches $(n,n)$, and the movement stops. It can be shown that the snake moves exactly $n-1$ times to the right and exactly $n-1$ times downwards.

There are $n$ hidden snakes, with the $i$-th snake having length $i$ for $1 \leq i \leq n$, each moving independently according to the rule above. You do not know how the snakes move. Define $f(l,T)$ as the maximum number that the snake with length $l$ covers at second $T$.

 ![](https://espresso.codeforces.com/5c2b21f2a8715336ccaa0374a0167cebcd4db0a3.gif) An example of a snake with length $l=3$.

Now, you are also given an integer $m$. Your task is to find the $m$ smallest values of $f(l,T)$, using at most $120n+m$ queries asking for the value of $f(l,T)$ for some $1 \leq l \leq n$ and $1 \leq T \leq 2n-1$.

Input

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

The first line of each test case contains two integers $n$ and $m$ ($2 \leq n \leq 500, 1 \leq m \leq n(2n-1)$).

The following $n$ lines contain the grid $G$. The $i$-th of these lines contains $n$ integers $G_{i,1}, G_{i,2}, \ldots, G_{i,n}$ ($1 \leq G_{i,j} \leq n^2$).

It is guaranteed that $G$ contains each number from $1$ to $n^2$ exactly once.

It is guaranteed that the sum of $n$ over all test cases does not exceed $500$, and the sum of $m$ over all test cases does not exceed $5\cdot 10^4$.

After you read the $n+1$ lines of input, the interaction begins with your first query.

Interaction

To make a query, output a line in the following format (without the quotes):

* "? $l\;T$" ($1 \leq l \leq n$, $1 \leq T \leq 2n-1$).

After each query, read in a single integer – the value of $f(l,T)$. You may ask at most $120n+m$ queries of this type.

When you are ready to output the answer, print a line in the following format:

* "! $S_1\;S_2\;S_3\;\ldots\;S_m$" ($1 \leq S_1 \leq S_2 \leq \ldots \leq S_m$).

This should contain the $m$ smallest values of $f(l,T)$ in non-decreasing order. Note that this does not count towards the query limit.

After this, proceed to the next test case, or exit if this is the last test case.

If you make more than $120n+m$ queries during an interaction, your program must terminate immediately, and you will receive the Wrong Answer verdict. Otherwise, you can get an arbitrary verdict because your solution will continue to read from a closed stream.

After printing each line, do not forget to output the end of line and flush the output buffer. Otherwise, you will receive the Idleness Limit Exceeded verdict. To flush, use:

* fflush(stdout) or cout.flush() in C++;
* System.out.flush() in Java;
* stdout.flush() in Python;
* see the documentation for other languages.

Example

Input

```
1
3 15
4 2 5
1 9 3
7 6 8

4

1

9

6

8

4

4

7

7

8

5

4

9

9

9
```

Output

```
? 1 1

? 1 2

? 1 3

? 1 4

? 1 5

? 2 1

? 2 2

? 2 3

? 2 4

? 2 5

? 3 1

? 3 2

? 3 3

? 3 4

? 3 5

! 1 4 4 4 4 5 6 7 7 8 8 9 9 9 9
```

Note

Below shows the tiles that the three snakes cover as they move across the grid.

 ![](https://espresso.codeforces.com/ae265aa3396b153d344d15880077f08b316cb1a9.gif) The tiles covered by the first snake.  ![](https://espresso.codeforces.com/f7a74347bd76ae802da45d66882bd4c957738d19.gif) The tiles covered by the second snake.

The tiles covered by the third snake are shown in the statement above.

#include "testlib.h"
#include <bits/stdc++.h>
using namespace std;

static long long current_queries = 0;
static long long current_limit = 0;

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

    }
}

void finish_verdict(TResult v, string msg) {
    log_metrics();
    quitf(v, "%s", msg.c_str());
}

vector<int> get_sliding_max(const vector<int>& vals, int window_size) {
    vector<int> res;
    deque<int> dq;
    for (int i = 0; i < (int)vals.size(); ++i) {

        if (!dq.empty() && dq.front() <= i - window_size) dq.pop_front();

        while (!dq.empty() && vals[dq.back()] <= vals[i]) dq.pop_back();

        dq.push_back(i);

        if (i >= window_size - 1) {
            res.push_back(vals[dq.front()]);
        }
    }
    return res;
}

void solve() {

    int n = inf.readInt(2, 500, "n");

    long long m = inf.readLong(1LL, (long long)n * (2 * n - 1), "m");

    current_queries = 0;
    current_limit = 120LL * n + m;
    log_metrics();

    vector<vector<int>> G(n + 1, vector<int>(n + 1));
    for (int i = 1; i <= n; ++i) {
        for (int j = 1; j <= n; ++j) {
            G[i][j] = inf.readInt(1, n * n, "G_ij");
        }
    }

    vector<string> paths(n + 1);
    for (int i = 1; i <= n; ++i) {
        paths[i] = inf.readToken("[DR]+", "path");
    }

    cout << n << " " << m << endl;
    for (int i = 1; i <= n; ++i) {
        for (int j = 1; j <= n; ++j) {
            cout << G[i][j] << (j == n ? "" : " ");
        }
        cout << endl;
    }
    cout.flush();

    vector<vector<int>> answers(n + 1, vector<int>(2 * n));
    vector<int> all_values;
    all_values.reserve(n * (2 * n));

    for (int l = 1; l <= n; ++l) {

        vector<int> stream;
        stream.reserve(l + 2 * n);

        for (int c = l; c >= 1; --c) {
            stream.push_back(G[1][c]);
        }

        int r = 1, c = 1;
        for (char move : paths[l]) {
            if (move == 'D') r++;
            else c++;
            stream.push_back(G[r][c]);
        }

        vector<int> maxs = get_sliding_max(stream, l);

        for (int k = 0; k < (int)maxs.size(); ++k) {
            int T = k + 1;
            if (T < 2 * n) {
                answers[l][T] = maxs[k];
                all_values.push_back(maxs[k]);
            }
        }
    }

    sort(all_values.begin(), all_values.end());
    vector<int> expected_ans;
    for (int i = 0; i < m; ++i) {
        expected_ans.push_back(all_values[i]);
    }

    while (true) {
        string token;
        if (!(cin >> token)) {
            finish_verdict(_wa, "Unexpected end of input from solution");
        }

        if (token == "!") {

            vector<int> user_ans;
            for (int i = 0; i < m; ++i) {
                int val;
                if (!(cin >> val)) finish_verdict(_wa, "Cannot read answer value");
                user_ans.push_back(val);
            }

            for (size_t i = 1; i < user_ans.size(); ++i) {
                if (user_ans[i] < user_ans[i-1]) {
                    finish_verdict(_wa, "Answer sequence must be non-decreasing");
                }
            }

            if (user_ans != expected_ans) {
                finish_verdict(_wa, "Wrong answer values");
            }

            return;
        } else {

            int l_in, t_in;
            bool valid_syntax = false;

            if (token == "?") {
                if (cin >> l_in >> t_in) valid_syntax = true;
            } else {
                try {
                    l_in = stoi(token);
                    if (cin >> t_in) valid_syntax = true;
                } catch (...) {
                    finish_verdict(_wa, "Invalid query token: " + token);
                }
            }

            if (!valid_syntax) finish_verdict(_wa, "Cannot read query parameters");

            current_queries++;

            if (current_queries % 2000 == 0) log_metrics();

            if (current_queries > current_limit) {
                finish_verdict(_wa, "Query limit exceeded");
            }

            if (l_in < 1 || l_in > n || t_in < 1 || t_in > 2 * n - 1) {
                finish_verdict(_wa, "Query parameters out of range");
            }

            cout << answers[l_in][t_in] << endl;
        }
    }
}

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

    int t = inf.readInt(1, 100, "t");

    cout << t << endl;
    cout.flush();

    for (int i = 0; i < t; ++i) {
        solve();
    }

    finish_verdict(_ok, "All test cases passed");
    return 0;
}

#include "testlib.h"
#include <bits/stdc++.h>

using namespace std;

static long long total_queries = 0;
static long long total_query_limit = 0;
static const long long HARD_CAP = 500000;

void log_metrics() {

    try {
        tout << "queries=" << total_queries << endl;
        tout << "query_limit=" << total_query_limit << endl;
    } catch (...) {}
}

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

bool is_path_str(const string& s) {
    if (s.empty()) return false;
    for (char c : s) {
        if (c != 'D' && c != 'R') return false;
    }
    return true;
}

string generate_path_adaptive(int n) {
    if (n == 2) return "DR";
    string s = "D";

    string suffix = "";
    for (int i = 0; i < n - 2; ++i) suffix += 'D';
    for (int i = 0; i < n - 1; ++i) suffix += 'R';

    if (!suffix.empty()) {
        for (int i = (int)suffix.size() - 1; i > 0; --i) {
            int j = rnd.next(i + 1);
            swap(suffix[i], suffix[j]);
        }
    }
    return s + suffix;
}

vector<int> get_all_values(int n, int m, const vector<vector<int>>& grid, const vector<string>& paths) {
    vector<int> all_vals;
    all_vals.reserve(n * (2 * n));

    for (int l = 1; l <= n; ++l) {
        const string& P = paths[l];

        int start_k = 2 - l;
        int end_k = 2 * n - 1;
        int len_seq = end_k - start_k + 1;

        vector<int> V(len_seq);

        for (int k = min(1, end_k); k >= start_k; --k) {
            int idx = k - start_k;
            V[idx] = grid[0][1 - k];
        }

        if (end_k > 1) {
            int curr_r = 0, curr_c = 0;
            for (int k = 2; k <= end_k; ++k) {
                char move = P[k - 2];
                if (move == 'D') curr_r++;
                else curr_c++;

                if (k >= start_k) {
                    int idx = k - start_k;
                    V[idx] = grid[curr_r][curr_c];
                }
            }
        }

        deque<int> dq;

        for (int i = 0; i < l; ++i) {
            while (!dq.empty() && V[dq.back()] <= V[i]) dq.pop_back();
            dq.push_back(i);
        }
        all_vals.push_back(V[dq.front()]);

        for (int i = l; i < (int)V.size(); ++i) {
            if (!dq.empty() && dq.front() <= i - l) dq.pop_front();
            while (!dq.empty() && V[dq.back()] <= V[i]) dq.pop_back();
            dq.push_back(i);
            all_vals.push_back(V[dq.front()]);
        }
    }
    return all_vals;
}

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

    int t = inf.readInt();
    cout << t << endl;

    string saved_token = "";
    bool has_saved = false;

    for (int test_idx = 0; test_idx < t; ++test_idx) {
        int n;
        if (has_saved) {
            n = stoi(saved_token);
            saved_token = "";
            has_saved = false;
        } else {
            n = inf.readInt();
        }

        long long m = inf.readLong();

        total_query_limit += (120LL * n + m);
        log_metrics();

        cout << n << " " << m << endl;

        vector<vector<int>> grid(n, vector<int>(n));
        for (int i = 0; i < n; ++i) {
            for (int j = 0; j < n; ++j) {
                grid[i][j] = inf.readInt();
                cout << grid[i][j] << (j == n - 1 ? "" : " ");
            }
            cout << endl;
        }
        cout.flush();

        if (inf.seekEof()) {

        } else {
            string tok = inf.readToken();
            if (is_path_str(tok)) {

                for (int i = 1; i < n; ++i) {
                    inf.readToken();
                }
            } else {

                saved_token = tok;
                has_saved = true;
            }
        }

        vector<string> snake_paths(n + 1);
        for (int i = 1; i <= n; ++i) {
            snake_paths[i] = generate_path_adaptive(n);
        }

        vector<int> all_f = get_all_values(n, m, grid, snake_paths);
        sort(all_f.begin(), all_f.end());

        bool case_active = true;
        long long queries_this_case = 0;
        long long limit_this_case = 120LL * n + m;

        while (case_active) {
            char type;
            if (!(cin >> type)) {
                finish(_wa, "Unexpected EOF from solution");
            }

            if (type == '?') {
                int l, T;
                if (!(cin >> l >> T)) finish(_wa, "Invalid query format");

                total_queries++;
                queries_this_case++;

                if (total_queries % 1000 == 0) log_metrics();

                if (queries_this_case > limit_this_case) {

                    finish(_wa, "Query limit exceeded for this test case");
                }
                if (total_queries > HARD_CAP) {
                    finish(_pe, "Hard query limit exceeded (infinite loop?)");
                }

                if (l < 1 || l > n || T < 1 || T > 2 * n - 1) {
                    finish(_wa, "Query parameters out of range");
                }

                const string& P = snake_paths[l];
                int max_val = -1;

                int start_k = T - l + 1;
                int end_k = T;

                for (int k = start_k; k <= min(end_k, 1); ++k) {
                    int val = grid[0][1 - k];
                    if (val > max_val) max_val = val;
                }

                if (end_k > 1) {
                    int curr_r = 0, curr_c = 0;
                    for (int k = 2; k <= end_k; ++k) {
                        char move = P[k - 2];
                        if (move == 'D') curr_r++; else curr_c++;
                        if (k >= start_k) {
                            int val = grid[curr_r][curr_c];
                            if (val > max_val) max_val = val;
                        }
                    }
                }

                cout << max_val << endl;

            } else if (type == '!') {

                vector<int> user_ans(m);
                for (int i = 0; i < m; ++i) {
                    if (!(cin >> user_ans[i])) finish(_wa, "Failed to read output values");
                }

                if (all_f.size() < m) finish(_fail, "Internal error: not enough values");

                for (int i = 0; i < m; ++i) {
                    if (user_ans[i] != all_f[i]) {

                        string msg = "Wrong answer. Expected " + to_string(all_f[i]) + ", found " + to_string(user_ans[i]) + " at index " + to_string(i+1);
                        finish(_wa, msg);
                    }
                }

                case_active = false;
            } else {
                finish(_wa, "Unknown query type");
            }
        }
    }

    finish(_ok, "All test cases passed");
}

#include "testlib.h"
#include <bits/stdc++.h>

using namespace std;

string generate_path(int n, int type) {

    if (n == 2) return "DR";

    string suffix = "";
    int d_rem = n - 2;
    int r_rem = n - 1;

    if (type == 0) {
        for(int i=0; i<d_rem; ++i) suffix += 'D';
        for(int i=0; i<r_rem; ++i) suffix += 'R';
        shuffle(suffix.begin(), suffix.end());
    } else if (type == 1) {
        for(int i=0; i<d_rem; ++i) suffix += 'D';
        for(int i=0; i<r_rem; ++i) suffix += 'R';
    } else if (type == 2) {
        for(int i=0; i<r_rem; ++i) suffix += 'R';
        for(int i=0; i<d_rem; ++i) suffix += 'D';
    } else if (type == 3) {
        int cd = d_rem, cr = r_rem;
        while(cd > 0 || cr > 0) {
            if (cr > 0) { suffix += 'R'; cr--; }
            if (cd > 0) { suffix += 'D'; cd--; }
        }
    }
    return "D" + suffix;
}

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

    string mode = opt<string>("mode", "non");
    int p_t = opt<int>("t", -1);
    int p_n = opt<int>("n", -1);
    int p_m = opt<int>("m", -1);

    vector<pair<int, long long>> cases;
    long long rem_m = 50000;
    int rem_n_sum = 500;

    if (p_t != -1) {
        int t = p_t;
        while(t--) {
            int n = (p_n != -1) ? p_n : rnd.next(2, 50);
            long long max_m = (long long)n * (2 * n - 1);
            long long m = (p_m != -1) ? p_m : rnd.next(1LL, min((long long)rem_m, max_m));
            if (p_m == -1 && m > rem_m) m = 1;
            if (p_m == -1) rem_m -= m;
            cases.push_back({n, m});
        }
    } else if (p_n != -1) {
        int n = p_n;
        long long max_m = (long long)n * (2 * n - 1);
        long long m = (p_m != -1) ? p_m : rnd.next(1LL, max_m);
        cases.push_back({n, m});
    } else {
        int seed = atoi(argv[1]);
        if (seed == 1) {
            cases.push_back({2, 1});
        } else if (seed == 2) {
            cases.push_back({500, 100});
        } else if (seed == 3) {
            cases.push_back({500, 50000});
        } else {

            if (rnd.next(2) == 0) {
                int n = rnd.next(200, 500);
                long long m_lim = min((long long)rem_m, (long long)n * (2 * n - 1));
                cases.push_back({n, rnd.next(1LL, m_lim)});
            } else {
                while(rem_n_sum >= 2 && rem_m > 0) {
                    int n_high = min(rem_n_sum, 60);
                    if (rem_n_sum >= 100 && rnd.next(4) == 0) n_high = min(rem_n_sum, 200);

                    int n = rnd.next(2, n_high);

                    long long max_m = (long long)n * (2 * n - 1);
                    long long m_lim = min((long long)rem_m, max_m);
                    if (m_lim < 1) m_lim = 1;

                    long long m;
                    if (rnd.next(2) == 0) m = rnd.next(1LL, min(m_lim, 200LL));
                    else m = rnd.next(1LL, m_lim);

                    rem_n_sum -= n;
                    rem_m -= m;

                    cases.push_back({n, m});
                    if (rnd.next(15) == 0) break;
                }
            }
        }
    }

    println(cases.size());
    for(auto& tc : cases) {
        int n = tc.first;
        long long m = tc.second;
        println(n, m);

        vector<int> g(n * n);
        iota(g.begin(), g.end(), 1);
        int g_type = rnd.next(100);
        if (g_type < 70) shuffle(g.begin(), g.end());
        else if (g_type < 80) {}
        else if (g_type < 90) reverse(g.begin(), g.end());
        else {
             for(int k=0; k<n*n/5; ++k) swap(g[rnd.next(n*n)], g[rnd.next(n*n)]);
        }

        for(int i=0; i<n; ++i) {
            for(int j=0; j<n; ++j) {
                cout << g[i*n + j] << (j == n - 1 ? "" : " ");
            }
            cout << "\n";
        }

        if (mode == "non") {
            int p_strat = rnd.next(5);
            string fixed_p = generate_path(n, 0);
            for(int i=1; i<=n; ++i) {
                if (p_strat == 0) println(generate_path(n, 0));
                else if (p_strat == 1) println(fixed_p);
                else if (p_strat == 2) println(generate_path(n, (i%2)+1));
                else if (p_strat == 3) println(generate_path(n, 1));
                else println(generate_path(n, 2));
            }
        }
    }
    return 0;
}


Filya just learned new geometry object — rectangle. He is given a field consisting of *n* × *n* unit cells. Rows are numbered from bottom to top with integer from 1 to *n*. Columns are numbered from left to right with integers from 1 to *n*. Cell, located at the intersection of the row *r* and column *c* is denoted as (*r*, *c*). Filya has painted two rectangles, such that their sides are parallel to coordinate axes and each cell lies fully inside or fully outside each of them. Moreover, no cell lies in both rectangles.

Later, hedgehog Filya became interested in the location of his rectangles but was unable to find the sheet of paper they were painted on. They were taken by Sonya and now she wants to play a little game with Filya. He tells her a query rectangle and she replies with the number of initial rectangles that lie fully inside the given query rectangle. The query rectangle should match the same conditions as initial rectangles. Rectangle lies fully inside the query if each o its cells lies inside the query.

Filya knows Sonya really well, so is sure that if he asks more than 200 questions she will stop to reply.

Input

The first line of the input contains an integer *n* (2 ≤ *n* ≤ 216) — size of the field.

For each query an integer between 0 and 2 is returned — the number of initial rectangles that lie fully inside the query rectangle.

Output

To make a query you have to print "? *x*1 *y*1 *x*2 *y*2" (without quotes) (1 ≤ *x*1 ≤ *x*2 ≤ *n*, 1 ≤ *y*1 ≤ *y*2 ≤ *n*), where (*x*1, *y*1) stands for the position of the bottom left cell of the query and (*x*2, *y*2) stands for the up right cell of the query. You are allowed to ask no more than 200 queries. After each query you should perform "flush" operation and read the answer.

In case you suppose you've already determined the location of two rectangles (or run out of queries) you should print "! *x*11 *y*11 *x*12 *y*12 *x*21 *y*21 *x*22 *y*22" (without quotes), where first four integers describe the bottom left and up right cells of the first rectangle, and following four describe the corresponding cells of the second rectangle. You can print the rectangles in an arbitrary order. After you have printed the answer, print the end of the line and perform "flush". Your program should terminate immediately after it print the answer.

Interaction

To flush you can use (just after printing an integer and end-of-line):

* fflush(stdout) in C++;
* System.out.flush() in Java;
* stdout.flush() in Python;
* flush(output) in Pascal;
* See the documentation for other languages.

You will get the Wrong Answer verdict if you ask more than 200 queries, or if you print an incorrect coordinates.

You will get the Idleness Limit Exceeded verdict if you don't print anything (but you should) or if you forget about flushing the output (more info below).

Example

Input

```
5
2
1
0
1
1
1
0
1
```

Output

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

#include "testlib.h"
#include <bits/stdc++.h>
using namespace std;

static long long queries = 0;
static long long query_limit = 200;

struct Rect {
    int x1, y1, x2, y2;

    bool operator==(const Rect& other) const {
        return x1 == other.x1 && y1 == other.y1 && x2 == other.x2 && y2 == other.y2;
    }
};

Rect r1, r2;
int n;

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());
}

bool is_inside(const Rect& r, const Rect& q) {
    return (q.x1 <= r.x1 && r.x2 <= q.x2 &&
            q.y1 <= r.y1 && r.y2 <= q.y2);
}

int main(int argc, char** argv) {

    registerInteraction(argc, argv);

    atexit(log_metrics);

    n = inf.readInt(2, 65536, "n");

    r1.x1 = inf.readInt(1, n, "r1.x1");
    r1.y1 = inf.readInt(1, n, "r1.y1");
    r1.x2 = inf.readInt(1, n, "r1.x2");
    r1.y2 = inf.readInt(1, n, "r1.y2");

    r2.x1 = inf.readInt(1, n, "r2.x1");
    r2.y1 = inf.readInt(1, n, "r2.y1");
    r2.x2 = inf.readInt(1, n, "r2.x2");
    r2.y2 = inf.readInt(1, n, "r2.y2");

    log_metrics();

    cout << n << endl;

    const int HARD_CAP = 2000;

    while (true) {

        string token;
        if (!(cin >> token)) {

            break;
        }

        if (token == "!") {

            vector<int> a(8);
            bool read_ok = true;
            for (int i = 0; i < 8; ++i) {
                if (!(cin >> a[i])) {
                    read_ok = false;
                    break;
                }
            }
            if (!read_ok) {
                finish(_pe, "Unexpected end of input reading answer coordinates");
            }

            Rect ans1 = {a[0], a[1], a[2], a[3]};
            Rect ans2 = {a[4], a[5], a[6], a[7]};

            bool correct = false;
            if ((ans1 == r1 && ans2 == r2) || (ans1 == r2 && ans2 == r1)) {
                correct = true;
            }

            if (correct) {
                finish(_ok, "Correct rectangles found");
            } else {
                finish(_wa, "Incorrect rectangles reported");
            }

        } else {

            int qx1, qy1, qx2, qy2;

            if (token == "?") {
                if (!(cin >> qx1 >> qy1 >> qx2 >> qy2)) {
                    finish(_pe, "Unexpected end of input reading query");
                }
            } else {

                try {
                    qx1 = stoi(token);
                } catch (...) {
                    finish(_pe, "Expected integer or '?' as first token");
                }
                if (!(cin >> qy1 >> qx2 >> qy2)) {
                    finish(_pe, "Unexpected end of input reading query");
                }
            }

            queries++;

            if (queries % 10 == 0) {
                log_metrics();
            }

            if (queries > HARD_CAP) {
                finish(_pe, "Hard query limit exceeded (infinite loop protection)");
            }

            if (qx1 < 1 || qx1 > qx2 || qx2 > n ||
                qy1 < 1 || qy1 > qy2 || qy2 > n) {
                finish(_wa, format("Query coordinates invalid: %d %d %d %d (n=%d)", qx1, qy1, qx2, qy2, n));
            }

            int cnt = 0;
            Rect q = {qx1, qy1, qx2, qy2};
            if (is_inside(r1, q)) cnt++;
            if (is_inside(r2, q)) cnt++;

            cout << cnt << endl;
        }
    }

    finish(_pe, "Interaction ended without final answer (!)");
    return 0;
}

#include "testlib.h"
#include <bits/stdc++.h>

using namespace std;

static long long queries = 0;
static const long long query_limit = 200;
static int n;

struct Rect {
    int x1, y1, x2, y2;

    bool operator==(const Rect& other) const {
        return x1 == other.x1 && y1 == other.y1 && x2 == other.x2 && y2 == other.y2;
    }

    bool inside(const Rect& query) const {
        return x1 >= query.x1 && x2 <= query.x2 &&
               y1 >= query.y1 && y2 <= query.y2;
    }

    bool valid(int limit) const {
        return x1 >= 1 && x1 <= x2 && x2 <= limit &&
               y1 >= 1 && y1 <= y2 && y2 <= limit;
    }
};

static Rect r1_hidden, r2_hidden;

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());
}

void generate_hidden() {

    rnd.setSeed(n * 239017LL + 7777);

    int axis = rnd.next(2);
    int split = rnd.next(1, n - 1);

    auto get_interval = [&](int min_v, int max_v) {
        int a = rnd.next(min_v, max_v);
        int b = rnd.next(min_v, max_v);
        if (a > b) swap(a, b);
        return pair<int,int>{a, b};
    };

    if (axis == 0) {

        pair<int,int> x1r = get_interval(1, split);
        pair<int,int> x2r = get_interval(split + 1, n);
        pair<int,int> y1r = get_interval(1, n);
        pair<int,int> y2r = get_interval(1, n);

        r1_hidden = {x1r.first, y1r.first, x1r.second, y1r.second};
        r2_hidden = {x2r.first, y2r.first, x2r.second, y2r.second};
    } else {

        pair<int,int> y1r = get_interval(1, split);
        pair<int,int> y2r = get_interval(split + 1, n);
        pair<int,int> x1r = get_interval(1, n);
        pair<int,int> x2r = get_interval(1, n);

        r1_hidden = {x1r.first, y1r.first, x1r.second, y1r.second};
        r2_hidden = {x2r.first, y2r.first, x2r.second, y2r.second};
    }
}

int main(int argc, char** argv) {

    registerInteraction(argc, argv);
    atexit(log_metrics);

    n = inf.readInt();

    if (!inf.seekEof()) {
        r1_hidden.x1 = inf.readInt();
        r1_hidden.y1 = inf.readInt();
        r1_hidden.x2 = inf.readInt();
        r1_hidden.y2 = inf.readInt();

        r2_hidden.x1 = inf.readInt();
        r2_hidden.y1 = inf.readInt();
        r2_hidden.x2 = inf.readInt();
        r2_hidden.y2 = inf.readInt();
    } else {

        generate_hidden();
    }

    log_metrics();

    cout << n << endl;

    string cmd;
    while (true) {
        if (cin.eof()) break;
        cin >> cmd;
        if (cin.fail()) break;

        if (cmd == "?") {
            queries++;

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

            if (queries % 10 == 0) log_metrics();

            Rect q;
            cin >> q.x1 >> q.y1 >> q.x2 >> q.y2;
            if (cin.fail()) finish(_pe, "Invalid query format");

            if (!q.valid(n)) {
                finish(_pe, format("Query out of bounds: %d %d %d %d", q.x1, q.y1, q.x2, q.y2));
            }

            int cnt = 0;
            if (r1_hidden.inside(q)) cnt++;
            if (r2_hidden.inside(q)) cnt++;

            cout << cnt << endl;
        } else if (cmd == "!") {
            Rect u1, u2;
            cin >> u1.x1 >> u1.y1 >> u1.x2 >> u1.y2;
            cin >> u2.x1 >> u2.y1 >> u2.x2 >> u2.y2;
            if (cin.fail()) finish(_pe, "Invalid answer format");

            if (!u1.valid(n) || !u2.valid(n)) {
                finish(_wa, "Answer coordinates out of bounds");
            }

            bool match = false;
            if ((u1 == r1_hidden && u2 == r2_hidden) || (u1 == r2_hidden && u2 == r1_hidden)) {
                match = true;
            }

            if (match) {
                finish(_ok, format("Correct! Used %d queries.", queries));
            } else {
                finish(_wa, format("Incorrect. Expected: (%d %d %d %d), (%d %d %d %d)",
                    r1_hidden.x1, r1_hidden.y1, r1_hidden.x2, r1_hidden.y2,
                    r2_hidden.x1, r2_hidden.y1, r2_hidden.x2, r2_hidden.y2));
            }
        } else {
            finish(_pe, "Unknown command: " + cmd);
        }
    }

    finish(_pe, "Unexpected EOF without answer");
    return 0;
}

#include "testlib.h"
#include <bits/stdc++.h>
using namespace std;

struct Rect {
    int x1, y1, x2, y2;
};

pair<int, int> getInterval(int minVal, int maxVal) {
    if (minVal > maxVal) return {minVal, minVal};
    int a = rnd.next(minVal, maxVal);
    int b = rnd.next(minVal, maxVal);
    if (a > b) swap(a, b);
    return {a, b};
}

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

    registerGen(argc, argv, 1);

    string mode = opt<string>("mode", "non");
    int n_arg = opt<int>("n", 0);

    int n;
    if (n_arg > 0) {
        n = n_arg;
    } else {

        long long seedVal = atoll(argv[1]);

        if (seedVal == 1) n = 2;
        else if (seedVal == 2) n = 65536;
        else if (seedVal == 3) n = 10;
        else if (seedVal == 4) n = 100;
        else if (seedVal == 5) n = 3;
        else {

            int p = rnd.next(100);
            if (p < 5) n = rnd.next(2, 50);
            else if (p < 15) n = rnd.next(51, 1000);
            else n = rnd.next(1001, 65536);
        }
    }

    if (mode == "adp") {
        cout << n << endl;
        return 0;
    }

    int axis = rnd.next(2);

    int split = rnd.next(1, n - 1);

    bool touch = (rnd.next(3) == 0);
    bool align = (rnd.next(5) == 0);

    pair<int, int> rA_split, rB_split;
    pair<int, int> rA_other, rB_other;

    rA_split = getInterval(1, split);
    rB_split = getInterval(split + 1, n);

    if (touch) {

        if (rnd.next(2)) rA_split.second = split;
        if (rnd.next(2)) rB_split.first = split + 1;
    }

    rA_other = getInterval(1, n);
    if (align) {
        rB_other = rA_other;
    } else {
        rB_other = getInterval(1, n);
    }

    if (rnd.next(10) == 0) {
        rA_other = {1, n};
        if (rnd.next(2)) rB_other = {1, n};
    }

    Rect r1, r2;
    if (axis == 0) {

        r1 = {rA_split.first, rA_other.first, rA_split.second, rA_other.second};
        r2 = {rB_split.first, rB_other.first, rB_split.second, rB_other.second};
    } else {

        r1 = {rA_other.first, rA_split.first, rA_other.second, rA_split.second};
        r2 = {rB_other.first, rB_split.first, rB_other.second, rB_split.second};
    }

    if (rnd.next(2)) swap(r1, r2);

    cout << n << endl;
    cout << r1.x1 << " " << r1.y1 << " " << r1.x2 << " " << r1.y2 << endl;
    cout << r2.x1 << " " << r2.y1 << " " << r2.x2 << " " << r2.y2 << endl;

    return 0;
}


D. Vladik and Favorite Game

This is an interactive problem.

Vladik has favorite game, in which he plays all his free time.

Game field could be represented as *n* × *m* matrix which consists of cells of three types:

* «.» — normal cell, player can visit it.
* «F» — finish cell, player has to finish his way there to win. There is exactly one cell of this type.
* «\*» — dangerous cell, if player comes to this cell, he loses.

Initially player is located in the left top cell with coordinates (1, 1).

Player has access to 4 buttons "U", "D", "L", "R", each of them move player up, down, left and right directions respectively.

But it’s not that easy! Sometimes friends play game and change functions of buttons. Function of buttons "L" and "R" could have been swapped, also functions of buttons "U" and "D" could have been swapped. Note that functions of buttons can be changed only at the beginning of the game.

Help Vladik win the game!

Input

First line contains two space-separated integers *n* and *m* (1 ≤ *n*, *m* ≤ 100) — number of rows and columns respectively.

Each of next *n* lines contains *m* characters describing corresponding row of field. Set of characters in field is described above.

Guaranteed that cell with coordinates (1, 1) is normal and there is at least one way from initial cell to finish cell without dangerous cells.

Interaction

You can press buttons no more than 2·*n*·*m* times.

To press a button you should print "U", "D", "L", "R" in new line. It’s necessary to print newline character and flush output. After flushing buffer you should read answer from input data. Answer is the pair of space-separated integers *x*, *y* — new position of player. In case, if there is no cell in direction of moving, position will not change. If after any move player lost, in other words player move to dangerous cell, then *x* and *y* will be equal to  - 1.

If after any move player is in finish or dangerous cell, then you should terminate your program.

To finish output buffer (i. e. for operation flush) right after printing direction and newline you should do next:

* fflush(stdout) in C++
* System.out.flush() in Java
* stdout.flush() in Python
* flush(output) in Pascal
* read documentation for other languages.

Example

Input

```
4 3
...
**.
F*.
...
1 1
1 2
1 3
1 3
2 3
3 3
4 3
4 2
4 1
3 1
```

Output

```
R
L
L
D
U
U
U
R
R
D
```

#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() {
    if (query_limit == 0) return;
    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(1, 100, "m");

    vector<string> grid(n);
    for (int i = 0; i < n; i++) {
        grid[i] = inf.readToken("([.F*]+)", "grid_row");

        if ((int)grid[i].size() != m) {
            quitf(_fail, "Grid row %d has length %d, expected %d", i + 1, (int)grid[i].size(), m);
        }
    }

    int swap_lr = inf.readInt(0, 1, "swap_lr");
    int swap_ud = inf.readInt(0, 1, "swap_ud");

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

    log_metrics();

    cout << n << " " << m << endl;
    for (int i = 0; i < n; i++) {
        cout << grid[i] << endl;
    }
    cout.flush();

    int r = 0;
    int c = 0;

    while (true) {

        if (queries > hard_cap) {
            finish(_pe, "Hard query limit exceeded (infinite loop?)");
        }

        string token;

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

        if (token == "?") {
            if (!(cin >> token)) {
                finish(_wa, "Unexpected EOF after '?'");
            }
        } else if (token == "!") {

        }

        if (token.length() != 1) {
            finish(_pe, "Invalid move format: expected single character U, D, L, or R");
        }

        char move = token[0];
        int dr = 0;
        int dc = 0;

        if (move == 'L') {
            dc = swap_lr ? 1 : -1;
        } else if (move == 'R') {
            dc = swap_lr ? -1 : 1;
        } else if (move == 'U') {
            dr = swap_ud ? 1 : -1;
        } else if (move == 'D') {
            dr = swap_ud ? -1 : 1;
        } else {
            finish(_pe, string("Invalid move character: ") + move);
        }

        queries++;

        if (queries % 20 == 0) log_metrics();

        int nr = r + dr;
        int nc = c + dc;

        if (nr >= 0 && nr < n && nc >= 0 && nc < m) {
            char cell = grid[nr][nc];
            if (cell == '*') {

                cout << "-1 -1" << endl;
                finish(_wa, "Moved to dangerous cell (*)");
            }

            r = nr;
            c = nc;
        }

        cout << (r + 1) << " " << (c + 1) << endl;

        if (grid[r][c] == 'F') {
            finish(_ok, "Reached finish cell (F)");
        }
    }

    return 0;
}

#include "testlib.h"
#include <bits/stdc++.h>
using namespace std;

static int N, M;
static vector<string> grid;

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

struct Config {
    int s_lr;
    int s_ud;
};
static vector<Config> valid_configs;

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 is_valid(int r, int c) {
    return r >= 0 && r < N && c >= 0 && c < M;
}

static pair<int,int> get_outcome(int r, int c, string move, int s_lr, int s_ud) {
    int dr = 0, dc = 0;

    if (move == "U") dr = (s_ud ? 1 : -1);
    else if (move == "D") dr = (s_ud ? -1 : 1);
    else if (move == "L") dc = (s_lr ? 1 : -1);
    else if (move == "R") dc = (s_lr ? -1 : 1);

    int nr = r + dr;
    int nc = c + dc;

    if (!is_valid(nr, nc)) return {r, c};

    if (grid[nr][nc] == '*') return {-1, -1};

    return {nr, nc};
}

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

    N = inf.readInt();
    M = inf.readInt();
    query_limit = 2LL * N * M;

    grid.resize(N);
    for(int i = 0; i < N; ++i) {
        grid[i] = inf.readToken();
    }

    cout << N << " " << M << endl;
    for(int i = 0; i < N; ++i) {
        cout << grid[i] << endl;
    }
    cout.flush();

    valid_configs = {{0,0}, {0,1}, {1,0}, {1,1}};
    int cur_r = 0, cur_c = 0;

    log_metrics();

    while (true) {

        if (queries % 20 == 0) log_metrics();

        string move = ouf.readToken();
        queries++;

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

        if (move != "L" && move != "R" && move != "U" && move != "D") {
            finish(_pe, "Invalid move format: " + move);
        }

        map<pair<int,int>, vector<Config>> outcomes;
        for (const auto& cfg : valid_configs) {
            outcomes[get_outcome(cur_r, cur_c, move, cfg.s_lr, cfg.s_ud)].push_back(cfg);
        }

        pair<int,int> best_pos = {-2, -2};
        int best_score = -1;
        size_t best_count = 0;

        for (auto& kv : outcomes) {
            pair<int,int> p = kv.first;
            int score = 0;
            if (p.first == -1) score = 2;
            else if (grid[p.first][p.second] == 'F') score = 0;
            else score = 1;

            bool better = false;
            if (score > best_score) better = true;
            else if (score == best_score) {
                if (kv.second.size() > best_count) better = true;
                else if (kv.second.size() == best_count) {
                    if (p < best_pos) better = true;
                }
            }

            if (better) {
                best_score = score;
                best_count = kv.second.size();
                best_pos = p;
            }
        }

        valid_configs = outcomes[best_pos];

        if (best_pos.first == -1) {
            cout << "-1 -1" << endl;
            finish(_wa, "Moved to dangerous cell");
        } else {
            cout << (best_pos.first + 1) << " " << (best_pos.second + 1) << endl;
        }

        cur_r = best_pos.first;
        cur_c = best_pos.second;

        if (best_score == 0) {
            finish(_ok, "Reached finish");
        }
    }

    return 0;
}

#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");
    long long seed_val = atoll(argv[1]);

    int n, m;
    vector<string> grid;
    int swap_lr = rnd.next(0, 1);
    int swap_ud = rnd.next(0, 1);

    if (seed_val == 1) {
        n = 1; m = 2;
        grid = {".F"};
    } else if (seed_val == 2) {
        n = 2; m = 1;
        grid = {".", "F"};
    } else if (seed_val == 3) {
        n = 2; m = 2;
        grid = {"..", ".F"};
    } else {

        int type = rnd.next(1, 2);

        if (mode == "adp") type = 1;

        if (seed_val < 10) {
            n = rnd.next(3, 10);
            m = rnd.next(3, 10);
        } else {
            n = rnd.next(2, 100);
            m = rnd.next(2, 100);
        }

        grid.assign(n, string(m, '*'));
        grid[0][0] = '.';

        if (type == 1) {
            vector<pair<int,int>> frontier;
            frontier.push_back({0,0});

            while(!frontier.empty()){

                int idx = rnd.next((int)frontier.size());
                if (mode == "adp" && rnd.next(2)) idx = frontier.size() - 1;

                auto [r, c] = frontier[idx];
                bool extended = false;

                vector<int> dirs = {0, 1, 2, 3};
                shuffle(dirs.begin(), dirs.end());
                int dr[] = {-1, 1, 0, 0};
                int dc[] = {0, 0, -1, 1};

                for(int d : dirs){
                    int nr = r + dr[d] * 2;
                    int nc = c + dc[d] * 2;
                    if(nr >= 0 && nr < n && nc >= 0 && nc < m){
                        if(grid[nr][nc] == '*'){
                            grid[r + dr[d]][c + dc[d]] = '.';
                            grid[nr][nc] = '.';
                            frontier.push_back({nr, nc});
                            extended = true;

                            if (rnd.next(3) == 0) break;
                        }
                    }
                }
                if (!extended) {
                    frontier.erase(frontier.begin() + idx);
                }
            }

            int noise_ops = rnd.next(n * m / 20, n * m / 5);
            for(int k=0; k<noise_ops; ++k) {
                grid[rnd.next(n)][rnd.next(m)] = '.';
            }
        } else {
            for(int i=0; i<n; ++i) fill(grid[i].begin(), grid[i].end(), '.');
            int obstacles = rnd.next(n * m / 5, n * m / 2);
            for(int k=0; k<obstacles; ++k) {
                int r = rnd.next(n);
                int c = rnd.next(m);
                if (r == 0 && c == 0) continue;
                grid[r][c] = '*';
            }
        }

        vector<vector<bool>> vis(n, vector<bool>(m, false));
        queue<pair<int,int>> q;
        q.push({0,0});
        vis[0][0] = true;
        vector<pair<int,int>> reachable;

        int dr[] = {-1, 1, 0, 0};
        int dc[] = {0, 0, -1, 1};

        while(!q.empty()){
            auto [r,c] = q.front(); q.pop();
            reachable.push_back({r,c});

            for(int i=0; i<4; ++i){
                int nr = r + dr[i];
                int nc = c + dc[i];
                if(nr>=0 && nr<n && nc>=0 && nc<m && !vis[nr][nc] && grid[nr][nc] != '*'){
                    vis[nr][nc] = true;
                    q.push({nr, nc});
                }
            }
        }

        vector<pair<int,int>> candidates;
        for(auto p : reachable) {
            if (p.first != 0 || p.second != 0) candidates.push_back(p);
        }

        if (candidates.empty()) {
            if (n > 1) { grid[1][0] = '.'; candidates.push_back({1,0}); }
            else if (m > 1) { grid[0][1] = '.'; candidates.push_back({0,1}); }
        }

        int f_idx = rnd.next((int)candidates.size());

        if (mode == "adp" && candidates.size() > 5) {
            f_idx = rnd.next((int)candidates.size() / 2, (int)candidates.size() - 1);
        }
        grid[candidates[f_idx].first][candidates[f_idx].second] = 'F';
    }

    cout << n << " " << m << endl;
    for(int i=0; i<n; ++i) cout << grid[i] << endl;
    cout << swap_lr << " " << swap_ud << endl;

    return 0;
}