import java.util.ArrayList;
import java.util.Scanner;
import java.io.File;

public class Problem_2_Black_And_Grey {

    public static void main(String[] args) {

        try {
            Scanner file = new Scanner(new File("C:\\Users\\Mike\\Desktop\\problem_2_black_and_grey_DATA21.txt"));

            while(file.hasNextLine()) {

                ArrayList<String> dataSet = new ArrayList<String>(); // ArrayList that represents the current data set for the board

                // for the next 6 lines in the file (current data set for the board)
                for (int l = 0; l < 6; l++) {
                    dataSet.add(file.nextLine());
                }

                // get the size of the board and then remove it from the data set (it's unneeded after recorded)
                int n = Integer.parseInt(dataSet.get(0));
                dataSet.remove(0);
                
                // find largest row and column in any of the six tiles
                int maxRow = 0, maxCol = 0;
                for (String s : dataSet) {
                    String[] rowAndCol = s.split("\\s+"); // split by whitespace. array has two elements: row and column
                    
                    int row = Integer.parseInt(rowAndCol[0]);
                    int col = Integer.parseInt(rowAndCol[1]);
                    
                    // if this row is larger than the previous largest row, this row is the new largest row
                    if (row > maxRow) maxRow = row;
                    if (col > maxCol) maxCol = col;
                }

                // board and transformed board matrices: are used to perform transformations throughout the stages
                // the dimensions are reduced to the maximum row and column values. the board won't need to be any
                // larger than that because no tiles on the board outside of this range will be tested (calculated above)
                int[][] board = new int[maxRow][maxCol], transformed = new int[maxRow][maxCol];

                ArrayList<Integer> factors = getFactors(n); // factors of the board dimensions (not reduced board)
                
                for (int factor : factors) { // for every factor
                    
                    int gridDimensions = n / factor; // the square dimensions of the grids inside the larger board
                    int numberOfGrids = factor; // the number of grids per side inside the larger board
                    
                    // make the checkerboards for each factor
                    for (int i = 0; i < numberOfGrids; i++) { // for every grid in each row
                        for (int j = 0; j < numberOfGrids; j++) { // for every grid in each column
                            // colour each grid going row by row
                            // i and j increment each grid
                            // k and l increment each tile in each grid
                            // start at the beginning of a grid (i * gridDimensions) and go until the end of the grid is reached (i * gridDimensions + gridDimensions)
                            // the + gridDimensions would mean that it's iterating over a new grid
                            // k < maxRow just makes sure that it's iterating within the reduced board array
                            for (int k = i * gridDimensions; k < i * gridDimensions + gridDimensions && k < maxRow; k++) {
                                for (int l = j * gridDimensions; l < j * gridDimensions + gridDimensions && l < maxCol; l++) {
                                    // if one of the row and column is even and one is odd, the grid is grey (if the checkerboard has the top left grid being black)
                                    if ( (i+j)%2 == 1) {
                                        board[k][l] = 0; // grey tile
                                    } else {
                                        board[k][l] = 1; // black tile
                                    }
                                }
                            }
                        }
                    }
                    
                    // add matrices (board matrix, which is the factored checkerboard, and transformed matrix, which is the last transformed board by adding, but will become the new transformed board)
                    // I call it adding the matrices, but it's really just putting them together and getting the resultant matrix
                    for (int i = 0; i < maxRow; i++) {
                        for (int j = 0; j < maxCol; j++) {
                            
                            // this is like an XOR operation: if either one is black, but not both, the result is black; otherwise (both the same), the result is grey.
                            if (transformed[i][j] == board[i][j]) { // if both tiles are the same colour
                                transformed[i][j] = 0; // turns grey
                            } else { // different colours
                                transformed[i][j] = 1; // turns black
                            }
                            
                            /* Another way of doing is using the actual XOR operator:
                            if ((transformed[i][j] ^ board[i][j]) == 1) { // use XOR operator to test if the tiles are not the same colour (one of them is black, but not both; or the same thing with grey)
                                transformed[i][j] = 1; // turns black                       
                            } else { // same colour; failed the XOR test
                                transformed[i][j] = 0; // turns grey
                            }*/
                        }
                    }
                }
                
                for (int i = 0; i < dataSet.size(); i++) { // for every tile to be looked at in the data set
                    int row = Integer.parseInt(dataSet.get(i).split("\\s+")[0]); // split the row and column string for the tile by whitespace and the first element will be the row
                    int col = Integer.parseInt(dataSet.get(i).split("\\s+")[1]); // second element is the column
                    
                    // find the tiles that the data set requests to be looked at
                    // and remember to subtract 1 from the array index because arrays start indexing at 0, but the data set starts at 1
                    if (transformed[row-1][col-1] == 0) {
                        System.out.print("G"); // grey
                    } else {
                        System.out.print("B"); // black
                    }
                }
                System.out.println();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /* returns the factors (as an ArrayList of integers) of the parameter n
       and this needs to return the list in descending order, hence the direction of the loops */
    public static ArrayList<Integer> getFactors(int n) {

        ArrayList<Integer> factors = new ArrayList<Integer>(); // ArrayList of factors to be returned
        
        for (int i = n; i >= Math.sqrt(n); i--) { // only test up to the square root of the number because that will contain exactly half of the factors, excluding the square root (increases speed)
            if (n % i == 0) factors.add(i); // if the looping variable is a factor of the number, add it to the factors list
        }

        int size = factors.size(); // size of the factors

        // add the other half of the factors of the number
        for (int i = size - 1; i >= 0; i--) { // for every factor in the factors list
            if (factors.get(i) != Math.sqrt(n)) { // only add the corresponding factor if the factor is not the square root of the number (the corresponding factor is itself - a duplicate)
                factors.add(n / factors.get(i)); // add the corresponding factor (the number divided by this factor) to the list
            }
        }
        return factors;
    }
}