#include <bits/stdc++.h>
using namespace std;
int in[400005];
void update(int *pen, int ind, int add) {
  assert(ind > 0);
  while (ind < 400005) {
    pen[ind] += add;
    ind += ind & (-ind);
  }
}
int query(int *pen, int ind) {
  int ret = 0;
  while (ind > 0) {
    ret += pen[ind];
    ind = ind & (ind - 1);
  }
  return ret;
}
int sum[400005], cc[400005], ret[400005];
int nextRow[400005];
void solve() {
  int n;
  scanf("%d ", &n);
  for (int i = 0; i < n; ++i) scanf("%d ", &in[i]);
  sort(in, in + n);
  vector<pair<int, int> > in2;
  for (int i = 0; i < n;) {
    int j;
    for (j = i; j < n; ++j) {
      if (in[j] != in[i]) {
        break;
      }
    }
    int len = j - i;
    update(sum, len, len);
    update(cc, len, 1);
    in2.push_back(make_pair(len, in[i]));
    i = j;
  }
  sort(in2.begin(), in2.end(), greater<pair<int, int> >());
  int p = 1, q = 1, x = 1;
  for (int row = 1; row <= n; ++row) {
    int maxEle =
        query(sum, row) + (query(cc, 400005 - 1) - query(cc, row)) * row;
    int col = maxEle / row;
    if (col < row) {
      break;
    }
    if (row * col > x) {
      p = row;
      q = col;
      x = row * col;
    }
  }
  for (int i = 0; i < p; ++i) {
    nextRow[i] = i;
  }
  int totalEle = 0, pos = 0;
  for (int i = 0; i < in2.size(); ++i) {
    int tmp = 0;
    int j;
    int a = in2[i].second;
    for (j = 0; j < in2[i].first; ++j) {
      if (tmp < p && totalEle < x) {
        ++tmp;
        ++totalEle;
        int col = pos;
        ++pos;
        if (pos == p) {
          pos = 0;
        }
        int row = nextRow[col]++;
        if (nextRow[col] == q) {
          nextRow[col] = 0;
        }
        ret[col * q + row] = a;
      }
    }
  }
  printf("%d\n%d %d\n", x, p, q);
  for (int i = 0; i < p; ++i) {
    for (int j = 0; j < q; ++j) {
      printf("%d ", ret[i * q + j]);
    }
    putchar('\n');
  }
}
int main() {
  solve();
  return 0;
}
