Problem: cf2135_b
Difficulty: medium
Categories: math
Time limit: 2000 ms, memory limit: 256 MB

This is an interactive problem.

The RiOI team is hosting a robot championship!

This time, your robot is teleported into an infinite 2D plane with the Cartesian coordinate system on it. There are $n$ anchor points on the plane, and the coordinates of the $i$-th anchor point are $(x_i, y_i)$ ($-10^9\le x_i,y_i\le 10^9$). These are given to your robot by the jury as soon as it is teleported into the plane. However, your robot doesn't know its initial coordinates at first.

To test the IQ of your robot, the RiOI team has come up with an interesting game. Your robot needs to find out the initial coordinates $(X, Y)$ ($-10^9\le X, Y\le 10^9$) by making the following moves.

In one move, assuming that its current coordinates are $(a,b)$, your robot can choose a non-negative integer $k$ ($0\le k\le 10^9$) and do one of the following four types of operations:

* Move up by $k$ units, i.e., your robot will move to $(a,b+k)$;
* Move down by $k$ units, i.e., your robot will move to $(a,b-k)$;
* Move left by $k$ units, i.e., your robot will move to $(a-k,b)$;
* Move right by $k$ units, i.e., your robot will move to $(a+k,b)$.

After each move, the jury will give the minimum Manhattan Distance between the current coordinates of your robot and any anchor point. More formally, assuming that the coordinates of your robot are $(c,d)$ after the move, the jury will output

 \min\_{1\le i\le n}\left ( \left|x\_i-c\right|+\left|y\_i-d\right|\right ). 

To win the prize, you must prove that your robot has a high IQ. So you have to write a program for your robot to find its initial coordinates $(X, Y)$ in no more than $10$ moves.

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 a single integer $n$ ($1\le n\le 100$) — the number of anchor points.

Then $n$ lines follow, the $i$-th line contains two integers $x_i$ and $y_i$ ($-10^9\le x_i,y_i\le 10^9$) — the coordinates of the $i$-th anchor point.

It is guaranteed that the coordinates of the anchor points are pairwise distinct.

Interaction

For each test case, first read the integer $n$ and the coordinates of anchor points. Then you may make up to $10$ moves.

To make a move, you should print a new line in one of the following formats:

* $\texttt{? U }k$ — move up by $k$ units;
* $\texttt{? D }k$ — move down by $k$ units;
* $\texttt{? L }k$ — move left by $k$ units;
* $\texttt{? R }k$ — move right by $k$ units.

You need to guarantee that $0\le k\le 10^{9}$.

At the end of each move, the jury will print an integer $s$ — the minimum Manhattan Distance between the current coordinates of your robot and any anchor point.

To report that you have found the initial coordinates of your robot, print a new line in the following format:

* $\texttt{! }X\texttt{ }Y$ — the initial coordinates of your robot are $(X, Y)$.

Printing the answer does not count as one of the $10$ moves.

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

Assume that the initial coordinates of your robot are $(X, Y)$. It is guaranteed that $-10^{9}\le X, Y\le 10^{9}$.

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

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

The interactor in this problem is not adaptive. In other words, the initial coordinates of the robot will not change during the interaction steps.

Example

Input

```
2
1
0 0

100

1

4
1 1
2 2
3 3
-1 -1

1

2

0
```

Output

```
? D 99

? L 101

! 100 99

? L 0

? U 1

? R 2

! -1 0
```

Note

Here is the progress of the example:

