Problem: This is an interactive task.

Dasha and NN like playing chess. While playing a match they decided that normal chess isn't interesting enough for them, so they invented a game described below.

There are 666 black rooks and 1 white king on the chess board of size 999 × 999. The white king wins if he gets checked by rook, or, in other words, if he moves onto the square which shares either a row or column with a black rook.

The sides take turns, starting with white. NN plays as a white king and on each of his turns he moves a king to one of the squares that are adjacent to his current position either by side or diagonally, or, formally, if the king was on the square (x, y), it can move to the square (nx, ny) if and only max (|nx - x|, |ny - y|) = 1 , 1 ≤ nx, ny ≤ 999. NN is also forbidden from moving onto the squares occupied with black rooks, however, he can move onto the same row or column as a black rook.

Dasha, however, neglects playing by the chess rules, and instead of moving rooks normally she moves one of her rooks on any space devoid of other chess pieces. It is also possible that the rook would move onto the same square it was before and the position wouldn't change. However, she can't move the rook on the same row or column with the king.

Each player makes 2000 turns, if the white king wasn't checked by a black rook during those turns, black wins. 

NN doesn't like losing, but thinks the task is too difficult for him, so he asks you to write a program that will always win playing for the white king. Note that Dasha can see your king and play depending on its position.

Input

In the beginning your program will receive 667 lines from input. Each line contains two integers x and y (1 ≤ x, y ≤ 999) — the piece's coordinates. The first line contains the coordinates of the king and the next 666 contain the coordinates of the rooks. The first coordinate denotes the number of the row where the piece is located, the second denotes the column. It is guaranteed that initially the king isn't in check and that all pieces occupy different squares.

Output

After getting king checked, you program should terminate immediately without printing anything extra.

Interaction

To make a move with the king, output two integers x and y (1 ≤ x, y ≤ 999) — the square to which the king would be moved. The king cannot move onto the square already occupied by a rook. It is guaranteed that the king would always have a valid move.

After each of your turns read the rook's turn in the following format: a single line containing three integers k, x and y (1 ≤ k ≤ 666, 1 ≤ x_i, y_i ≤ 999) — the number of the rook that would move and the square it would move to. It is guaranteed that the rook wouldn't move to a square already occupied by another chess piece, but it can move onto the square where it was before the turn so that its position wouldn't change. It is guaranteed that the move does not put your king into a check. If your king got in check, all three integers would be equal to -1 and in that case your program should terminate immediately.

After printing your turn do not forget to output 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 documentation for other languages.



Answer "0 0 0" instead of a correct answer means that you made an invalid query. Exit immediately after receiving "0 0 0" and you will see Wrong answer verdict. Otherwise you can get an arbitrary verdict because your solution will continue to read from a closed stream.

Hacks are not allowed for this problem.

Example

Input

999 999
1 1
1 2
2 1
2 2
1 3
2 3
&lt;...&gt;
26 13
26 14
26 15
26 16

1 700 800

2 1 2

&lt;...&gt;

-1 -1 -1


Output












999 998

999 997

&lt;...&gt;

999 26

Note

The example is trimmed. The full initial positions of the rooks in the first test are available at <https://pastebin.com/qQCTXgKP>. It is not guaranteed that they will behave as in the example.

Solution (in JAVA):

Solution:
import java.util.*;
import java.lang.*;
import java.io.*;
import java.math.*;

public class Codeforces {

    private static Print writer;

    private static Scan reader;

    static class Scan {
        private byte[] buf = new byte[1024]; // Buffer of Bytes
        private int index;
        private InputStream in;
        private int total;

        public Scan() throws IOException {
            in = System.in;
        }

        private int next() throws IOException { // Scan method used to scan buf
            if (total < 0)
                throw new InputMismatchException();
            if (index >= total) {
                index = 0;
                total = in.read(buf);
                if (total <= 0)
                    return -1;
            }
            return buf[index++];
        }

        int ni() throws IOException {
            int integer = 0;
            int n = next();
            while (isWhiteSpace(n)) // Removing startPointing whitespaces
                n = next();
            int neg = 1;
            if (n == '-') { // If Negative Sign encounters
                neg = -1;
                n = next();
            }
            while (!isWhiteSpace(n)) {
                if (n >= '0' && n <= '9') {
                    integer *= 10;
                    integer += n - '0';
                    n = next();
                } else
                    throw new InputMismatchException();
            }
            return neg * integer;
        }

        private boolean isNewLine(int n) {
            return n == '\n' || n == '\r' || n == -1;
        }

        private boolean isWhiteSpace(int n) {
            return n == ' ' || isNewLine(n) || n == '\t';
        }
    }

    static class Print {
        private final BufferedWriter bw;

        Print() {
            bw = new BufferedWriter(new OutputStreamWriter(System.out));
        }

        <T> void print(T str) {
            try {
                bw.append(str.toString());
            } catch (IOException e) {
                System.out.println(e.toString());
            }
        }

        void println() {
            print("\n");
        }

        <T> void println(T str) {
            print(str + "\n");
        }

        void flush() throws IOException {
            bw.flush();
        }

        void close() {
            try {
                bw.close();
            } catch (IOException e) {
                System.out.println(e.toString());
            }
        }
    }

