#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
void quick_sort(int a[],int first,int end){
int i, j,
temp = a[first];
i = first;
j = end;
if (i<j){
while (i < j){
while (i < j && a[j] >= temp) j--;
a[i] = a[j];
while (i<j && a[i]<=temp) i++;
a[j] = a[i];
}
a[i] = temp;
quick_sort(a,first,i-1);
quick_sort(a, i+1, end);
}
}
int main(){
int N, i, j, n, m;
int juzheng[10002],input[10100];
scanf("%d", &N);
for (i = 0; i < N; i++){
scanf("%d", &input[i]);
}
quick_sort(input, 0, N - 1);
for (i = 1; i <= sqrt((double)N); i++){//找出满足m*n == N 且m -n 最小
if (N%i == 0){
m = N / i;
n = i;
}
}
int count, input_num;
input_num = N - 1; //我的排序为递增,所以最后一个元素为最大。
count = 0; //标志层数
while (2 * count < m || 2 * count < n){ //注意输出改行或该列前,是否还需要输出。上边行和右边列需要满足m - 2 * count >0,才需要输出;下边行和左边列需要m - 2 * count >1才需要输出
for (i = count; i < n - count && m - 2 * count >0; i++){ //一层中的上方的行
juzheng[count* n +i] = input[input_num--];
}
for (i = count + 1; i < m - count && n - 2 * count >0; i++){//一层中右边的列
juzheng[i * n + n - 1 - count] = input[input_num--];
}
for (i = n - count - 2; i >= count && m - 2 * count >1; i--){//一层中下方的行
juzheng[(m - 1 -count)* n + i] = input[input_num--];
}
for (i = m - 2 - count; i > count && n - 2 * count >1;i--){//一层中左边的列。
juzheng[i * n +count] = input[input_num--];
}
count++; //层数+1
}
for (i = 0; i < m;i++){ //输出矩阵
for (j = 0; j < n;j++){
if (j == n-1)
printf("%d\n", juzheng[i*n +j]);
else
printf("%d ", juzheng[i*n+j]);
}
}
return 0;
}