#include <bits/stdc++.h>
using namespace std;
const int maxn = 4e5 + 5;
const int inf = 0x3f3f3f3f;
int a[maxn], ans[maxn], sum[maxn];
struct node {
  int v, num;
  bool operator<(const node x) const { return num > x.num; }
};
node b[maxn];
int main() {
  int n;
  scanf("%d", &n);
  for (int i = 1; i <= n; ++i) {
    scanf("%d", &a[i]);
  }
  sort(a + 1, a + n + 1);
  int num = 1, lb = 0;
  for (int i = 2; i <= n; ++i) {
    if (a[i] == a[i - 1]) {
      ++num;
    } else {
      b[++lb].num = num;
      b[lb].v = a[i - 1];
      num = 1;
    }
  }
  b[++lb].num = num;
  b[lb].v = a[n];
  sort(b + 1, b + lb + 1);
  for (int i = 1; i <= lb; ++i) {
    ++sum[b[i].num];
  }
  int num_max = 0;
  int select = 0, unselect = lb, row, col;
  for (int i = 1; i * i <= n; ++i) {
    select += sum[i] * i;
    unselect -= sum[i];
    int ma = select + unselect * i;
    if (ma < i * i) {
      continue;
    }
    if (i * (ma / i) > num_max) {
      num_max = i * (ma / i);
      row = i, col = ma / i;
    }
  }
  int x = 1, y = 1;
  for (int i = 1; i <= lb; ++i) {
    num = min(row, b[i].num);
    while (num--) {
      ans[(x - 1) * col + y] = b[i].v;
      x = (x % row) + 1, y = (y % col) + 1;
      if (ans[(x - 1) * col + y]) {
        y = (y % col) + 1;
      }
    }
  }
  printf("%d\n", num_max);
  printf("%d %d\n", row, col);
  for (int i = 1; i <= row; ++i) {
    for (int j = 1; j <= col; ++j) {
      printf("%d ", ans[(i - 1) * col + j]);
    }
    putchar('\n');
  }
}
