#include <bits/stdc++.h>
using namespace std;
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(NULL);
  cout.tie(NULL);
  cout.precision(10);
  cout << fixed;
  long long n;
  cin >> n;
  vector<long long> v(n);
  map<long long, long long> cnt;
  for (long long i = 0; i < n; i++) {
    cin >> v[i];
    cnt[v[i]]++;
  }
  priority_queue<pair<long long, long long>> pq;
  for (auto par : cnt) pq.push({par.second, par.first});
  long long tot = n;
  long long mx = -1;
  long long cntFilas = -1;
  for (long long i = n; i >= 1; i--) {
    while (!pq.empty() && pq.top().first > i) {
      long long filas = pq.top().first;
      long long num = pq.top().second;
      pq.pop();
      tot--;
      cnt[num]--;
      if (cnt[num] != 0) pq.push({cnt[num], num});
    }
    long long filas = i;
    if (filas * pq.top().first <= tot) {
      long long realTot = tot / filas;
      realTot *= filas;
      if (mx < realTot) {
        mx = realTot;
        cntFilas = filas;
      }
    }
  }
  cnt.clear();
  for (long long i = 0; i < n; i++) cnt[v[i]]++;
  vector<pair<long long, long long>> ord;
  for (auto par : cnt) ord.push_back({min(par.second, cntFilas), par.first});
  sort(ord.rbegin(), ord.rend());
  vector<long long> toUse;
  for (auto par : ord) {
    for (long long i = 0; i < par.first; i++) toUse.push_back(par.second);
  }
  long long rows = cntFilas;
  long long cols = mx / cntFilas;
  vector<vector<long long>> ans(rows, vector<long long>(cols, 0));
  long long xx = 0;
  long long yy = 0;
  for (long long i = 0; i < mx; i++) {
    ans[xx % rows][yy % cols] = toUse[i];
    xx++;
    yy++;
    if (i == mx - 1) break;
    while (ans[xx % rows][yy % cols] != 0) yy++;
  }
  cout << rows * cols << "\n";
  cout << rows << " " << cols << "\n";
  for (long long i = 0; i < rows; i++) {
    for (long long j = 0; j < cols; j++) {
      cout << ans[i][j] << " ";
    }
    cout << "\n";
  }
  return 0;
}
