#include <bits/stdc++.h>
using namespace std;
bool cmp(pair<int, int> &a, pair<int, int> &b) { return a.second < b.second; }
pair<int, int> find_largest_multiplicity(map<int, int> F, int n) {
  vector<int> T, S, Vf;
  int curr_T = 0, curr_S = 0;
  int f, N;
  int sumN = 0;
  Vf.push_back(0);
  T.push_back(0);
  S.push_back(0);
  for (auto it = F.begin(); it != F.end(); it++) {
    f = it->first;
    N = it->second;
    Vf.push_back(f);
    curr_T += f * N;
    curr_S += N;
    T.push_back(curr_T);
    S.push_back(curr_S);
  }
  sumN = curr_S;
  int maxf = Vf[Vf.size() - 1];
  int k = (int)sqrt(n);
  int quantity;
  int Tk, Sk;
  int best_quantity = 0, best_k;
  while (k) {
    int idx = upper_bound(Vf.begin(), Vf.end(), k) - Vf.begin() - 1;
    Tk = T[idx];
    Sk = S[idx];
    quantity = Tk + k * (sumN - Sk);
    if (quantity >= k * k) {
      if (k * (quantity / k) > best_quantity) {
        best_k = k;
        best_quantity = k * (quantity / k);
      }
    }
    k--;
  }
  return make_pair(best_k, best_quantity);
}
int main() {
  int n, a;
  cin >> n;
  map<int, int> m;
  for (size_t i = 0; i < n; i++) {
    scanf("%d", &a);
    m[a]++;
  }
  map<int, vector<int>> F2N;
  map<int, int> F;
  for (auto p : m) {
    F2N[p.second].push_back(p.first);
    F[p.second]++;
  }
  int f, N, curr = 0;
  vector<int> T, fs;
  for (auto p : F) {
    f = p.first;
    N = p.second;
    curr += f * N - N;
    T.push_back(curr + f * f);
    fs.push_back(f);
  }
  pair<int, int> pp = find_largest_multiplicity(F, n);
  int k = pp.first;
  int quantity = pp.second;
  int height = k;
  int width = quantity / height;
  int cnt = 0;
  vector<vector<int>> mat(height, vector<int>(width));
  for (auto it = F2N.rbegin(); it != F2N.rend(); it++) {
    vector<int> v = it->second;
    f = min(it->first, k);
    for (auto x : v) {
      for (size_t i = 0; i < f; i++) {
        mat[cnt % height][cnt / height] = x;
        cnt++;
        if (cnt >= height * width) break;
      }
      if (cnt >= height * width) break;
    }
    if (cnt >= height * width) break;
  }
  cout << quantity << endl;
  cout << height << ' ' << width << endl;
  for (size_t i = 0; i < height; i++) {
    for (size_t j = 0; j < width; j++) {
      cout << mat[i][(j - i + width) % width] << ' ';
    }
    cout << endl;
  }
  return 0;
}
