//Warnsdorff suggested a simple rule: Always move the knight to a square from which it will have the fewest available subsequent moves.
#include<iostream>
#include<vector>
#include<algorithm>
#include<array>
using namespace std;
int vis[9][9],degree[9][9];
int X[]={1,2,2,1,-1,-2,-2,-1};
int Y[]={2,1,-1,-2,2,1,-1,-2};
inline bool isValid(int i,int j){
return i>=1 and i<=8 and j>=1 and j<=8 and !vis[i][j];
}
inline int getDegree(int x,int y){
int cnt=0;
for(int i=0;i<8;i++){cnt+=isValid(x+X[i],y+Y[i]);}
return cnt;
}
bool dfs(int x,int y,int num){
vis[x][y]=num;
if(num==64)return true;
vector<array<int,2>>moves;
for(int i=0;i<8;i++){
if(isValid(x+X[i],y+Y[i])){
moves.push_back({x+X[i],y+Y[i]});
}
}
sort(moves.begin(),moves.end(),[&](auto &a,auto &b){
return getDegree(a[0],a[1])<getDegree(b[0],b[1]);
});
for(auto &move:moves){
if(dfs(move[0],move[1],num+1))return true;
}
return false;
}
int main(){
int a,b;
cin>>b>>a;
dfs(a,b,1);
for(int i=1;i<=8;i++){
for(int j=1;j<=8;j++){
cout<<vis[i][j]<<" ";
}
cout<<endl;
}
}