#include <bits/stdc++.h>
using namespace std;
int n;
int a[400005];
unordered_map<int, int> f;
int **A;
multiset<int> s;
priority_queue<pair<int, int> > pq;
set<pair<int, int> > s2;
int main() {
  scanf("%d", &n);
  for (int i = 1; i <= n; ++i) {
    scanf("%d", &a[i]);
    ++f[a[i]];
  }
  int Sum = 0, NR = 0;
  for (int i = 1; i <= n; ++i) {
    if (f[a[i]]) {
      s.insert(f[a[i]]);
      ++NR;
      pq.push({f[a[i]], a[i]});
      f[a[i]] = 0;
    }
  }
  int Max = 0, L = 0, C = 0;
  for (int i = 1; i <= n; ++i) {
    Sum = Sum + NR;
    while (!s.empty() && *s.begin() <= i) {
      --NR;
      s.erase(s.begin());
    }
    int l = i, c = Sum / i;
    if (c < l) continue;
    if (l * c > Max) Max = l * c, L = l, C = c;
  }
  printf("%d\n", Max);
  printf("%d %d\n", L, C);
  A = new int *[L + 3];
  for (int i = 1; i <= L; ++i) A[i] = new int[C + 3];
  int ap = min(pq.top().first, L), val = pq.top().second;
  pq.pop();
  int c = 1;
  for (int i = 1; i <= C; ++i) {
    int l = 1;
    c = i;
    while (l <= L) {
      --ap;
      A[l][c] = val;
      if (ap == 0 && !pq.empty()) {
        ap = min(pq.top().first, L), val = pq.top().second;
        pq.pop();
      }
      ++l;
      ++c;
      if (c > C) c = 1;
    }
  }
  for (int i = 1; i <= L; ++i) {
    for (int j = 1; j <= C; ++j) printf("%d ", A[i][j]);
    printf("\n");
  }
  return 0;
}
