import java.util.*;
public class Main{
public static void main(String args[]){
Scanner in = new Scanner(System.in);
int countElement = in.nextInt();
int countRow = in.nextInt();
int countColumn = 0;
if(countElement % countRow == 0){
countColumn = countElement / countRow;
}
else{
countColumn = (countElement / countRow) + 1;
}
// 此时 行数、列数、元素总个数 均已求出
int [][]martix = new int[countRow][countColumn];
int countColumnAll = countColumn;
int countRowAll = countRow;
// 代替 行列数 并在每次转圈中更新 行列数
// 此次一圈 的最上行应填写的数字个数
int leftFirstColumn = countColumnAll; // 若小于等于0则不用再写
// 此次一圈 的最右列应填写的数字个数
int leftFirstRow = countRowAll-1; // 若小于等于0则不用再写
// 此次一圈 的最下行应填写的数字个数
int leftSecondColumn = countColumnAll-1; // 若小于等于0则不用再写
// 此次一圈 的最左列应填写的数字个数
int leftSecondRow = countRowAll-2; // 若小于等于0 则不用再写
// 转完 一圈之后 countColumn = countColumn-2; countRow = countRow-2;
// 若新的countColumn和新的countRow都大于0 [fistStart][firstStart] = [firstStart+1][firstStart+1]
int firstStartRow = 0;
int firstStartColumn = 0;
// 当前要被填入的二维矩阵的元素的位置坐标
int leftElements = countElement;
// 当前还剩下多少个元素等待填入二维矩阵
int element = 1; // 当前要被填入的元素的值
int thisContain = 0; // 当前转满一圈能填进去多少个元素
boolean symbol = false;
while(leftElements > 0){
// 计算 当前转满一圈能装满多少个元素
if(leftFirstColumn > 0){
thisContain += leftFirstColumn;
if(leftFirstRow > 0){
thisContain += leftFirstRow;
}
if(leftSecondColumn > 0){
thisContain += leftSecondColumn;
}
if(leftSecondRow > 0){
thisContain += leftSecondRow;
}
//System.out.println("当前转一圈的容纳总数:" + thisContain);
thisContain = 0;
}
int thisColumn = firstStartColumn;
int thisRow = firstStartRow;
// 记录 当前在走这一圈的时候 每一步步进的时候的行/列坐标
// 每一圈都遵循右循环的次序
for(int i=0;i<leftFirstColumn;i++){
// 循环次数 为当前这一行要填入 多少个数据 就循环几次
martix[thisRow][thisColumn] = element;
element++;
// element 自增更新下次要填的数据
thisColumn++;
leftElements--;
// 剩余的元素数量减一
if(leftElements==0){
// 如果数据都填完了 更新填完的标志
// 然后退出for循环
symbol = true;
break;
}
}
if(symbol){
// 标志着数据都填完了 退出while循环
break;
}
thisRow++;
thisColumn--;
for(int i=0;i<leftFirstRow;i++){
martix[thisRow][thisColumn] = element;
thisRow++;
element++;
leftElements--;
if(leftElements==0){
symbol=true;
break;
}
}
if(symbol){
break;
}
thisRow--;
thisColumn--;
for(int i=0;i<leftSecondColumn;i++){
martix[thisRow][thisColumn] = element;
element++;
thisColumn--;
leftElements--;
if(leftElements==0){
symbol=true;
break;
}
}
if(symbol){
break;
}
thisColumn++;
thisRow--;
for(int i=0;i<leftSecondRow;i++){
martix[thisRow][thisColumn] = element;
element++;
thisRow--;
leftElements--;
if(leftElements==0){
symbol=true;
break;
}
}
if(symbol){
break;
}
// 每次转完一圈之后的 行数/列数 都 减2
countColumnAll = countColumnAll-2;
countRowAll = countRowAll-2;
// 此次一圈 的最上行应填写的数字个数
leftFirstColumn = countColumnAll; // 若小于等于0则不用再写
// 此次一圈 的最右列应填写的数字个数
leftFirstRow = countRowAll-1; // 若小于等于0则不用再写
// 此次一圈 的最下行应填写的数字个数
leftSecondColumn = countColumnAll-1; // 若小于等于0则不用再写
// 此次一圈 的最左列应填写的数字个数
leftSecondRow = countRowAll-2; // 若小于等于0 则不用再写
if(countColumnAll>0){
firstStartColumn++;
}
if(countRow>0){
firstStartRow++;
}
// 如果 此时 行数/列数 大于0 则对应的 下一圈起始位置坐标应该 +1
}
// 输出
for(int i=0;i<countRow;i++){
for(int j=0;j<countColumn;j++){
if(martix[i][j] == 0){
System.out.print("* ");
}
else{
System.out.print(martix[i][j]+" ");
}
}
System.out.println();
}
}
}