|  |  |  |
| --- | --- | --- |
| Solution | Jury | Explanation |
|  | 2 | There are $2$ test cases in this test. |
|  | 1 | There is $1$ anchor point in this test case. |
|  | 0 0 | The coordinates of the only anchor point are $(0,0)$. |
|  |  | The jury chooses $(100,99)$ as the robot's initial coordinates. |
| ? D 99 | 100 | The robot moves down by $99$ units, and its current coordinates are $(100, 0)$. Then, the jury prints $|100-0|+|0-0|=100$ as the response to this move. |
| ? L 101 | 1 | The robot moves left by $101$ units, and its current coordinates are $(-1, 0)$. Then, the jury prints $|(-1)-0|+|0-0|=1$ as the response to this move. |
| ! 100 99 |  | The robot has somehow determined its initial coordinates and reports the answer. Since the output is correct, the jury continues to the next test case. |
|  | 4 | There are $4$ anchor points in this test case. |
|  | 1 1 | The coordinates of the first anchor point are $(1,1)$. |
|  | 2 2 | The coordinates of the second anchor point are $(2,2)$. |
|  | 3 3 | The coordinates of the third anchor point are $(3,3)$. |
|  | -1 -1 | The coordinates of the fourth anchor point are $(-1,-1)$. |
|  |  | The jury chooses $(-1,0)$ as the robot's initial coordinates. |
| ? L 0 | 1 | The robot moves left by $0$ units, i.e., stays at the same position. Then, the jury prints $|(-1)-(-1)|+|0-(-1)|=1$ as the response to this move. It can be shown that this is the minimum Manhattan Distance between the robot and any anchor point. |
| ? U 1 | 2 | The robot moves up by $1$ unit, and its current coordinates are $(-1, 1)$. Then, the jury prints $|(-1)-(-1)|+|1-(-1)|=2$ as the response to this move. |
| ? R 2 | 0 | The robot moves right by $2$ units, and its current coordinates are $(1, 1)$. Then, the jury prints $|1-1|+|1-1|=0$ as the response to this move. |
| ! -1 0 |  | The robot has somehow determined its initial coordinates and reports the answer. Since the output is correct and there are no more test cases, the jury and the solution exit. |

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

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

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

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

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

static bool readLongLongSafe(long long& v) {
    if (!(cin >> v)) return false;
    return true;
}

static long long manhattanMin(const vector<pair<long long, long long>>& pts, long long x, long long y) {
    long long best = (1LL << 62);
    for (const auto& p : pts) {
        long long d = llabs(p.first - x) + llabs(p.second - y);
        if (d < best) best = d;
    }
    return best;
}

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

    int t = 0;
    try {
        t = inf.readInt(1, 100, "t");
    } catch (...) {
        query_limit = 0;
        log_metrics();
        finish(_pe, "Failed to read t from inf.");
    }

    query_limit = 10LL * t;
    log_metrics(); 

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

    cout << t << "\n" << flush;

    for (int tc = 1; tc <= t; tc++) {
        int n = 0;
        try {
            n = inf.readInt(1, 100, "n");
        } catch (...) {
            finish(_pe, "Failed to read n from inf.");
        }

        vector<pair<long long, long long>> pts;
        pts.reserve(n);
        for (int i = 0; i < n; i++) {
            long long xi = 0, yi = 0;
            try {
                xi = inf.readLong(-1000000000LL, 1000000000LL, "x[i]");
                yi = inf.readLong(-1000000000LL, 1000000000LL, "y[i]");
            } catch (...) {
                finish(_pe, "Failed to read anchor point from inf.");
            }
            pts.push_back({xi, yi});
        }

        long long X0 = 0, Y0 = 0;
        try {
            X0 = inf.readLong(-1000000000LL, 1000000000LL, "X");
            Y0 = inf.readLong(-1000000000LL, 1000000000LL, "Y");
        } catch (...) {
            finish(_pe, "Failed to read hidden start (X,Y) from inf.");
        }

        long long curX = X0, curY = Y0;

        cout << n << "\n";
        for (auto& p : pts) cout << p.first << " " << p.second << "\n";
        cout << flush;

        while (true) {
            if (queries > hard_cap) {
                finish(_pe, "Hard cap exceeded (too many queries).");
            }

            string op;
            if (!readTokenSafe(op)) {
                finish(_pe, "Unexpected EOF from contestant.");
            }

            if (op == "?") {
                string dirTok;
                if (!readTokenSafe(dirTok)) finish(_pe, "Missing direction after '?'.");
                if (dirTok.empty()) finish(_pe, "Empty direction token after '?'.");
                char dir = dirTok[0];

                long long k;
                if (!readLongLongSafe(k)) finish(_pe, "Missing/invalid k after direction.");
                if (k < 0 || k > 1000000000LL) {
                    cout << -1 << "\n" << flush;
                    finish(_pe, "k out of range [0, 1e9].");
                }

                queries++;

                if (dir == 'U' || dir == 'u') curY += k;
                else if (dir == 'D' || dir == 'd') curY -= k;
                else if (dir == 'L' || dir == 'l') curX -= k;
                else if (dir == 'R' || dir == 'r') curX += k;
                else {
                    cout << -1 << "\n" << flush;
                    finish(_pe, "Invalid direction (expected U/D/L/R).");
                }

                long long s = manhattanMin(pts, curX, curY);
                cout << s << "\n" << flush;
                continue;
            }

            if (op == "!") {
                long long gx, gy;
                if (!readLongLongSafe(gx) || !readLongLongSafe(gy)) {
                    finish(_pe, "Malformed answer after '!'.");
                }
                if (gx == X0 && gy == Y0) {
                    break; 
                }
                finish(_wa, "Wrong answer coordinates.");
            }

            
            finish(_pe, "Invalid command token (expected '?' or '!').");
        }
    }

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


