#include <bits/stdc++.h>
#pragma GCC optimize("Ofast")
using namespace std;
vector<int> cnt[500005];
map<int, int> mp;
int n, x;
int main() {
  scanf("%d", &n);
  for (int i = 0; i < n; i++) {
    scanf("%d", &x);
    mp[x]++;
  }
  vector<int> g(n + 2);
  for (auto it : mp) cnt[it.second].push_back(it.first);
  for (int i = n; i > 0; i--) {
    g[i] = g[i + 1] + cnt[i].size();
  }
  int x, y, ans_x, ans_y, tot = 0, cur = 0;
  for (int X = 1; X <= n; X++) {
    tot += g[X];
    int Y = tot / X;
    if (X <= Y && cur < X * Y) {
      cur = X * Y;
      ans_x = X;
      ans_y = Y;
    }
  }
  printf("%d\n%d %d\n", cur, ans_y, ans_x);
  vector<vector<int> > ans(ans_x, vector<int>(ans_y));
  x = y = 0;
  for (int i = n; i >= 1; i--) {
    for (auto val : cnt[i]) {
      for (int j = 0; j < min(i, ans_x); j++) {
        if (ans[x][y] != 0) x = (x + 1) % ans_x;
        if (ans[x][y] == 0) ans[x][y] = val;
        x = (x + 1) % ans_x;
        y = (y + 1) % ans_y;
      }
    }
  }
  for (int i = 0; i < ans_y; i++) {
    for (int j = 0; j < ans_x; j++) {
      printf("%d%c", ans[j][i], " \n"[j == ans_x - 1]);
    }
  }
  return 0;
}