    public static void main(String[] args) throws Exception {
        long startPointTime = System.currentTimeMillis();
        reader = new Scan();
        writer = new Print();
        main2();
        long endTime = System.currentTimeMillis();
        float totalProgramTime = endTime - startPointTime;
        if (args.length > 0 && args[0].equals("time"))
            writer.print("Execution time is " + totalProgramTime + " (" + (totalProgramTime / 1000) + "s)");
        writer.close();
    }

    // START HERE
    // Holds row and col information
    static class Point {
        int row;
        int col;

        Point(int row, int col) {
            this.row = row;
            this.col = col;
        }
    }

    // board to check for positions of rooks
    // will be updated when computer gives input
    static boolean[][] board;
    // to access any given rooks position
    static Point[] rooks;

    // object to track king's position
    static Point king;

    static void main2() throws Exception {
        // x maps to col
        // y maps to row
        int col = reader.ni();
        int row = reader.ni();
        king = new Point(row, col);

        // following 1 based indexing in this program
        board = new boolean[1000][1000];
        rooks = new Point[667];

        // init data of rooks
        for (int i = 1; i <= 666; i++) {
            col = reader.ni();
            row = reader.ni();
            rooks[i] = new Point(row, col);
            board[row][col] = true;
        }

        // take king to centre
        // there is a possibility of finding rooks on the way
        // even on the diagonals when going towards (500,500)
        while (king.row != 500 || king.col != 500) {
            // Get the direction to move towards
            // point's row and col data can be -1(decrease), 0(stay), 1(increase)
            // calculates delta for king
            Point delta = getDirection(500, 500);
            if (board[king.row + delta.row][king.col + delta.col]) {
                // rook found on diagonal
                // this can never be on same row or col as moveKing will
                // indicate termination request

                // rook found so just change row or col, but not both
                // or judge will say rook eaten by king
                moveKing(king.row + delta.row, king.col);
                return;
            } else {
                // normal move for king.
                // if moving results in a win, terminate program
                if (moveKing(king.row + delta.row, king.col + delta.col)) {
                    return;
                }
            }
        }

        // king now at centre
        // find which corner to go to

        // this function gives corner information
        // after calculating mininmum quadrant, go to the corner opposite
        // it. information for that is provided in the diff(or delta) Point object
        Point[] data = getCorner();
        // corner to go to. one of (1, 1), (1, 999), (999, 1), (999, 999)
        Point corner = data[0];
        // diff, one of (-1, -1), (-1, 1), (1, -1), (1, 1)
        Point diff = data[1];

        // while king hasn't reached the corner
        while (king.row != corner.row || king.col != corner.col) {

            // below logic is same as when moving king to centre
            if (board[king.row + diff.row][king.col + diff.col]) {
                // if rook at diagonal..we can win
                moveKing(king.row + diff.row, king.col);
                return;
            } else {
                if (moveKing(king.row + diff.row, king.col + diff.col))
                    return;
            }
        }
    }

    static Point getDirection(int row, int col) {
        Point p = new Point(0, 0);
        if (king.row == row)
            p.row = 0;
        else if (king.row > row)
            p.row = -1;
        else
            p.row = 1;

        if (king.col == col)
            p.col = 0;
        else if (king.col > col)
            p.col = -1;
        else
            p.col = 1;
        return p;
    }

    // moveKing to new row and col position
    static boolean moveKing(int newRow, int newCol) throws Exception {
        king.row = newRow;
        king.col = newCol;
        // print in opposite way as x -> col & y -> row
        writer.println(king.col + " " + king.row);
        // very imp
        writer.flush();

        // read in oppo way coz of mapping
        int r = reader.ni();
        int rncol = reader.ni();
        int rnrow = reader.ni();

        if (r == -1) {
            // game over you win
            return true;
        } else if (r == 0) {
            // fail
            return true;
        }
        // reset old position to unoccupied (false)
        board[rooks[r].row][rooks[r].col] = false;
        rooks[r].row = rnrow;
        rooks[r].col = rncol;
        // set rook to new position as occupied (true)
        board[rnrow][rncol] = true;

        return false;
    }

    // function to get corner information after king is at the centre
    // returns a Point[] array of size 2.
    // arr[0] has corner value and arr[1] has direction(or diff or delta) value
    static Point[] getCorner() {
        int quadI = 0, quadII = 0, quadIII = 0, quadIV = 0;

        for (int row = 1; row < 1000; row++) {
            for (int col = 1; col < 1000; col++) {
                if (!board[row][col])
                    continue;
                else {
                    if (row < 500 && col < 500) {
                        quadII++;
                    } else if (row < 500 && col > 500) {
                        quadI++;
                    } else if (row > 500 && col < 500) {
                        quadIII++;
                    } else {
                        quadIV++;
                    }
                }
            }
        }
        int min = min(quadI, quadII, quadIII, quadIV);
        if (quadI == min) {
            // go to quad III
            return new Point[] { new Point(999, 1), new Point(1, -1) };
        } else if (quadII == min) {
            // go to quad IV
            return new Point[] { new Point(999, 999), new Point(1, 1) };
        } else if (quadIII == min) {
            // go to quad I
            return new Point[] { new Point(1, 999), new Point(-1, 1) };
        }
        // go to quad II
        return new Point[] { new Point(1, 1), new Point(-1, -1) };
    }

    static int min(int... arr) {
        int min = Integer.MAX_VALUE;
        for (int var : arr) {
            min = Math.min(min, var);
        }
        return min;
    }
}