Adaptive interactor (C++):

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

using ll = long long;

static ll clampLL(ll v, ll lo, ll hi) {
    if (v < lo) return lo;
    if (v > hi) return hi;
    return v;
}

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

    string mode = opt<string>("mode", "non");
    ll C = opt<ll>("C", 1000000000LL);
    int nOpt = opt<int>("n", 100);

    int seed = 0;
    if (argc >= 2) {
        try {
            seed = stoi(string(argv[1]));
        } catch (...) {
            seed = 0;
        }
    }

    int t = 1;
    cout << t << "\n";

    auto output_case = [&](int n, const vector<pair<ll,ll>>& pts, ll X, ll Y, ll xl, ll xr, ll yl, ll yr) {
        cout << n << "\n";
        for (auto &p : pts) cout << p.first << " " << p.second << "\n";
        if (mode == "non") {
            cout << X << " " << Y << "\n";
        } else if (mode == "adp") {
            cout << xl << " " << xr << " " << yl << " " << yr << "\n";
        } else {
            quitf(_fail, "Unknown mode: %s", mode.c_str());
        }
    };

    auto make_unique_points = [&](int n, function<pair<ll,ll>(int)> gen) {
        set<pair<ll,ll>> used;
        vector<pair<ll,ll>> pts;
        pts.reserve(n);
        int it = 0;
        while ((int)pts.size() < n) {
            auto p = gen(it++);
            if (p.first < -C || p.first > C || p.second < -C || p.second > C) continue;
            if (used.insert(p).second) pts.push_back(p);
            if (it > 2000000) break;
        }
        return pts;
    };

    auto add_point = [&](set<pair<ll,ll>>& used, vector<pair<ll,ll>>& pts, ll x, ll y) -> bool {
        if (x < -C || x > C || y < -C || y > C) return false;
        pair<ll,ll> p = {x, y};
        if (!used.insert(p).second) return false;
        pts.push_back(p);
        return true;
    };

    auto add_diamond_points = [&](set<pair<ll,ll>>& used, vector<pair<ll,ll>>& pts, ll cx, ll cy, ll R, int cnt) {
        if (cnt <= 0) return;
        if (cnt == 1) {
            add_point(used, pts, cx + R, cy);
            return;
        }
        for (int i = 0; i < cnt; i++) {
            ll t = -R + (2LL * R) * i / (cnt - 1);
            ll yabs = R - llabs(t);
            int pick = rnd.next(0, 3);
            ll x = cx + t;
            ll y = cy;
            if (pick == 0) y = cy + yabs;
            else if (pick == 1) y = cy - yabs;
            else if (pick == 2) { x = cx + yabs; y = cy + t; }
            else { x = cx - yabs; y = cy + t; }
            add_point(used, pts, x, y);
        }
    };

    
    if (seed == 1) {
        int n = 1;
        vector<pair<ll,ll>> pts = {{0, 0}};
        ll X = C, Y = -C;
        if (mode == "adp") {
            output_case(n, pts, X, Y, X, X, Y, Y);
        } else {
            output_case(n, pts, X, Y, 0, 0, 0, 0);
        }
        return 0;
    }
    if (seed == 2) {
        vector<pair<ll,ll>> pts;
        pts.push_back({0, 1});
        pts.push_back({1, 0});
        pts.push_back({0, -1});
        pts.push_back({-1, 0});
        pts.push_back({C, C});
        pts.push_back({C, -C});
        pts.push_back({-C, C});
        pts.push_back({-C, -C});
        int n = (int)pts.size();
        ll X = 0, Y = 0; 
        if (mode == "adp") {
            output_case(n, pts, X, Y, X, X, Y, Y);
        } else {
            output_case(n, pts, X, Y, 0, 0, 0, 0);
        }
        return 0;
    }
    if (seed == 3) {
        
        vector<pair<ll,ll>> pts;
        pts.reserve(100);
        for (int x = -50; x <= -1; x++) pts.push_back({x, 0});
        for (int x = 1; x <= 50; x++) pts.push_back({x, 0});
        
        pts[0] = {-C, 0};
        pts[1] = {C, 0};
        ll X = 0, Y = C - 7; 
        if (mode == "adp") {
            output_case((int)pts.size(), pts, X, Y, X, X, Y, Y);
        } else {
            output_case((int)pts.size(), pts, X, Y, 0, 0, 0, 0);
        }
        return 0;
    }

    
    int n = clampLL((ll)nOpt, 1LL, 100LL);
    set<pair<ll,ll>> used;
    vector<pair<ll,ll>> pts;
    pts.reserve(n);

    ll safety = 10000;
    ll maxR = max(1LL, C - safety);
    ll minR = min(200000000LL, maxR);
    if (minR < 10) minR = max(1LL, maxR / 2);

    ll R1 = rnd.next(minR, maxR);
    int cnt1 = min(n, 60);

    add_diamond_points(used, pts, 0, 0, R1, cnt1);

    int remaining = n - (int)pts.size();
    ll R2 = max(1LL, R1 / 3);
    R2 = min(R2, maxR);

    ll cx2lo = -C + R2 + 3;
    ll cx2hi = C - R2 - 3;
    ll cy2lo = -C + R2 + 3;
    ll cy2hi = C - R2 - 3;
    if (cx2lo > cx2hi) cx2lo = cx2hi = 0;
    if (cy2lo > cy2hi) cy2lo = cy2hi = 0;

    ll cx2 = rnd.next((ll)cx2lo, (ll)cx2hi);
    ll cy2 = rnd.next((ll)cy2lo, (ll)cy2hi);
    int cnt2 = min(remaining, 30);

    add_diamond_points(used, pts, cx2, cy2, R2, cnt2);

    remaining = n - (int)pts.size();

    
    int fillIter = 0;
    while (remaining > 0 && fillIter < 200000) {
        fillIter++;
        int tp = rnd.next(0, 4);
        ll x = 0, y = 0;

        if (tp == 0) {
            
            ll t = rnd.next(-R1, R1);
            ll yabs = R1 - llabs(t);
            ll jitter = rnd.next(-2000LL, 2000LL);
            int sgn = rnd.next(0, 1) ? 1 : -1;
            x = t + rnd.next(-2000LL, 2000LL);
            y = sgn * (yabs + jitter);
        } else if (tp == 1) {
            
            ll t = rnd.next(-R2, R2);
            ll yabs = R2 - llabs(t);
            ll jitter = rnd.next(-1500LL, 1500LL);
            int sgn = rnd.next(0, 1) ? 1 : -1;
            x = cx2 + t + rnd.next(-1500LL, 1500LL);
            y = cy2 + sgn * (yabs + jitter);
        } else if (tp == 2) {
            
            ll base = rnd.next(-C / 2, C / 2);
            ll step = rnd.next(1LL, 50000000LL);
            ll k = rnd.next(-20LL, 20LL);
            x = clampLL(base + k * step, -C, C);
            y = (rnd.next(0, 1) ? 0 : 1);
        } else if (tp == 3) {
            
            ll ex = (rnd.next(0, 1) ? -C : C);
            ll ey = rnd.next(-C, C);
            x = ex;
            y = ey;
        } else {
            
            x = rnd.next(-C, C);
            y = rnd.next(-C, C);
        }

        if (add_point(used, pts, x, y)) remaining--;
    }

    
    ll delta = rnd.next(1LL, 200LL);
    ll X = rnd.next(-R1 / 2, R1 / 2);
    ll absY = R1 + delta - llabs(X);
    if (absY < 0) { X = 0; absY = R1 + delta; }
    absY = min(absY, C);
    ll Y = (rnd.next(0, 1) ? absY : -absY);

    
    if (used.count({X, Y})) {
        if (Y + 1 <= C) Y++;
        else if (Y - 1 >= -C) Y--;
        else X = clampLL(X + 1, -C, C);
    }

    
    ll xl, xr, yl, yr;
    if (mode == "adp") {
        ll span = opt<ll>("span", 1000000000LL); 
        span = clampLL(span, 0LL, 1000000000LL);
        if (span == 1000000000LL) {
            xl = -C; xr = C; yl = -C; yr = C;
        } else {
            xl = clampLL(X - span, -C, C);
            xr = clampLL(X + span, -C, C);
            yl = clampLL(Y - span, -C, C);
            yr = clampLL(Y + span, -C, C);
            if (xl > xr) swap(xl, xr);
            if (yl > yr) swap(yl, yr);
        }
    } else {
        xl = xr = yl = yr = 0;
    }

    output_case(n, pts, X, Y, xl, xr, yl, yr);
    return 0;
}