Stuck Conveyor
Contest: Codeforces Round 877 (Div. 2)
Difficulty rating: 3000
Tags: binary search, constructive algorithms, interactive

This is an interactive problem.

There is an $$$n$$$ by $$$n$$$ grid of conveyor belts, in positions $$$(1, 1)$$$ through $$$(n, n)$$$ of a coordinate plane. Every other square in the plane is empty. Each conveyor belt can be configured to move boxes up ('^'), down ('v'), left ('<'), or right ('>'). If a box moves onto an empty square, it stops moving.

However, one of the $$$n^2$$$ belts is stuck, and will always move boxes in the same direction, no matter how it is configured. Your goal is to perform a series of tests to determine which conveyor belt is stuck, and the direction in which it sends items.

To achieve this, you can perform up to $$$25$$$ tests. In each test, you assign a direction to all $$$n^2$$$ belts, place a box on top of one of them, and then turn all of the conveyors on.

One possible result of a query with $$$n=4$$$. In this case, the box starts at $$$(2, 2)$$$. If there were no stuck conveyor, it would end up at $$$(5, 4)$$$, but because of the stuck '>' conveyor at $$$(3, 3)$$$, it enters an infinite loop.

The conveyors move the box around too quickly for you to see, so the only information you receive from a test is whether the box eventually stopped moving, and if so, the coordinates of its final position.

Interaction format:
You begin the interaction by reading a single integer $$$n$$$ ($$$2 \le n\le 100$$$) — the number of rows and columns in the grid.

Then, you can make at most $$$25$$$ queries.

Each query should begin with a line of the form ? r c, where r and c are the initial row and column of the box, respectively.

The next $$$n$$$ lines of the query should contain $$$n$$$ characters each. The $$$j$$$th character of the $$$i$$$th row should be one of '^', 'v', '<', or '>', indicating the direction of conveyor $$$(i, j)$$$ for this query.

After each query, you will receive two integers $$$x$$$ and $$$y$$$. If $$$x = y = -1$$$, then the box entered an infinite loop. Otherwise, its final position was $$$(x, y)$$$.

If you make too many queries or make an invalid query, you will receive the Wrong Answer verdict.

After you have found the stuck conveyor and its direction, print a single line ! r c dir, where r and c are the row and column of the stuck conveyor, respectively, and dir is one of '^', 'v', '<', or '>', indicating the direction of the stuck conveyor. Note that printing this answer does not count towards your total of $$$25$$$ queries. After printing this line, your program should terminate.

The interactor is non-adaptive. This means that the location and direction of the stuck belt is fixed at the start of the interaction, and does not change after the queries.

After printing a query do not forget to output the end of line and flush the output. Otherwise, you will get Idleness limit exceeded. To do this, use:

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

Hacks

To make a hack, use the following format.

The first line should contain a single integer $$$n$$$ ($$$1 \le n \le 100$$$) — the number of rows and columns in the grid.

The next line should contain two integers $$$r$$$ and $$$c$$$ ($$$1 \le r, c \le n$$$), as well as a character $$$\mathrm{dir}$$$ ($$$\mathrm{dir}$$$ is one of '^', 'v', '<', '>') — the position of the stuck conveyor and its fixed direction. These values should be separated by spaces.

Constraints:
Time limit: 2.0 s
Memory limit: 256.0 MB

Note:
For the first query of the first sample input, the box starts on $$$(2, 2)$$$ and enters an infinite loop containing rows $$$2$$$ and $$$3$$$. Because the stuck conveyor is in row $$$1$$$, it does not affect the outcome of the query.

For the second query of the first sample input, the conveyors are configured in the same way, but the box starts on $$$(1, 1)$$$. If there were no stuck conveyor, it would enter an infinite loop between $$$(1, 2)$$$ and $$$(1, 3)$$$. However, the stuck conveyor redirects it to $$$(0, 2)$$$.

After these two queries, the program is able to determine that the stuck conveyor is at $$$(1, 2)$$$ and directs items upward.

The query for the second sample input corresponds to the picture above. After asking the query, there are many possibilities for the stuck conveyor, but the program correctly guesses that it is at $$$(3, 3)$$$ and directs items to the right.

Example input:
3




-1 -1




0 2

Example output:
? 2 2
>><
>>v
^<<

? 1 1
>><
>>v
^<<

! 1 2 ^

Example input:
4





-1 -1

Example output:
? 2 2
v>v<
^v<v
v>v^
>v>v

! 3 3 >

Editorial:
The key to our solution will be these two "snake" configurations:
We will initially query the first snake with the box on the top left, and the second snake with the box on the bottom left (or bottom right, depending on parity of $$$n$$$).
Note that these two snakes, with the box on the given starting positions, each form a single path such that the box visits all squares, and the second snake visits squares in the reverse order of the first.
Now, consider some cases.
If the stuck conveyor belt directs items to an empty square, then for both of the above configurations, the box will end up in that empty square. This cannot be the "intended" behavior for both of them, because the intended behavior for both of them is different. So in one snake, we will know that this is unintended behavior. Because each possible empty square is only adjacent to one belt, we know exactly which belt must have sent it there, and therefore which one is broken.
If the stuck conveyor belt directs items to another belt, number the conveyor belts from $$$1$$$ to $$$n^2$$$ in the order they are visited by the first snake, and consider two subcases:
1. If the other belt has a lower number than the stuck belt, then the box will enter an infinite loop for the first snake query, and will terminate for the second snake query. Since the opposite will happen in the other case, this allows us to distinguish these two subcases.Consider what happens if we ask the first snake query again, but place the box on belt $$$i$$$ instead of belt $$$1$$$. Assume the stuck belt is belt $$$j$$$. Because the stuck belt directs items to a belt with smaller number, if $$$i \le j$$$, the box will hit the stuck belt, and enter an infinite loop. If $$$i > j$$$, the box will never encounter the stuck belt, so it will eventually reach the end of the snake and stop moving.So with one query, by checking whether the box enters an infinite loop, we can determine whether $$$i \le j$$$ or $$$i > j$$$. This allows us to binary search for $$$j$$$ in $$$\log (n^2)$$$ queries.
2. The case where the other belt has a higher number than the stuck belt is analogous, using the second snake query rather than the first.
So now, in all cases, we know which of the $$$n^2$$$ belts is stuck. In order to determine the direction in which it is stuck, we use one more query. Place the box on the stuck conveyor, and direct all belts in the same row or column as the stuck belt away from it (all other belts can be directed arbitrarily). Here is one example for $$$n=4$$$ where the stuck belt is $$$(2, 2)$$$:
So we will get a different final position for the box for each of the four directions in which it could be stuck, and can recover the direction.
The total number of queries for these steps is bounded by $$$2 + log(n^2) + 1$$$. Since $$$n \le 100$$$, this is at most $$$17$$$.
Complexity: $$$O(n^2 \log (n^2))$$$