#include <iostream>
 
using namespace std;
 
const int row[8] = {-2, -1, +1, +2, +2, +1, -1, -2};
const int col[8] = {+1, +2, +2, +1, -1, -2, -2, -1};
 
void try2Move(int count, int x, int y, int** board, int n);
void printAns(int** board, int n);
bool isInBoard(int x, int y, int n);
 
int main() {
    int n;
    cin >> n;
 
    int** board = new int*[n]();
    for(int i=0; i<n; i++)
        board[i] = new int[n]();
 
    int x, y;
    cin >> x >> y;
 
    board[x][y] = 1;
    try2Move(2, x, y, board, n);
 
    for(int i=0; i<n; i++)
        delete[] board[i];
    delete[] board;
 
    return 0;
}
 
void printAns(int** board, int n) {
    for(int i=0; i<n; i++) {
        for(int j=0; j<n; j++) {
            cout << board[i][j] << " ";
        }
        cout<<"\n";
    }
}
 
bool isInBoard(int x, int y, int n) {
    if(x < 0 || x >= n) return false;
    if(y < 0 || y >= n) return false;
    return true;
}
 
//===============================================================

bool checkAns = false;

bool nextCellIsFirstCell(int x, int y, int** board, int n) {
    for (int i=0; i<8; i++) {
        int xN = x + row[i];
        int yN = y + col[i];
        if(!isInBoard(xN, yN, n)) continue;
        
        if(board[xN][yN] == 1)
            return true;
    }
    return false;
}

int numCan(pair<int, int> cur, int** board, int n) {
    int x = cur.first;
    int y = cur.second;
    int num = 0;
    
    for(int i=0; i<8; i++) {
        int xN = x + row[i];
        int yN = y + col[i];
        if(!isInBoard(xN, yN, n)) continue;
        
        if(board[xN][yN] > 0) continue;
        num++;
    }
    
    return num;
}

void try2Move(int count, int x, int y, int** board, int n) {
    if(checkAns == true) return;
    if(count > n*n) {
        if(!nextCellIsFirstCell(x, y, board, n)) return;
        printAns(board, n);
        checkAns = true;
    }
    
    pair<int, int> candidates[8];
    int nCandidate = 0;
    
    for (int i=0; i<8; i++) {
        int xN = x + row[i];
        int yN = y + col[i];
        if(!isInBoard(xN, yN, n)) continue;
        
        //If the number of candidates of first knight's
        //position is 0, it means there're no way back 
        //to the first position
        if(board[xN][yN] == 1) {
            if(numCan({xN, yN}, board, n) == 0) return;
        }
        
        if(board[xN][yN] == 0) {
            candidates[nCandidate++] = {xN, yN};
        }
    }
    
    // Sort candidates by the number of next_candidates
    // using bubble sort
    for(int i=0; i < nCandidate - 1; i++) {
        for (int j = 0; j < nCandidate - i - 1; j++) {
            int num_a = numCan(candidates[j], board, n);
            int num_b = numCan(candidates[j+1], board, n);
            if(num_a > num_b)
                swap(candidates[j], candidates[j+1]);
        }
    }
    
    for(int i=0; i < nCandidate; i++) {
        int xN = candidates[i].first;
        int yN = candidates[i].second;
        if(!isInBoard(xN, yN, n)) continue;
        
        if(board[xN][yN] == 0) {
            board[xN][yN] = count;
            try2Move(count+1, xN, yN, board, n);
            board[xN][yN] = 0;
        }
    }
}