#include <stdio.h>
#include <stdlib.h>

#define MAX_SIZE 100

void read_matrix_static(int matrix[MAX_SIZE][MAX_SIZE], int rows, int cols);
void print_matrix_static(int matrix[MAX_SIZE][MAX_SIZE], int rows, int cols);

int **allocate_matrix_dynamic1(int rows, int cols);
void read_matrix_dynamic1(int **matrix, int rows, int cols);
void print_matrix_dynamic1(int **matrix, int rows, int cols);
void free_matrix_dynamic1(int **matrix, int rows);

int *allocate_matrix_dynamic2(int rows, int cols);
void read_matrix_dynamic2(int *matrix, int rows, int cols);
void print_matrix_dynamic2(int *matrix, int rows, int cols);
void free_matrix_dynamic2(int *matrix);

int **allocate_matrix_dynamic3(int rows, int cols);
void read_matrix_dynamic3(int **matrix, int rows, int cols);
void print_matrix_dynamic3(int **matrix, int rows, int cols);
void free_matrix_dynamic3(int **matrix, int rows);

int main() {
    int choice, rows, cols;
    printf("Выберите метод выделения памяти:\n1. Статически\n2. Динамически (2D массив указателей)\n3. Динамически (1D массив)\n4. Динамически (массив указателей на строки)\n");

    if (scanf("%d", &choice) != 1 || choice < 1 || choice > 4) {
        printf("n/a\n");
        return 1;
    }

    if (scanf("%d %d", &rows, &cols) != 2 || rows < 1 || cols < 1 || rows > MAX_SIZE || cols > MAX_SIZE) {
        printf("n/a\n");
        return 1;
    }

    switch (choice) {
        case 1: {
            int matrix[MAX_SIZE][MAX_SIZE];
            read_matrix_static(matrix, rows, cols);
            print_matrix_static(matrix, rows, cols);
            break;
        }
        case 2: {
            int **matrix = allocate_matrix_dynamic1(rows, cols);
            if (matrix == NULL) {
                printf("n/a\n");
                return 1;
            }
            read_matrix_dynamic1(matrix, rows, cols);
            print_matrix_dynamic1(matrix, rows, cols);
            free_matrix_dynamic1(matrix, rows);
            break;
        }
        case 3: {
            int *matrix = allocate_matrix_dynamic2(rows, cols);
            if (matrix == NULL) {
                printf("n/a\n");
                return 1;
            }
            read_matrix_dynamic2(matrix, rows, cols);
            print_matrix_dynamic2(matrix, rows, cols);
            free_matrix_dynamic2(matrix);
            break;
        }
        case 4: {
            int **matrix = allocate_matrix_dynamic3(rows, cols);
            if (matrix == NULL) {
                printf("n/a\n");
                return 1;
            }
            read_matrix_dynamic3(matrix, rows, cols);
            print_matrix_dynamic3(matrix, rows, cols);
            free_matrix_dynamic3(matrix, rows);
            break;
        }
    }

    return 0;
}

void read_matrix_static(int matrix[MAX_SIZE][MAX_SIZE], int rows, int cols) {
    for (int i = 0; i < rows; i++) {
        for (int j = 0; j < cols; j++) {
            if (scanf("%d", &matrix[i][j]) != 1) {
                printf("n/a\n");
                exit(1);
            }
        }
    }
}

void print_matrix_static(int matrix[MAX_SIZE][MAX_SIZE], int rows, int cols) {
    for (int i = 0; i < rows; i++) {
        for (int j = 0; j < cols; j++) {
            printf("%d", matrix[i][j]);
            if (j < cols - 1) {
                printf(" ");
            }
        }
        if (i < rows - 1) {
            printf("\n");
        }
    }
}

int **allocate_matrix_dynamic1(int rows, int cols) {
    int **matrix = malloc(rows * sizeof(int*));
    if (matrix == NULL) return NULL;

    for (int i = 0; i < rows; i++) {
        matrix[i] = malloc(cols * sizeof(int));
        if (matrix[i] == NULL) {
            for (int j = 0; j < i; j++) {
                free(matrix[j]);
            }
            free(matrix);
            return NULL;
        }
    }
    return matrix;
}

void read_matrix_dynamic1(int **matrix, int rows, int cols) {
    for (int i = 0; i < rows; i++) {
        for (int j = 0; j < cols; j++) {
            if (scanf("%d", &matrix[i][j]) != 1) {
                printf("n/a\n");
                exit(1);
            }
        }
    }
}

void print_matrix_dynamic1(int **matrix, int rows, int cols) {
    for (int i = 0; i < rows; i++) {
        for (int j = 0; j < cols; j++) {
            printf("%d", matrix[i][j]);
            if (j < cols - 1) {
                printf(" ");
            }
        }
        if (i < rows - 1) {
            printf("\n");
        }
    }
}

void free_matrix_dynamic1(int **matrix, int rows) {
    for (int i = 0; i < rows; i++) {
        free(matrix[i]);
    }
    free(matrix);
}

int *allocate_matrix_dynamic2(int rows, int cols) {
    return malloc(rows * cols * sizeof(int));
}

void read_matrix_dynamic2(int *matrix, int rows, int cols) {
    for (int i = 0; i < rows; i++) {
        for (int j = 0; j < cols; j++) {
            if (scanf("%d", &matrix[i * cols + j]) != 1) {
                printf("n/a\n");
                exit(1);
            }
        }
    }
}

void print_matrix_dynamic2(int *matrix, int rows, int cols) {
    for (int i = 0; i < rows; i++) {
        for (int j = 0; j < cols; j++) {
            printf("%d", matrix[i * cols + j]);
            if (j < cols - 1) {
                printf(" ");
            }
        }
        if (i < rows - 1) {
            printf("\n");
        }
    }
}

void free_matrix_dynamic2(int *matrix) {
    free(matrix);
}

int **allocate_matrix_dynamic3(int rows, int cols) {
    int **matrix = malloc(rows * sizeof(int*));
    if (matrix == NULL) return NULL;

    for (int i = 0; i < rows; i++) {
        matrix[i] = malloc(cols * sizeof(int));
        if (matrix[i] == NULL) {
            for (int j = 0; j < i; j++) {
                free(matrix[j]);
            }
            free(matrix);
            return NULL;
        }
    }
    return matrix;
}

void read_matrix_dynamic3(int **matrix, int rows, int cols) {
    for (int i = 0; i < rows; i++) {
        for (int j = 0; j < cols; j++) {
            if (scanf("%d", &matrix[i][j]) != 1) {
                printf("n/a\n");
                exit(1);
            }
        }
    }
}

void print_matrix_dynamic3(int **matrix, int rows, int cols) {
    for (int i = 0; i < rows; i++) {
        for (int j = 0; j < cols; j++) {
            printf("%d", matrix[i][j]);
            if (j < cols - 1) {
                printf(" ");
            }
        }
        if (i < rows - 1) {
            printf("\n");
        }
    }
}

void free_matrix_dynamic3(int **matrix, int rows) {
    for (int i = 0; i < rows; i++) {
        free(matrix[i]);
    }
    free(matrix);
}