#include <stdio.h>
#include <stdlib.h> // malloc, freeを使うために必要 [cite: 12]

int main(){
    int i, j, k;
    int a, b;
    int **mat; // 「int型のポインタ」のポインタ [cite: 18]
    scanf("%d %d", &a, &b);

    // --- 【1】ここで2次元配列の動的確保をする ---
    // 手順①：まず「各行の先頭アドレス」を格納するためのポインタ配列を確保する [cite: 17, 18]
    mat = (int **)malloc(sizeof(int *) * a); 
    
    for(i = 0; i < a; i++){
        // 手順②：各行に対して、実際の数値(int)を入れるための領域を確保する [cite: 17, 18]
        mat[i] = (int *)malloc(sizeof(int) * b);
    }
    
    // --- 【2】ここで2次元配列に数値を代入する ---
    // スライドの課題1では「1, 2, 3...と順に自然数を代入」する指示があります [cite: 19]
    int count = 1;
    for(i = 0; i < a; i++){
        for(j = 0; j < b; j++){
            mat[i][j] = count++; 
        }
    }
    
    // 表示の部分
    for(i = 0; i < a; i++){
        for(j = 0; j < b; j++){
            printf("%d ", mat[i][j]);
        }
        printf("\n");
    }
    
    // --- 【3】最後に忘れずにすること（メモリ解放） ---
    // 使い終わったら free( ) をして後始末をします 
    // 確保した時と「逆の手順」で解放するのがルールです
    for(i = 0; i < a; i++){
        free(mat[i]); // まず各行の中身を解放 
    }
    free(mat); // 最後に外枠のポインタ配列を解放 

    return 0;
}