#include <bits/stdc++.h>
using namespace std;

typedef long long int ll;
typedef unsigned long long int ull;
ll power(ll x,ll y,ll p){ll r=1; x=x%p; while(y>0){ if(y&1) r= r*x%p; y=y>>1; x=x*x%p; } return r; }

#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;
typedef tree<int, null_type, less_equal<int>, rb_tree_tag, tree_order_statistics_node_update> ordered_set;

mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
int csrand(int l=0, int r=1e9){
    uniform_int_distribution<int> uid(l, r);
    return uid(rng);
}

#define PR(x) cout<<#x<<" : "<<x<<"\n";
#define PR1(x,y) cout<<#x<<" : "<<x<<"  |  "<<#y<<" : "<<y<<"\n";
#define PR2(x,y,z) cout<<#x<<" : "<<x<<"  |  "<<#y<<" : "<<y<<"  |  "<<#z<<" : "<<z<<"\n";
#define ED cout<<'\n';

#define IO              ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define FILEIO          freopen("input.txt", "r", stdin);freopen("output.txt", "w", stdout);
#define all(v)          v.begin(),v.end()
#define endl            '\n'
#define fr1(j,n)        for(int j=0;j<n;j++)
// #define fr(n)           for(int i=0;i<n;i++)
#define PB              push_back
#define pii             pair<int,int>
#define pll             pair<long long int,long long int>
#define F               first
#define S               second

const ll mod=1e9+7;
const ll mod9=998244353;
const int N=4e5+99;

ll arr[N],sum[N];
vector<ll> fq;

ll chk(ll rr,ll cc)
{
    ll mi=min(rr,cc);
    ll ii=upper_bound(all(fq),mi)-fq.begin();

    ll tot=0;
    if(ii) tot=sum[ii-1];
    ll ss=(fq.size()-ii);
    tot = ss*mi + tot;
    return tot;
}

int main()
{
    IO
    #ifndef ONLINE_JUDGE
    FILEIO
    #endif

    ll n;
    cin>>n;
    map<ll,ll> mp;

    ll mx=0,sz=0;
    fr1(i,n)
    {
        cin>>arr[i];
        mp[arr[i]]++;
        mx=max(mx,mp[arr[i]]);
    }

    sz=mp.size();
    for(auto x:mp) fq.PB(x.S);
    sort(all(fq));

    for(int i=0;i<sz;i++)
    {
        sum[i]=fq[i];
        if(i) sum[i]+=sum[i-1];
    }

    ll fc=1,fr=1,ar=1;
    for(ll rr=1;rr<=min(sz,n);rr++)
    {

        ll lo=1,hi=n/rr,mi,ans;

        while(lo<=hi)
        {
            mi=(lo+hi)/2;

            if( sz>=(ll)max(rr,mi) && chk(rr,mi)>=rr*mi)
                ans=mi,
                lo=mi+1;
            else
                hi=mi-1;
        }
        if(rr*ans > ar)
        {
            ar=rr*ans;
            fr=rr;
            fc=ans;
        }
    }

    if(fr>fc) swap(fr,fc);

    ll ans[fr][fc];

    fr1(i,fr)fr1(j,fc)ans[i][j]=0;

    cout<<fr*fc<<endl;
    cout<<fr<<" "<<fc<<endl;
    vector<pii> pos;

    for(int c=0;c<fc;c++)
    {
        int r=0;
        for(int i=0;i<fr;i++)
        {
            pos.PB({i+r,(c+i)%fc});
        }
    }
    reverse(all(pos));

    for(auto x:mp)
    {
        fr1(i,min(x.S,fr))
        {
            if(pos.empty()) break;
            auto xx=pos.back();
            pos.pop_back();
            ans[xx.F][xx.S]=x.F;
        }
        if(pos.empty()) break;
    }

    fr1(i,fr)
    {
        fr1(j,fc)
        cout<<ans[i][j]<<" ";
        ED
    }

}


#include <bits/stdc++.h>

using namespace std;

map<int,int> amap,omap;
int a[400005],b[400005];
int occ[400005];
vector<pair<int,int>> avec;
int **ans;

bool compq(const pair<int,int>& a, const pair<int,int>& b){
    return a.first>b.first;
}

bool cmpo(const int& a, const int& b){
    return omap[a]<omap[b];
}

