#include <bits/stdc++.h>
using namespace std;
  
#define IOS ios_base::sync_with_stdio(false);cin.tie(NULL); 
  
#define ff first
#define ss second
#define pb push_back
#define pf push_front
#define mp make_pair
#define pu push
#define pp pop_back
#define in insert
#define ld long double
 
 
#define TRACE
#ifdef TRACE
#define trace(...) __f(#__VA_ARGS__, __VA_ARGS__)
template <typename Arg1>
void __f(const char* name, Arg1&& arg1){
  cerr << name << " : " << arg1 << std::endl;
}
template <typename Arg1, typename... Args>
void __f(const char* names, Arg1&& arg1, Args&&... args){
  const char* comma = strchr(names + 1, ',');cerr.write(names, comma - names) << " : " << arg1<<" | ";__f(comma+1, args...);
}
#else
#define trace(...) 1
#endif
template<class T> ostream& operator<<(ostream &os, vector<T> V) {os << "[ "; for(auto v : V) os << v << " "; return os << "]";}
template<class L, class R> ostream& operator<<(ostream &os, pair<L,R> P) {return os << "(" << P.first << "," << P.second << ")";}
  
typedef long long int ll;
  
typedef vector<int> vi;
typedef vector<ll> vl;
typedef vector<vi> vvi;
typedef vector<vl> vvl;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
typedef vector<pii> vpii;
typedef vector<pll> vpll;
const ll maxn=20001;

struct FT {
	vector<ll> s;
	FT(int n) : s(n,0) {}
	void update(int pos, ll dif) { // a[pos] += dif
		for (; pos < (s).size(); pos |= pos + 1) s[pos] = (s[pos]+dif);
	}
	ll query(int pos) { // sum of values in [0, pos)
		ll res = 0;
		for (; pos > 0; pos &= pos - 1) res = (res+s[pos-1]);
		return res;
	}
};
void solve()
{
  ll n;
  cin>>n;
  ll a[n];
  map<ll,ll> m;
  for(ll i=0;i<n;i++)
  {
    cin>>a[i];
      m[a[i]]++;
  }
  FT bt(n+5);
  ll cnt[n+2]={0};
  vl g[n+1];
  for(auto x:m)
  {
    cnt[x.ss]++;
  }
  sort(a,a+n);
  for(ll i=0;i<n;i++)
  {
    g[m[a[i]]].pb(a[i]);
  }
  for(auto x:m)
    bt.update(x.ss,x.ss);
  for(ll i=n-1;i>=0;i--)
  {
    cnt[i]+=cnt[i+1];
  }
  ll ans_h=1,max_ans=1;
  for(ll h=1;h<=n;h++)
  { 
    ll temp=bt.query(h)+(cnt[h])*h;
    if((temp/h)>=h)
      {
        max_ans=max(max_ans,(h*(temp/h)));
        if(max_ans==(h*(temp/h)))
          ans_h=h;
      }
  }
  vl s2;
  for(ll  i=ans_h;i<=n;i++)
    { 
      set<ll> v;
      for(auto x:g[i])
        v.in(x);
      for(auto x:v)
        for(ll j=1;j<=ans_h;j++)
          s2.pb(x);
    }
  for(ll i=1;i<ans_h;i++)
  { 
    for(auto x:g[i])
      {
          s2.pb(x);
      }
  }
  
    reverse(s2.begin(),s2.end());
  ll sz=0;
  vvl ans(ans_h);
  for(ll i=0;i<ans_h;i++)
    ans[i].resize(max_ans/ans_h);
  for(ll j=0;j<max_ans/ans_h;j++)
  { 
    for(ll i=0;i<ans_h;i++)
    {
      ans[i][j]=s2[sz++];
      //trace(i,j,ans[i][j]);
    }
  }
  for(ll i=0;i<ans_h;i++)
    rotate(ans[i].begin(),ans[i].begin()+i,ans[i].end());
  cout<<max_ans<<endl<<ans_h<<" "<<max_ans/ans_h<<endl;

  for(ll i=0;i<ans_h;i++)
  {
    for(ll j=0;j<max_ans/ans_h;j++)
    {
      cout<<ans[i][j]<<" ";
    }
    assert(ans[i].end()==unique(ans[i].begin(),ans[i].end()));
    cout<<endl;
  }  
  return ;



}

int main()
{
    #ifndef ONLINE_JUDGE
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
    #endif
  IOS
  ll t;
  t=1;
  while(t--)
  {
    solve();
  }
  
 
}
  
 
 
  
 