Link to this code: https://cses.fi/paste/3133cd0f31590b2869e36d/
//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;
  }
}