int main(){
    ios::sync_with_stdio(0);
    int n;
    cin >> n;
    for(int i = 0; i<n; i++){
        cin >> a[i];
        amap[a[i]]++;
    }
    for(auto it:amap)
        avec.push_back({it.second,it.first});
    sort(avec.begin(),avec.end(),compq);
    int usz = (int)avec.size();
    for(int i = 0; i<usz; i++){
        omap[avec[i].second] = i;
        for(int j = 0; j<avec[i].first; j++)
            occ[j+1]++;
    }
    avec.push_back({0,-1});
    int p = 0;
    for(int i = 1; i<=n; i++){
        if(avec[p].first){
            b[i] = avec[p].second;
            avec[p].first--;
            p++;
        }else{
            p = 0;
            i--;
        }
    }
    int amt = 0;
    int bans = 0, br = 0, bc = 0;
    for(int i = 1; i<=n; i++){
        amt+=occ[i];
        int c = i;
        int r = max(c,amt/c);
        if(r*c<=amt&&r*c>bans){
            bans = r*c;
            br = r;
            bc = c;
        }
    }
    cout << bans << "\n" << br << " " << bc << "\n";
    sort(b+1,b+bans+1,cmpo);
    int ir = 0, ic = 0;
    ans = new int*[br];
    for(int i = 0; i<br; i++){
        ans[i] = new int[bc];
        for(int j = 0; j<bc; j++)
            ans[i][j] = -1;
    }
    for(int i = 0; i<bans; i++){
        ans[ir][ic] = b[i+1];
        ir = (ir+1)%br;
        ic = (ic+1)%bc;
        if(ans[ir][ic] != -1){
            ic = (ic+1)%bc;
        }
    }
    for(int i = 0; i<br; i++){
        for(int j = 0; j<bc; j++)
            cout << ans[i][j] << " ";
        cout << endl;
    }
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

map<int,int> amap;
int a[400005],b[400005];
int pref[400005],occ[400005];
vector<pair<int,int>> avec;
int **ans;

bool compq(const pair<int,int>& a, const pair<int,int>& b){
    return a.first>b.first;
}

int mysqrt(int a){
    long long s = 1,e = a;
    int ans = -1;
    while(s<=e){
        long long m = (s+e)/2;
        if(m*m<=a){
            ans = m;
            s = m+1;
        }else
            e = m-1;
    }
    return ans;
}

int main(){
    ios::sync_with_stdio(0);
    int n;
    cin >> n;
    for(int i = 0; i<n; i++){
        cin >> a[i];
        amap[a[i]]++;
    }
    for(auto it:amap)
        avec.push_back({it.second,it.first});
    sort(avec.begin(),avec.end(),compq);
    int usz = (int)avec.size();
    avec.push_back({0,-1});
    int p = 0;
    for(int i = 1; i<=n; i++){
        if(avec[p].first){
            b[i] = avec[p].second;
            avec[p].first--;
            p++;
        }else{
            p = 0;
            i--;
        }
    }
    int amt = 0;
    int bans = 0, br = 0, bc = 0;
    for(int i = 1; i<=n; i++){
        if(b[i]==b[1])
            amt++;
        int c = amt;
        int r = max(c,i/c);
        if(r*c>bans&&r*c<=i){
            bans = r*c;
            br = r;
            bc = c;
        }
    }
    cout << bans << "\n" << br << " " << bc << "\n";
    sort(b+1,b+bans+1);
    int ir = 0, ic = 0;
    ans = new int*[br];
    for(int i = 0; i<br; i++){
        ans[i] = new int[bc];
        for(int j = 0; j<bc; j++)
            ans[i][j] = -1;
    }
    for(int i = 0; i<bans; i++){
        ans[ir][ic] = b[i+1];
        ir = (ir+1)%br;
        ic = (ic+1)%bc;
        if(ans[ir][ic] != -1)
            ir = (ir+1)%br;
    }
    for(int i = 0; i<br; i++){
        for(int j = 0; j<bc; j++)
            cout << ans[i][j] << " ";
        cout << endl;
    }
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

map<int,int> amap;
int a[400005],b[400005];
int pref[400005],occ[400005];
vector<pair<int,int>> avec;
int **ans;

bool compq(const pair<int,int>& a, const pair<int,int>& b){
    return a.first>b.first;
}

int mysqrt(int a){
    long long s = 1,e = a;
    int ans = -1;
    while(s<=e){
        long long m = (s+e)/2;
        if(m*m<=a){
            ans = m;
            s = m+1;
        }else
            e = m-1;
    }
    return ans;
}

int main(){
    ios::sync_with_stdio(0);
    int n;
    cin >> n;
    for(int i = 0; i<n; i++){
        cin >> a[i];
        amap[a[i]]++;
    }
    for(auto it:amap)
        avec.push_back({it.second,it.first});
    sort(avec.begin(),avec.end(),compq);
    int usz = (int)avec.size();
    avec.push_back({0,-1});
    int p = 0;
    for(int i = 1; i<=n; i++){
        if(avec[p].first){
            b[i] = avec[p].second;
            avec[p].first--;
            p++;
        }else{
            p = 0;
            i--;
        }
    }
    int amt = 0;
    int bans = 0, br = 0, bc = 0;
    for(int i = 1; i<=n; i++){
        if(b[i]==b[1])
            amt++;
        int c = amt;
        int r = max(c,i/c);
        if(r*c>bans&&r*c<=i){
            bans = r*c;
            br = r;
            bc = c;
        }
    }
    cout << bans << "\n" << br << " " << bc << "\n";
    sort(b+1,b+bans+1);
    int ir = 0, ic = 0;
    ans = new int*[br];
    for(int i = 0; i<br; i++){
        ans[i] = new int[bc];
        for(int j = 0; j<bc; j++)
            ans[i][j] = -1;
    }
    for(int i = 0; i<bans; i++){
        ans[ir][ic] = b[i+1];
        ir = (ir+1)%br;
        ic = (ic+1)%bc;
        if(ans[ir][ic] != -1){
            ic = (ic+1)%bc;
        }
    }
    for(int i = 0; i<br; i++){
        for(int j = 0; j<bc; j++)
            cout << ans[i][j] << " ";
        cout << endl;
    }
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

map<int,int> amap;
int a[400005],b[400005];
int pref[400005],occ[400005];
vector<pair<int,int>> avec;
int **ans;

bool compq(const pair<int,int>& a, const pair<int,int>& b){
    return a.first>b.first;
}

int mysqrt(int a){
    long long s = 1,e = a;
    int ans = -1;
    while(s<=e){
        long long m = (s+e)/2;
        if(m*m<=a){
            ans = m;
            s = m+1;
        }else
            e = m-1;
    }
    return ans;
}

int main(){
    ios::sync_with_stdio(0);
    int n;
    cin >> n;
    for(int i = 0; i<n; i++){
        cin >> a[i];
        amap[a[i]]++;
    }
    for(auto it:amap)
        avec.push_back({it.second,it.first});
    sort(avec.begin(),avec.end(),compq);
    int usz = (int)avec.size();
    avec.push_back({0,-1});
    int p = 0;
    for(int i = 1; i<=n; i++){
        if(avec[p].first){
            b[i] = avec[p].second;
            avec[p].first--;
            p++;
        }else{
            p = 0;
            i--;
        }
    }
    int amt = 0;
    int bans = 0, br = 0, bc = 0;
    for(int i = 1; i<=n; i++){
        if(b[i]==b[1])
            amt++;
        int c = amt;
        int r = max(c,i/c);
        if(r*c>bans&&r*c<=i){
            bans = r*c;
            br = r;
            bc = c;
        }
    }
    cout << bans << "\n" << br << " " << bc << "\n";
    sort(b+1,b+bans+1);
    int ir = 0, ic = 0;
    ans = new int*[br];
    for(int i = 0; i<br; i++)
        ans[i] = new int[bc];
    for(int i = 0; i<bans; i++){
        ans[ir][ic] = b[i+1];
        ir = (ir+1)%br;
        ic = (ic+1)%bc;
    }
    for(int i = 0; i<br; i++){
        for(int j = 0; j<bc; j++)
            cout << ans[i][j] << " ";
        cout << endl;
    }
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

map<int,int> amap;
int a[400005],b[400005];
int occ[400005];
vector<pair<int,int>> avec;
int **ans;

bool compq(const pair<int,int>& a, const pair<int,int>& b){
    return a.first>b.first;
}

int main(){
    int n;
    scanf("%d",&n);
    for(int i = 0; i<n; i++){
        scanf("%d",&a[i]);
        amap[a[i]]++;
    }
    for(auto it:amap)
        avec.push_back({it.second,it.first});
    sort(avec.begin(),avec.end(),compq);
    int usz = (int)avec.size();
    for(int i = 0; i<usz; i++){
        for(int j = 0; j<avec[i].first; j++)
            occ[j+1]++;
    }
    avec.push_back({0,-1});
    int amt = 0;
    int bans = 0, br = 0, bc = 0;
    for(int i = 1; i<=n; i++){
        amt+=occ[i];
        int c = i;
        int r = amt/c;
        if(r>=c&&r*c>bans){
            bans = r*c;
            br = r;
            bc = c;
        }
    }
    printf("%d\n%d %d\n",bans,br,bc);
    int p = 0;
    for(int i = 0; i<usz; i++){
        for(int j = 0; j<min(bc,avec[i].first); j++)
            b[p++] = avec[i].second;
    }
    int ir = 0, ic = 0;
    ans = new int*[br];
    for(int i = 0; i<br; i++){
        ans[i] = new int[bc];
        for(int j = 0; j<bc; j++)
            ans[i][j] = -1;
    }
    for(int i = 0; i<bans; i++){
        ans[ir][ic] = b[i];
        ir = (ir+1)%br;
        ic = (ic+1)%bc;
        if(ans[ir][ic] != -1){
            ic = (ic+1)%bc;
        }
    }
    for(int i = 0; i<br; i++){
        for(int j = 0; j<bc; j++)
            printf("%d ",ans[i][j]);
        printf("\n");
    }
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

map<int,int> amap;
int a[400005],b[400005];
int pref[400005],occ[400005];
vector<pair<int,int>> avec;
int **ans;

bool compq(const pair<int,int>& a, const pair<int,int>& b){
    return a.first>b.first;
}

int mysqrt(int a){
    long long s = 1,e = a;
    int ans = -1;
    while(s<=e){
        long long m = (s+e)/2;
        if(m*m<=a){
            ans = m;
            s = m+1;
        }else
            e = m-1;
    }
    return ans;
}

int main(){
    ios::sync_with_stdio(0);
    int n;
    cin >> n;
    for(int i = 0; i<n; i++){
        cin >> a[i];
        amap[a[i]]++;
    }
    for(auto it:amap)
        avec.push_back({it.second,it.first});
    sort(avec.begin(),avec.end(),compq);
    int usz = (int)avec.size();
    avec.push_back({0,-1});
    int p = 0;
    for(int i = 1; i<=n; i++){
        if(avec[p].first){
            b[i] = avec[p].second;
            avec[p].first--;
            p++;
        }else{
            p = 0;
            i--;
        }
    }
    int amt = 0;
    int bans = 0, br = 0, bc = 0;
    for(int i = 1; i<=n; i++){
        if(b[i]==b[1])
            amt++;
        int c = amt;
        int r = max(c,i/c);
        if(r*c>bans&&r*c<=i){
            bans = r*c;
            br = r;
            bc = c;
        }
    }
    cout << bans << "\n" << bc << " " << br << "\n";
    sort(b+1,b+bans+1);
    int ir = 0, ic = 0;
    ans = new int*[br];
    for(int i = 0; i<br; i++)
        ans[i] = new int[bc];
    for(int i = 0; i<bans; i++){
        ans[ir][ic] = b[i+1];
        ir = (ir+1)%br;
        ic = (ic+1)%bc;
    }
    for(int i = 0; i<br; i++){
        for(int j = 0; j<bc; j++)
            cout << ans[i][j] << " ";
        cout << endl;
    }
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

map<int,int> amap;
int a[400005],b[400005];
int pref[400005],occ[400005];
vector<pair<int,int>> avec;
int **ans;

bool compq(const pair<int,int>& a, const pair<int,int>& b){
    return a.first>b.first;
}

int mysqrt(int a){
    long long s = 1,e = a;
    int ans = -1;
    while(s<=e){
        long long m = (s+e)/2;
        if(m*m<=a){
            ans = m;
            s = m+1;
        }else
            e = m-1;
    }
    return ans;
}

int main(){
    ios::sync_with_stdio(0);
    int n;
    cin >> n;
    for(int i = 0; i<n; i++){
        cin >> a[i];
        amap[a[i]]++;
    }
    for(auto it:amap)
        avec.push_back({it.second,it.first});
    sort(avec.begin(),avec.end(),compq);
    int usz = (int)avec.size();
    avec.push_back({0,-1});
    int p = 0;
    for(int i = 1; i<=n; i++){
        if(avec[p].first){
            b[i] = avec[p].second;
            avec[p].first--;
            p++;
        }else{
            p = 0;
            i--;
        }
    }
    int amt = 0;
    int bans = 0, br = 0, bc = 0;
    for(int i = 1; i<=n; i++){
        if(b[i]==b[1])
            amt++;
        int c = amt;
        int r = max(c,i/c);
        if(r*c>bans&&r*c<=i){
            bans = r*c;
            br = r;
            bc = c;
        }
    }
    cout << bans << "\n" << br << " " << bc << "\n";
    sort(b+1,b+bans+1);
    int ir = 0, ic = 0;
    ans = new int*[br];
    for(int i = 0; i<br; i++){
        ans[i] = new int[bc];
        for(int j = 0; j<bc; j++)
            ans[i][j] = -1;
    }
    for(int i = 0; i<bans; i++){
        ans[ir][ic] = b[i+1];
        ir = (ir+1)%br;
        ic = (ic+1)%bc;
        if(ans[ir][ic] != -1){
            ic = (ic+2)%bc;
            ir = (ir+1)%br;
        }
    }
    for(int i = 0; i<br; i++){
        for(int j = 0; j<bc; j++)
            cout << ans[i][j] << " ";
        cout << endl;
    }
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

map<int,int> amap,omap;
int a[400005],b[400005];
vector<pair<int,int>> avec;
int **ans;

bool compq(const pair<int,int>& a, const pair<int,int>& b){
    return a.first>b.first;
}

bool cmpo(const int& a, const int& b){
    return omap[a]<omap[b];
}

int mysqrt(int a){
    long long s = 1,e = a;
    int ans = -1;
    while(s<=e){
        long long m = (s+e)/2;
        if(m*m<=a){
            ans = m;
            s = m+1;
        }else
            e = m-1;
    }
    return ans;
}

int main(){
    ios::sync_with_stdio(0);
    int n;
    cin >> n;
    for(int i = 0; i<n; i++){
        cin >> a[i];
        amap[a[i]]++;
    }
    for(auto it:amap)
        avec.push_back({it.second,it.first});
    sort(avec.begin(),avec.end(),compq);
    int usz = (int)avec.size();
    for(int i = 0; i<usz; i++)
        omap[avec[i].second] = i;
    avec.push_back({0,-1});
    int p = 0;
    for(int i = 1; i<=n; i++){
        if(avec[p].first){
            b[i] = avec[p].second;
            avec[p].first--;
            p++;
        }else{
            p = 0;
            i--;
        }
    }
    int amt = 0;
    int bans = 0, br = 0, bc = 0;
    for(int i = 1; i<=n; i++){
        if(b[i]==b[1])
            amt++;
        int c = amt;
        int r = max(c,i/c);
        if(r*c>bans&&r*c<=i){
            bans = r*c;
            br = r;
            bc = c;
        }
    }
    cout << bans << "\n" << br << " " << bc << "\n";
    sort(b+1,b+bans+1,cmpo);
    int ir = 0, ic = 0;
    ans = new int*[br];
    for(int i = 0; i<br; i++){
        ans[i] = new int[bc];
        for(int j = 0; j<bc; j++)
            ans[i][j] = -1;
    }
    for(int i = 0; i<bans; i++){
        ans[ir][ic] = b[i+1];
        ir = (ir+1)%br;
        ic = (ic+1)%bc;
        if(ans[ir][ic] != -1){
            ic = (ic+1)%bc;
        }
    }
    for(int i = 0; i<br; i++){
        for(int j = 0; j<bc; j++)
            cout << ans[i][j] << " ";
        cout << endl;
    }
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

map<int,int> amap;
int a[400005],b[400005];
int occ[400005];
vector<pair<int,int>> avec;
int **ans;

bool compq(const pair<int,int>& a, const pair<int,int>& b){
    return a.first>b.first;
}

int main(){
    ios::sync_with_stdio(0);
    int n;
    cin >> n;
    for(int i = 0; i<n; i++){
        cin >> a[i];
        amap[a[i]]++;
    }
    for(auto it:amap)
        avec.push_back({it.second,it.first});
    sort(avec.begin(),avec.end(),compq);
    int usz = (int)avec.size();
    for(int i = 0; i<usz; i++){
        for(int j = 0; j<avec[i].first; j++)
            occ[j+1]++;
    }
    avec.push_back({0,-1});
    int amt = 0;
    int bans = 0, br = 0, bc = 0;
    for(int i = 1; i<=n; i++){
        amt+=occ[i];
        int c = i;
        int r = max(c,amt/c);
        if(r*c<=amt&&r*c>bans){
            bans = r*c;
            br = r;
            bc = c;
        }
    }
    cout << bans << "\n" << br << " " << bc << "\n";
    int p = 0;
    for(int i = 0; i<usz; i++){
        for(int j = 0; j<min(bc,avec[i].first); j++)
            b[p++] = avec[i].second;
    }
    int ir = 0, ic = 0;
    ans = new int*[br];
    for(int i = 0; i<br; i++){
        ans[i] = new int[bc];
        for(int j = 0; j<bc; j++)
            ans[i][j] = -1;
    }
    for(int i = 0; i<bans; i++){
        ans[ir][ic] = b[i];
        ir = (ir+1)%br;
        ic = (ic+1)%bc;
        if(ans[ir][ic] != -1){
            ic = (ic+1)%bc;
        }
    }
    for(int i = 0; i<br; i++){
        for(int j = 0; j<bc; j++)
            cout << ans[i][j] << " ";
        cout << '\n';
    }
    return 0;
}


#include <bits/stdc++.h>
using namespace std;

namespace debug{
    void __(short x){cout<<x;}
    void __(unsigned x){cout<<x;}
    void __(int x){cout<<x;}
    void __(long long x){cout<<x;}
    void __(unsigned long long x){cout<<x;}
    void __(double x){cout<<x;}
    void __(long double x){cout<<x;}
    void __(char x){cout<<x;}
    void __(const char*x){cout<<x;}
    void __(const string&x){cout<<x;}
    void __(bool x){cout<<(x?"true":"false");}
    template<class P1,class P2>
    void __(const pair<P1,P2>&x){__("("),__(x.first),__(", "),__(x.second),__(")");}
    template<class T>
    void __(const vector<T>&x){__("{");bool _ffs=0;for(const auto&v:x)__(_ffs?", ":""),__(v),_ffs=1;__("}");}
    template<class T>
    void __(const set<T>&x){__("{");bool _ffs=0;for(const auto&v:x)__(_ffs?", ":""),__(v),_ffs=1;__("}");}
    template<class T,class T2>
    void __(const map<T,T2>&x){__("{");bool _ffs=0;for(const auto&v:x)__(_ffs?", ":""),__(make_pair(v.first,v.second)),_ffs=1;__("}");}
    void screm(){__("\n");}
    template<class T1,class... T2>
    void screm(const T1&t1,const T2&...t2){__(t1);if(sizeof...(t2))__(" | "),screm(t2...);else __("\n");}
    void pr(){__("\n");}
    template<class T1,class... T2>
    void pr(const T1&t1,const T2&...t2){__(t1);if(sizeof...(t2))__(" "),pr(t2...);else __("\n");}

}

using namespace debug;

typedef long long ll;
typedef long double ld;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
typedef pair<double,double> pdd;
typedef pair<ld,ld> pld;
typedef vector<int> vi;
typedef vector<ll> vl;

#define pb push_back
#define fox(i,x,y) for(int i=(x);i<=(y);i++)
#define foxr(i,x,y) for(int i=(x);i>=(y);i--)

const int MN = 4e5+5;
int n, i, j, k, ans, kk, x, y;
map<int,int> cnt; vi arr;
vector<vi> sna;

int main(){
    scanf("%d",&n);
    fox(i,1,n){
        arr.pb(0);
        scanf("%d",&arr.back());
        cnt[arr[i-1]]++;
    }
    sort(arr.begin(),arr.end());
    arr.erase(unique(arr.begin(),arr.end()),arr.end());
    int s = ceil(sqrt(n+0.0));
    fox(k,1,s){
        int sm = 0;
        for(auto v : arr){
            sm += min(k,cnt[v]);
        }
        if(k*k<=sm){
            if(ans<sm){
                ans = sm;
                kk = k;
            }
        }
    }
    int rr = ans/kk;
    printf("%d\n%d %d\n",rr*kk,kk,rr);
    fox(i,1,kk){
        sna.pb(vi());
        sna.back().resize(rr);
    }
    int ct = rr*kk;
    for(auto v : arr){
        int cc = min(kk,cnt[v]);
        while(cc--&&ct){
            sna[x][y]=v;
            x++, y=(y+1)%rr;
            if(x==kk){
                x = 0;
                y -= kk-1;
                if(y<0) y+=rr;
            }
            ct--;
        }
    }
    for(i=0;i<kk;i++){
        for(j=0;j<rr;j++){
            printf("%d ",sna[i][j]);
        }
        printf("\n");
    }
    return 0;
}


#include <bits/stdc++.h>
using namespace std;

namespace debug{
    void __(short x){cout<<x;}
    void __(unsigned x){cout<<x;}
    void __(int x){cout<<x;}
    void __(long long x){cout<<x;}
    void __(unsigned long long x){cout<<x;}
    void __(double x){cout<<x;}
    void __(long double x){cout<<x;}
    void __(char x){cout<<x;}
    void __(const char*x){cout<<x;}
    void __(const string&x){cout<<x;}
    void __(bool x){cout<<(x?"true":"false");}
    template<class P1,class P2>
    void __(const pair<P1,P2>&x){__("("),__(x.first),__(", "),__(x.second),__(")");}
    template<class T>
    void __(const vector<T>&x){__("{");bool _ffs=0;for(const auto&v:x)__(_ffs?", ":""),__(v),_ffs=1;__("}");}
    template<class T>
    void __(const set<T>&x){__("{");bool _ffs=0;for(const auto&v:x)__(_ffs?", ":""),__(v),_ffs=1;__("}");}
    template<class T,class T2>
    void __(const map<T,T2>&x){__("{");bool _ffs=0;for(const auto&v:x)__(_ffs?", ":""),__(make_pair(v.first,v.second)),_ffs=1;__("}");}
    void screm(){__("\n");}
    template<class T1,class... T2>
    void screm(const T1&t1,const T2&...t2){__(t1);if(sizeof...(t2))__(" | "),screm(t2...);else __("\n");}
    void pr(){__("\n");}
    template<class T1,class... T2>
    void pr(const T1&t1,const T2&...t2){__(t1);if(sizeof...(t2))__(" "),pr(t2...);else __("\n");}

}

using namespace debug;

typedef long long ll;
typedef long double ld;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
typedef pair<double,double> pdd;
typedef pair<ld,ld> pld;
typedef vector<int> vi;
typedef vector<ll> vl;

#define pb push_back
#define fox(i,x,y) for(int i=(x);i<=(y);i++)
#define foxr(i,x,y) for(int i=(x);i>=(y);i--)

const int MN = 4e5+5;
int n, i, j, k, ans, kk, x, y;
map<int,int> cnt; vi arr;
vector<vi> sna;

int main(){
    scanf("%d",&n);
    fox(i,1,n){
        arr.pb(0);
        scanf("%d",&arr.back());
        cnt[arr[i-1]]++;
    }
    sort(arr.begin(),arr.end());
    arr.erase(unique(arr.begin(),arr.end()),arr.end());
    int s = sqrt(n+0.0);
    fox(k,1,s){
        int sm = 0;
        for(auto v : arr){
            sm += min(k,cnt[v]);
        }
        if(k*k<=sm){
            if(ans<sm){
                ans = sm;
                kk = k;
            }
        }
    }
    int rr = ans/kk;
    printf("%d\n%d %d\n",rr*kk,kk,rr);
    fox(i,1,kk){
        sna.pb(vi());
        sna.back().resize(rr);
    }
    for(auto v : arr){
        int cc = min(kk,cnt[v]);
        while(cc--){
            sna[x][y]=v;
            x++, y=(y+1)%rr;
            if(x==kk){
                x = 0;
                y -= kk-1;
                if(y<0) y+=rr;
            }
        }
    }
    for(i=0;i<kk;i++){
        for(j=0;j<rr;j++){
            printf("%d ",sna[i][j]);
        }
        printf("\n");
    }
    return 0;
}


#include <bits/stdc++.h>
using namespace std;

namespace debug{
    void __(short x){cout<<x;}
    void __(int x){cout<<x;}
    void __(long long x){cout<<x;}
    void __(unsigned long long x){cout<<x;}
    void __(double x){cout<<x;}
    void __(long double x){cout<<x;}
    void __(char x){cout<<x;}
    void __(const char*x){cout<<x;}
    void __(const string&x){cout<<x;}
    void __(bool x){cout<<(x?"true":"false");}
    template<class P1,class P2>
    void __(const pair<P1,P2>&x){__("("),__(x.first),__(", "),__(x.second),__(")");}
    template<class T>
    void __(const vector<T>&x){__("{");bool _ffs=0;for(const auto&v:x)__(_ffs?", ":""),__(v),_ffs=1;__("}");}
    void screm(){__("\n");}
    template<class T1,class... T2>
    void screm(const T1&t1,const T2&...t2){__(t1);if(sizeof...(t2))__(" | "),screm(t2...);else __("\n");}
    void pr(){__("\n");}
    template<class T1,class... T2>
    void pr(const T1&t1,const T2&...t2){__(t1);if(sizeof...(t2))__(" "),pr(t2...);else __("\n");}
}

using namespace debug;

typedef long long ll;
typedef long double ld;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
typedef pair<double,double> pdd;
typedef pair<ld,ld> pld;
typedef vector<int> vi;
typedef vector<ll> vl;

#define pb push_back
#define fox(i,x,y) for(int i=(x);i<=(y);i++)

const int MN = 4e5+5;
int n, i, j, k, ans, kk, x, y;
map<int,int> cnt; vi arr;
vector<vi> sna;

int main(){
    scanf("%d",&n);
    fox(i,1,n){
        arr.pb(0);
        scanf("%d",&arr.back());
        cnt[arr[i-1]]++;
    }
    sort(arr.begin(),arr.end());
    arr.erase(unique(arr.begin(),arr.end()),arr.end());
    int s = ceil(sqrt(n+0.0));
    fox(k,1,s){
        int sm = 0;
        for(auto v : arr){
            sm += min(k,cnt[v]);
        }
        if(k*k<=sm){
            int rr = (sm/k);
            if(ans<k*rr){
                ans = k*rr;
                kk = k;
            }
        }
    }
    int rr = ans/kk;
    printf("%d\n%d %d\n",rr*kk,kk,rr);
    fox(i,1,kk){
        sna.pb(vi());
        sna.back().resize(rr);
    }
    int ct = rr*kk;
    for(auto v : arr){
        int cc = min(kk,cnt[v]);
        while(cc--&&ct){
            sna[x%kk][y%rr]=v;
            x++, y++;
            if(x==kk){
                x = 0;
                y -= kk-1;
            }
            ct--;
        }
    }
    for(i=0;i<kk;i++){
        for(j=0;j<rr;j++){
            printf("%d ",sna[i][j]);
        }
        printf("\n");
    }
    return 0;
}


#include <bits/stdc++.h>
using namespace std;

namespace debug{
    void __(short x){cout<<x;}
    void __(int x){cout<<x;}
    void __(long long x){cout<<x;}
    void __(unsigned long long x){cout<<x;}
    void __(double x){cout<<x;}
    void __(long double x){cout<<x;}
    void __(char x){cout<<x;}
    void __(const char*x){cout<<x;}
    void __(const string&x){cout<<x;}
    void __(bool x){cout<<(x?"true":"false");}
    template<class P1,class P2>
    void __(const pair<P1,P2>&x){__("("),__(x.first),__(", "),__(x.second),__(")");}
    template<class T>
    void __(const vector<T>&x){__("{");bool _ffs=0;for(const auto&v:x)__(_ffs?", ":""),__(v),_ffs=1;__("}");}
    void screm(){__("\n");}
    template<class T1,class... T2>
    void screm(const T1&t1,const T2&...t2){__(t1);if(sizeof...(t2))__(" | "),screm(t2...);else __("\n");}
    void pr(){__("\n");}
    template<class T1,class... T2>
    void pr(const T1&t1,const T2&...t2){__(t1);if(sizeof...(t2))__(" "),pr(t2...);else __("\n");}
}

using namespace debug;

typedef long long ll;
typedef long double ld;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
typedef pair<double,double> pdd;
typedef pair<ld,ld> pld;
typedef vector<int> vi;
typedef vector<ll> vl;

#define pb push_back
#define fox(i,x,y) for(int i=(x);i<=(y);i++)

const int MN = 4e5+5;
int n, i, j, k, ans, kk, x, y, cnt[MN];
map<int,int> mp, rev; vi arr;
vector<vi> sna;

int main(){
    scanf("%d",&n);
    fox(i,1,n){
        arr.pb(0);
        scanf("%d",&arr.back());
        mp[arr[i-1]];
    }
    i=0;
    for(auto it=mp.begin();it!=mp.end();it++){
        it->second = ++i;
        rev[i] = it->first;
    }
    for(i=0;i<n;i++) arr[i]=mp[arr[i]], cnt[arr[i]]++;
    sort(arr.begin(),arr.end());
    arr.erase(unique(arr.begin(),arr.end()),arr.end());
    int s = ceil(sqrt(n+0.0));
    fox(k,1,s){
        int sm = 0;
        for(auto v : arr){
            sm += min(k,cnt[v]);
        }
        if(k*k<=sm){
            int rr = sm/k;
            if(ans<rr*k){
                ans = rr*k;
                kk = k;
            }
        }
    }
    int rr = ans/kk;
    printf("%d\n%d %d\n",rr*kk,kk,rr);
    fox(i,1,kk){
        sna.pb(vi());
        sna.back().resize(rr);
    }
    srand(time(0));
    sort(arr.begin(),arr.end(),[](int i,int j){return cnt[i]>cnt[j];});
    int ct = rr*kk;
    for(auto v : arr){
        int cc = min(kk,cnt[v]);
        int heh = rev[v];
        while(cc--&&ct){
            sna[x%kk][y%rr]=heh;
            x++, y++;
            if(x==kk){
                x = 0;
                y -= kk-1;
            }
            ct--;
        }
    }
    for(i=0;i<kk;i++){
        for(j=0;j<rr;j++){
            printf("%d ",sna[i][j]);
        }
        printf("\n");
    }
    return 0;
}


#include <bits/stdc++.h>
using namespace std;

namespace debug{
    void __(short x){cout<<x;}
    void __(unsigned x){cout<<x;}
    void __(int x){cout<<x;}
    void __(long long x){cout<<x;}
    void __(unsigned long long x){cout<<x;}
    void __(double x){cout<<x;}
    void __(long double x){cout<<x;}
    void __(char x){cout<<x;}
    void __(const char*x){cout<<x;}
    void __(const string&x){cout<<x;}
    void __(bool x){cout<<(x?"true":"false");}
    template<class P1,class P2>
    void __(const pair<P1,P2>&x){__("("),__(x.first),__(", "),__(x.second),__(")");}
    template<class T>
    void __(const vector<T>&x){__("{");bool _ffs=0;for(const auto&v:x)__(_ffs?", ":""),__(v),_ffs=1;__("}");}
    template<class T>
    void __(const set<T>&x){__("{");bool _ffs=0;for(const auto&v:x)__(_ffs?", ":""),__(v),_ffs=1;__("}");}
    template<class T,class T2>
    void __(const map<T,T2>&x){__("{");bool _ffs=0;for(const auto&v:x)__(_ffs?", ":""),__(make_pair(v.first,v.second)),_ffs=1;__("}");}
    void screm(){__("\n");}
    template<class T1,class... T2>
    void screm(const T1&t1,const T2&...t2){__(t1);if(sizeof...(t2))__(" | "),screm(t2...);else __("\n");}
    void pr(){__("\n");}
    template<class T1,class... T2>
    void pr(const T1&t1,const T2&...t2){__(t1);if(sizeof...(t2))__(" "),pr(t2...);else __("\n");}

}

using namespace debug;

typedef long long ll;
typedef long double ld;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
typedef pair<double,double> pdd;
typedef pair<ld,ld> pld;
typedef vector<int> vi;
typedef vector<ll> vl;

#define pb push_back
#define fox(i,x,y) for(int i=(x);i<=(y);i++)
#define foxr(i,x,y) for(int i=(x);i>=(y);i--)

const int MN = 4e5+5;
int n, i, j, k, ans, kk, x, y;
map<int,int> cnt; vi arr;
vector<vi> sna;

int main(){
    scanf("%d",&n);
    fox(i,1,n){
        arr.pb(0);
        scanf("%d",&arr.back());
        cnt[arr[i-1]]++;
    }
    sort(arr.begin(),arr.end());
    arr.erase(unique(arr.begin(),arr.end()),arr.end());
    int s = ceil(sqrt(n+0.0));
    fox(k,1,s){
        int sm = 0;
        for(auto v : arr){
            sm += min(k,cnt[v]);
        }
        if(k*k<=sm){
            if(ans<sm){
                ans = sm;
                kk = k;
            }
        }
    }
    int rr = ans/kk;
    printf("%d\n%d %d\n",rr*kk,kk,rr);
    fox(i,1,kk){
        sna.pb(vi());
        sna.back().resize(rr);
    }
    int ct = rr*kk;
    for(auto v : arr){
        int cc = min(kk,cnt[v]);
        while(cc--&&ct){
            sna[x%kk][y%rr]=v;
            x++, y++;
            if(x==kk){
                x = 0;
                y -= kk-1;
            }
            ct--;
        }
    }
    for(i=0;i<kk;i++){
        for(j=0;j<rr;j++){
            printf("%d ",sna[i][j]);
        }
        printf("\n");
    }
    return 0;
}


#include <bits/stdc++.h>
using namespace std;

namespace debug{
    void __(short x){cout<<x;}
    void __(int x){cout<<x;}
    void __(long long x){cout<<x;}
    void __(unsigned long long x){cout<<x;}
    void __(double x){cout<<x;}
    void __(long double x){cout<<x;}
    void __(char x){cout<<x;}
    void __(const char*x){cout<<x;}
    void __(const string&x){cout<<x;}
    void __(bool x){cout<<(x?"true":"false");}
    template<class P1,class P2>
    void __(const pair<P1,P2>&x){__("("),__(x.first),__(", "),__(x.second),__(")");}
    template<class T>
    void __(const vector<T>&x){__("{");bool _ffs=0;for(const auto&v:x)__(_ffs?", ":""),__(v),_ffs=1;__("}");}
    void screm(){__("\n");}
    template<class T1,class... T2>
    void screm(const T1&t1,const T2&...t2){__(t1);if(sizeof...(t2))__(" | "),screm(t2...);else __("\n");}
    void pr(){__("\n");}
    template<class T1,class... T2>
    void pr(const T1&t1,const T2&...t2){__(t1);if(sizeof...(t2))__(" "),pr(t2...);else __("\n");}
}

using namespace debug;

typedef long long ll;
typedef long double ld;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
typedef pair<double,double> pdd;
typedef pair<ld,ld> pld;
typedef vector<int> vi;
typedef vector<ll> vl;

#define pb push_back
#define fox(i,x,y) for(int i=(x);i<=(y);i++)

const int MN = 4e5+5;
int n, i, j, k, ans, kk, x, y;
map<int,int> cnt; vi arr;
vector<vi> sna;

int main(){
    scanf("%d",&n);
    fox(i,1,n){
        arr.pb(0);
        scanf("%d",&arr.back());
        cnt[arr[i-1]]++;
    }
    sort(arr.begin(),arr.end());
    arr.erase(unique(arr.begin(),arr.end()),arr.end());
    int s = ceil(sqrt(n+0.0));
    fox(k,1,s){
        int sm = 0;
        for(auto v : arr){
            sm += min(k,cnt[v]);
        }
        if(k*k<=sm){
            int rr = sm/k;
            if(ans<rr*k){
                ans = rr*k;
                kk = k;
            }
        }
    }
    int rr = ans/kk;
    printf("%d\n%d %d\n",rr*kk,kk,rr);
    fox(i,1,kk){
        sna.pb(vi());
        sna.back().resize(rr);
    }
    srand(time(0));
    sort(arr.begin(),arr.end(),[](int i,int j){return cnt[i]>cnt[j];});
    int ct = rr*kk;
    for(auto v : arr){
        int cc = min(kk,cnt[v]);
        while(cc--&&ct){
            sna[x%kk][y%rr]=v;
            x++, y++;
            if(x==kk){
                x = 0;
                y -= kk-1;
            }
            ct--;
        }
    }
    for(i=0;i<kk;i++){
        for(j=0;j<rr;j++){
            printf("%d ",sna[i][j]);
        }
        printf("\n");
    }
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ull = unsigned long long;

#define REP(i,n) for(long long i = 0; i < (n); i++)
#define FOR(i, m, n) for(long long i = (m);i < (n); ++i)
#define ALL(obj) (obj).begin(),(obj).end()
#define SPEED cin.tie(0);ios::sync_with_stdio(false);

template<class T> using V = vector<T>;
template<class T, class U> using P = pair<T, U>;
template<class T> using PQ = priority_queue<T>;
template<class T> using PQR = priority_queue<T,vector<T>,greater<T>>;

constexpr long long MOD = (long long)1e9 + 7;
constexpr long long MOD2 = 998244353;
constexpr long long HIGHINF = (long long)1e18;
constexpr long long LOWINF = (long long)1e15;
constexpr long double PI = 3.1415926535897932384626433;

template <class T> vector<T> multivector(size_t N,T init){return vector<T>(N,init);}
template <class... T> auto multivector(size_t N,T... t){return vector<decltype(multivector(t...))>(N,multivector(t...));}
template <class T> void corner(bool flg, T hoge) {if (flg) {cout << hoge << endl; exit(0);}}
template <class T, class U>ostream &operator<<(ostream &o, const map<T, U>&obj) {o << "{"; for (auto &x : obj) o << " {" << x.first << " : " << x.second << "}" << ","; o << " }"; return o;}
template <class T>ostream &operator<<(ostream &o, const set<T>&obj) {o << "{"; for (auto itr = obj.begin(); itr != obj.end(); ++itr) o << (itr != obj.begin() ? ", " : "") << *itr; o << "}"; return o;}
template <class T>ostream &operator<<(ostream &o, const multiset<T>&obj) {o << "{"; for (auto itr = obj.begin(); itr != obj.end(); ++itr) o << (itr != obj.begin() ? ", " : "") << *itr; o << "}"; return o;}
template <class T>ostream &operator<<(ostream &o, const vector<T>&obj) {o << "{"; for (int i = 0; i < (int)obj.size(); ++i)o << (i > 0 ? ", " : "") << obj[i]; o << "}"; return o;}
template <class T, class U>ostream &operator<<(ostream &o, const pair<T, U>&obj) {o << "{" << obj.first << ", " << obj.second << "}"; return o;}
template <template <class tmp>  class T, class U> ostream &operator<<(ostream &o, const T<U> &obj) {o << "{"; for (auto itr = obj.begin(); itr != obj.end(); ++itr)o << (itr != obj.begin() ? ", " : "") << *itr; o << "}"; return o;}
void print(void) {cout << endl;}
template <class Head> void print(Head&& head) {cout << head;print();}
template <class Head, class... Tail> void print(Head&& head, Tail&&... tail) {cout << head << " ";print(forward<Tail>(tail)...);}
template <class T> void chmax(T& a, const T b){a=max(a,b);}
template <class T> void chmin(T& a, const T b){a=min(a,b);}
void YN(bool flg) {cout << (flg ? "YES" : "NO") << endl;}
void Yn(bool flg) {cout << (flg ? "Yes" : "No") << endl;}
void yn(bool flg) {cout << (flg ? "yes" : "no") << endl;}

int main() {
    ll N; cin >> N;
    vector<ll> A(N);
    for(int i = 0; i < N; ++i) cin >> A[i];
    map<ll,ll> mp;
    for(int i = 0; i < N; ++i) mp[A[i]]++;
    priority_queue<pair<ll,ll>> pq;
    for(auto e:mp){
        pq.push({e.second,e.first});
    }
    ll cnt = N;
    ll y = 0,x = 0,maxi = 0;
    for(int i = N; 1 <= i; --i){
        while(pq.size()){
            auto e = pq.top();
            if(e.first > i){
                pq.pop();
                e.first--;
                cnt--;
                pq.push(e);
            }
            else break;
        }
        int M = cnt/i;
        if(M<i) continue;
        if(maxi < M*i){
            maxi = M*i;
            y = i;
            x = M;
        }
    }
    auto G = multivector(y,x,0LL);
    for(auto& e:mp) chmin(e.second,y);
    vector<ll> C;
    for(auto& e:mp) for(int i = 0; i < e.second; ++i) C.push_back(e.first);
    int idx = 0;
    int s = 0,t = 0;
    while(G[s][t]==0){
        G[s][t] = C[idx++];
        s++;
        t++;
        s %= y;
        t %= x;
    }
    cout << maxi << endl;
    cout << y << " " << x << endl;
    for(int i = 0; i < y; ++i){
        for(int j = 0; j < x; ++j){
            cout << G[i][j] << " ";
        }
        cout << endl;
    }
}


#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ull = unsigned long long;

#define REP(i,n) for(long long i = 0; i < (n); i++)
#define FOR(i, m, n) for(long long i = (m);i < (n); ++i)
#define ALL(obj) (obj).begin(),(obj).end()
#define SPEED cin.tie(0);ios::sync_with_stdio(false);

template<class T> using V = vector<T>;
template<class T, class U> using P = pair<T, U>;
template<class T> using PQ = priority_queue<T>;
template<class T> using PQR = priority_queue<T,vector<T>,greater<T>>;

constexpr long long MOD = (long long)1e9 + 7;
constexpr long long MOD2 = 998244353;
constexpr long long HIGHINF = (long long)1e18;
constexpr long long LOWINF = (long long)1e15;
constexpr long double PI = 3.1415926535897932384626433;

template <class T> vector<T> multivector(size_t N,T init){return vector<T>(N,init);}
template <class... T> auto multivector(size_t N,T... t){return vector<decltype(multivector(t...))>(N,multivector(t...));}
template <class T> void corner(bool flg, T hoge) {if (flg) {cout << hoge << endl; exit(0);}}
template <class T, class U>ostream &operator<<(ostream &o, const map<T, U>&obj) {o << "{"; for (auto &x : obj) o << " {" << x.first << " : " << x.second << "}" << ","; o << " }"; return o;}
template <class T>ostream &operator<<(ostream &o, const set<T>&obj) {o << "{"; for (auto itr = obj.begin(); itr != obj.end(); ++itr) o << (itr != obj.begin() ? ", " : "") << *itr; o << "}"; return o;}
template <class T>ostream &operator<<(ostream &o, const multiset<T>&obj) {o << "{"; for (auto itr = obj.begin(); itr != obj.end(); ++itr) o << (itr != obj.begin() ? ", " : "") << *itr; o << "}"; return o;}
template <class T>ostream &operator<<(ostream &o, const vector<T>&obj) {o << "{"; for (int i = 0; i < (int)obj.size(); ++i)o << (i > 0 ? ", " : "") << obj[i]; o << "}"; return o;}
template <class T, class U>ostream &operator<<(ostream &o, const pair<T, U>&obj) {o << "{" << obj.first << ", " << obj.second << "}"; return o;}
template <template <class tmp>  class T, class U> ostream &operator<<(ostream &o, const T<U> &obj) {o << "{"; for (auto itr = obj.begin(); itr != obj.end(); ++itr)o << (itr != obj.begin() ? ", " : "") << *itr; o << "}"; return o;}
void print(void) {cout << endl;}
template <class Head> void print(Head&& head) {cout << head;print();}
template <class Head, class... Tail> void print(Head&& head, Tail&&... tail) {cout << head << " ";print(forward<Tail>(tail)...);}
template <class T> void chmax(T& a, const T b){a=max(a,b);}
template <class T> void chmin(T& a, const T b){a=min(a,b);}
void YN(bool flg) {cout << (flg ? "YES" : "NO") << endl;}
void Yn(bool flg) {cout << (flg ? "Yes" : "No") << endl;}
void yn(bool flg) {cout << (flg ? "yes" : "no") << endl;}

int main() {
    SPEED
    ll N; cin >> N;
    vector<ll> A(N);
    for(int i = 0; i < N; ++i) cin >> A[i];
    map<ll,ll> mp;
    for(int i = 0; i < N; ++i) mp[A[i]]++;
    priority_queue<pair<ll,ll>> pq;
    for(auto e:mp){
        pq.push({e.second,e.first});
    }
    ll cnt = N;
    ll y = 0,x = 0,maxi = 0;
    for(ll i = N; 1 <= i; --i){
        while(pq.size()){
            auto e = pq.top();
            if(e.first > i){
                pq.pop();
                e.first--;
                cnt--;
                pq.push(e);
            }
            else break;
        }
        ll M = cnt/i;
        if(M<i) continue;
        if(maxi < M*i){
            maxi = M*i;
            y = i;
            x = M;
        }
    }
    auto G = multivector(y,x,0LL);

    for(auto& e:mp) chmin(e.second,min(y,x));
    vector<pair<ll,ll>> v;
    for(auto& e:mp) v.push_back({e.second,e.first});
    sort(ALL(v),greater<>());
    vector<ll> C;
    for(auto& e:v) for(int i = 0; i < e.first; ++i) C.push_back(e.second);

    int idx = 0;
    for(int j = 0; j < x; ++j){
        for(int i = 0; i < y; ++i){
            if(G[i][(j+i)%x]==0) G[i][(j+i)%x] = C[idx++];
        }
    }

    cout << maxi << endl;
    cout << y << " " << x << endl;
    for(int i = 0; i < y; ++i){
        for(int j = 0; j < x; ++j){
            cout << G[i][j] << " ";
        }
        cout << endl;
    }
}


#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ull = unsigned long long;

#define REP(i,n) for(long long i = 0; i < (n); i++)
#define FOR(i, m, n) for(long long i = (m);i < (n); ++i)
#define ALL(obj) (obj).begin(),(obj).end()
#define SPEED cin.tie(0);ios::sync_with_stdio(false);

template<class T> using V = vector<T>;
template<class T, class U> using P = pair<T, U>;
template<class T> using PQ = priority_queue<T>;
template<class T> using PQR = priority_queue<T,vector<T>,greater<T>>;

constexpr long long MOD = (long long)1e9 + 7;
constexpr long long MOD2 = 998244353;
constexpr long long HIGHINF = (long long)1e18;
constexpr long long LOWINF = (long long)1e15;
constexpr long double PI = 3.1415926535897932384626433;

template <class T> vector<T> multivector(size_t N,T init){return vector<T>(N,init);}
template <class... T> auto multivector(size_t N,T... t){return vector<decltype(multivector(t...))>(N,multivector(t...));}
template <class T> void corner(bool flg, T hoge) {if (flg) {cout << hoge << endl; exit(0);}}
template <class T, class U>ostream &operator<<(ostream &o, const map<T, U>&obj) {o << "{"; for (auto &x : obj) o << " {" << x.first << " : " << x.second << "}" << ","; o << " }"; return o;}
template <class T>ostream &operator<<(ostream &o, const set<T>&obj) {o << "{"; for (auto itr = obj.begin(); itr != obj.end(); ++itr) o << (itr != obj.begin() ? ", " : "") << *itr; o << "}"; return o;}
template <class T>ostream &operator<<(ostream &o, const multiset<T>&obj) {o << "{"; for (auto itr = obj.begin(); itr != obj.end(); ++itr) o << (itr != obj.begin() ? ", " : "") << *itr; o << "}"; return o;}
template <class T>ostream &operator<<(ostream &o, const vector<T>&obj) {o << "{"; for (int i = 0; i < (int)obj.size(); ++i)o << (i > 0 ? ", " : "") << obj[i]; o << "}"; return o;}
template <class T, class U>ostream &operator<<(ostream &o, const pair<T, U>&obj) {o << "{" << obj.first << ", " << obj.second << "}"; return o;}
template <template <class tmp>  class T, class U> ostream &operator<<(ostream &o, const T<U> &obj) {o << "{"; for (auto itr = obj.begin(); itr != obj.end(); ++itr)o << (itr != obj.begin() ? ", " : "") << *itr; o << "}"; return o;}
void print(void) {cout << endl;}
template <class Head> void print(Head&& head) {cout << head;print();}
template <class Head, class... Tail> void print(Head&& head, Tail&&... tail) {cout << head << " ";print(forward<Tail>(tail)...);}
template <class T> void chmax(T& a, const T b){a=max(a,b);}
template <class T> void chmin(T& a, const T b){a=min(a,b);}
void YN(bool flg) {cout << (flg ? "YES" : "NO") << endl;}
void Yn(bool flg) {cout << (flg ? "Yes" : "No") << endl;}
void yn(bool flg) {cout << (flg ? "yes" : "no") << endl;}

int main() {
    ll N; cin >> N;
    vector<ll> A(N);
    for(int i = 0; i < N; ++i) cin >> A[i];
    map<ll,ll> mp;
    for(int i = 0; i < N; ++i) mp[A[i]]++;
    priority_queue<pair<ll,ll>> pq;
    for(auto e:mp){
        pq.push({e.second,e.first});
    }
    ll cnt = N;
    ll y = 0,x = 0,maxi = 0;
    for(ll i = N; 1 <= i; --i){
        while(pq.size()){
            auto e = pq.top();
            if(e.first > i){
                pq.pop();
                e.first--;
                cnt--;
                pq.push(e);
            }
            else break;
        }
        ll M = cnt/i;
        if(M<i) continue;
        if(maxi < M*i){
            maxi = M*i;
            y = i;
            x = M;
        }
    }
    auto G = multivector(y,x,0LL);
    for(auto& e:mp) chmin(e.second,y);
    vector<ll> C;
    for(auto& e:mp) for(int i = 0; i < e.second; ++i) C.push_back(e.first);

    int idx = 0;
    for(int j = 0; j < x; ++j){
        for(int i = 0; i < y; ++i){
            if(G[i][(j+i)%x]==0) G[i][(j+i)%x] = C[idx++];
        }
    }

    cout << maxi << endl;
    cout << y << " " << x << endl;
    for(int i = 0; i < y; ++i){
        for(int j = 0; j < x; ++j){
            cout << G[i][j] << " ";
        }
        cout << endl;
    }
}


#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ull = unsigned long long;

#define REP(i,n) for(long long i = 0; i < (n); i++)
#define FOR(i, m, n) for(long long i = (m);i < (n); ++i)
#define ALL(obj) (obj).begin(),(obj).end()
#define SPEED cin.tie(0);ios::sync_with_stdio(false);

template<class T> using V = vector<T>;
template<class T, class U> using P = pair<T, U>;
template<class T> using PQ = priority_queue<T>;
template<class T> using PQR = priority_queue<T,vector<T>,greater<T>>;

constexpr long long MOD = (long long)1e9 + 7;
constexpr long long MOD2 = 998244353;
constexpr long long HIGHINF = (long long)1e18;
constexpr long long LOWINF = (long long)1e15;
constexpr long double PI = 3.1415926535897932384626433;

template <class T> vector<T> multivector(size_t N,T init){return vector<T>(N,init);}
template <class... T> auto multivector(size_t N,T... t){return vector<decltype(multivector(t...))>(N,multivector(t...));}
template <class T> void corner(bool flg, T hoge) {if (flg) {cout << hoge << endl; exit(0);}}
template <class T, class U>ostream &operator<<(ostream &o, const map<T, U>&obj) {o << "{"; for (auto &x : obj) o << " {" << x.first << " : " << x.second << "}" << ","; o << " }"; return o;}
template <class T>ostream &operator<<(ostream &o, const set<T>&obj) {o << "{"; for (auto itr = obj.begin(); itr != obj.end(); ++itr) o << (itr != obj.begin() ? ", " : "") << *itr; o << "}"; return o;}
template <class T>ostream &operator<<(ostream &o, const multiset<T>&obj) {o << "{"; for (auto itr = obj.begin(); itr != obj.end(); ++itr) o << (itr != obj.begin() ? ", " : "") << *itr; o << "}"; return o;}
template <class T>ostream &operator<<(ostream &o, const vector<T>&obj) {o << "{"; for (int i = 0; i < (int)obj.size(); ++i)o << (i > 0 ? ", " : "") << obj[i]; o << "}"; return o;}
template <class T, class U>ostream &operator<<(ostream &o, const pair<T, U>&obj) {o << "{" << obj.first << ", " << obj.second << "}"; return o;}
template <template <class tmp>  class T, class U> ostream &operator<<(ostream &o, const T<U> &obj) {o << "{"; for (auto itr = obj.begin(); itr != obj.end(); ++itr)o << (itr != obj.begin() ? ", " : "") << *itr; o << "}"; return o;}
void print(void) {cout << endl;}
template <class Head> void print(Head&& head) {cout << head;print();}
template <class Head, class... Tail> void print(Head&& head, Tail&&... tail) {cout << head << " ";print(forward<Tail>(tail)...);}
template <class T> void chmax(T& a, const T b){a=max(a,b);}
template <class T> void chmin(T& a, const T b){a=min(a,b);}
void YN(bool flg) {cout << (flg ? "YES" : "NO") << endl;}
void Yn(bool flg) {cout << (flg ? "Yes" : "No") << endl;}
void yn(bool flg) {cout << (flg ? "yes" : "no") << endl;}

int main() {
    ll N; cin >> N;
    vector<ll> A(N);
    for(int i = 0; i < N; ++i) cin >> A[i];
    map<ll,ll> mp;
    for(int i = 0; i < N; ++i) mp[A[i]]++;
    priority_queue<pair<ll,ll>> pq;
    for(auto e:mp){
        pq.push({e.second,e.first});
    }
    ll cnt = N;
    ll y = 0,x = 0,maxi = 0;
    for(int i = N; 1 <= i; --i){
        while(pq.size()){
            auto e = pq.top();
            if(e.first > i){
                pq.pop();
                e.first--;
                cnt--;
                pq.push(e);
            }
            else break;
        }
        int M = cnt/i;
        if(M<i) continue;
        if(maxi < M*i){
            maxi = M*i;
            y = i;
            x = M;
        }
    }
    auto G = multivector(y,x,0LL);
    for(auto& e:mp) chmin(e.second,y);
    vector<ll> C;
    for(auto& e:mp) for(int i = 0; i < e.second; ++i) C.push_back(e.first);

    int idx = 0;
    for(int j = 0; j < x; ++j){
        for(int i = 0; i < y; ++i){
            G[i][(j+i)%x] = C[idx++];
        }
    }

    cout << maxi << endl;
    cout << y << " " << x << endl;
    for(int i = 0; i < y; ++i){
        for(int j = 0; j < x; ++j){
            cout << G[i][j] << " ";
        }
        cout << endl;
    }
}


#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ull = unsigned long long;

#define REP(i,n) for(long long i = 0; i < (n); i++)
#define FOR(i, m, n) for(long long i = (m);i < (n); ++i)
#define ALL(obj) (obj).begin(),(obj).end()
#define SPEED cin.tie(0);ios::sync_with_stdio(false);

template<class T> using V = vector<T>;
template<class T, class U> using P = pair<T, U>;
template<class T> using PQ = priority_queue<T>;
template<class T> using PQR = priority_queue<T,vector<T>,greater<T>>;

constexpr long long MOD = (long long)1e9 + 7;
constexpr long long MOD2 = 998244353;
constexpr long long HIGHINF = (long long)1e18;
constexpr long long LOWINF = (long long)1e15;
constexpr long double PI = 3.1415926535897932384626433;

template <class T> vector<T> multivector(size_t N,T init){return vector<T>(N,init);}
template <class... T> auto multivector(size_t N,T... t){return vector<decltype(multivector(t...))>(N,multivector(t...));}
template <class T> void corner(bool flg, T hoge) {if (flg) {cout << hoge << endl; exit(0);}}
template <class T, class U>ostream &operator<<(ostream &o, const map<T, U>&obj) {o << "{"; for (auto &x : obj) o << " {" << x.first << " : " << x.second << "}" << ","; o << " }"; return o;}
template <class T>ostream &operator<<(ostream &o, const set<T>&obj) {o << "{"; for (auto itr = obj.begin(); itr != obj.end(); ++itr) o << (itr != obj.begin() ? ", " : "") << *itr; o << "}"; return o;}
template <class T>ostream &operator<<(ostream &o, const multiset<T>&obj) {o << "{"; for (auto itr = obj.begin(); itr != obj.end(); ++itr) o << (itr != obj.begin() ? ", " : "") << *itr; o << "}"; return o;}
template <class T>ostream &operator<<(ostream &o, const vector<T>&obj) {o << "{"; for (int i = 0; i < (int)obj.size(); ++i)o << (i > 0 ? ", " : "") << obj[i]; o << "}"; return o;}
template <class T, class U>ostream &operator<<(ostream &o, const pair<T, U>&obj) {o << "{" << obj.first << ", " << obj.second << "}"; return o;}
template <template <class tmp>  class T, class U> ostream &operator<<(ostream &o, const T<U> &obj) {o << "{"; for (auto itr = obj.begin(); itr != obj.end(); ++itr)o << (itr != obj.begin() ? ", " : "") << *itr; o << "}"; return o;}
void print(void) {cout << endl;}
template <class Head> void print(Head&& head) {cout << head;print();}
template <class Head, class... Tail> void print(Head&& head, Tail&&... tail) {cout << head << " ";print(forward<Tail>(tail)...);}
template <class T> void chmax(T& a, const T b){a=max(a,b);}
template <class T> void chmin(T& a, const T b){a=min(a,b);}
void YN(bool flg) {cout << (flg ? "YES" : "NO") << endl;}
void Yn(bool flg) {cout << (flg ? "Yes" : "No") << endl;}
void yn(bool flg) {cout << (flg ? "yes" : "no") << endl;}

int main() {
    ll N; cin >> N;
    vector<ll> A(N);
    for(int i = 0; i < N; ++i) cin >> A[i];
    map<ll,ll> mp;
    for(int i = 0; i < N; ++i) mp[A[i]]++;
    priority_queue<pair<ll,ll>> pq;
    for(auto e:mp){
        pq.push({e.second,e.first});
    }
    ll cnt = N;
    ll y = 0,x = 0,maxi = 0;
    for(ll i = N; 2 <= i; --i){
        while(pq.size()){
            auto e = pq.top();
            if(e.first > i){
                pq.pop();
                e.first--;
                cnt--;
                pq.push(e);
            }
            else break;
        }
        ll M = cnt/i;
        if(M<i || i==1 || M == 1) continue;
        if(maxi < M*i){
            maxi = M*i;
            y = i;
            x = M;
        }
    }
    if(y==0){
        cout << 1 << endl << 1 << " " << 1 << endl << A[0] << endl;
        return 0;
    }
    auto G = multivector(y,x,0LL);
    for(auto& e:mp) chmin(e.second,min(y,x));
    vector<ll> C;
    for(auto& e:mp) for(int i = 0; i < e.second; ++i) C.push_back(e.first);

    int idx = 0;
    for(int j = 0; j < x; ++j){
        for(int i = 0; i < y; ++i){
            if(G[i][(j+i)%x]==0) G[i][(j+i)%x] = C[idx++];
        }
    }

    cout << maxi << endl;
    cout << y << " " << x << endl;
    for(int i = 0; i < y; ++i){
        for(int j = 0; j < x; ++j){
            cout << G[i][j] << " ";
        }
        cout << endl;
    }
}


#include<bits/stdc++.h>

using namespace std;

#define all(x) (x).begin(), (x).end()
#define sz(x) ( (int)(x).size() )
#define fi first
#define se second
using LL = long long;

int n;
vector<int> ma, qu;
map<int, int> cnt, cnt2;
vector<vector<int> > divisor;

int main() {
    ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);

//    freopen("input", "r", stdin);

    cin >> n;
    for (int i = 0; i < n; ++i) {
        int a; cin >> a;
        ++cnt[a];
    }

    divisor.assign(n + 1, {} );
    for (int i = 1; i <= n; ++i) {
        for (int j = i; j <= n; j += i) divisor[j].emplace_back(i);
    }

    int mx = 0;

    auto check = [&]() {
        int val = sz(ma) + sz(qu);
        int pos = (int)(lower_bound(all(divisor[val]), mx) - divisor[val].begin() );

        if (pos == sz(divisor[val]) ) return false;
        else return val / divisor[val][pos] >= mx;
    };

    while (sz(cnt) ) {
        vector<int> tmp;
        for (auto& _ : cnt) {
            qu.emplace_back(_.fi);
            mx = max(mx, ++cnt2[_.fi]);

            if (check() ) {
                for (auto a : qu) ma.emplace_back(a);
                qu.clear();
            }

            --_.se;
            if (!_.se) tmp.emplace_back(_.fi);
        }

        for (auto _ : tmp) cnt.erase(_);
    }

    mx = 0;
    cnt2.clear();
    for (int a : ma) mx = max(mx, ++cnt2[a]);
    int p = divisor[sz(ma)][ (int)(lower_bound(all(divisor[sz(ma)]), mx) - divisor[sz(ma)].begin() ) ],
        q = sz(ma) / p;

    vector<vector<int> > ans(p, vector<int>(q) );

    sort(all(ma), [&](int i, int j) { return make_pair(cnt2[i], i) < make_pair(cnt2[j], j); });
    int x = 0, y = 0;
    while (sz(ma) ) {
        ans[x][(y + x) % q] = ma.back(); ma.pop_back();
//        cerr << x << ' ' << (y + x) % q << '\n';
        ++x;
        if (x >= p) { x = 0; ++y; }
    }

    cout << p * q << '\n';
    cout << p << ' ' << q << '\n';
    for (int i = 0; i < p; ++i) {
        for (int j = 0; j < q; ++j) cout << ans[i][j] << ' ';
        cout << '\n';
    }

    return 0;
}


#include<bits/stdc++.h>

using namespace std;

#define all(x) (x).begin(), (x).end()
#define sz(x) ( (int)(x).size() )
#define fi first
#define se second
using LL = long long;

int n;
vector<int> ma, qu;
map<int, int> cnt, cnt2;
vector<vector<int> > divisor;

int main() {
    ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);

//    freopen("input", "r", stdin);

    cin >> n;
    for (int i = 0; i < n; ++i) {
        int a; cin >> a;
        ++cnt[a];
    }

    divisor.assign(n + 1, {} );
    for (int i = 1; i <= n; ++i) {
        for (int j = i; j <= n; j += i) divisor[j].emplace_back(i);
    }

    int mx = 0;

    auto check = [&]() {
        int val = sz(ma) + sz(qu);
        int pos = (int)(lower_bound(all(divisor[val]), mx) - divisor[val].begin() );

        if (pos == sz(divisor[val]) ) return false;
        else return val / divisor[val][pos] >= mx;
    };

    while (sz(cnt) ) {
        vector<int> tmp;
        for (auto& _ : cnt) {
            qu.emplace_back(_.fi);
            mx = max(mx, ++cnt2[_.fi]);

            if (check() ) {
                for (auto a : qu) ma.emplace_back(a);
                qu.clear();
            }

            --_.se;
            if (!_.se) tmp.emplace_back(_.fi);
        }

        for (auto _ : tmp) cnt.erase(_);
    }

    mx = 0;
    cnt2.clear();
    for (int a : ma) mx = max(mx, ++cnt2[a]);
    int p = divisor[sz(ma)][ (int)(lower_bound(all(divisor[sz(ma)]), mx) - divisor[sz(ma)].begin() ) ],
        q = sz(ma) / p;

    set<pair<int, int> > rem;
    for (int i = 0; i < p; ++i) {
        for (int j = 0; j < q; ++j) rem.emplace(i, j);
    }
    vector<vector<int> > ans(p, vector<int>(q) );

    sort(all(ma) );
    int x = -1, y = -1;
    while (sz(ma) ) {
        if (!rem.count(make_pair(x, y) ) ) {
            x = rem.begin()->fi;
            y = rem.begin()->se;
        }
        ans[x][y] = ma.back(); ma.pop_back();
        rem.erase(make_pair(x, y) );
        x = (x + 1) % p; y = (y + 1) % q;
    }

    cout << p * q << '\n';
    cout << p << ' ' << q << '\n';
    for (int i = 0; i < p; ++i) {
        for (int j = 0; j < q; ++j) cout << ans[i][j] << ' ';
        cout << '\n';
    }

    return 0;
}


#include<bits/stdc++.h>

using namespace std;

#define all(x) (x).begin(), (x).end()
#define sz(x) ( (int)(x).size() )
#define fi first
#define se second
using LL = long long;

int n;
vector<int> ma, qu;
map<int, int> cnt, cnt2;
vector<vector<int> > divisor;

int main() {
    ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);

//    freopen("input", "r", stdin);

    cin >> n;
    for (int i = 0; i < n; ++i) {
        int a; cin >> a;
        ++cnt[a];
    }

    divisor.assign(n + 1, {} );
    for (int i = 1; i <= n; ++i) {
        for (int j = i; j <= n; j += i) divisor[j].emplace_back(i);
    }

    int mx = 0;

    auto check = [&]() {
        int val = sz(ma) + sz(qu);
        int pos = (int)(lower_bound(all(divisor[val]), mx) - divisor[val].begin() );

        if (pos == sz(divisor[val]) ) return false;
        else return val / divisor[val][pos] >= mx;
    };

    while (sz(cnt) ) {
        vector<int> tmp;
        for (auto& _ : cnt) {
            qu.emplace_back(_.fi);
            mx = max(mx, ++cnt2[_.fi]);

            if (check() ) {
                for (auto a : qu) ma.emplace_back(a);
                qu.clear();
            }

            --_.se;
            if (!_.se) tmp.emplace_back(_.fi);
        }

        for (auto _ : tmp) cnt.erase(_);
    }

    mx = 0;
    cnt2.clear();
    for (int a : ma) mx = max(mx, ++cnt2[a]);
    int p = divisor[sz(ma)][ (int)(lower_bound(all(divisor[sz(ma)]), mx) - divisor[sz(ma)].begin() ) ],
        q = sz(ma) / p;

    set<pair<int, int> > rem;
    for (int i = 0; i < p; ++i) {
        for (int j = 0; j < q; ++j) rem.emplace(i, j);
    }
    vector<vector<int> > ans(p, vector<int>(q) );

    sort(all(ma) );
    int x = -1, y = -1;
    while (sz(ma) ) {
        if (!rem.count(make_pair(x, y) ) ) {
            x = rem.begin()->fi;
            y = rem.begin()->se;
        }
        ans[x][y] = ma.back(); ma.pop_back();
        x = (x + 1) % p; y = (y + 1) % q;
    }

    cout << p * q << '\n';
    cout << p << ' ' << q << '\n';
    for (int i = 0; i < p; ++i) {
        for (int j = 0; j < q; ++j) cout << ans[i][j] << ' ';
        cout << '\n';
    }

    return 0;
}


#include<bits/stdc++.h>

using namespace std;

#define all(x) (x).begin(), (x).end()
#define sz(x) ( (int)(x).size() )
#define fi first
#define se second
using LL = long long;

int n;
vector<int> a, ma, qu, com;
map<int, int> cnt, cnt2;
vector<vector<int> > divisor;

int main() {
    ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);

//    freopen("input", "r", stdin);

    cin >> n;
    a.assign(n, 0);
    for (int i = 0; i < n; ++i) {
        cin >> a[i];
        com.emplace_back(a[i]);
    }
    sort(all(com) ); com.erase(unique(all(com) ), com.end() );
    for (int i = 0; i < n; ++i) {
        a[i] = (int)(lower_bound(all(com), a[i]) - com.begin() );
        ++cnt[ a[i] ];
    }

    divisor.assign(n + 1, {} );
    for (int i = 1; i <= n; ++i) {
        for (int j = i; j <= n; j += i) divisor[j].emplace_back(i);
    }

    int mx = 0;

    auto check = [&]() {
        int val = sz(ma) + sz(qu);
        int pos = (int)(lower_bound(all(divisor[val]), mx) - divisor[val].begin() );

        if (pos == sz(divisor[val]) ) return false;
        else return val / divisor[val][pos] >= mx;
    };

    while (sz(cnt) ) {
        vector<int> tmp;
        for (auto& _ : cnt) {
            qu.emplace_back(_.fi);
            mx = max(mx, ++cnt2[_.fi]);

            if (check() ) {
                for (auto b : qu) ma.emplace_back(b);
                qu.clear();
            }

            --_.se;
            if (!_.se) tmp.emplace_back(_.fi);
        }

        for (auto _ : tmp) cnt.erase(_);
    }

    mx = 0;
    vector<int> cnt3(sz(com), 0);
    for (int b : ma) mx = max(mx, ++cnt3[b]);
    int p = divisor[sz(ma)][ (int)(lower_bound(all(divisor[sz(ma)]), mx) - divisor[sz(ma)].begin() ) ],
        q = sz(ma) / p;

    vector<vector<int> > ans(p, vector<int>(q) );

    sort(all(ma), [&](int i, int j) { return make_pair(cnt3[i], i) < make_pair(cnt3[j], j); } );
    int x = 0, y = 0;
    while (sz(ma) ) {
        ans[x][(y + x) % q] = ma.back(); ma.pop_back();
        ++x;
        if (x >= p) { x = 0; ++y; }
    }

    cout << p * q << '\n';
    cout << p << ' ' << q << '\n';
    for (int i = 0; i < p; ++i) {
        for (int j = 0; j < q; ++j) cout << com[ ans[i][j] ] << ' ';
        cout << '\n';
    }

    return 0;
}


#include <bits/stdc++.h>

using namespace std;
#define int long long
const int MOD = 1000000007;

signed main() {
	cin.tie(0);
	ios::sync_with_stdio(false);
	int N;
	cin >> N;
	map<int, int> mp;
	int a;
	int mx = 0;
	vector<pair<int, int> > vp;
	for (int i = 0; i < N; i++) {
		cin >> a;
		mp[a]++;
		mx = max(mx, mp[a]);
	}
	for (auto m : mp) {
		vp.emplace_back(m.second, m.first);
	}
	int H;
	int t = 0;
	int tot = N;
	for (int i = mx; i >= 1; i--) {
		int w = min((int)vp.size(), (tot / i));
		if (i <= vp.size() && w >= i) {
        //int w = tot / i;
        //if(w >= i){
			int area = i * w;
			if (t < area) {
				t = area;
				H = i;
			}
		}
		for (int j = 0; j < vp.size(); j++) {
			if (vp[j].first == i) {
				vp[j].first--;
				tot--;
			} else {
				break;
			}
		}
	}
	vp.clear();
	for (auto m : mp) {
		vp.emplace_back(m.second, m.first);
	}
	tot = N;
	for (int i = mx; i > H; i--) {
		for (int j = 0; j < vp.size(); j++) {
			if (vp[j].first == i) {
				vp[j].first--;
				tot--;
			} else {
				break;
			}
		}
	}
	vector<int> A;
	for (int i = 0; i < vp.size(); i++) {
		for (int j = 0; j < vp[i].first; j++) {
			A.push_back(vp[i].second);
		}
	}
	int W = min((int)vp.size(), (tot / H));
    //int W = tot / H;
	vector<vector<int> > res(H, vector<int>(W));
	for (int j = 0; j < W; j++) {
		for (int i = 0; i < H; i++) {
			res[i][(i + j) % W] = A[j * H + i];
		}
	}
	cout << H * W << endl;
	cout << H << " " << W << endl;
	for (int i = 0; i < H; i++) {
		for (int j = 0; j < W; j++) {
			if (j > 0) cout << " ";
			cout << res[i][j];
		}
		cout << endl;
	}
}


#include <bits/stdc++.h>

using namespace std;
#define int long long
const int MOD = 1000000007;

signed main() {
	cin.tie(0);
	ios::sync_with_stdio(false);
	int N;
	cin >> N;
	map<int, int> mp;
	int a;
	int mx = 0;
	vector<pair<int, int> > vp;
	for (int i = 0; i < N; i++) {
		cin >> a;
		mp[a]++;
		mx = max(mx, mp[a]);
	}
	for (auto m : mp) {
		vp.emplace_back(m.second, m.first);
	}
	sort(vp.rbegin(), vp.rend());
	int H;
	int t = 0;
	int tot = N;
	for (int i = N; i >= 1; i--) {
		int w = min((int)vp.size(), (tot / i));
		if (i <= vp.size() && w >= i) {
			//int w = tot / i;
			//if(w >= i){
			int area = i * w;
			if (t < area) {
				t = area;
				H = i;
			}
		}
		for (int j = 0; j < vp.size(); j++) {
			if (vp[j].first == i) {
				vp[j].first--;
				tot--;
			} else {
				break;
			}
		}
	}
	vp.clear();
	for (auto m : mp) {
		vp.emplace_back(m.second, m.first);
	}
	sort(vp.rbegin(), vp.rend());

	tot = N;
	for (int i = N; i > H; i--) {
		for (int j = 0; j < vp.size(); j++) {
			if (vp[j].first == i) {
				vp[j].first--;
				tot--;
			} else {
				break;
			}
		}
	}
	vector<int> A;
	for (int i = 0; i < vp.size(); i++) {
		for (int j = 0; j < vp[i].first; j++) {
			A.push_back(vp[i].second);
		}
	}
	int W = min((int)vp.size(), (tot / H));
	//int W = tot / H;
	vector<vector<int> > res(H, vector<int>(W));
	for (int j = 0; j < W; j++) {
		for (int i = 0; i < H; i++) {
			res[i][(i + j) % W] = A[j * H + i];
		}
	}
	cout << H * W << endl;
	cout << H << " " << W << endl;
	for (int i = 0; i < H; i++) {
		for (int j = 0; j < W; j++) {
			if (j > 0) cout << " ";
			cout << res[i][j];
		}
		cout << endl;
	}
}


#include <bits/stdc++.h>

using namespace std;
#define int long long
const int MOD = 1000000007;

signed main() {
	cin.tie(0);
	ios::sync_with_stdio(false);
	int N;
	cin >> N;
	map<int, int> mp;
	int a;
	int mx = 0;
	vector<pair<int, int> > vp;
	for (int i = 0; i < N; i++) {
		cin >> a;
		mp[a]++;
		mx = max(mx, mp[a]);
	}
	for (auto m : mp) {
		vp.emplace_back(m.second, m.first);
	}
	int H;
	int t = 0;
	int tot = N;
	for (int i = mx; i >= 1; i--) {
		//int w = min((int)vp.size(), (tot / i));
		//if (i <= vp.size() && w >= i) {
        int w = tot / i;
        if(w >= i){
			int area = i * w;
			if (t < area) {
				t = area;
				H = i;
			}
		}
		for (int j = 0; j < vp.size(); j++) {
			if (vp[j].first == i) {
				vp[j].first--;
				tot--;
			} else {
				break;
			}
		}
	}
	vp.clear();
	for (auto m : mp) {
		vp.emplace_back(m.second, m.first);
	}
	tot = N;
	for (int i = mx; i > H; i--) {
		for (int j = 0; j < vp.size(); j++) {
			if (vp[j].first == i) {
				vp[j].first--;
				tot--;
			} else {
				break;
			}
		}
	}
	vector<int> A;
	for (int i = 0; i < vp.size(); i++) {
		for (int j = 0; j < vp[i].first; j++) {
			A.push_back(vp[i].second);
		}
	}
	//int W = min((int)vp.size(), (tot / H));
    int W = tot / H;
	vector<vector<int> > res(H, vector<int>(W));
	for (int j = 0; j < W; j++) {
		for (int i = 0; i < H; i++) {
			res[i][(i + j) % W] = A[j * H + i];
		}
	}
	cout << H * W << endl;
	cout << H << " " << W << endl;
	for (int i = 0; i < H; i++) {
		for (int j = 0; j < W; j++) {
			if (j > 0) cout << " ";
			cout << res[i][j];
		}
		cout << endl;
	}
}


#include <bits/stdc++.h>

using namespace std;
#define int long long
const int MOD = 1000000007;

signed main() {
	cin.tie(0);
	ios::sync_with_stdio(false);
	int N;
	cin >> N;
	map<int, int> mp;
	int a;
	int mx = 0;
	vector<pair<int, int> > vp;
	for (int i = 0; i < N; i++) {
		cin >> a;
		mp[a]++;
		mx = max(mx, mp[a]);
	}
	for (auto m : mp) {
		vp.emplace_back(m.second, m.first);
	}
	int H;
	int t = 0;
	int tot = N;
	for (int i = mx; i >= 1; i--) {
		int w = min((int)vp.size(), (tot / i));
		if (i <= vp.size() && w >= i) {
			int area = i * w;
			if (t < area) {
				t = area;
				H = i;
			}
		}
		for (int j = 0; j < vp.size(); j++) {
			if (vp[j].first == mx) {
				vp[j].first--;
				tot--;
			} else {
				break;
			}
		}
	}
	vp.clear();
	for (auto m : mp) {
		vp.emplace_back(m.second, m.first);
	}
	tot = N;
	for (int i = mx; i > H; i--) {
		for (int j = 0; j < vp.size(); j++) {
			if (vp[j].first == i) {
				vp[j].first--;
				tot--;
			} else {
				break;
			}
		}
	}
	vector<int> A;
	for (int i = 0; i < vp.size(); i++) {
		for (int j = 0; j < vp[i].first; j++) {
			A.push_back(vp[i].second);
		}
	}
	int W = min((int)vp.size(), (tot / H));
	vector<vector<int> > res(H, vector<int>(W));
	for (int j = 0; j < W; j++) {
		for (int i = 0; i < H; i++) {
			res[i][(i + j) % W] = A[j * H + i];
		}
	}
	cout << H * W << endl;
	cout << H << " " << W << endl;
	for (int i = 0; i < H; i++) {
		for (int j = 0; j < W; j++) {
			if (j > 0) cout << " ";
			cout << res[i][j];
		}
		cout << endl;
	}
}


#include <bits/stdc++.h>

using namespace std;
#define int long long
const int MOD = 1000000007;

signed main() {
	cin.tie(0);
	ios::sync_with_stdio(false);
	int N;
	cin >> N;
	map<int, int> mp;
	int a;
	int mx = 0;
	vector<pair<int, int> > vp;
	for (int i = 0; i < N; i++) {
		cin >> a;
		mp[a]++;
		mx = max(mx, mp[a]);
	}
	for (auto m : mp) {
		vp.emplace_back(m.second, m.first);
	}
	sort(vp.rbegin(), vp.rend());
	int H;
	int t = 0;
	int tot = N;
	for (int i = mx; i >= 1; i--) {
		int w = min((int)vp.size(), (tot / i));
		if (i <= vp.size() && w >= i) {
			//int w = tot / i;
			//if(w >= i){
			int area = i * w;
			if (t < area) {
				t = area;
				H = i;
			}
		}
		for (int j = 0; j < vp.size(); j++) {
			if (vp[j].first == i) {
				vp[j].first--;
				tot--;
			} else {
				break;
			}
		}
	}
	vp.clear();
	for (auto m : mp) {
		vp.emplace_back(m.second, m.first);
	}
	sort(vp.rbegin(), vp.rend());

	tot = N;
	for (int i = mx; i > H; i--) {
		for (int j = 0; j < vp.size(); j++) {
			if (vp[j].first == i) {
				vp[j].first--;
				tot--;
			} else {
				break;
			}
		}
	}
	vector<int> A;
	for (int i = 0; i < vp.size(); i++) {
		for (int j = 0; j < vp[i].first; j++) {
			A.push_back(vp[i].second);
		}
	}
	int W = min((int)vp.size(), (tot / H));
	//int W = tot / H;
	vector<vector<int> > res(H, vector<int>(W));
	for (int j = 0; j < W; j++) {
		for (int i = 0; i < H; i++) {
			res[i][(i + j) % W] = A[j * H + i];
		}
	}
	cout << H * W << endl;
	cout << H << " " << W << endl;
	for (int i = 0; i < H; i++) {
		for (int j = 0; j < W; j++) {
			if (j > 0) cout << " ";
			cout << res[i][j];
		}
		cout << endl;
	}
}


#include <iostream>
#include <set>
#include <vector>
#include <map>
#include <algorithm>
#include <cmath>

using namespace std;
typedef long long int ll;
typedef vector <int> vi;
typedef vector <vi> vvi;
typedef vector <vvi> vvvi;
typedef vector <vvvi> vvvvi;

vvi W;
vector <bool> occupied;

void update(int l, int w, int& column, int& x, int& y){
    ++x; ++y;

    if (x == l) x = 0;
    if (y == w) y = 0;

    if (x != 0) return;

    while (occupied[y]){
        ++y;
        if (y == w) y = 0;
    }

    occupied[y] = true;
}

bool comp(vi a, vi b){
    if (a[0] != b[0]) return a[0] > b[0];
    return a[1] < b[1];
}

int main(){
    ios::sync_with_stdio(0);
    cin.tie(0);

    ll n;
    cin >> n;

    vi V(n);
    for (int i = 0; i < n; ++i) cin >> V[i];

    sort(V.begin(), V.end());

    W = {{1, V[0]}};
    int last = V[0];

    for (int i = 1; i < n; ++i){
        if (V[i] == last) ++W.back()[0];
        else W.push_back({1, V[i]});

        last = V[i];
    }

    sort(W.begin(), W.end());

    int m = W.size();

    vi dp(m+1, 0);
    for (int i = 1; i <= m; ++i) dp[i] = dp[i-1] + W[i-1][0];

    int l = 0, maximum = 0;

    for (ll i = 1; i * i <= n; ++i){
        vi aux = {(int)i, -1};
        int pos = -1 + lower_bound(W.begin(), W.end(), aux) - W.begin();

        int cells = (m - 1 - pos) * i + dp[pos+1];
        cells /= i;

        if (cells < i) continue;

        cells *= i;
        if (cells > maximum){
            maximum = cells;
            l = i;
        }
    }

    int w = maximum / l;
    vvi ans(l, vi(w));

    occupied = vector <bool> (w, false);
    occupied[0] = true;

    sort(W.begin(), W.end(), comp);

    int x = 0, y = 0, amount = 0, column = 0;
    for (int i = 0; amount < maximum and i < W.size(); ++i){
        for (int j = 0; amount < maximum and j < min(W[i][0], l); ++j){
            ans[x][y] = W[i][1];
            ++amount;
            if (amount < maximum) update(l, w, column, x, y);
        }
    }

    cout << maximum << endl;
    cout << l << " " << w << endl;

    for (int i = 0; i < l; ++i){
        for (int j = 0; j < w; ++j) {
            cout << ans[i][j] << " ";
        }
        cout << '\n';
    }
}


#include <iostream>
#include <set>
#include <vector>
#include <map>
#include <algorithm>
#include <cmath>

using namespace std;
typedef vector <int> vi;
typedef vector <vi> vvi;
typedef vector <vvi> vvvi;
typedef vector <vvvi> vvvvi;

vvi W;

void update(int l, int w, int& column, int& x, int& y){
    ++x; ++y;

    if (x == l) {
        ++column;
        x = 0; y = column;
    }

    if (y == w) y = 0;
}

int main(){
    ios::sync_with_stdio(0);
    cin.tie(0);

    int n;
    cin >> n;

    vi V(n);
    for (int i = 0; i < n; ++i) cin >> V[i];

    sort(V.begin(), V.end());

    W = {{1, V[0]}};
    int last = V[0];

    for (int i = 1; i < n; ++i){
        if (V[i] == last) ++W.back()[0];
        else W.push_back({1, V[i]});

        last = V[i];
    }

    sort(W.begin(), W.end());

    int m = W.size();

    vi dp(m+1, 0);
    for (int i = 1; i <= m; ++i) dp[i] = dp[i-1] + W[i-1][0];

    int l = 0, maximum = 0;

    for (int i = 1; i * i <= n; ++i){
        vi aux = {i, -1};
        int pos = -1 + lower_bound(W.begin(), W.end(), aux) - W.begin();

        int cells = (m - 1 - pos) * i + dp[pos+1];
        cells /= i;

        if (cells < i) continue;

        cells *= i;
        if (cells > maximum){
            maximum = cells;
            l = i;
        }
    }

    int w = maximum / l;
    vvi ans(l, vi(w));

    int x = 0, y = 0, amount = 0, column = 0;
    for (int i = 0; amount < maximum and i < W.size(); ++i){
        for (int j = 0; amount < maximum and j < min(W[i][0], l); ++j){
            ans[x][y] = W[i][1];
            ++amount;
            update(l, w, column, x, y);
        }
    }

    cout << maximum << endl;
    cout << l << " " << w << endl;

    for (int i = 0; i < l; ++i){
        for (int j = 0; j < w; ++j) {
            cout << ans[i][j] << " ";
        }
        cout << '\n';
    }
}


#include <iostream>
#include <set>
#include <vector>
#include <map>
#include <algorithm>
#include <cmath>

using namespace std;
typedef long long int ll;
typedef vector <int> vi;
typedef vector <vi> vvi;
typedef vector <vvi> vvvi;
typedef vector <vvvi> vvvvi;

vvi W;
vector <bool> occupied;

void update(int l, int w, int& column, int& x, int& y){
    ++x; ++y;

    if (x == l) {
        ++column;
        x = 0; y = column;
    }

    if (y == w) y = 0;
}

bool comp(vi a, vi b){
    if (a[0] != b[0]) return a[0] > b[0];
    return a[1] < b[1];
}

int main(){
    ios::sync_with_stdio(0);
    cin.tie(0);

    ll n;
    cin >> n;

    vi V(n);
    for (int i = 0; i < n; ++i) cin >> V[i];

    sort(V.begin(), V.end());

    W = {{1, V[0]}};
    int last = V[0];

    for (int i = 1; i < n; ++i){
        if (V[i] == last) ++W.back()[0];
        else W.push_back({1, V[i]});

        last = V[i];
    }

    sort(W.begin(), W.end());

    int m = W.size();

    vi dp(m+1, 0);
    for (int i = 1; i <= m; ++i) dp[i] = dp[i-1] + W[i-1][0];

    int l = 0, maximum = 0;

    for (ll i = 1; i * i <= n; ++i){
        vi aux = {(int)i, -1};
        int pos = -1 + lower_bound(W.begin(), W.end(), aux) - W.begin();

        int cells = (m - 1 - pos) * i + dp[pos+1];
        cells /= i;

        if (cells < i) continue;

        cells *= i;
        if (cells > maximum){
            maximum = cells;
            l = i;
        }
    }

    int w = maximum / l;
    vvi ans(l, vi(w));

    occupied = vector <bool> (w, false);
    occupied[0] = true;

    sort(W.begin(), W.end(), comp);

    int x = 0, y = 0, amount = 0, column = 0;
    for (int i = 0; amount < maximum and i < W.size(); ++i){
        for (int j = 0; amount < maximum and j < min(W[i][0], l); ++j){
            ans[x][y] = W[i][1];
            ++amount;
            if (amount < maximum) update(l, w, column, x, y);
        }
    }

    cout << maximum << endl;
    cout << l << " " << w << endl;

    for (int i = 0; i < l; ++i){
        for (int j = 0; j < w; ++j) {
            cout << ans[i][j] << " ";
        }
        cout << '\n';
    }
}


#include <iostream>
#include <set>
#include <vector>
#include <map>
#include <algorithm>
#include <cmath>

using namespace std;
typedef vector <int> vi;
typedef vector <vi> vvi;
typedef vector <vvi> vvvi;
typedef vector <vvvi> vvvvi;

vvi W;

void update(int l, int w, int& x, int& y){
    ++x; ++y;

    if (x == l) x = 0;
    if (y == w) y = 0;
}

int main(){
    ios::sync_with_stdio(0);
    cin.tie(0);

    int n;
    cin >> n;

    vi V(n);
    for (int i = 0; i < n; ++i) cin >> V[i];

    sort(V.begin(), V.end());

    W = {{1, V[0]}};
    int last = V[0];

    for (int i = 1; i < n; ++i){
        if (V[i] == last) ++W.back()[0];
        else W.push_back({1, V[i]});

        last = V[i];
    }

    sort(W.begin(), W.end());

    int m = W.size();

    vi dp(m+1, 0);
    for (int i = 1; i <= m; ++i) dp[i] = dp[i-1] + W[i-1][0];

    int l = 0, maximum = 0;

    for (int i = 1; i * i <= n; ++i){
        vi aux = {i, -1};
        int pos = -1 + lower_bound(W.begin(), W.end(), aux) - W.begin();

        int cells = (m - 1 - pos) * i + dp[pos+1];
        cells /= i;

        if (cells < i) continue;

        cells *= i;
        if (cells > maximum){
            maximum = cells;
            l = i;
        }
    }

    int w = maximum / l;
    vvi ans(l, vi(w));

    int x = 0, y = 0, amount = 0;
    for (int i = 0; amount < maximum and i < W.size(); ++i){

        for (int j = 0; amount < maximum and j < min(W[i][0], l); ++j){
            ans[x][y] = W[i][1];
            ++amount;
            update(l, w, x, y);
        }
    }

    cout << maximum << endl;
    cout << l << " " << w << endl;

    for (int i = 0; i < l; ++i){
        for (int j = 0; j < w; ++j) {
            cout << ans[i][j] << " ";
        }
        cout << '\n';
    }
}


#include <iostream>
#include <set>
#include <vector>
#include <map>
#include <algorithm>
#include <cmath>

using namespace std;
typedef long long int ll;
typedef vector <int> vi;
typedef vector <vi> vvi;
typedef vector <vvi> vvvi;
typedef vector <vvvi> vvvvi;

vvi W;
vector <bool> occupied;

void update(int l, int w, int& column, int& x, int& y){
    ++x; ++y;

    if (x == l) x = 0;
    if (y == w) y = 0;

    if (x != 0) return;

    while (occupied[y]){
        ++y;
        if (y == w) y = 0;
    }

    occupied[y] = true;
}

int main(){
    ios::sync_with_stdio(0);
    cin.tie(0);

    ll n;
    cin >> n;

    vi V(n);
    for (int i = 0; i < n; ++i) cin >> V[i];

    sort(V.begin(), V.end());

    W = {{1, V[0]}};
    int last = V[0];

    for (int i = 1; i < n; ++i){
        if (V[i] == last) ++W.back()[0];
        else W.push_back({1, V[i]});

        last = V[i];
    }

    sort(W.begin(), W.end());

    int m = W.size();

    vi dp(m+1, 0);
    for (int i = 1; i <= m; ++i) dp[i] = dp[i-1] + W[i-1][0];

    int l = 0, maximum = 0;

    for (ll i = 1; i * i <= n; ++i){
        vi aux = {(int)i, -1};
        int pos = -1 + lower_bound(W.begin(), W.end(), aux) - W.begin();

        int cells = (m - 1 - pos) * i + dp[pos+1];
        cells /= i;

        if (cells < i) continue;

        cells *= i;
        if (cells > maximum){
            maximum = cells;
            l = i;
        }
    }

    int w = maximum / l;
    vvi ans(l, vi(w));

    occupied = vector <bool> (w, false);
    occupied[0] = true;

    int x = 0, y = 0, amount = 0, column = 0;
    for (int i = 0; amount < maximum and i < W.size(); ++i){
        for (int j = 0; amount < maximum and j < min(W[i][0], l); ++j){
            ans[x][y] = W[i][1];
            ++amount;
            if (amount < maximum) update(l, w, column, x, y);
        }
    }

    cout << maximum << endl;
    cout << l << " " << w << endl;

    for (int i = 0; i < l; ++i){
        for (int j = 0; j < w; ++j) {
            cout << ans[i][j] << " ";
        }
        cout << '\n';
    }
}


#include <iostream>
#include <set>
#include <vector>
#include <map>
#include <algorithm>
#include <cmath>

using namespace std;
typedef long long int ll;
typedef vector <int> vi;
typedef vector <vi> vvi;
typedef vector <vvi> vvvi;
typedef vector <vvvi> vvvvi;

vvi W;
vector <bool> occupied;

void update(int l, int w, int& column, int& x, int& y){
    ++x; ++y;

    if (x == l) x = 0;
    if (y == w) y = 0;

    if (x != 0) return;

    while (occupied[y]){
        ++y;
        if (y == w) y = 0;
    }

    occupied[y] = true;
}

int main(){
    ios::sync_with_stdio(0);
    cin.tie(0);

    ll n;
    cin >> n;

    vi V(n);
    for (int i = 0; i < n; ++i) cin >> V[i];

    sort(V.begin(), V.end());

    W = {{1, V[0]}};
    int last = V[0];

    for (int i = 1; i < n; ++i){
        if (V[i] == last) ++W.back()[0];
        else W.push_back({1, V[i]});

        last = V[i];
    }

    sort(W.begin(), W.end());

    int m = W.size();

    vi dp(m+1, 0);
    for (int i = 1; i <= m; ++i) dp[i] = dp[i-1] + W[i-1][0];

    int l = 0, maximum = 0;

    for (ll i = 1; i <= m; ++i){
        vi aux = {(int)i, -1};
        int pos = -1 + lower_bound(W.begin(), W.end(), aux) - W.begin();

        int cells = (m - 1 - pos) * i + dp[pos+1];
        //cout << "with i = " << i << " we have " << cells << " because " << pos << endl;

        cells /= i;

        cells *= i;
        if (cells > maximum){
            maximum = cells;
            l = i;
        }
    }

    int w = maximum / l;
    vvi ans(l, vi(w));

    occupied = vector <bool> (w, false);
    occupied[0] = true;

    int x = 0, y = 0, amount = 0, column = 0;
    for (int i = 0; amount < maximum and i < W.size(); ++i){
        for (int j = 0; amount < maximum and j < min(W[i][0], l); ++j){
            ans[x][y] = W[i][1];
            ++amount;
            if (amount < maximum)
                update(l, w, column, x, y);
        }
    }

    if (l > w) swap(l, w);

    cout << maximum << endl;
    cout << l << " " << w << endl;

    for (int i = 0; i < l; ++i){
        for (int j = 0; j < w; ++j) {
            cout << ans[i][j] << " ";
        }
        cout << '\n';
    }
}


#include <iostream>
#include <set>
#include <vector>
#include <map>
#include <algorithm>
#include <cmath>

using namespace std;
typedef long long int ll;
typedef vector <int> vi;
typedef vector <vi> vvi;
typedef vector <vvi> vvvi;
typedef vector <vvvi> vvvvi;

vvi W;

void update(int l, int w, int& column, int& x, int& y){
    ++x; ++y;

    if (x == l) {
        ++column;
        x = 0; y = column;
    }

    if (y == w) y = 0;
}

int main(){
    ios::sync_with_stdio(0);
    cin.tie(0);

    ll n;
    cin >> n;

    vi V(n);
    for (int i = 0; i < n; ++i) cin >> V[i];

    sort(V.begin(), V.end());

    W = {{1, V[0]}};
    int last = V[0];

    for (int i = 1; i < n; ++i){
        if (V[i] == last) ++W.back()[0];
        else W.push_back({1, V[i]});

        last = V[i];
    }

    sort(W.begin(), W.end());

    int m = W.size();

    vi dp(m+1, 0);
    for (int i = 1; i <= m; ++i) dp[i] = dp[i-1] + W[i-1][0];

    int l = 0, maximum = 0;

    for (ll i = 1; i * i <= n; ++i){
        vi aux = {(int)i, -1};
        int pos = -1 + lower_bound(W.begin(), W.end(), aux) - W.begin();

        int cells = (m - 1 - pos) * i + dp[pos+1];
        cells /= i;

        if (cells < i) continue;

        cells *= i;
        if (cells > maximum){
            maximum = cells;
            l = i;
        }
    }

    int w = maximum / l;
    vvi ans(l, vi(w));

    int x = 0, y = 0, amount = 0, column = 0;
    for (int i = 0; amount < maximum and i < W.size(); ++i){
        for (int j = 0; amount < maximum and j < min(W[i][0], l); ++j){
            ans[x][y] = W[i][1];
            ++amount;
            update(l, w, column, x, y);
        }
    }

    cout << maximum << endl;
    cout << l << " " << w << endl;

    for (int i = 0; i < l; ++i){
        for (int j = 0; j < w; ++j) {
            cout << ans[i][j] << " ";
        }
        cout << '\n';
    }
}


#include <iostream>
#include <set>
#include <vector>
#include <map>
#include <algorithm>
#include <cmath>

using namespace std;
typedef long long int ll;
typedef vector <int> vi;
typedef vector <vi> vvi;
typedef vector <vvi> vvvi;
typedef vector <vvvi> vvvvi;

vvi W;

void update(int l, int w, int& column, int& x, int& y){
    ++x; ++y;

    if (x == l) {
        ++column;
        x = 0; y = column;
    }

    if (y == w) y = 0;
}

int main(){
    ios::sync_with_stdio(0);
    cin.tie(0);

    ll n;
    cin >> n;

    vi V(n);
    for (int i = 0; i < n; ++i) cin >> V[i];

    sort(V.begin(), V.end());

    W = {{1, V[0]}};
    int last = V[0];

    for (int i = 1; i < n; ++i){
        if (V[i] == last) ++W.back()[0];
        else W.push_back({1, V[i]});

        last = V[i];
    }

    sort(W.begin(), W.end());

    int m = W.size();

    vi dp(m+1, 0);
    for (int i = 1; i <= m; ++i) dp[i] = dp[i-1] + W[i-1][0];

    int l = 0, maximum = 0;

    for (ll i = 1; i * i <= n; ++i){
        vi aux = {(int)i, -1};
        int pos = -1 + lower_bound(W.begin(), W.end(), aux) - W.begin();

        int cells = (m - 1 - pos) * i + dp[pos+1];
        cells /= i;

        if (cells < i) continue;

        cells *= i;
        if (cells > maximum){
            maximum = cells;
            l = i;
        }
    }

    int w = maximum / l;
    vvi ans(l, vi(w));

    sort(W.begin(), W.end(), greater<vi>());

    int x = 0, y = 0, amount = 0, column = 0;
    for (int i = 0; amount < maximum and i < W.size(); ++i){
        for (int j = 0; amount < maximum and j < min(W[i][0], l); ++j){
            ans[x][y] = W[i][1];
            ++amount;
            if (amount < maximum) update(l, w, column, x, y);
        }
    }

    cout << maximum << '\n';
    cout << l << ' ' << w << '\n';

    for (int i = 0; i < l; ++i){
        for (int j = 0; j < w; ++j) {
            cout << ans[i][j] << ' ';
        }
        cout << '\n';
    }
}


#include <iostream>
#include <algorithm>
#include <vector>
#include <map>
#include <set>
#include <cmath>
#define int long long
using namespace std;

const int N = 400 * 1000 + 5;
const int SQ = 1000;
int n;

int a[N];
int cnt[N];
map <int, int> real;
vector <int> vec;
set <pair <int, int> > s;
vector <int> v;
vector <int> ans[N];

void comp() {
	for (int i = 0; i < n; i++) {
		vec.push_back(a[i]);
	}
	sort(vec.begin(), vec.end());
	vec.resize(unique(vec.begin(), vec.end()) - vec.begin());
	for (int i = 0; i < n; i++) {
		int x = lower_bound(vec.begin(), vec.end(), a[i]) - vec.begin();
		real[x] = a[i];
		a[i] = x;
		cnt[x]++;
	}
}

int32_t main() {
	cin >> n;
	for (int i = 0; i < n; i++) {
		cin >> a[i];
	}
	comp();
	for (int i = 0; i < vec.size(); i++) {
		s.insert({-cnt[i], i});
	}
//	cout << 41 << endl;
	int m = n;
	while (s.size()) {
		pair <int, int> p = *s.begin();
		int c = p.first, x = p.second;
		if (1ll * c * c > (long long) m) {
			m--;
			s.erase(s.begin());
			cnt[x]--;
			s.insert({-cnt[x], x});
		}
		else {
			break;
		}
	}
//	cout << 42 << endl;
	int rad = 1;
	while (1ll * rad * rad <= m) {
		rad++;
	}
	rad--;
	pair <int, int> p = *s.begin();
	int maxc = -p.first;
	int ansfor = maxc;
	for (int j = maxc; j <= rad; j++) {
		if (m % j <= m % ansfor) {
			ansfor = j;
		}
	}
	int x = ansfor, y = m / ansfor;
	for (auto p : s) {
		for (int i = 0; i < -p.first; i++) {
			v.push_back(p.second);
		}
	}
	for (int i = 0; i <= x; i++) {
		for (int j = 0; j <= y; j++) {
			ans[i].push_back(0);
		}
	}
	sort(v.begin(), v.end());
	for (int i = 0; i < x * y; i++) {
		int c = i % x;
		int d = (c + (i / x)) % y;
		ans[c][d] = v[i];
	}
	cout << x * y << endl;
	cout << x << " " << y << endl;
	for (int i = 0; i < x; i++) {
		for (int j = 0; j < y; j++) {
			cout << real[ans[i][j]] << " ";
		}
		cout << endl;
	}
	return 0;
}


#include <iostream>
#include <algorithm>
#include <vector>
#include <map>
#include <set>
#include <cmath>
#define int long long
using namespace std;

const int N = 400 * 1000 + 5;
int n;

int a[N];
int cnt[N];
map <int, int> real;
vector <int> vec;
set <pair <int, int> > s;
vector <pair <int, int> > v;
vector <int> ans[N];

void comp() {
	for (int i = 0; i < n; i++) {
		vec.push_back(a[i]);
	}
	sort(vec.begin(), vec.end());
	vec.resize(unique(vec.begin(), vec.end()) - vec.begin());
	for (int i = 0; i < n; i++) {
		int x = lower_bound(vec.begin(), vec.end(), a[i]) - vec.begin();
		real[x] = a[i];
		a[i] = x;
		cnt[x]++;
	}
}

int32_t main() {
	cin >> n;
	for (int i = 0; i < n; i++) {
		cin >> a[i];
	}
	comp();
	for (int i = 0; i < vec.size(); i++) {
		s.insert({-cnt[i], i});
	}
//	cout << 41 << endl;
	int m = n;
	while (s.size()) {
		pair <int, int> p = *s.begin();
		int c = p.first, x = p.second;
		if (1ll * c * c > (long long) m) {
			m--;
			s.erase(s.begin());
			cnt[x]--;
			s.insert({-cnt[x], x});
		}
		else {
			break;
		}
	}
//	cout << 42 << endl;
	int rad = 1;
	while (1ll * rad * rad <= m) {
		rad++;
	}
	rad--;
//	cout << rad << endl;
	pair <int, int> p = *s.begin();
	int maxc = -p.first;
	int ansfor = maxc;
	for (int j = 1; j <= rad; j++) {
		if (m % j < m % ansfor) {
			ansfor = j;
		}
	}
	int x = ansfor, y = m / ansfor;
	for (auto p : s) {
		for (int i = 0; i < -p.first; i++) {
			v.push_back(p);
		}
	}
	for (int i = 0; i <= x; i++) {
		for (int j = 0; j <= y; j++) {
			ans[i].push_back(0);
		}
	}
	sort(v.begin(), v.end());
	for (int i = 0; i < x * y; i++) {
		int c = i % x;
		int d = (c + (i / x)) % y;
		ans[c][d] = v[i].second;
	}
	cout << x * y << endl;
	cout << x << " " << y << endl;
	for (int i = 0; i < x; i++) {
		for (int j = 0; j < y; j++) {
			cout << real[ans[i][j]] << " ";
		}
		cout << endl;
	}
	return 0;
}


#include <iostream>
#include <algorithm>
#include <vector>
#include <map>
#include <set>
#include <cmath>
#define int long long
using namespace std;

const int N = 400 * 1000 + 5;
const int SQ = 1000;
int n;

int a[N];
int cnt[N];
map <int, int> real;
vector <int> vec;
set <pair <int, int> > s;
vector <pair <int, int> > v;
vector <int> ans[N];
int b[N];

void comp() {
	for (int i = 0; i < n; i++) {
		vec.push_back(a[i]);
	}
	sort(vec.begin(), vec.end());
	vec.resize(unique(vec.begin(), vec.end()) - vec.begin());
	for (int i = 0; i < n; i++) {
		int x = lower_bound(vec.begin(), vec.end(), a[i]) - vec.begin();
		real[x] = a[i];
		a[i] = x;
		cnt[x]++;
	}
}

int32_t main() {
	cin >> n;
	for (int i = 0; i < n; i++) {
		cin >> a[i];
	}
	comp();
	for (int i = 0; i < vec.size(); i++) {
		s.insert({-cnt[i], i});
	}
//	cout << 41 << endl;
	int m = n;
	while (s.size()) {
		pair <int, int> p = *s.begin();
		int c = p.first, x = p.second;
		if (1ll * c * c > (long long) m) {
			m--;
			s.erase(s.begin());
			cnt[x]--;
			s.insert({-cnt[x], x});
		}
		else {
			break;
		}
	}
	for (auto p : s) {
		int c = p.first, x = p.second;
		for (int i = 1; i <= -c; i++) {
			b[i]++;
		}
	}
	for (int i = 1; i <= n; i++) {
		b[i] = b[i - 1] + b[i];
	}
//	cout << 42 << endl;
	int rad = 1;
	while (1ll * rad * rad <= m) {
		rad++;
	}
	rad--;
	pair <int, int> p = *s.begin();
	int maxc = -p.first;
	int ansfor = maxc;
	for (int j = 1; j <= rad; j++) {
		if (j * (b[j] / j) >= ansfor * (b[ansfor] / ansfor)) {
			ansfor = j;
		}
	}
	int x = ansfor;
	int y = b[x] / ansfor;
	for (auto p : s) {
		for (int i = 0; i < -p.first; i++) {
			v.push_back(p);
		}
	}
	for (int i = 0; i <= x; i++) {
		for (int j = 0; j <= y; j++) {
			ans[i].push_back(0);
		}
	}
	sort(v.begin(), v.end());
	for (int i = 0; i < x * y; i++) {
		int c = i % x;
		int d = (c + (i / x)) % y;
		ans[c][d] = v[i].second;
	}
	cout << x * y << endl;
	cout << x << " " << y << endl;
	for (int i = 0; i < x; i++) {
		for (int j = 0; j < y; j++) {
			cout << real[ans[i][j]] << " ";
		}
		cout << endl;
	}
	return 0;
}


#include <iostream>
#include <algorithm>
#include <vector>
#include <map>
#include <set>
#include <cmath>
#define int long long
using namespace std;

const int N = 400 * 1000 + 5;
const int SQ = 1000;
int n;

int a[N];
int cnt[N];
map <int, int> real;
vector <int> vec;
set <pair <int, int> > s;
vector <pair <int, int> > v;
vector <int> ans[N];
int b[N];

void comp() {
	for (int i = 0; i < n; i++) {
		vec.push_back(a[i]);
	}
	sort(vec.begin(), vec.end());
	vec.resize(unique(vec.begin(), vec.end()) - vec.begin());
	for (int i = 0; i < n; i++) {
		int x = lower_bound(vec.begin(), vec.end(), a[i]) - vec.begin();
		real[x] = a[i];
		a[i] = x;
		cnt[x]++;
	}
}

int32_t main() {
	cin >> n;
	for (int i = 0; i < n; i++) {
		cin >> a[i];
	}
	comp();
	for (int i = 0; i < vec.size(); i++) {
		s.insert({-cnt[i], i});
	}
//	cout << 41 << endl;
	int m = n;
	while (s.size()) {
		pair <int, int> p = *s.begin();
		int c = p.first, x = p.second;
		if (1ll * c * c > (long long) m) {
			m--;
			s.erase(s.begin());
			cnt[x]--;
			s.insert({-cnt[x], x});
		}
		else {
			break;
		}
	}
	for (auto p : s) {
		int c = p.first, x = p.second;
		for (int i = 1; i <= -c; i++) {
			b[i]++;
		}
	}
	for (int i = 1; i <= n; i++) {
		b[i] = b[i - 1] + b[i];
	}
//	cout << 42 << endl;
	int rad = 1;
	while (1ll * rad * rad <= m) {
		rad++;
	}
	rad--;
	pair <int, int> p = *s.begin();
	int maxc = -p.first;
	int ansfor = maxc;
	for (int j = 1; j <= rad; j++) {
		if (j * (b[j] / j) >= ansfor * (b[ansfor] / ansfor)) {
			ansfor = j;
		}
	}
	int x = ansfor;
	int y = b[x] / ansfor;
	for (auto p : s) {
		for (int i = 0; i < min(-p.first, x); i++) {
			v.push_back(p);
		}
	}
	for (int i = 0; i <= x; i++) {
		for (int j = 0; j <= y; j++) {
			ans[i].push_back(0);
		}
	}
	sort(v.begin(), v.end());
	for (int i = 0; i < x * y; i++) {
		int c = i % x;
		int d = (c + (i / x)) % y;
		ans[c][d] = v[i].second;
	}
	cout << x * y << endl;
	cout << x << " " << y << endl;
	for (int i = 0; i < x; i++) {
		for (int j = 0; j < y; j++) {
			cout << real[ans[i][j]] << " ";
		}
		cout << endl;
	}
	return 0;
}


#include <iostream>
#include <algorithm>
#include <vector>
#include <map>
#include <set>
#include <cmath>
#define int long long
using namespace std;

const int N = 400 * 1000 + 5;
const int SQ = 1000;
int n;

int a[N];
int cnt[N];
map <int, int> real;
vector <int> vec;
set <pair <int, int> > s;
vector <pair <int, int> > v;
vector <int> ans[N];
int b[N];

void comp() {
	for (int i = 0; i < n; i++) {
		vec.push_back(a[i]);
	}
	sort(vec.begin(), vec.end());
	vec.resize(unique(vec.begin(), vec.end()) - vec.begin());
	for (int i = 0; i < n; i++) {
		int x = lower_bound(vec.begin(), vec.end(), a[i]) - vec.begin();
		real[x] = a[i];
		a[i] = x;
		cnt[x]++;
	}
}

int32_t main() {
	ios :: sync_with_stdio(false);
	cin >> n;
	for (int i = 0; i < n; i++) {
		cin >> a[i];
	}
	comp();
	for (int i = 0; i < vec.size(); i++) {
		s.insert({-cnt[i], i});
	}
//	cout << 41 << endl;
	int m = n;
	while (s.size()) {
		pair <int, int> p = *s.begin();
		int c = p.first, x = p.second;
		if (1ll * c * c > (long long) m) {
			m--;
			s.erase(s.begin());
			cnt[x]--;
			s.insert({-cnt[x], x});
		}
		else {
			break;
		}
	}
	for (auto p : s) {
		int c = p.first, x = p.second;
		for (int i = 1; i <= -c; i++) {
			b[i]++;
		}
	}
	for (int i = 1; i <= n; i++) {
		b[i] = b[i - 1] + b[i];
	}
//	cout << 42 << endl;
	int rad = 1;
	while (1ll * rad * rad <= m) {
		rad++;
	}
	rad--;
	pair <int, int> p = *s.begin();
	int maxc = -p.first;
	int ansfor = maxc;
	for (int j = 1; j <= rad; j++) {
		if (j * (b[j] / j) >= ansfor * (b[ansfor] / ansfor)) {
			ansfor = j;
		}
	}
	int x = ansfor;
	int y = b[x] / ansfor;
	for (auto p : s) {
		for (int i = 0; i < min(-p.first, x); i++) {
			v.push_back(p);
		}
	}
	for (int i = 0; i <= x; i++) {
		for (int j = 0; j <= y; j++) {
			ans[i].push_back(0);
		}
	}
	sort(v.begin(), v.end());
	for (int i = 0; i < x * y; i++) {
		int c = i % x;
		int d = (c + (i / x)) % y;
		ans[c][d] = v[i].second;
	}
	cout << x * y << '\n';
	cout << x << " " << y << '\n';
	for (int i = 0; i < x; i++) {
		for (int j = 0; j < y; j++) {
			cout << real[ans[i][j]] << " ";
		}
		cout << '\n';
	}
	return 0;
}