#include <bits/stdc++.h>

using namespace std;
typedef long long ll;

#define f first
#define s second

vector<pair<int, int> >f;
int n, v[40002], solA, solB, ans;
map<int, int>mp;

int main()
{
  ios_base::sync_with_stdio(false);
  cin.tie(0); cout.tie(0);
  cin >> n;
  for (int i = 1; i <= n; i++) {
    cin >> v[i];
    mp[v[i]]++;
  }
  int poz = 0;
  for (auto it : mp) {
    f.push_back({it.s, it.f});
  }
  sort(f.begin(), f.end());
  int sum = 0;
  for (int a = 1; a <=n; a++) {
    while (poz < f.size() && f[poz].f < a) {
      sum += f[poz].f;
      poz++;
    }
    int b = (sum + a * (f.size()  - poz)) / a;
    if (a <= b && ans < a * b) {
      ans = a * b;
      solA = a;
      solB = b;
    }
  }
  vector<vector<int> >mat;
  mat.resize(solA);
  for (int i = 0; i < solA; i++)
    mat[i].resize(solB);
  int x = 0, y = 0;
  for (int i = 0; i < f.size(); i++) {
    for (int j = 0; j < min(f[i].f, solA); j++) {
      mat[x][y] = f[i].s;
      x = (x + 1) % solA;
      y = (y + 1) % solB;
    }
  }
  cout << ans << "\n" << solA << " " << solB << "\n";
  for (int i = 0; i < solA; i++) {
    for(int j = 0; j < solB; j++)
      cout << mat[i][j] << " ";
    cout << "\n";
  }
  return 0;
}


#include <iostream>
#include <vector>
#include <functional>
#include <algorithm>
#include <map>
using namespace std;

int main()
{
	int n; cin >> n;

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

	vector<pair<int, int>>  va;
	for (auto it : m)
		va.push_back({ it.second, it.first });
	sort(va.begin(), va.end());

	vector<int> sum(va.size() + 1);
	for (int i = 1; i <= va.size(); i++)
		sum[i] = sum[i - 1] + va[i - 1].first;

	int maxs = 0, p, q, maxp = min(va.back().first, (int)va.size()) + 1;
	for (int i = 1; i <= maxp; i++)
	{
		int j = lower_bound(va.begin(), va.end(), make_pair(i, (int)1e9)) - va.begin();
		int num = sum[j] + (va.size() - j) * i;
		if (i <= num / i && num / i * i > maxs)
			maxs = num / i * i, p = i, q = num / i;
	}
	cout << maxs << endl << p << " " << q << endl;

	for (int i = 1; i < va.size(); i++)
		if (va[i].first > p)
			va[i].first = p;

	vector<vector<int>> a(p, vector<int>(q));
	for (int i = 0, vi = va.size() - 1; i < p; i++)
		for (int j = 0; j < q; j++)
		{
			a[(i + j) % p][j] = va[vi].second;
			if (!--va[vi].first) vi--;
		}

	for (int i = 0; i < p; i++)
	{
		for (int j = 0; j < q; j++)
			cout << a[i][j] << " ";
		cout << endl;
	}
	cout << endl;

	return 0;
}

///////////////////////////////////////////////////////////////////////


#include <iostream>
#include <vector>
#include <functional>
#include <algorithm>
#include <map>
using namespace std;

int main()
{
	int n; cin >> n;

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

	vector<pair<int, int>>  va;
	for (auto it : m)
		va.push_back({ it.second, it.first });
	sort(va.begin(), va.end());

	vector<int> sum(va.size() + 1);
	for (int i = 1; i <= va.size(); i++)
		sum[i] = sum[i - 1] + va[i - 1].first;

	int maxs = 0, p, q;
	for (int i = 1; i <= va.size(); i++)
	{
		int j = lower_bound(va.begin(), va.end(), make_pair(i, (int)1e9)) - va.begin();
		int num = sum[j] + (va.size() - j) * i;
		if (i <= num / i && num / i * i > maxs)
			maxs = num / i * i, p = i, q = num / i;
	}
	cout << maxs << endl << p << " " << q << endl;

	for (int i = 0; i < va.size(); i++)
		if (va[i].first > p)
			va[i].first = p;

	vector<vector<int>> a(p, vector<int>(q));
	for (int i = 0, vi = va.size() - 1; i < p; i++)
		for (int j = 0; j < q; j++)
		{
			a[(i + j) % p][j] = va[vi].second;
			if (!--va[vi].first) vi--;
		}

	for (int i = 0; i < p; i++)
	{
		for (int j = 0; j < q; j++)
			cout << a[i][j] << " ";
		cout << endl;
	}
	cout << endl;

	return 0;
}

///////////////////////////////////////////////////////////////////////


#include <iostream>
#include <vector>
#include <functional>
#include <algorithm>
#include <map>
using namespace std;

int main()
{
	int n; cin >> n;

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

	vector<pair<int, int>>  va;
	for (auto it : m)
		va.push_back({ it.second, it.first });
	sort(va.begin(), va.end());

	vector<int> sum(va.size() + 1);
	for (int i = 1; i <= va.size(); i++)
		sum[i] = sum[i - 1] + va[i - 1].first;

	int maxs = 0, p, q;
	for (int i = 1; i <= va.size(); i++)
	{
		int j = lower_bound(va.begin(), va.end(), make_pair(i, (int)1e9)) - va.begin();
		int num = sum[j] + (va.size() - j) * i, qi = num / i;
		if (i <= qi && qi * i > maxs)
			maxs = qi * i, p = i, q = qi;
	}
	cout << maxs << endl << p << " " << q << endl;

	for (int i = 0; i < va.size(); i++)
		if (va[i].first > p)
			va[i].first = p;

	vector<vector<int>> a(p, vector<int>(q));
	for (int j = 0, vi = va.size() - 1; j < q; j++)
		for (int i = 0; i < p; i++)
		{
			a[i][(i + j) % q] = va[vi].second;
			if (!--va[vi].first) vi--;
		}

	for (int i = 0; i < p; i++)
	{
		for (int j = 0; j < q; j++)
			cout << a[i][j] << " ";
		cout << endl;
	}
	cout << endl;

	return 0;
}

///////////////////////////////////////////////////////////////////////


#include <iostream>
#include <vector>
#include <functional>
#include <algorithm>
#include <map>
using namespace std;

int main()
{
	int n; cin >> n;

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

	vector<pair<int, int>>  va;
	for (auto it : m)
		va.push_back({ it.second, it.first });
	sort(va.begin(), va.end());

	vector<int> sum(va.size() + 1);
	for (int i = 1; i <= va.size(); i++)
		sum[i] = sum[i - 1] + va[i - 1].first;

	int maxs = 0, p, q, maxp = min(va.back().first, (int)va.size());
	for (int i = 1; i <= maxp; i++)
	{
		int j = lower_bound(va.begin(), va.end(), make_pair(i, (int)1e9)) - va.begin();
		int num = sum[j] + (va.size() - j) * i;
		if (num / i * i > maxs)
			maxs = num / i * i, p = i, q = num / i;
	}
	cout << maxs << endl << p << " " << q << endl;

	for (int i = 1; i < va.size(); i++)
		if (va[i].first > p)
			va[i].first = p;

	vector<vector<int>> a(p, vector<int>(q));
	for (int i = 0, vi = va.size() - 1; i < p; i++)
		for (int j = 0; j < q; j++)
		{
			a[(i + j) % p][j] = va[vi].second;
			if (!--va[vi].first) vi--;
		}

	for (int i = 0; i < p; i++)
	{
		for (int j = 0; j < q; j++)
			cout << a[i][j] << " ";
		cout << endl;
	}
	cout << endl;

	return 0;
}

///////////////////////////////////////////////////////////////////////


#include <iostream>
#include <vector>
#include <functional>
#include <algorithm>
#include <map>
using namespace std;

int main()
{
	int n; cin >> n;

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

	vector<pair<int, int>>  va;
	for (auto it : m)
		va.push_back({ it.second, it.first });
	sort(va.begin(), va.end());

	vector<int> sum(va.size() + 1);
	for (int i = 1; i <= va.size(); i++)
		sum[i] = sum[i - 1] + va[i - 1].first;

	int maxs = 0, p, q, maxp = min(va.back().first, (int)va.size());
	for (int i = 1; i <= maxp; i++)
	{
		int j = lower_bound(va.begin(), va.end(), make_pair(i, (int)1e9)) - va.begin();
		int64_t num = sum[j] + (va.size() - j) * 1LL * i;
		if (num / i * i > maxs)
			maxs = num / i * i, p = i, q = num / i;
	}
	cout << maxs << endl << p << " " << q << endl;

	for (int i = 1; i < va.size(); i++)
		if (va[i].first > p)
			va[i].first = p;

	vector<vector<int>> a(p, vector<int>(q));
	for (int i = 0, vi = va.size() - 1; i < p; i++)
		for (int j = 0; j < q; j++)
		{
			a[(i + j) % p][j] = va[vi].second;
			if (!--va[vi].first) vi--;
		}

	for (int i = 0; i < p; i++)
	{
		for (int j = 0; j < q; j++)
			cout << a[i][j] << " ";
		cout << endl;
	}
	cout << endl;

	return 0;
}

///////////////////////////////////////////////////////////////////////


#include <iostream>
#include <vector>
#include <functional>
#include <algorithm>
#include <map>
using namespace std;

int main()
{
	int n; cin >> n;

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

	vector<pair<int, int>>  va;
	for (auto it : m)
		va.push_back({ it.second, it.first });
	sort(va.begin(), va.end());

	vector<int> sum(va.size() + 1);
	for (int i = 1; i <= va.size(); i++)
		sum[i] = sum[i - 1] + va[i - 1].first;

	int maxs = 0, p, q, maxp = min(va.back().first, (int)va.size());
	for (int i = 1; i <= maxp; i++)
	{
		int j = lower_bound(va.begin(), va.end(), make_pair(i, (int)1e9)) - va.begin();
		int num = sum[j] + (va.size() - j) * i;
		if (i <= num / i && num / i * i > maxs)
			maxs = num / i * i, p = i, q = num / i;
	}
	cout << maxs << endl << p << " " << q << endl;

	for (int i = 1; i < va.size(); i++)
		if (va[i].first > p)
			va[i].first = p;

	vector<vector<int>> a(p, vector<int>(q));
	for (int i = 0, vi = va.size() - 1; i < p; i++)
		for (int j = 0; j < q; j++)
		{
			a[(i + j) % p][j] = va[vi].second;
			if (!--va[vi].first) vi--;
		}

	for (int i = 0; i < p; i++)
	{
		for (int j = 0; j < q; j++)
			cout << a[i][j] << " ";
		cout << endl;
	}
	cout << endl;

	return 0;
}

///////////////////////////////////////////////////////////////////////


#include <iostream>
#include <vector>
#include <functional>
#include <algorithm>
#include <map>
using namespace std;

int main()
{
	int n; cin >> n;

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

	vector<pair<int, int>>  va;
	for (auto it : m)
		va.push_back({ it.second, it.first });
	sort(va.begin(), va.end());

	vector<int> sum(va.size() + 1);
	for (int i = 1; i <= va.size(); i++)
		sum[i] = sum[i - 1] + va[i - 1].first;

	int maxs = 0, p, q;
	for (int i = 1; i <= va.size(); i++)
	{
		int j = lower_bound(va.begin(), va.end(), make_pair(i, (int)1e9)) - va.begin();
		int num = sum[j] + (va.size() - j) * i;
		if (i <= num / i && num / i * i > maxs)
			maxs = num / i * i, p = i, q = num / i;
	}
	cout << maxs << endl << p << " " << q << endl;

	for (int i = 1; i < va.size(); i++)
		if (va[i].first > p)
			va[i].first = p;

	vector<vector<int>> a(p, vector<int>(q));
	for (int i = 0, vi = va.size() - 1; i < p; i++)
		for (int j = 0; j < q; j++)
		{
			a[(i + j) % p][j] = va[vi].second;
			if (!--va[vi].first) vi--;
		}

	for (int i = 0; i < p; i++)
	{
		for (int j = 0; j < q; j++)
			cout << a[i][j] << " ";
		cout << endl;
	}
	cout << endl;

	return 0;
}

///////////////////////////////////////////////////////////////////////


#include <iostream>
#include <vector>
#include <functional>
#include <algorithm>
#include <map>
using namespace std;

int main()
{
	int n; cin >> n;

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

	vector<pair<int, int>>  va;
	for (auto it : m)
		va.push_back({ it.second, it.first });
	sort(va.begin(), va.end());

	vector<int> sum(va.size() + 1);
	for (int i = 1; i <= va.size(); i++)
		sum[i] = sum[i - 1] + va[i - 1].first;

	int maxs = 0, p, q;
	for (int i = 1; i <= va.size(); i++)
	{
		int j = lower_bound(va.begin(), va.end(), make_pair(i, (int)1e9)) - va.begin();
		int num = sum[j] + (va.size() - j) * i, qi = num / i;
		if (i <= qi && qi * i > maxs)
			maxs = qi * i, p = i, q = qi;
	}
	cout << maxs << endl << p << " " << q << endl;

	for (int i = 0; i < va.size(); i++)
		if (va[i].first > p)
			va[i].first = p;

	vector<vector<int>> a(p, vector<int>(q));
	for (int i = 0, vi = 0; i < p; i++)
		for (int j = 0; j < q; j++)
		{
			a[(i + j) % p][j] = va[vi].second;
			if (!--va[vi].first) vi++;
		}

	for (int i = 0; i < p; i++)
	{
		for (int j = 0; j < q; j++)
			cout << a[i][j] << " ";
		cout << endl;
	}
	cout << endl;

	return 0;
}

///////////////////////////////////////////////////////////////////////


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

using namespace std;

typedef long long ll;
typedef long double ldb;

#define print(s) cout << (s) << endl;

bool cmp(pair<int, int> &a, pair<int, int> &b) {
    return a.second < b.second;
}

pair<int, int> find_largest_multiplicity(map<int, int> F, int n) {
    vector<int> T, S, Vf;
    int curr_T = 0, curr_S = 0;
    int f, N;
    int sumN = 0;
    Vf.push_back(0);
    T.push_back(0);
    S.push_back(0);
    for (auto it = F.begin(); it != F.end(); it++) {
        f = it->first;
        N = it->second;
        Vf.push_back(f);
        curr_T += f * N ;
        curr_S += N;
        T.push_back(curr_T);
        S.push_back(curr_S);
    }
    sumN = curr_S;
    int maxf = Vf[Vf.size() - 1];
    int k = maxf;
    int quantity;
    int Tk, Sk;
    int best_quantity = 0, best_k;
    while (k) {
        int idx = upper_bound(Vf.begin(), Vf.end(), k) - Vf.begin() - 1;
        Tk = T[idx];
        Sk = S[idx];
        quantity = Tk + k * (sumN - Sk);
        if (quantity >= k * k) {
            if (k * (quantity / k) > best_quantity) {
                best_k = k;
                best_quantity = k * (quantity / k);
            }
        }
        k--;
    }
    return make_pair(best_k, best_quantity);
}

int main() {
    int n, a;
    cin >> n;
    map<int, int> m;
    for (size_t i = 0; i < n; i++)
    {
        scanf("%d", &a);
        m[a]++;
    }
    map<int, vector<int>> F2N;
    map<int, int> F;
    for (auto p: m) {
        F2N[p.second].push_back(p.first);
        F[p.second]++;
    }
    int f, N, curr = 0;
    vector<int> T, fs;
    for (auto p: F) {
        f = p.first;
        N = p.second;
        curr += f * N - N;
        T.push_back(curr + f * f);
        fs.push_back(f);
    }
    pair<int, int> pp = find_largest_multiplicity(F, n);
    int k = pp.first;
    int quantity = pp.second;

    int height = k;
    int width = quantity / height;
    int cnt = 0;
    vector<vector<int>> mat(height, vector<int>(width));
    for (auto it = F2N.rbegin(); it != F2N.rend(); it++) {
        vector<int> v = it->second;
        f = min(it->first, k);
        for (auto x: v) {
            for (size_t i = 0; i < f; i++)
            {
                mat[cnt % height][cnt / height] = x;
                cnt++;
                if (cnt > height * width) break;
            }
        }
        if (cnt > height * width) break;
    }
    cout << quantity << endl;
    cout << height << ' ' << width << endl;
    for (size_t i = 0; i < height; i++)
    {
        for (size_t j = 0; j < width; j++)
        {
            cout << mat[i][(j-i+width)%width] << ' ';
        }
        cout << endl;
    }

    return 0;
}


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

using namespace std;

typedef long long ll;
typedef long double ldb;

#define print(s) cout << (s) << endl;

bool cmp(pair<int, int> &a, pair<int, int> &b) {
    return a.second < b.second;
}

pair<int, int> find_largest_multiplicity(map<int, int> F, int n) {
    vector<int> T, S, Vf;
    int curr_T = 0, curr_S = 0;
    int f, N;
    int sumN = 0;
    Vf.push_back(0);
    T.push_back(0);
    S.push_back(0);
    for (auto it = F.begin(); it != F.end(); it++) {
        f = it->first;
        N = it->second;
        Vf.push_back(f);
        curr_T += f * N ;
        curr_S += N;
        T.push_back(curr_T);
        S.push_back(curr_S);
    }
    sumN = curr_S;
    int maxf = Vf[Vf.size() - 1];
    int k = (int) sqrt(n);
    int quantity;
    int Tk, Sk;
    int best_quantity = 0, best_k;
    while (k) {
        int idx = upper_bound(Vf.begin(), Vf.end(), k) - Vf.begin() - 1;
        Tk = T[idx];
        Sk = S[idx];
        quantity = Tk + k * (sumN - Sk);
        if (quantity >= k * k) {
            if (k * (quantity / k) > best_quantity) {
                best_k = k;
                best_quantity = k * (quantity / k);
            }
        }
        k--;
    }
    return make_pair(best_k, best_quantity);
}

int main() {
    int n, a;
    cin >> n;
    map<int, int> m;
    for (size_t i = 0; i < n; i++)
    {
        scanf("%d", &a);
        m[a]++;
    }
    map<int, vector<int>> F2N;
    map<int, int> F;
    for (auto p: m) {
        F2N[p.second].push_back(p.first);
        F[p.second]++;
    }
    int f, N, curr = 0;
    vector<int> T, fs;
    for (auto p: F) {
        f = p.first;
        N = p.second;
        curr += f * N - N;
        T.push_back(curr + f * f);
        fs.push_back(f);
    }
    pair<int, int> pp = find_largest_multiplicity(F, n);

    int k = pp.first;
    int quantity = pp.second;

    int height = k;
    int width = quantity / height;
    int cnt = 0;
    vector<vector<int>> mat(height, vector<int>(width));
    for (auto it = F2N.rbegin(); it != F2N.rend(); it++) {
        vector<int> v = it->second;
        f = min(it->first, k);
        for (auto x: v) {
            for (size_t i = 0; i < f; i++)
            {
                mat[cnt % height][cnt / height] = x;
                cnt++;
                if (cnt >= height * width) break;
            }
            if (cnt >= height * width) break;

        }
        if (cnt >= height * width) break;
    }
    cout << quantity << endl;
    cout << height << ' ' << width << endl;
    for (size_t i = 0; i < height; i++)
    {
        for (size_t j = 0; j < width; j++)
        {
            cout << mat[i][(j-i+width)%width] << ' ';
        }
        cout << endl;
    }

    return 0;
}


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

using namespace std;

typedef long long ll;
typedef long double ldb;

#define print(s) cout << (s) << endl;

int main() {
    int n, a;
    cin >> n;
    map<int, int> m;
    for (size_t i = 0; i < n; i++)
    {
        scanf("%d", &a);
        m[a]++;
    }

    map<int, int> F;
    for (auto p: m) F[p.second]++;
    vector<int> T(n+1, 0);
    int buf = m.size();
    int best_height = 0, best_size = 0;
    for (size_t i = 1; i <= n; i++)
    {
        T[i] = T[i-1] + buf;
        if (F.count(i)) buf -= F[i];
        if (i * i > T[i]) {
            i--; break;
        }
        if (i * (T[i] / i) > best_size) {
            best_height = i;
            best_size = i * (T[i] / i);
        }
    }
    int x = 0, y = 0;
    int height = best_height, width = best_size / best_height;
    vector<int> nums;
    for (auto p: m) {
        for (size_t i = 0; i < min(p.second, height); i++) nums.push_back(p.first);
    }
    //for (auto x: nums) cout << x << ' '; cout << endl;
    vector<vector<int>> mat(height, vector<int>(width));
    for (size_t i = 0; i < best_size; i++)
    {
        mat[x][y] = nums[best_size - 1 - i];
        x = (x + 1 + (y + 1 == width)) % height;
        y = (y + 1) % width;
    }
    cout << best_size << endl;
    cout << height << ' ' << width << endl;
    for (size_t i = 0; i < best_size; i++)
    {
        cout << mat[i / width][i % width] << ' ';
        if ((i + 1) % width == 0) cout << endl;
    }
    return 0;
}


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

using namespace std;

typedef long long ll;
typedef long double ldb;

#define print(s) cout << (s) << endl;

int main() {
    int n, a;
    cin >> n;
    map<int, int> m;
    for (size_t i = 0; i < n; i++)
    {
        scanf("%d", &a);
        m[a]++;
    }

    map<int, int> F;
    for (auto p: m) F[p.second]++;
    vector<int> T(n+1, 0);
    int buf = m.size();
    int best_height = 0, best_size = 0;
    for (size_t i = 1; i <= n; i++)
    {
        T[i] = T[i-1] + buf;
        if (F.count(i)) buf -= F[i];
        if (i * i > T[i]) {
            i--; break;
        }
        if (i * (T[i] / i) > best_size) {
            best_height = i;
            best_size = i * (T[i] / i);
        }
    }
    int x = 0, y = 0;
    int height = best_height, width = best_size / best_height;
    vector<int> nums;
    for (auto p: m) {
        for (size_t i = 0; i < min(p.second, height); i++) nums.push_back(p.first);
    }
    //for (auto x: nums) cout << x << ' '; cout << endl;
    int circ = 0;
    vector<vector<int>> mat(height, vector<int>(width));
    for (size_t i = 0; i < best_size; i++)
    {
        mat[x][y] = nums[best_size - 1 - i];
        x++;
        y = (y + 1) % width;
        if (x == height) {
            x = 0;
            y = (++circ) % width;
        }
    }
    cout << best_size << endl;
    cout << height << ' ' << width << endl;
    for (size_t i = 0; i < best_size; i++)
    {
        cout << mat[i / width][i % width] << ' ';
        if ((i + 1) % width == 0) cout << endl;
    }
    return 0;
}


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

using namespace std;

typedef long long ll;
typedef long double ldb;

#define print(s) cout << (s) << endl;

bool cmp(pair<int, int> &a, pair<int, int> &b) {
    return a.second < b.second;
}

pair<int, int> find_largest_multiplicity(map<int, int> F, int n) {
    vector<int> T, S, Vf;
    int curr_T = 0, curr_S = 0;
    int f, N;
    int sumN = 0;
    T.push_back(0);
    S.push_back(0);
    for (auto it = F.begin(); it != F.end(); it++) {
        f = it->first;
        N = it->second;
        Vf.push_back(f);
        curr_T += f * N ;
        curr_S += N;
        T.push_back(curr_T);
        S.push_back(curr_S);
    }
    sumN = curr_S;
    int maxf = Vf[Vf.size() - 1];
    int k = maxf;
    int quantity;
    int Tk, Sk;
    while (k) {
        Tk = *lower_bound(T.begin(), T.end(), k);
        Sk = *lower_bound(T.begin(), T.end(), k);
        quantity = Tk + k * (sumN - Sk);
        if (quantity >= k * k) break;
        k--;
    }
    return make_pair(k, quantity);
}

int main() {
    int n, a;
    cin >> n;
    map<int, int> m;
    for (size_t i = 0; i < n; i++)
    {
        scanf("%d", &a);
        m[a]++;
    }
    map<int, vector<int>> F2N;
    map<int, int> F;
    for (auto p: m) {
        F2N[p.second].push_back(p.first);
        F[p.second]++;
    }
    int f, N, curr = 0;
    vector<int> T, fs;
    for (auto p: F) {
        f = p.first;
        N = p.second;
        curr += f * N - N;
        T.push_back(curr + f * f);
        fs.push_back(f);
    }
    pair<int, int> pp = find_largest_multiplicity(F, n);
    int k = pp.first;
    int quantity = pp.second;
    int height = k, width = quantity / k;
    int best_quantity = height * width;
    int best_height = height;
    while (1) {
        height++;
        width = quantity / height;
        if (height > width) break;
        if (height * width > best_quantity) {
            best_height = height;
            best_quantity = height * width;
        }
    }

    height = best_height;
    width = best_quantity / height;
    int cnt = 0;
    vector<vector<int>> mat(height, vector<int>(width));
    for (auto it = F2N.rbegin(); it != F2N.rend(); it++) {
        vector<int> v = it->second;
        f = min(it->first, k);
        for (auto x: v) {
            for (size_t i = 0; i < f; i++)
            {
                mat[cnt % height][cnt / height] = x;
                cnt++;
                if (cnt > height * width) break;
            }
        }
        if (cnt > height * width) break;
    }
    cout << best_quantity << endl;
    cout << height << ' ' << width << endl;
    for (size_t i = 0; i < height; i++)
    {
        for (size_t j = 0; j < width; j++)
        {
            cout << mat[i][(j-i+width)%width] << ' ';
        }
        cout << endl;
    }

    return 0;
}


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

using namespace std;

typedef long long ll;
typedef long double ldb;

#define print(s) cout << (s) << endl;

int main() {
    int n, a;
    cin >> n;
    map<int, int> m;
    for (size_t i = 0; i < n; i++)
    {
        scanf("%d", &a);
        m[a]++;
    }

    map<int, int> F;
    for (auto p: m) F[p.second]++;
    vector<int> T(n+1, 0);
    int buf = m.size();
    int best_height = 0, best_size = 0;
    for (size_t i = 1; i <= n; i++)
    {
        T[i] = T[i-1] + buf;
        if (F.count(i)) buf -= F[i];
        if (i * i > T[i]) {
            i--; break;
        }
        if (i * (T[i] / i) > best_size) {
            best_height = i;
            best_size = i * (T[i] / i);
        }
    }
    int x = 0, y = 0;
    int height = best_height, width = best_size / best_height;
    vector<int> nums;
    for (auto p: m) {
        for (size_t i = 0; i < min(p.second, height); i++) nums.push_back(p.first);
    }
    vector<vector<int>> mat(height, vector<int>(width));
    for (size_t i = 0; i < best_size; i++)
    {
        mat[x][y] = nums[i];
        x = (x + 1) % height;
        y = (y + 1) % width;
    }
    cout << best_size << endl;
    cout << height << ' ' << width << endl;
    for (size_t i = 0; i < best_size; i++)
    {
        cout << mat[i / width][i % width] << ' ';
        if ((i + 1) % width == 0) cout << endl;
    }
    return 0;
}


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

using namespace std;

typedef long long ll;
typedef long double ldb;

#define print(s) cout << (s) << endl;

int main() {
    int n, a;
    cin >> n;
    map<int, int> m;
    for (size_t i = 0; i < n; i++)
    {
        scanf("%d", &a);
        m[a]++;
    }

    map<int, int> F;
    for (auto p: m) F[p.second]++;
    vector<int> T(n+1, 0);
    int buf = m.size();
    int best_height = 0, best_size = 0;
    for (size_t i = 1; i <= n; i++)
    {
        T[i] = T[i-1] + buf;
        if (F.count(i)) buf -= F[i];
        if (i * i > T[i]) {
            i--; break;
        }
        if (i * (T[i] / i) > best_size) {
            best_height = i;
            best_size = i * (T[i] / i);
        }
    }
    int x = 0, y = 0;
    int height = best_height, width = best_size / best_height;
    vector<int> nums;
    for (auto p: m) {
        for (size_t i = 0; i < min(p.second, height); i++) nums.push_back(p.first);
    }
    //for (auto x: nums) cout << x << ' '; cout << endl;
    int circ = 0;
    vector<vector<int>> mat(height, vector<int>(width));
    for (size_t i = 0; i < best_size; i++)
    {
        mat[x][y] = nums[i];
        x = (x + 1) % height;
        y = (y + 1) % width;
        if ((i + 1) % height == 0 && (i + 1) % width == 0) y = (y + 1) % width;
    }
    cout << best_size << endl;
    cout << height << ' ' << width << endl;
    for (size_t i = 0; i < best_size; i++)
    {
        cout << mat[i / width][i % width] << ' ';
        if ((i + 1) % width == 0) cout << endl;
    }
    return 0;
}


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

using namespace std;

typedef long long ll;
typedef long double ldb;

#define print(s) cout << (s) << endl;

bool cmp(pair<int, int> &a, pair<int, int> &b) {
    return a.second < b.second;
}

pair<int, int> find_largest_multiplicity(map<int, int> F, int n) {
    vector<int> T, S, Vf;
    int curr_T = 0, curr_S = 0;
    int f, N;
    int sumN = 0;
    Vf.push_back(0);
    T.push_back(0);
    S.push_back(0);
    for (auto it = F.begin(); it != F.end(); it++) {
        f = it->first;
        N = it->second;
        Vf.push_back(f);
        curr_T += f * N ;
        curr_S += N;
        T.push_back(curr_T);
        S.push_back(curr_S);
    }
    sumN = curr_S;
    int maxf = Vf[Vf.size() - 1];
    int k = maxf;
    int quantity;
    int Tk, Sk;
    int best_quantity = 0, best_k;
    while (k) {
        int idx = upper_bound(Vf.begin(), Vf.end(), k) - Vf.begin() - 1;
        Tk = T[idx];
        Sk = S[idx];
        quantity = Tk + k * (sumN - Sk);
        if (quantity >= k * k) {
            if (k * (quantity / k) > best_quantity) {
                best_k = k;
                best_quantity = k * (quantity / k);
            }
        }
        k--;
    }
    return make_pair(best_k, best_quantity);
}

int main() {
    int n, a;
    cin >> n;
    map<int, int> m;
    for (size_t i = 0; i < n; i++)
    {
        scanf("%d", &a);
        m[a]++;
    }
    map<int, vector<int>> F2N;
    map<int, int> F;
    for (auto p: m) {
        F2N[p.second].push_back(p.first);
        F[p.second]++;
    }
    int f, N, curr = 0;
    vector<int> T, fs;
    for (auto p: F) {
        f = p.first;
        N = p.second;
        curr += f * N - N;
        T.push_back(curr + f * f);
        fs.push_back(f);
    }
    pair<int, int> pp = find_largest_multiplicity(F, n);

    int k = pp.first;
    int quantity = pp.second;

    int height = k;
    int width = quantity / height;
    int cnt = 0;
    vector<vector<int>> mat(height, vector<int>(width));
    for (auto it = F2N.rbegin(); it != F2N.rend(); it++) {
        vector<int> v = it->second;
        f = min(it->first, k);
        for (auto x: v) {
            for (size_t i = 0; i < f; i++)
            {
                mat[cnt % height][cnt / height] = x;
                cnt++;
                if (cnt >= height * width) break;
            }
            if (cnt >= height * width) break;

        }
        if (cnt >= height * width) break;
    }
    cout << quantity << endl;
    cout << height << ' ' << width << endl;
    for (size_t i = 0; i < height; i++)
    {
        for (size_t j = 0; j < width; j++)
        {
            cout << mat[i][(j-i+width)%width] << ' ';
        }
        cout << endl;
    }

    return 0;
}


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

using namespace std;

typedef long long ll;
typedef long double ldb;

#define print(s) cout << (s) << endl;

int main() {
    int n, a;
    cin >> n;
    map<int, int> m;
    for (size_t i = 0; i < n; i++)
    {
        scanf("%d", &a);
        m[a]++;
    }

    map<int, int> F;
    for (auto p: m) F[p.second]++;
    vector<int> T(n+1, 0);
    int buf = m.size();
    int best_height = 0, best_size = 0;
    for (size_t i = 1; i <= n; i++)
    {
        T[i] = T[i-1] + buf;
        if (F.count(i)) buf -= F[i];
        if (i * i > T[i]) {
            i--; break;
        }
        if (i * (T[i] / i) > best_size) {
            best_height = i;
            best_size = i * (T[i] / i);
        }
    }
    int x = 0, y = 0;
    int height = best_height, width = best_size / best_height;
    vector<int> nums;
    for (auto p: m) {
        for (size_t i = 0; i < min(p.second, height); i++) nums.push_back(p.first);
    }
    vector<vector<int>> mat(height, vector<int>(width));
    for (size_t i = 0; i < best_size; i++)
    {
        mat[x][y] = nums[i];
        x = (x + 1) % height;
        y = (y + 1) % width;
    }
    for (size_t i = 0; i < best_size; i++)
    {
        cout << mat[i / width][i % width] << ' ';
        if ((i + 1) % width == 0) cout << endl;
    }
    return 0;
}


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

using namespace std;

typedef long long ll;
typedef long double ldb;

#define print(s) cout << (s) << endl;

bool cmp(pair<int, int> &a, pair<int, int> &b) {
    return a.second < b.second;
}

pair<int, int> find_largest_multiplicity(map<int, int> F, int n) {
    vector<int> T, S, Vf;
    int curr_T = 0, curr_S = 0;
    int f, N;
    int sumN = 0;
    Vf.push_back(0);
    T.push_back(0);
    S.push_back(0);
    for (auto it = F.begin(); it != F.end(); it++) {
        f = it->first;
        N = it->second;
        Vf.push_back(f);
        curr_T += f * N ;
        curr_S += N;
        T.push_back(curr_T);
        S.push_back(curr_S);
    }
    sumN = curr_S;
    int maxf = Vf[Vf.size() - 1];
    int k = maxf;
    int quantity;
    int Tk, Sk;
    while (k) {
        int idx = upper_bound(Vf.begin(), Vf.end(), k) - Vf.begin() - 1;
        Tk = T[idx];
        Sk = S[idx];
        quantity = Tk + k * (sumN - Sk);
        if (quantity >= k * k) break;
        k--;
    }
    return make_pair(k, quantity);
}

int main() {
    int n, a;
    cin >> n;
    map<int, int> m;
    for (size_t i = 0; i < n; i++)
    {
        scanf("%d", &a);
        m[a]++;
    }
    map<int, vector<int>> F2N;
    map<int, int> F;
    for (auto p: m) {
        F2N[p.second].push_back(p.first);
        F[p.second]++;
    }
    int f, N, curr = 0;
    vector<int> T, fs;
    for (auto p: F) {
        f = p.first;
        N = p.second;
        curr += f * N - N;
        T.push_back(curr + f * f);
        fs.push_back(f);
    }
    pair<int, int> pp = find_largest_multiplicity(F, n);
    int k = pp.first;
    int quantity = pp.second;
    int height = k, width = quantity / k;
    int best_quantity = height * width;
    int best_height = height;
    while (1) {
        height++;
        width = quantity / height;
        if (height > width) break;
        if (height * width > best_quantity) {
            best_height = height;
            best_quantity = height * width;
        }
    }

    height = best_height;
    width = best_quantity / height;
    int cnt = 0;
    vector<vector<int>> mat(height, vector<int>(width));
    for (auto it = F2N.rbegin(); it != F2N.rend(); it++) {
        vector<int> v = it->second;
        f = min(it->first, k);
        for (auto x: v) {
            for (size_t i = 0; i < f; i++)
            {
                mat[cnt % height][cnt / height] = x;
                cnt++;
                if (cnt > height * width) break;
            }
        }
        if (cnt > height * width) break;
    }
    cout << best_quantity << endl;
    cout << height << ' ' << width << endl;
    for (size_t i = 0; i < height; i++)
    {
        for (size_t j = 0; j < width; j++)
        {
            cout << mat[i][(j-i+width)%width] << ' ';
        }
        cout << endl;
    }

    return 0;
}


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

using namespace std;

typedef long long ll;
typedef long double ldb;

#define print(s) cout << (s) << endl;

bool cmp(pair<int, int> &a, pair<int, int> &b) {
    return a.second < b.second;
}

pair<int, int> find_largest_multiplicity(map<int, int> F, int n) {
    vector<int> T, S, Vf;
    int curr_T = 0, curr_S = 0;
    int f, N;
    int sumN = 0;
    Vf.push_back(0);
    T.push_back(0);
    S.push_back(0);
    for (auto it = F.begin(); it != F.end(); it++) {
        f = it->first;
        N = it->second;
        Vf.push_back(f);
        curr_T += f * N ;
        curr_S += N;
        T.push_back(curr_T);
        S.push_back(curr_S);
    }
    sumN = curr_S;
    int maxf = Vf[Vf.size() - 1];
    int k = maxf;
    int quantity;
    int Tk, Sk;
    while (k) {
        int idx = lower_bound(Vf.begin(), Vf.end(), k) - Vf.begin();
        Tk = T[idx];
        Sk = S[idx];
        quantity = Tk + k * (sumN - Sk);
        if (quantity >= k * k) break;
        k--;
    }
    return make_pair(k, quantity);
}

int main() {
    int n, a;
    cin >> n;
    map<int, int> m;
    for (size_t i = 0; i < n; i++)
    {
        scanf("%d", &a);
        m[a]++;
    }
    map<int, vector<int>> F2N;
    map<int, int> F;
    for (auto p: m) {
        F2N[p.second].push_back(p.first);
        F[p.second]++;
    }
    int f, N, curr = 0;
    vector<int> T, fs;
    for (auto p: F) {
        f = p.first;
        N = p.second;
        curr += f * N - N;
        T.push_back(curr + f * f);
        fs.push_back(f);
    }
    pair<int, int> pp = find_largest_multiplicity(F, n);
    int k = pp.first;
    int quantity = pp.second;
    int height = k, width = quantity / k;
    int best_quantity = height * width;
    int best_height = height;
    while (1) {
        height++;
        width = quantity / height;
        if (height > width) break;
        if (height * width > best_quantity) {
            best_height = height;
            best_quantity = height * width;
        }
    }

    height = best_height;
    width = best_quantity / height;
    int cnt = 0;
    vector<vector<int>> mat(height, vector<int>(width));
    for (auto it = F2N.rbegin(); it != F2N.rend(); it++) {
        vector<int> v = it->second;
        f = min(it->first, k);
        for (auto x: v) {
            for (size_t i = 0; i < f; i++)
            {
                mat[cnt % height][cnt / height] = x;
                cnt++;
                if (cnt > height * width) break;
            }
        }
        if (cnt > height * width) break;
    }
    cout << best_quantity << endl;
    cout << height << ' ' << width << endl;
    for (size_t i = 0; i < height; i++)
    {
        for (size_t j = 0; j < width; j++)
        {
            cout << mat[i][(j-i+width)%width] << ' ';
        }
        cout << endl;
    }

    return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> ii;
typedef pair<ii,int> iii;
typedef vector<iii> viii;
typedef pair<ll,ll> pll;
typedef vector<ii> vii;
typedef vector<int> vi;
typedef vector<ll> vll;
typedef vector<string> vs;
#define pb push_back
#define INF 1000000000
#define LINF (ll)INF*INF
#define all(x) x.begin(),x.end()
#define F first
#define S second
/*
	It's good to be back!
*/
int main()
{
	ios_base::sync_with_stdio(false);
	cin.tie(0);cout.tie(0);
	map<int,int> mp;
	int n;cin>>n;
	vector<int> a(n);
	vector<int> freq;
	for(int i=0;i<n;i++)
	{
		cin>>a[i];
		mp[a[i]]++;
	}
	for(auto it:mp)
		freq.pb(it.second);
	sort(all(freq));
	vector<int> sum(freq.size()+1);
	sum[0] = 0;
	for(int i=1;i<sum.size();i++)
		sum[i]= sum[i-1]+freq[i-1];
	int mxfreq = freq.back();
	int marea = 0;
	int ind = 0;
	for(int mxd=1;mxd<=mxfreq;mxd++)
	{
		int tot = 0;
		auto it = lower_bound(freq.begin(),freq.end(),mxd);
		int lower = (it-freq.begin());
		int upper = (int)freq.size()-lower;
		// cout<<lower<<" "<<upper<<endl;
		tot = sum[lower]+upper*mxd;
		if(tot-mxd >= mxd*mxd-mxd){
		int area = (tot/mxd)*mxd;
		// cout<<tot<<" FREQ: "<<mxd<<" "<<area<<endl;
		if(area > marea)
		{
			marea = area;
			ind = mxd;
		}
		}
	}
	int row = ind;
	int col = marea/row;
	// cout<<"ROW: "<<row<<" "<<col<<endl;
	vector<int> num(row*col);
	vector<vector<int> > mat(row,vector<int>(col));
	int x = 0;
	vector<ii> a2;
	for(auto it:mp)
	{
		// for(int i=0;i<min(it.second,ind)&&x<marea;i++)
			// num[x++] = it.first;
		// mp2[min(it.second,)]
		a2.pb({min(it.second,ind),it.first});
	}
	sort(a2.rbegin(),a2.rend());
	for(auto it:a2)
	{
		for(int i=0;i<it.first&&x<marea;i++)
			num[x++] = it.second;
	}

	x = 0;
	for(int i=0;i<col;i++)
	{
		int ii=i,ij=0;
		for(ij;ij<row;ij++)
		{
			// cout<<ij<<" "<<ii<<endl;
			mat[ij][ii]=num[x++];
			ii=(ii+1)%(col);
		}
	// 	for(auto it:mat)
	// {
	// 	for(auto it2:it)
	// 		cout<<it2<<" ";
	// 	cout<<"\n";
	// }
	}
	cout<<marea<<endl;
	cout<<row<<" "<<col<<endl;
	for(auto it:mat)
	{
		for(auto it2:it)
			cout<<it2<<" ";
		cout<<"\n";
	}
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> ii;
typedef pair<ii,int> iii;
typedef vector<iii> viii;
typedef pair<ll,ll> pll;
typedef vector<ii> vii;
typedef vector<int> vi;
typedef vector<ll> vll;
typedef vector<string> vs;
#define pb push_back
#define INF 1000000000
#define LINF (ll)INF*INF
#define all(x) x.begin(),x.end()
#define F first
#define S second
/*
	It's good to be back!
*/
int main()
{
	ios_base::sync_with_stdio(false);
	cin.tie(0);cout.tie(0);
	map<int,int> mp;
	int n;cin>>n;
	vector<int> a(n);
	vector<int> freq;
	for(int i=0;i<n;i++)
	{
		cin>>a[i];
		mp[a[i]]++;
	}
	for(auto it:mp)
		freq.pb(it.second);
	sort(all(freq));
	vector<int> sum(freq.size()+1);
	sum[0] = 0;
	for(int i=1;i<sum.size();i++)
		sum[i]= sum[i-1]+freq[i-1];
	int mxfreq = freq.back();
	int marea = 0;
	int ind = 0;
	int sqt = sqrt(n);
	for(int mxd=1;mxd<=sqt;mxd++)
	{
		int tot = 0;
		auto it = lower_bound(freq.begin(),freq.end(),mxd);
		int lower = (it-freq.begin());
		int upper = (int)freq.size()-lower;
		// cout<<lower<<" "<<upper<<endl;
		tot = sum[lower]+upper*mxd;
		if(tot-mxd >= mxd*mxd-mxd){
		int area = (tot/mxd)*mxd;
		// cout<<tot<<" FREQ: "<<mxd<<" "<<area<<endl;
		if(area > marea)
		{
			marea = area;
			ind = mxd;
		}
		}
	}
	int row = ind;
	int col = marea/row;
	// cout<<"ROW: "<<row<<" "<<col<<endl;
	vector<int> num(row*col);
	vector<vector<int> > mat(row,vector<int>(col));
	int x = 0;
	vector<ii> a2;
	for(auto it:mp)
	{
		// for(int i=0;i<min(it.second,ind)&&x<marea;i++)
			// num[x++] = it.first;
		// mp2[min(it.second,)]
		a2.pb({min(it.second,ind),it.first});
	}
	sort(a2.rbegin(),a2.rend());
	for(auto it:a2)
	{
		for(int i=0;i<it.first&&x<marea;i++)
			num[x++] = it.second;
	}

	x = 0;
	for(int i=0;i<col;i++)
	{
		int ii=i,ij=0;
		for(ij;ij<row;ij++)
		{
			// cout<<ij<<" "<<ii<<endl;
			mat[ij][ii]=num[x++];
			ii=(ii+1)%(col);
		}
	// 	for(auto it:mat)
	// {
	// 	for(auto it2:it)
	// 		cout<<it2<<" ";
	// 	cout<<"\n";
	// }
	}
	cout<<marea<<endl;
	cout<<row<<" "<<col<<endl;
	for(auto it:mat)
	{
		for(auto it2:it)
			cout<<it2<<" ";
		cout<<"\n";
	}
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> ii;
typedef pair<ii,int> iii;
typedef vector<iii> viii;
typedef pair<ll,ll> pll;
typedef vector<ii> vii;
typedef vector<int> vi;
typedef vector<ll> vll;
typedef vector<string> vs;
#define pb push_back
#define INF 1000000000
#define LINF (ll)INF*INF
#define all(x) x.begin(),x.end()
#define F first
#define S second
/*
	It's good to be back!
*/
int main()
{
	ios_base::sync_with_stdio(false);
	cin.tie(0);cout.tie(0);
	map<int,int> mp;
	int n;cin>>n;
	vector<int> a(n);
	vector<int> freq;
	for(int i=0;i<n;i++)
	{
		cin>>a[i];
		mp[a[i]]++;
	}
	for(auto it:mp)
		freq.pb(it.second);
	sort(all(freq));
	vector<int> sum(freq.size()+1);
	sum[0] = 0;
	for(int i=1;i<sum.size();i++)
		sum[i]= sum[i-1]+freq[i-1];
	int mxfreq = freq.back();
	int marea = 0;
	int ind = 0;
	for(int mxd=1;mxd<=mxfreq;mxd++)
	{
		int tot = 0;
		auto it = lower_bound(freq.begin(),freq.end(),mxd);
		int lower = (it-freq.begin());
		int upper = (int)freq.size()-lower;
		// cout<<lower<<" "<<upper<<endl;
		tot = sum[lower]+upper*mxd;
		if(tot-mxd >= mxd*mxd-mxd){
		int area = (tot/mxd)*mxd;
		// cout<<tot<<" FREQ: "<<mxd<<" "<<area<<endl;
		if(area > marea)
		{
			marea = area;
			ind = mxd;
		}
		}
	}
	int row = ind;
	int col = marea/row;
	// cout<<"ROW: "<<row<<" "<<col<<endl;
	vector<int> num(row*col);
	vector<vector<int> > mat(row,vector<int>(col));
	int x = 0;
	for(auto it:mp)
	{
		for(int i=0;i<min(it.second,ind)&&x<marea;i++)
			num[x++] = it.first;
	}

	x = 0;
	for(int i=0;i<col;i++)
	{
		int ii=i,ij=0;
		for(ij;ij<row;ij++)
		{
			// cout<<ij<<" "<<ii<<endl;
			mat[ij][ii]=num[x++];
			ii=(ii+1)%(col);
		}
	// 	for(auto it:mat)
	// {
	// 	for(auto it2:it)
	// 		cout<<it2<<" ";
	// 	cout<<"\n";
	// }
	}
	cout<<marea<<endl;
	cout<<row<<" "<<col<<endl;
	for(auto it:mat)
	{
		for(auto it2:it)
			cout<<it2<<" ";
		cout<<"\n";
	}
	return 0;
}


//SW4gdGhlIE5hbWUgb2YgR29k
//WWEgQWxp

#include <bits/stdc++.h>

#define err(A) cout << #A << " = " << (A) << endl

using namespace std;

const int maxn = 400400;

int f[maxn];

int n;

map<int, int> cnt;
pair<int, int> a[maxn];

int k;

vector<int> r[maxn];

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

  for (int i = 1; i * i < maxn; i ++)
    for (int j = i * i; j < maxn; j += i)
      f[j] = i;

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

  sort(a, a + n);

  for (int i = 0; i < n; i ++)
    if (f[i + 1] >= a[i].first)
      k = i + 1;

  int x = f[k];
  int y = k / x;

  for (int i = 0; i < y; i ++)
    r[i].resize(x);

  for (int I = 0, J = 0, i = k; i --; )
    if (cnt[a[i].second])
      {
	cnt[a[i].second] = 0;
	for (int j = 0; j < a[i].first; j ++)
	  {
	    r[I][J] = a[i].second;
	    J ++;
	    I += J / x;
	    J %= x;
	  }
      }

  cout << k << "\n";
  cout << y << " " << x << "\n";

  for (int i = 0; i < y; i ++, cout << "\n")
    for (int j = 0; j < x; j ++)
      cout << r[(i - j + y) % y][j] << " ";

  return 0;
}


//SW4gdGhlIE5hbWUgb2YgR29k
//WWEgQWxp

#include <bits/stdc++.h>

#define err(A) cout << #A << " = " << (A) << endl

using namespace std;

const int maxn = 400400;

int f[maxn];

int n;

map<int, int> cnt;
pair<int, int> a[maxn];

int k;

vector<int> r[maxn];

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

  for (int i = 1; i * i < maxn; i ++)
    for (int j = i * i; j < maxn; j += i)
      f[j] = i;

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

  sort(a, a + n);

  for (int i = 0; i < n; i ++)
    if (f[i + 1] >= a[i].second)
      k = i + 1;

  int x = f[k];
  int y = k / x;

  for (int i = 0; i < y; i ++)
    r[i].resize(x);

  for (int I = 0, J = 0, i = k; i --; )
    if (cnt[a[i].first])
      {
	cnt[a[i].first] = 0;
	for (int j = 0; j < a[i].second; j ++)
	  {
	    r[I][J] = a[i].first;
	    J ++;
	    I += J / x;
	    J %= x;
	  }
      }

  cout << k << endl;
  cout << y << " " << x << endl;

  for (int i = 0; i < y; i ++, cout << endl)
    for (int j = 0; j < x; j ++)
      cout << r[(i - j + y) % y][j] << " ";

  return 0;
}


#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <vector>
#include <string>
#include <cstdio>
#include <algorithm>
#include <set>
#include <map>
#include <math.h>
#include <cmath>
#include <queue>
#include <iomanip>
#include <bitset>
#include <numeric>
#include <stack>
#include <deque>
#include <memory.h>
#include <string>
#include <unordered_map>

#define ull unsigned long long
#define mp make_pair
#define pb push_back
#define all(x) (x).begin(),(x).end()
#define rall(x) (x).rbegin(),(x).rend()
#define vI vector<int>
#define vvI vector<vector<int>>
#define vLL vector<ll>
#define vS vector<string>
#define fori(i, n) for(int (i)=0; (i)<n; (i)++)
#define forn(it,from,to) for(int (it)=from; (it)<to; (it)++)
#define forI(tmp) for(auto(it)=(tmp).begin();(it)!=(tmp).end();(it)++)
#define PI 3.14159265356
#define LD long double
#define sc(a) scanf("%d", &(a))
#define scc(a) scanf("%I64d", &(a))
#pragma comment (linker, "/STACK:5000000000")
typedef long long ll;
const ll mod = 1000000007;
int Inf = (int)2e9;
ll LINF = (ll)1e18 + 1e17;

using namespace std;

map<int, int> cnt;

int check(int row)
{
	int can = 0;
	forI(cnt)
	{
		can += min(it->second, row);
	}
	return can;
}

int main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
#ifdef _DEBUG
	freopen("input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);
#endif
	int n;
	cin >> n;
	fori(i, n)
	{
		int x;
		cin >> x;
		cnt[x]++;
	}

	int row = 1, col = 1;

	for (int i = 1; i * i <= n; i++)
	{
		int can = check(i);
		int j = can / i;
		if (i * j > row * col && j >= i)
		{
			row = i, col = j;
		}
	}

	cout << row * col << endl;
	cout << row << " " << col << endl;
	vector<vector<int>> ans(row, vector<int>(col));

	deque<int> a;
	forI(cnt)
	{
		int x = min(it->second, row);
		fori(i, x)
		{
			if (x == row)
				a.push_front(it->first);
			else
				a.push_back(it->first);
		}
		if (a.size() >= row*col)
			break;
	}

	int id = 0;
	for (int j = 0; j < col; j++)
	{
		for (int i = 0; i < row; i++)
		{
			int jj = (j + i) % col;
			ans[i][jj] = a[id];
			id++;
		}
	}
	fori(i, row)
	{
		fori(j, col)
		{
			cout << ans[i][j] << " ";
		}
		cout << endl;
	}

	return 0;
}


#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <vector>
#include <string>
#include <cstdio>
#include <algorithm>
#include <set>
#include <map>
#include <math.h>
#include <cmath>
#include <queue>
#include <iomanip>
#include <bitset>
#include <numeric>
#include <stack>
#include <deque>
#include <memory.h>
#include <string>
#include <unordered_map>

#define ull unsigned long long
#define mp make_pair
#define pb push_back
#define all(x) (x).begin(),(x).end()
#define rall(x) (x).rbegin(),(x).rend()
#define vI vector<int>
#define vvI vector<vector<int>>
#define vLL vector<ll>
#define vS vector<string>
#define fori(i, n) for(int (i)=0; (i)<n; (i)++)
#define forn(it,from,to) for(int (it)=from; (it)<to; (it)++)
#define forI(tmp) for(auto(it)=(tmp).begin();(it)!=(tmp).end();(it)++)
#define PI 3.14159265356
#define LD long double
#define sc(a) scanf("%d", &(a))
#define scc(a) scanf("%I64d", &(a))
#pragma comment (linker, "/STACK:5000000000")
typedef long long ll;
const ll mod = 1000000007;
int Inf = (int)2e9;
ll LINF = (ll)1e18 + 1e17;

using namespace std;

map<int, int> cnt;

int check(int row)
{
	int can = 0;
	forI(cnt)
	{
		can += min(it->second, row);
	}
	return can;
}

int main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
#ifdef _DEBUG
	freopen("input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);
#endif
	int n;
	cin >> n;
	fori(i, n)
	{
		int x;
		cin >> x;
		cnt[x]++;
	}
	int l = 0, r = n + 1;
	while (r - l > 1)
	{
		int m = (r + l) / 2;
		int row = sqrt(m);
		int col = (m + row - 1) / row;
		int can = check(min(row, col));
		if (can >= m)
			l = m;
		else
			r = m;
	}
	int row = sqrt(l);
	int col = (l + row - 1) / row;
	cout << row * col << endl;
	cout << row << " " << col << endl;
	vector<vector<int>> ans(row, vector<int>(col));

	deque<int> a;
	forI(cnt)
	{
		int x = min(it->second, row);
		fori(i, x)
		{
			if (x == row)
				a.push_front(it->first);
			else
				a.push_back(it->first);
		}
		if (a.size() >= row*col)
			break;
	}

	int id = 0;
	for (int j = 0; j < col; j++)
	{
		for (int i = 0; i < row; i++)
		{
			int jj = (j + i) % col;
			ans[i][jj] = a[id];
			id++;
		}
	}
	fori(i, row)
	{
		fori(j, col)
		{
			cout << ans[i][j] << " ";
		}
		cout << endl;
	}

	return 0;
}


#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <vector>
#include <string>
#include <cstdio>
#include <algorithm>
#include <set>
#include <map>
#include <math.h>
#include <cmath>
#include <queue>
#include <iomanip>
#include <bitset>
#include <numeric>
#include <stack>
#include <deque>
#include <memory.h>
#include <string>
#include <unordered_map>

#define ull unsigned long long
#define mp make_pair
#define pb push_back
#define all(x) (x).begin(),(x).end()
#define rall(x) (x).rbegin(),(x).rend()
#define vI vector<int>
#define vvI vector<vector<int>>
#define vLL vector<ll>
#define vS vector<string>
#define fori(i, n) for(int (i)=0; (i)<n; (i)++)
#define forn(it,from,to) for(int (it)=from; (it)<to; (it)++)
#define forI(tmp) for(auto(it)=(tmp).begin();(it)!=(tmp).end();(it)++)
#define PI 3.14159265356
#define LD long double
#define sc(a) scanf("%d", &(a))
#define scc(a) scanf("%I64d", &(a))
#pragma comment (linker, "/STACK:5000000000")
typedef long long ll;
const ll mod = 1000000007;
int Inf = (int)2e9;
ll LINF = (ll)1e18 + 1e17;

using namespace std;

map<int, int> cnt;
vector<int> b;
int check(int row)
{
	int can = 0;
	fori(i, b.size())
	{
		can += min(b[i], row);
	}
	return can;
}

int main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
#ifdef _DEBUG
	freopen("input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);
#endif
	int n;
	cin >> n;
	fori(i, n)
	{
		int x;
		cin >> x;
		cnt[x]++;
	}
	forI(cnt)
	{
		b.push_back(it->second);
	}

	int row = 1, col = 1;

	for (int i = 1; i * i <= n; i++)
	{
		int can = check(i);
		int j = can / i;
		if (i * j > row * col && j >= i)
		{
			row = i, col = j;
		}
	}

	cout << row * col << endl;
	cout << row << " " << col << endl;
	vector<vector<int>> ans(row, vector<int>(col));

	deque<int> a;
	forI(cnt)
	{
		int x = min(it->second, row);
		fori(i, x)
		{
			if (x == row)
				a.push_front(it->first);
			else
				a.push_back(it->first);
		}
		if (a.size() >= row*col)
			break;
	}

	int id = 0;
	for (int j = 0; j < col; j++)
	{
		for (int i = 0; i < row; i++)
		{
			int jj = (j + i) % col;
			ans[i][jj] = a[id];
			id++;
		}
	}
	fori(i, row)
	{
		fori(j, col)
		{
			cout << ans[i][j] << " ";
		}
		cout << endl;
	}

	return 0;
}


#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <vector>
#include <string>
#include <cstdio>
#include <algorithm>
#include <set>
#include <map>
#include <math.h>
#include <cmath>
#include <queue>
#include <iomanip>
#include <bitset>
#include <numeric>
#include <stack>
#include <deque>
#include <memory.h>
#include <string>
#include <unordered_map>

#define ull unsigned long long
#define mp make_pair
#define pb push_back
#define all(x) (x).begin(),(x).end()
#define rall(x) (x).rbegin(),(x).rend()
#define vI vector<int>
#define vvI vector<vector<int>>
#define vLL vector<ll>
#define vS vector<string>
#define fori(i, n) for(int (i)=0; (i)<n; (i)++)
#define forn(it,from,to) for(int (it)=from; (it)<to; (it)++)
#define forI(tmp) for(auto(it)=(tmp).begin();(it)!=(tmp).end();(it)++)
#define PI 3.14159265356
#define LD long double
#define sc(a) scanf("%d", &(a))
#define scc(a) scanf("%I64d", &(a))
#pragma comment (linker, "/STACK:5000000000")
typedef long long ll;
const ll mod = 1000000007;
int Inf = (int)2e9;
ll LINF = (ll)1e18 + 1e17;

using namespace std;

unordered_map<int, int> cnt;

int check(int row)
{
	int can = 0;
	forI(cnt)
	{
		can += min(it->second, row);
	}
	return can;
}

int main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
#ifdef _DEBUG
	freopen("input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);
#endif
	int n;
	cin >> n;
	fori(i, n)
	{
		int x;
		cin >> x;
		cnt[x]++;
	}

	int row = 1, col = 1;

	for (int i = 1; i * i <= n; i++)
	{
		int can = check(i);
		int j = can / i;
		if (i * j > row * col && j >= i)
		{
			row = i, col = j;
		}
	}

	cout << row * col << endl;
	cout << row << " " << col << endl;
	vector<vector<int>> ans(row, vector<int>(col));

	deque<int> a;
	forI(cnt)
	{
		int x = min(it->second, row);
		fori(i, x)
		{
			if (x == row)
				a.push_front(it->first);
			else
				a.push_back(it->first);
		}
		if (a.size() >= row*col)
			break;
	}

	int id = 0;
	for (int j = 0; j < col; j++)
	{
		for (int i = 0; i < row; i++)
		{
			int jj = (j + i) % col;
			ans[i][jj] = a[id];
			id++;
		}
	}
	fori(i, row)
	{
		fori(j, col)
		{
			cout << ans[i][j] << " ";
		}
		cout << endl;
	}

	return 0;
}


#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <vector>
#include <cmath>
#define re register
using namespace std;

inline int read() {
    int X=0,w=1; char c=getchar();
    while (c<'0'||c>'9') { if (c=='-') w=-1; c=getchar(); }
    while (c>='0'&&c<='9') X=X*10+c-'0',c=getchar();
    return X*w;
}

const int N=400000+10;

int n;
int a[N],S[N],cnt[N];
vector<pair<int,int> > vec;
vector<int> num;
vector<vector<int> > ans;

int main() {
    n=read();
    for (re int i=1;i<=n;++i) S[i]=a[i]=read();
    sort(S+1,S+n+1); int m=unique(S+1,S+n+1)-S-1;
    for (re int i=1;i<=n;++i) a[i]=lower_bound(S+1,S+m+1,a[i])-S;

    for (re int i=1;i<=n;++i) ++cnt[a[i]];
    for (re int i=1;i<=m;++i) vec.push_back(make_pair(cnt[i],i));
    sort(vec.begin(),vec.end());
    int ansS=0,ansr,ansc;
    for (re int r=1;r*r<=n;++r) { int s=0;
        for (auto j:vec) s+=min(j.first,r);
        int c=s/r;
        if (c<r) continue;
        if (r*c>ansS) ansS=r*c,ansr=r,ansc=c;
    }
    printf("%d\n%d %d\n",ansS,ansr,ansc);

    reverse(vec.begin(),vec.end());
    for (auto i:vec) {
        for (re int j=1;j<=min(ansr,i.first);++j)
            num.push_back(i.second);
    }
    ans.resize(ansr);
    for (re int i=0;i<ansr;++i) ans[i].resize(ansc);
    for (re int i=0,x=0,y=0;i<ansS;++i) {
        ans[x][y]=num[i]; ++x,++y;
        if (x==ansr) x=0,y-=ansr-1;
        if (y<0) y+=ansc;
        if (y>=ansc) y-=ansc;
    }
    for (re int i=0;i<ansr;++i) {
        for (re int j=0;j<ansc;++j) printf("%d ",S[ans[i][j]]);
        puts("");
    }
    return 0;
}


#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <vector>
#include <cmath>
#define re register
using namespace std;

inline int read() {
    int X=0,w=1; char c=getchar();
    while (c<'0'||c>'9') { if (c=='-') w=-1; c=getchar(); }
    while (c>='0'&&c<='9') X=X*10+c-'0',c=getchar();
    return X*w;
}

const int N=400000+10;

int n;
int a[N],S[N],cnt[N];
vector<pair<int,int> > vec;
vector<int> num;
vector<vector<int> > ans;

int main() {
    n=read();
    for (re int i=1;i<=n;++i) S[i]=a[i]=read();
    sort(S+1,S+n+1); int m=unique(S+1,S+n+1)-S-1;
    for (re int i=1;i<=n;++i) a[i]=lower_bound(S+1,S+m+1,a[i])-S;

    for (re int i=1;i<=n;++i) ++cnt[a[i]];
    for (re int i=1;i<=m;++i) vec.push_back(make_pair(cnt[i],i));
    sort(vec.begin(),vec.end());
    int ansS=0,ansr,ansc;
    for (re int r=1;r*r<=n;++r) { int s=0;
        for (auto j:vec) s+=min(j.first,r);
        int c=s/r;
    //    if (c<r) continue;
        if (r*c>ansS) ansS=r*c,ansr=r,ansc=c;
    }
    printf("%d\n%d %d\n",ansS,ansr,ansc);

    reverse(vec.begin(),vec.end());
    for (auto i:vec) {
        for (re int j=1;j<=min(ansr,i.first);++j)
            num.push_back(i.second);
    }
    ans.resize(ansr);
    for (re int i=0;i<ansr;++i) ans[i].resize(ansc);
    for (re int i=0,x=0,y=0;i<ansS;++i) {
        ans[x][y]=num[i]; ++x,++y;
        if (x==ansr) x=0,y-=ansr-1;
        if (y<0) y+=ansc;
        if (y>=ansc) y-=ansc;
    }
    for (re int i=0;i<ansr;++i) {
        for (re int j=0;j<ansc;++j) printf("%d ",S[ans[i][j]]);
        puts("");
    }
    return 0;
}


#pragma GCC optimize "-O3"
#pragma GCC optimize("Ofast")
#pragma GCC optimization ("unroll-loops")
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
using namespace std;
using namespace __gnu_pbds;
#define NumberOfOnes __builtin_popcount
#define LSOne(S) (S & (-S))
#define ll long long
#define two pair<int,int>
#define twoll pair<ll,ll>
#define four pair<two,two>
#define pb push_back
#define eb emplace_back
#define mk make_pair
#define y1 y1922
#define INF 1000000000000000000
#define P 1000000007
#define lmax 1000000000
#define nn 1000003
#define ff first.first
#define fs first.second
#define sf second.first
#define ss second.second
#define f first
#define s second
#define vi vector<int>
#define vll vector<ll>
#define vtwo vector<two>
#define ALL(container) (container).begin(), (container).end()
#define sz(container) (int)(container.size())
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
#define mid(a,b) (a+b>>1)
#define minN 0
#define maxN 10000000
#define na(x) ((x)<P?(x):(x)-P)
#define ab(a) (-(a)<(a)?(a):-(a))
#define FAST std::ios::sync_with_stdio(false)
#define xRand mt19937 rng(chrono::steady_clock::now().time_since_epoch().count())
#define rnd rng
#define IT iterator
typedef
tree<
  int,// aq pair<int,int> shegidzlia
  null_type,
  less/*_equal*/<int>,// aqac
  rb_tree_tag,
  tree_order_statistics_node_update>
ordered_set;
// '_equal' mashin ginda roca multiset gchirdeba
template<class key, class value,class cmp = std::less<key>>
using ordered_map = tree<key, value, cmp, rb_tree_tag, tree_order_statistics_node_update>;
ordered_map<int, int> my_map;
inline int rin(){
	int x=0,w=1;char ch=getchar();
	while ((ch<'0'||ch>'9')&&ch!='-') ch=getchar();
	if (ch=='-') w=0,ch=getchar();
	while (ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();
	return w?x:-x;
}
inline int bin(){
	int x=0;char ch=getchar();
	while (ch<'0'||ch>'9') ch=getchar();
	while (ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();
	return x;
}
int main(){FAST;xRand;
int n;
scanf("%d", &n);

map<int,int> cnts;
for(int i=0;i<n;i++) {
    int x;
    scanf("%d", &x);
    cnts[x]++;
}

vector<vector<int>> val_by_cnt(n + 1);
for (auto val_cnt: cnts)
    val_by_cnt[val_cnt.second].push_back(val_cnt.first);

vector<int> geq(n + 1);
geq[n] = val_by_cnt[n].size();
for(int i = n - 1; i >= 1; i--)
    geq[i] = geq[i + 1] + val_by_cnt[i].size();
int tot = 0, best = 0, best_a, best_b;
for (int a = 1; a <= n; a++) {
    tot += geq[a];
    int b = tot / a;
    if (a <= b && best < a * b) {
        best = a * b;
        best_a = a;
        best_b = b;
    }
}

cout << best << endl << best_a << " " << best_b << endl;
vector<vector<int>> r(best_a, vector<int>(best_b));

int x = 0, y = 0;
for (int i = n; i >= 1; i--)
    for (auto val: val_by_cnt[i])
        for(int j=0;j<min(i, best_a);j++) {
            if (r[x][y] != 0)
                x = (x + 1) % best_a;
            if (r[x][y] == 0)
                r[x][y] = val;
            x = (x + 1) % best_a;
            y = (y + 1) % best_b;
        }

for(int i=0;i<best_a;i++) {
    for(int j=0;j<best_b;j++)
        cout << r[i][j] << " ";
    cout << endl;
}
}
/*

                   *         *
                  * *       * *
                 *   *     *   *
                *     *   *     *
                 *   *   * *   *
                  *   *   *   *
                   *   * *   *
                     *  *   *
					   *  *

*/


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int mod = 1e9+7;
const int inf=0x3f3f3f3f;
const int N=4e5+5;
int a[N],b[N],c[N],d[N];
struct data
{
    int x,y;
}tmp[N];
bool cmp(data a,data b)
{
    return a.y>b.y;
}
map<int,int>mp;
int main()
{
#ifndef ONLINE_JUDGE
    freopen("in","r",stdin);
#endif
    ios::sync_with_stdio(0);
    cin.tie(0);

    int n;
    cin>>n;
    for(int i=1;i<=n;i++)
    {
        cin>>a[i];
        b[i]=a[i];
    }
    sort(b+1,b+1+n);
    int m=unique(b+1,b+1+n)-(b+1);
    for(int i=1;i<=m;i++)
        mp[b[i]]=i;
    for(int i=1;i<=n;i++)
        c[mp[a[i]]]++;
//    for(int i=1;i<=m;i++)
//        cout<<i<<' '<<b[i]<<' '<<c[i]<<endl;
    for(int i=1;i<=m;i++)
        d[1]++,d[c[i]+1]--;
    for(int i=1;i<=n;i++)
        d[i]+=d[i-1];
    for(int i=1;i<=n;i++)
        d[i]+=d[i-1];

    int ti=0,tj=0;
    for(int i=1;i*i<=n;i++)
    {
        int j=d[i]/i;
        if(j<i) continue;
        if(i*j>ti*tj) ti=i,tj=j;
    }
    printf("%d\n",ti*tj);
    printf("%d %d\n",ti,tj);
    for(int i=1;i<=m;i++)
        tmp[i].x=b[i],tmp[i].y=min(c[i],ti);
    sort(tmp+1,tmp+1+m,cmp);
    int ans[ti+10][tj+10]={0};
    int i=1,j=1,p=1,tp=0;
    do
    {
        ans[i][j]=tmp[p].x;
        tmp[p].y--;
        if(tmp[p].y==0) p++;
        i=i%ti+1;
        j=j%tj+1;
        if(ans[i][j]) i=i%ti+1;
        tp++;
//        cout<<i<<' '<<j<<endl;
    }
    while(tp<ti*tj);
    for(int i=1;i<=ti;i++)
        for(int j=1;j<=tj;j++)
            printf("%d%c",ans[i][j],j==tj?'\n':' ');
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int mod = 1e9+7;
const int inf=0x3f3f3f3f;
const int N=4e6+5;
int a[N],b[N],c[N],d[N];
map<int,int>mp;
int main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);

    int n;
    cin>>n;
    for(int i=1;i<=n;i++)
    {
        cin>>a[i];
        b[i]=a[i];
    }
    sort(b+1,b+1+n);
    int m=unique(b+1,b+1+n)-(b+1);
    for(int i=1;i<=m;i++)
        mp[b[i]]=i;
    for(int i=1;i<=n;i++)
        c[mp[a[i]]]++;
//    for(int i=1;i<=m;i++)
//        cout<<i<<' '<<b[i]<<' '<<c[i]<<endl;
    for(int i=1;i<=m;i++)
        d[1]++,d[c[i]+1]--;
    for(int i=1;i<=n;i++)
        d[i]+=d[i-1];
    for(int i=1;i<=n;i++)
        d[i]+=d[i-1];

    int ti=0,tj=0;
    for(int i=1;i*i<=n;i++)
    {
        int j=d[i]/i;
        if(j<i) continue;
        if(i*j>ti*tj) ti=i,tj=j;
    }
    printf("%d\n",ti*tj);
    printf("%d %d\n",ti,tj);
    int ans[ti+10][tj+10]={0};
    int i=1,j=1,p=1,tp=0;
    do
    {
        c[p]=min(c[p],ti);
        ans[i][j]=b[p];
        c[p]--;
        if(c[p]==0) p++;
        i=i%ti+1;
        j=j%tj+1;
        if(ans[i][j]) i=i%ti+1;
        tp++;
//        cout<<i<<' '<<j<<endl;
    }
    while(tp<ti*tj);
    for(int i=1;i<=ti;i++)
        for(int j=1;j<=tj;j++)
        printf("%d%c",ans[i][j],j==tj?'\n':' ');
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int mod = 1e9+7;
const int inf=0x3f3f3f3f;
const int N=4e6+5;
int a[N],b[N],c[N],d[N];
map<int,int>mp;
int main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);

    int n;
    cin>>n;
    for(int i=1;i<=n;i++)
    {
        cin>>a[i];
        b[i]=a[i];
    }
    sort(b+1,b+1+n);
    int m=unique(b+1,b+1+n)-(b+1);
    for(int i=1;i<=m;i++)
        mp[b[i]]=i;
    for(int i=1;i<=n;i++)
        c[mp[a[i]]]++;
//    for(int i=1;i<=m;i++)
//        cout<<i<<' '<<b[i]<<' '<<c[i]<<endl;
    for(int i=1;i<=m;i++)
        d[1]++,d[c[i]+1]--;
    for(int i=1;i<N;i++)
        d[i]+=d[i-1];
    for(int i=1;i<N;i++)
        d[i]+=d[i-1];

    int ti=0,tj=0;
    for(int i=1;i<=n;i++)
    {
        int j=d[i]/i;
        if(j<i) continue;
        if(i*j>ti*tj) ti=i,tj=j;
    }
    printf("%d\n",ti*tj);
    printf("%d %d\n",ti,tj);
    int ans[ti+100][tj+100]={0};
    int i=1,j=1,p=1,tp=0;
    do
    {
        c[p]=min(c[p],ti);
        ans[i][j]=b[p];
        c[p]--;
        if(c[p]==0) p++;
        i=i%ti+1;
        j=j%tj+1;
        if(ans[i][j]) i=i%ti+1;
        tp++;
//        cout<<i<<' '<<j<<endl;
    }
    while(tp<ti*tj);
    for(int i=1;i<=ti;i++)
        for(int j=1;j<=tj;j++)
        printf("%d%c",ans[i][j],j==tj?'\n':' ');
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int mod = 1e9+7;
const int inf=0x3f3f3f3f;
const int N=4e5+5;
int a[N],b[N],c[N],d[N];
map<int,int>mp;
int main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);

    int n;
    cin>>n;
    for(int i=1;i<=n;i++)
    {
        cin>>a[i];
        b[i]=a[i];
    }
    sort(b+1,b+1+n);
    int m=unique(b+1,b+1+n)-(b+1);
    for(int i=1;i<=m;i++)
        mp[b[i]]=i;
    for(int i=1;i<=n;i++)
        c[mp[a[i]]]++;
//    for(int i=1;i<=m;i++)
//        cout<<i<<' '<<b[i]<<' '<<c[i]<<endl;
    for(int i=1;i<=m;i++)
        d[1]++,d[c[i]+1]--;
    for(int i=1;i<=n;i++)
        d[i]+=d[i-1];
    for(int i=1;i<=n;i++)
        d[i]+=d[i-1];

    int ti=0,tj=0;
    for(int i=1;i*i<=n;i++)
    {
        int j=d[i]/i;
        if(j<i) continue;
        if(i*j>ti*tj) ti=i,tj=j;
    }
    printf("%d\n",ti*tj);
    printf("%d %d\n",ti,tj);
    int ans[ti+10][tj+10]={0};
    int i=1,j=1,p=1,tp=0;
    do
    {
        c[p]=min(c[p],ti);
        ans[i][j]=b[p];
        c[p]--;
        if(c[p]==0) p++;
        i=i%ti+1;
        j=j%tj+1;
        if(ans[i][j]) i=i%ti+1;
        tp++;
//        cout<<i<<' '<<j<<endl;
    }
    while(tp<ti*tj);
    for(int i=1;i<=ti;i++)
        for(int j=1;j<=tj;j++)
        printf("%d%c",ans[i][j],j==tj?'\n':' ');
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int mod = 1e9+7;
const int inf=0x3f3f3f3f;
const int N=4e5+5;
int a[N],b[N],c[N],d[N];
map<int,int>mp;
int main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);

    int n;
    cin>>n;
    for(int i=1;i<=n;i++)
    {
        cin>>a[i];
        b[i]=a[i];
    }
    sort(b+1,b+1+n);
    int m=unique(b+1,b+1+n)-(b+1);
    for(int i=1;i<=m;i++)
        mp[b[i]]=i;
    for(int i=1;i<=n;i++)
        c[mp[a[i]]]++;
//    for(int i=1;i<=m;i++)
//        cout<<i<<' '<<b[i]<<' '<<c[i]<<endl;
    for(int i=1;i<=m;i++)
        d[1]++,d[c[i]+1]--;
    for(int i=1;i<=n;i++)
        d[i]+=d[i-1];
    for(int i=1;i<=n;i++)
        d[i]+=d[i-1];
    int ti=0,tj=0;
    for(int i=1;i*i<=n;i++)
    {
        int j=d[i]/i;
        if(j<i) continue;
        if(i*j>ti*tj) ti=i,tj=j;
    }
    printf("%d\n",ti*tj);
    printf("%d %d\n",ti,tj);
    int ans[ti+10][tj+10];
    int i=1,j=1,p=1;
    do
    {
        c[p]=min(c[p],ti);
        ans[i][j]=b[p];
        c[p]--;
        if(c[p]==0) p++;
        i=i%ti+1;
        j=j%tj+1;
    }
    while(!(i==1&&j==1));
    for(int i=1;i<=ti;i++)
        for(int j=1;j<=tj;j++)
        printf("%d%c",ans[i][j],j==tj?'\n':' ');
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int mod = 1e9+7;
const int inf=0x3f3f3f3f;
const int N=4e5+5;
int a[N],b[N],c[N],d[N];
map<int,int>mp;
int main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);

    int n;
    cin>>n;
    for(int i=1;i<=n;i++)
    {
        cin>>a[i];
        b[i]=a[i];
    }
    sort(b+1,b+1+n);
    int m=unique(b+1,b+1+n)-(b+1);
    for(int i=1;i<=m;i++)
        mp[b[i]]=i;
    for(int i=1;i<=n;i++)
        c[mp[a[i]]]++;
//    for(int i=1;i<=m;i++)
//        cout<<i<<' '<<b[i]<<' '<<c[i]<<endl;
    for(int i=1;i<=m;i++)
        d[1]++,d[c[i]+1]--;
    for(int i=1;i<=n;i++)
        d[i]+=d[i-1];
    for(int i=1;i<=n;i++)
        d[i]+=d[i-1];
    int ti=0,tj=0;
    for(int i=1;i*i<=n;i++)
    {
        int j=d[i]/i;
        if(j<i) continue;
        if(i*j>ti*tj) ti=i,tj=j;
    }
    printf("%d\n",ti*tj);
    printf("%d %d\n",ti,tj);
    int ans[ti+10][tj+10];
    int i=1,j=1,p=1;
    do
    {
        ans[i][j]=b[p];
        c[p]--;
        if(c[p]==0) p++;
        i=i%ti+1;
        j=j%tj+1;
    }
    while(!(i==1&&j==1));
    for(int i=1;i<=ti;i++)
        for(int j=1;j<=tj;j++)
        printf("%d%c",ans[i][j],j==tj?'\n':' ');
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

typedef long long ll;

int num[400005];
vector<pair<int, int> > cnt;
vector<int> use_num;

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

    int n;
    cin >> n;

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

    sort(num, num + n);

    int prev = 0;
    int Cnt = 0;
    for(int i = 0; i < n; i++)
    {
        if(prev != num[i])
        {
            if(prev != 0)
                cnt.push_back({Cnt, prev});
            prev = num[i];
            Cnt = 1;
        }
        else
            Cnt++;
        if(i == n - 1)
            cnt.push_back({Cnt, prev});
    }

    sort(cnt.begin(), cnt.end(), greater<pair<int, int> >());
    cnt.push_back({0, 0});

    prev = sqrt(n) + 1;
    int c = 0, r = 0;
    int maxRect = n;
    for(int i = 0; i < cnt.size(); i++)
    {
        if(cnt[i].first == prev) continue;
        int cur = cnt[i].first;

        for(int j = prev - 1; j >= cur && j >= 1; j--)
        {
            maxRect -= i;
            int col = maxRect / j;
            if(col < j)
                continue;
            if(col * j > c * r)
            {
                c = col;
                r = j;
            }
        }
        prev = cur;
    }

    cout << r * c << "\n" << r << " " << c << "\n";

    for(int i = 0; i < cnt.size() - 1; i++)
        for(int j = 0; j < min(r, cnt[i].first); j++)
            use_num.push_back(cnt[i].second);

    vector<vector<int> > ans(r, vector<int>(c));

    int ind = 0;
    for(int i = 0; i < c; i++)
    {
        int placeC = i;
        for(int j = 0; j < r; j++)
        {
            ans[j][placeC] = use_num[ind++];
            placeC = (placeC + 1) % c;
        }
    }

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

    return 0;
}


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

#define watch(x) cerr << (#x) << ": " << (x) << endl
#define int long long

const int N = 400009;
int n, a[N];

map<int, int> f;
map<int, vector<int>> s;
int pre[N];

void fillgrid(int arows, int cols, vector<vector<int>>& grid) {
    int x = 0, y = 0;
    for(auto it = s.rbegin(); it != s.rend(); it++) {
        int ct = it->first;
        vector<int>& cur = it->second;
        for(int num : cur) {
            for(int i = 0; i < ct; ++i) {
                grid[x][y] = num;
                x++;
                if(x == arows) {
                    x = 0;
                    y++;
                }
                if(y == cols) return;
            }
        }
    }
}

int32_t main() {

    ios_base::sync_with_stdio(false);
    cin.tie(NULL);

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

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

    for(auto p : f) {
        s[p.second].push_back(p.first);
    }

    for(int i = n; i > 0; --i) {
        pre[i] = pre[i+1];
        if(s.count(i)) {
            pre[i] += s[i].size();
        }
    }

    int ans = 0, arows = 0;
    int nums = 0;
    for(int rows = 1; rows*rows <= n; ++rows) {
        nums += pre[rows];
        int cand = (nums/rows)*rows;
        if(cand > ans) {
            ans = cand;
            arows = rows;
        }
        if (rows == nums/rows) break;
    }
    int cols = ans/arows;
    cout << ans << '\n' << arows << ' ' << cols << '\n';

    vector<vector<int>> grid(arows, vector<int>(cols));

    fillgrid(arows, cols, grid);

    for(int i = 0; i < arows; ++i) {
        int j = cols-1-i;
        do {
            cout << grid[i][j] << ' ';
            j++;
            if(j == cols) j = 0;
        }while(j != cols-1-i);
        cout << '\n';
    }

    return 0;
}


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

#define watch(x) cerr << (#x) << ": " << (x) << endl
#define int long long

const int N = 400009;
int n, a[N];

map<int, int> f;
map<int, vector<int>> s;
int pre[N];

void fillgrid(int arows, int cols, vector<vector<int>>& grid) {
    int x = 0, y = 0;
    for(auto it = s.rbegin(); it != s.rend(); it++) {
        int ct = min(arows, it->first);
        vector<int>& cur = it->second;
        for(int num : cur) {
            for(int i = 0; i < ct; ++i) {
                grid[x][y] = num;
                x++;
                if(x == arows) {
                    x = 0;
                    y++;
                }
                if(y == cols) return;
            }
        }
    }
}

int32_t main() {

    ios_base::sync_with_stdio(false);
    cin.tie(NULL);

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

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

    for(auto p : f) {
        s[p.second].push_back(p.first);
    }

    for(int i = n; i > 0; --i) {
        pre[i] = pre[i+1];
        if(s.count(i)) {
            pre[i] += s[i].size();
        }
    }

    int ans = 0, arows = 0;
    int nums = 0;
    for(int rows = 1; rows*rows <= n; ++rows) {
        nums += pre[rows];
        int cand = (nums/rows)*rows;
        if(cand > ans) {
            ans = cand;
            arows = rows;
        }
        if (rows == nums/rows) break;
    }
    int cols = ans/arows;
    cout << ans << '\n' << arows << ' ' << cols << '\n';

    vector<vector<int>> grid(arows, vector<int>(cols));

    fillgrid(arows, cols, grid);

    for(int i = 0; i < arows; ++i) {
        int j = cols-1-i;
        do {
            cout << grid[i][j] << ' ';
            j++;
            if(j == cols) j = 0;
        }while(j != cols-1-i);
        cout << '\n';
    }

    return 0;
}


#include<vector>
#include<string>
#include<iostream>
#include<utility>
#include<map>
#include<math.h>
#include<algorithm>
#define ll long long
#define pii pair<int,int>
#define pip pair<int,pii>
using namespace std;
int main() {
    ios_base::sync_with_stdio(false), cin.tie(0), cout.tie(0);
    int n;
    cin>>n;
    map<int,int> mp;
    for (int i=0;i<n;i++){
        int curr;
        cin>>curr;
        mp[curr]++;
    }
    vector<int> nums(mp.size());
    int counter=0;
    for (auto i:mp){
        nums[counter]=i.second;
        counter++;
    }
    sort(nums.begin(),nums.end());
    vector<int> sums(nums.size());
    sums[nums.size()-1]=nums.back();
    for (int i=sums.size()-2;i>=0;i--){
        sums[i]=sums[i+1]+nums[i];
    }
    int sqr=(int)sqrt(n);
    int mx=0;
    pii dimensions;
    for (int i=sqr;i>0;i--){
        int low=0;
        int high=nums.size()-1;
        while(low<=high){
            int mid=(low+high)>>1;
            if (nums[mid]<=i){
                low=mid+1;
            }
            else{
                high=mid-1;
            }
        }
        int res=n;
        if (i<nums.back()){
            res-=sums[low]-(nums.size()-low)*i;
        }
        low=i;
        high=n;
        if (res<i*i){
            continue;
        }
        while(low<=high){
            int mid=(low+high)>>1;
            if (mid*i<res){
                low=mid+1;
            }
            else if (mid*i>res){
                high=mid-1;
            }
            else{
                high=mid;
                break;
            }
        }
        if (mx<i*high){
            mx=i*high;
            dimensions.first=i;
            dimensions.second=high;
        }
    }
    cout<<mx<<"\n";
    cout<<dimensions.first<<" "<<dimensions.second<<"\n";
    int arr[dimensions.first][dimensions.second];
    auto itr=mp.begin();
    int sz=0;
    counter=min(itr->second,dimensions.first);
    int r =0;
    int c=0;
    while(sz<mx){
        if (counter==0){
            itr++;
            counter=min(itr->second,dimensions.first);
        }
        arr[r][c]=itr->first;
        counter--;
        r=(r+1)%dimensions.first;
        c=(c+1)%dimensions.second;
        sz++;
    }
    for (int i=0;i<dimensions.first;i++){
        for (int a=0;a<dimensions.second-1;a++){
            cout<<arr[i][a]<<" ";
        }
        cout<<arr[i][dimensions.second-1]<<"\n";
    }
}


#include<vector>
#include<string>
#include<iostream>
#include<utility>
#include<map>
#include<math.h>
#include<algorithm>
#define ll long long
#define pii pair<int,int>
#define pip pair<int,pii>
using namespace std;
int main() {
    ios_base::sync_with_stdio(false), cin.tie(0), cout.tie(0);
    int n;
    cin>>n;
    map<int,int> mp;
    for (int i=0;i<n;i++){
        int curr;
        cin>>curr;
        mp[curr]++;
    }
    vector<int> nums(mp.size());
    int counter=0;
    for (auto i:mp){
        nums[counter]=i.second;
        counter++;
    }
    sort(nums.begin(),nums.end());
    vector<int> sums(nums.size());
    sums[nums.size()-1]=nums.back();
    for (int i=sums.size()-2;i>=0;i--){
        sums[i]=sums[i+1]+nums[i];
    }
    int sqr=(int)sqrt(n);
    int mx=0;
    pii dimensions;
    for (int i=sqr;i>0;i--){
        int low=0;
        int high=nums.size()-1;
        while(low<=high){
            int mid=(low+high)>>1;
            if (nums[mid]<=i){
                low=mid+1;
            }
            else{
                high=mid-1;
            }
        }
        int res=n;
        if (i<nums.back()){
            res-=sums[low]-(nums.size()-low)*i;
        }
        low=i;
        high=n;
        if (res<i*i){
            continue;
        }
        while(low<=high){
            int mid=(low+high)>>1;
            if (mid*i<res){
                low=mid+1;
            }
            else if (mid*i>res){
                high=mid-1;
            }
            else{
                high=mid;
                break;
            }
        }
        if (mx<i*high){
            mx=i*high;
            dimensions.first=i;
            dimensions.second=high;
        }
    }
    cout<<mx<<"\n";
    cout<<dimensions.first<<" "<<dimensions.second<<"\n";
    int arr[dimensions.first][dimensions.second];
    auto itr=mp.begin();
    counter=min(itr->second,dimensions.first);
    for (int i=0;i<dimensions.second;i++){
        int start=i;
        for (int a=0;a<dimensions.first;a++){
            if (counter==0){
                itr++;
                counter=itr->second;
            }
            arr[a][start]=itr->first;
            counter--;
            start=(start+1)%dimensions.second;
        }
    }
    for (int i=0;i<dimensions.first;i++){
        for (int a=0;a<dimensions.second-1;a++){
            cout<<arr[i][a]<<" ";
        }
        cout<<arr[i][dimensions.second-1]<<"\n";
    }
}


#include <iostream>

#include <algorithm>
#include <vector>
#include <stdio.h>
#include <string.h>

using namespace std;
const int MAXN = 205;
char a[MAXN][MAXN];
vector<pair<int,int> >ss;
vector<int>qss;
char b[MAXN][MAXN];
int main()
{
     ios::sync_with_stdio(false);
    cin.tie(0);     cout.tie(0);
    int T;
    cin>>T;

    while(T--)
    {
        int n;cin>>n;
        ss.push_back(make_pair(1,2));
        ss.push_back(make_pair(2,1));
        ss.push_back(make_pair(n-1,n));
        ss.push_back(make_pair(n,n-1));

        for(int y =  1 ;y<=n;y++)
        {
            cin>>a[y]+1;

        }
        int j = 4;

        for(int y = 0;y<(1<<5);y++){
            int i = 0;
            qss.clear();
            for(int u = 0;u<4;u++)
            {
                if((y>>u)&1){
                    i++;
                    qss.push_back(u);
                }
            }
            if(i>=3) {continue;}
            int len = qss.size();
            for(int u = 0;u<4;u++)
            {
                b[ss[u].first][ss[u].second] = a[ss[u].first][ss[u].second];
            }

            for(int u = 0;u<len;u++)
            {
                b[ss[qss[u]].first][ss[qss[u]].second] = (b[ss[qss[u]].first][ss[qss[u]].second]-'0')^1+'0';

            }
            if(b[1][2]==b[2][1]&&b[n-1][n]==b[n][n-1]&&b[1][2]!=b[n-1][n]){
                cout<<len<<endl;
                for(int u = 0;u<len;u++)
                {
                    cout<<ss[qss[u]].first<<' '<<ss[qss[u]].second<<endl;
                }
            break;
            }
        }

    }

    return 0;
}


#include <iostream>

#include <algorithm>
#include <vector>
#include <stdio.h>
#include <string.h>

using namespace std;
const int MAXN = 205;
char a[MAXN][MAXN];
vector<pair<int,int> >ss;
vector<int>qss;
char b[MAXN][MAXN];
int main()
{
    int T;
    cin>>T;
    while(T--)
    {
        ss.clear();
        int n;cin>>n;

        for(int y =  1 ;y<=n;y++)
        {
            cin>>a[y]+1;

        }
        ss.push_back(make_pair(1,2));
        ss.push_back(make_pair(2,1));
        ss.push_back(make_pair(n-1,n));
        ss.push_back(make_pair(n,n-1));
        int j = 4;

        for(int y = 0;y<(1<<5);y++){
            int i = 0;
            qss.clear();
            for(int u = 0;u<4;u++)
            {
                if((y>>u)&1){
                    i++;
                    qss.push_back(u);
                }
            }
            if(i>=3) continue;
            int len = qss.size();
            for(int u = 0;u<4;u++)
            {
                b[ss[u].first][ss[u].second] = a[ss[u].first][ss[u].second];
            }

            for(int u = 0;u<len;u++)
            {
                b[ss[qss[u]].first][ss[qss[u]].second] = (b[ss[qss[u]].first][ss[qss[u]].second]-'0')^1;

            }
            if(b[1][2]==b[2][1]&&b[n-1][n]==b[n][n-1]&&b[1][2]!=b[n-1][n]){
                cout<<len<<endl;
                for(int u = 0;u<len;u++)
                {
                    cout<<ss[qss[y]].first<<' '<<ss[qss[y]].second<<endl;
                }
            break;
            }
        }

    }

    return 0;
}


#include <iostream>

#include <algorithm>
#include <vector>
#include <stdio.h>
#include <string.h>

using namespace std;
const int MAXN = 205;
char a[MAXN][MAXN];
vector<pair<int,int> >ss;
vector<int>qss;
char b[MAXN][MAXN];
int main()
{
    int T;
    cin>>T;
    while(T--)
    {
        ss.clear();
        int n;cin>>n;

        for(int y =  1 ;y<=n;y++)
        {
            cin>>a[y]+1;

        }
        ss.push_back(make_pair(1,2));
        ss.push_back(make_pair(2,1));
        ss.push_back(make_pair(n-1,n));
        ss.push_back(make_pair(n,n-1));
        int j = 4;

        for(int y = 0;y<(1<<5);y++){
            int i = 0;
            qss.clear();
            for(int u = 0;u<4;u++)
            {
                if((y>>u)&1){
                    i++;
                    qss.push_back(u);
                }
            }
            if(i>=3) {continue;}
            int len = qss.size();
            for(int u = 0;u<4;u++)
            {
                b[ss[u].first][ss[u].second] = a[ss[u].first][ss[u].second];
            }

            for(int u = 0;u<len;u++)
            {
                b[ss[qss[u]].first][ss[qss[u]].second] = (b[ss[qss[u]].first][ss[qss[u]].second]-'0')^1+'0';

            }
            if(b[1][2]==b[2][1]&&b[n-1][n]==b[n][n-1]&&b[1][2]!=b[n-1][n]){
                cout<<len<<endl;
                for(int u = 0;u<len;u++)
                {
                    cout<<ss[qss[u]].first<<' '<<ss[qss[u]].second<<endl;
                }
            break;
            }
        }

    }

    return 0;
}


#include <iostream>

#include <algorithm>
#include <vector>
#include <stdio.h>
#include <string.h>

using namespace std;
const int MAXN = 205;
char a[MAXN][MAXN];
vector<pair<int,int> >ss;
vector<int>qss;
char b[MAXN][MAXN];
int main()
{
    int T;
    cin>>T;
    ss.push_back(make_pair(1,2));
    ss.push_back(make_pair(2,1));
    ss.push_back(make_pair(n-1,n));
    ss.push_back(make_pair(n,n-1));
    while(T--)
    {
        int n;cin>>n;

        for(int y =  1 ;y<=n;y++)
        {
            cin>>a[y]+1;

        }
        ss.push_back(make_pair(1,2));
        ss.push_back(make_pair(2,1));
        ss.push_back(make_pair(n-1,n));
        ss.push_back(make_pair(n,n-1));
        int j = 4;

        for(int y = 0;y<(1<<5);y++){
            int i = 0;
            qss.clear();
            for(int u = 0;u<4;u++)
            {
                if((y>>u)&1){
                    i++;
                    qss.push_back(u);
                }
            }
            if(i>=3) {continue;}
            int len = qss.size();
            for(int u = 0;u<4;u++)
            {
                b[ss[u].first][ss[u].second] = a[ss[u].first][ss[u].second];
            }

            for(int u = 0;u<len;u++)
            {
                b[ss[qss[u]].first][ss[qss[u]].second] = (b[ss[qss[u]].first][ss[qss[u]].second]-'0')^1+'0';

            }
            if(b[1][2]==b[2][1]&&b[n-1][n]==b[n][n-1]&&b[1][2]!=b[n-1][n]){
                cout<<len<<endl;
                for(int u = 0;u<len;u++)
                {
                    cout<<ss[qss[u]].first<<' '<<ss[qss[u]].second<<endl;
                }
            break;
            }
        }

    }

    return 0;
}


    #include <iostream>

    #include <algorithm>
    #include <vector>
    #include <stdio.h>
    #include <string.h>

    using namespace std;
    const int MAXN = 205;
    char a[MAXN][MAXN];
    vector<pair<int,int> >ss;
    vector<int>qss;
    char b[MAXN][MAXN];
    int main()
    {
         ios::sync_with_stdio(false);
    cin.tie(0);     cout.tie(0);
        int T;
        cin>>T;
        while(T--)
        {
            ss.clear();
            int n;cin>>n;

            for(int y =  1 ;y<=n;y++)
            {
                cin>>a[y]+1;

            }
            ss.push_back(make_pair(1,2));
            ss.push_back(make_pair(2,1));
            ss.push_back(make_pair(n-1,n));
            ss.push_back(make_pair(n,n-1));
            int j = 4;

            for(int y = 0;y<(1<<5);y++){
                int i = 0;
                qss.clear();
                for(int u = 0;u<4;u++)
                {
                    if((y>>u)&1){
                        i++;
                        qss.push_back(u);
                    }
                }
                if(i>=3) {continue;}
                int len = qss.size();
                for(int u = 0;u<4;u++)
                {
                    b[ss[u].first][ss[u].second] = a[ss[u].first][ss[u].second];
                }

                for(int u = 0;u<len;u++)
                {
                    b[ss[qss[u]].first][ss[qss[u]].second] = (b[ss[qss[u]].first][ss[qss[u]].second]-'0')^1+'0';

                }
                if(b[1][2]==b[2][1]&&b[n-1][n]==b[n][n-1]&&b[1][2]!=b[n-1][n]){
                    cout<<len<<endl;
                    for(int u = 0;u<len;u++)
                    {
                        cout<<ss[qss[u]].first<<' '<<ss[qss[u]].second<<endl;
                    }
                break;
                }
            }

        }

        return 0;
    }


/*
problem:CF 1421B
created:Programmer juruo
*/
#include <bits/stdc++.h>
using namespace std;
typedef pair<int, int> P;
#define fr first
#define sc second
int n, grid[205][205];
int used[205][205];
queue<P> Q;
int dx[] = {1, -1, 0, 0}, dy[] = {0, 0, 1, -1};
int Check() {
	memset(used, 0, sizeof(used));
	while(!Q.empty()) Q.pop();
	Q.push(P(1, 1));
	used[1][1] = 1;
	while(!Q.empty()) {
		P now = Q.front();Q.pop();
//		printf("(%d, %d)\n", now.fr, now.sc);
		if(now.fr == n && now.sc == n) {
			return true;
		}
		for(int k = 0; k < 4; k++) {
			int x = now.fr + dx[k], y = now.sc + dy[k];
			if(x < 1 || y < 1 || x > n || y > n || used[x][y] || grid[x][y]) continue;
			used[x][y] = 1;
			Q.push(P(x, y));
		}
	}
	return false;
}
int bfs() {
	memset(used, 0, sizeof(used));
	while(!Q.empty()) Q.pop();
	Q.push(P(1, 1));
	used[1][1] = 1;
	while(!Q.empty()) {
		P now = Q.front();Q.pop();
		if(Q.empty() && !(now.fr == 1 && now.sc == 1) && !(now.fr == n && now.sc == n)) {
			puts("1");
			cout << now.fr << ' ' << now.sc << endl;
			return true;
		}
		for(int k = 0; k < 4; k++) {
			int x = now.fr + dx[k], y = now.sc + dy[k];
			if(x < 1 || y < 1 || x > n || y > n || used[x][y] || grid[x][y]) continue;
			used[x][y] = 1;
			Q.push(P(x, y));
		}
	}
	return false;
}

void solve() {
	if(!Check()) {
		cout << 0 << endl;
		return ;
	}
	if(!bfs()) {
		puts("2\n1 2\n2 1");
	}
}
int main() {
	int tt;cin >> tt;
	while(tt--) {
		cin >> n;
		for(int i = 1; i <= n; i++) {
			for(int j = 1; j <= n; j++) {
				char c;cin >> c;
				if(i == 1 && j == 1 || i == n && j == n) {
					grid[i][j] = 0;continue;
				}
				grid[i][j] = c - '0';
			}
		}
		solve();
	}
	return 0;
}


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

#define ff              first
#define ss              second
#define ll          long long
#define pb              push_back
#define mp              make_pair
#define pii             pair<int,int>
#define vi              vector<int>
#define mii             map<int,int>
#define mod             1000000007
#define inf             1e18
#define ps(x,y)         fixed<<setprecision(y)<<x
#define mk(arr,n,type)  type *arr=new type[n];
#define w(x)             while(x--)
#define f(i, a, n)     for (int i = a; i < n; i++)
void c_p_c()
{
    ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
}

int main()
{
    c_p_c();
    int t;
    cin>>t;
    while(t--){ll x;ll n;ll i;ll j;
    cin>>n;ll maxa=-1;char a[n+1][n+1];
    for(i=0;i<n;i++)
    	{for(j=0;j<n;j++){cin>>a[i][j];
    }}
    char c=a[0][1];
    char s=a[1][0];
    char p=a[n-1][n-2];
    char q=a[n-2][n-1];
    if(c==s)
        {if(p==q&&p!=s)
            {cout<<"0"<<endl;
            }
        else if(p==q&&p==s)
            {cout<<"2"<<endl;
            cout<<n<<" "<<n-1<<endl;
            cout<<n-1<<" "<<n<<endl;
            }
        else if (p!=q&&p==s)
            {cout<<"1"<<endl;
                cout<<n<<" "<<n-1<<endl;}
        else if(p!=q&&q==s)
            {cout<<"1"<<endl;
            cout<<n-1<<" "<<n<<endl;}
        }
        else
        {if(p==q&&p==c&&c!=s)
            {cout<<"1"<<endl;
            cout<<1<<" "<<"2"<<endl;
            }
        else
            {cout<<"1"<<endl;
            cout<<"2"<<" "<<"1"<<endl;}}
    }

    return 0;
}


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

#define ff              first
#define ss              second
#define ll          long long
#define pb              push_back
#define mp              make_pair
#define pii             pair<int,int>
#define vi              vector<int>
#define mii             map<int,int>
#define mod             1000000007
#define inf             1e18
#define ps(x,y)         fixed<<setprecision(y)<<x
#define mk(arr,n,type)  type *arr=new type[n];
#define w(x)             while(x--)
#define f(i, a, n)     for (int i = a; i < n; i++)
void c_p_c()
{
    ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
}

int main()
{
    c_p_c();
    int t;
    cin>>t;
    while(t--){ll x;ll n;ll i;ll j;
    cin>>n;ll maxa=-1;char a[n+1][n+1];
    for(i=0;i<n;i++)
    	{for(j=0;j<n;j++){cin>>a[i][j];
    }}
    char c=a[0][1];
    char s=a[1][0];
    char p=a[n-1][n-2];
    char q=a[n-2][n-1];
    if(c==s)
        {if(p==q&&p!=s)
            {cout<<"0"<<endl;
            }
        else if(p==q&&p==s)
            {cout<<"2"<<endl;
            cout<<n<<" "<<n-1<<endl;
            cout<<n-1<<" "<<n<<endl;
            }
        else if (p!=q&&p==s)
            {cout<<"1"<<endl;
                cout<<n<<" "<<n-1<<endl;}
        else if(p!=q&&q==s)
            {cout<<"1"<<endl;
            cout<<n-1<<" "<<n<<endl;}
        }
        else
        {if(p==q&&p==c&&c!=s)
            {cout<<"1"<<endl;
            cout<<1<<" "<<"2"<<endl;
            }
        else if(p==q&&p==s&&c!=s)
            {cout<<"1"<<endl;
            cout<<"2"<<" "<<"1"<<endl;}
          else
            {
                if (p== c)
                {
                    cout << 2 << "\n";
                    cout << 1 << " " << 2 << "\n";
                    cout << n-1 << " " << n << "\n";
                }
                else if (p == s)
                {
                    cout << 2 << "\n";
                    cout << 2 << " " << 1 << "\n";
                    cout << n-1 << " " << n << "\n";
                }

            }}

    }

    return 0;
}


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

#define ff              first
#define ss              second
#define ll          long long
#define pb              push_back
#define mp              make_pair
#define pii             pair<int,int>
#define vi              vector<int>
#define mii             map<int,int>
#define mod             1000000007
#define inf             1e18
#define ps(x,y)         fixed<<setprecision(y)<<x
#define mk(arr,n,type)  type *arr=new type[n];
#define w(x)             while(x--)
#define f(i, a, n)     for (int i = a; i < n; i++)
void c_p_c()
{
    ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
}

int main()
{
    c_p_c();
    int t;
    cin>>t;
    while(t--){ll x;ll n;ll i;ll j;
    cin>>n;ll maxa=-1;char a[n+1][n+1];
    for(i=0;i<n;i++)
    	{for(j=0;j<n;j++){cin>>a[i][j];
    }}
    char c=a[0][1];
    char s=a[1][0];
    char p=a[n-1][n-2];
    char q=a[n-2][n-1];
    if(c==s)
        {if(p==q&&p!=s)
            {cout<<"0"<<endl;
            }
        else if(p==q&&p==s)
            {cout<<"2"<<endl;
            cout<<n<<" "<<n-1<<endl;
            cout<<n-1<<" "<<n<<endl;
            }
        else if (p!=q&&p==s)
            {cout<<"1"<<endl;
                cout<<n<<" "<<n-1<<endl;}
        else
            {cout<<"1"<<endl;
            cout<<n-1<<" "<<n<<endl;}
        }}

    return 0;
}


#include <iostream>
#include <cmath>
#include <utility>
#include <vector>

using namespace std;

typedef pair<int,int> pii;
typedef long long ll;
#define mp make_pair
#define x first
#define y second

vector<pii> sol;

int main () {
	int t;
	cin>>t;
	while(t--){
		int n;
		cin>>n;
		char grid[203][203];
		for(int i=1;i<=n;i++){
			for(int j=1;j<=n;j++){
				cin>>grid[i][j];
			}
		}
		int s1=int(grid[1][2])-48;
		int s2=int(grid[2][1])-48;
		int f1=int(grid[n][n-1])-48;
		int f2=int(grid[n-1][n])-48;
		if(s1==s2){
			int x=(s1+1)%2;
			if(f1!=x){
				sol.push_back(mp(n,n-1));
			}
			if(f2!=x){
				sol.push_back(mp(n-1,n));
			}
			cout<<sol.size()<<endl;
			for(int i=0;i<sol.size();i++){
				cout<<sol[i].x<<" "<<sol[i].y<<endl;
			}
			sol.clear();
		}
		else if(f1==f2){
			int x=(s1+1)%2;
			if(s1!=x){
				sol.push_back(mp(1,2));
			}
			if(s2!=x){
				sol.push_back(mp(2,1));
			}
			cout<<sol.size()<<endl;
			for(int i=0;i<sol.size();i++){
				cout<<sol[i].x<<" "<<sol[i].y<<endl;
			}
			sol.clear();
		}
		else{
			int x=(s1+1)%2;
			sol.push_back(mp(2,1));
			if(f1!=x){
				sol.push_back(mp(n,n-1));
			}
			if(f2!=x){
				sol.push_back(mp(n-1,n));
			}
			cout<<sol.size()<<endl;
			for(int i=0;i<sol.size();i++){
				cout<<sol[i].x<<" "<<sol[i].y<<endl;
			}
			sol.clear();
		}
	}

return 0;
}


#include <iostream>
#include <cmath>
#include <utility>
#include <vector>

using namespace std;

typedef pair<int,int> pii;
typedef long long ll;
#define mp make_pair
#define x first
#define y second

int main () {
	int t;
	cin>>t;
	while(t--){
		int n;
		cin>>n;
		char grid[203][203];
		for(int i=1;i<=n;i++){
			for(int j=1;j<=n;j++){
				cin>>grid[i][j];
			}
		}
		int s1=int(grid[1][2])-48;
		int s2=int(grid[2][1])-48;
		int f1=int(grid[n][n-1])-48;
		int f2=int(grid[n-1][n])-48;
		vector<pii> sol;
		if(s1==s2){
			int x=(s1+1)%2;
			if(f1!=x){
				sol.push_back(mp(n,n-1));
			}
			if(f2!=x){
				sol.push_back(mp(n-1,n));
			}
			cout<<sol.size()<<endl;;
			for(int i=0;i<sol.size();i++){
				cout<<sol[i].x<<" "<<sol[i].y<<endl;
			}
		}
		else if(f1==f2){
			int x=(s1+1)%2;
			if(s1!=x){
				sol.push_back(mp(1,2));
			}
			if(s2!=x){
				sol.push_back(mp(2,1));
			}
			cout<<sol.size()<<endl;;
			for(int i=0;i<sol.size();i++){
				cout<<sol[i].x<<" "<<sol[i].y<<endl;
			}
		}
		else{
			int x=(s1+1)%2;
			sol.push_back(mp(2,1));
			if(f1!=x){
				sol.push_back(mp(n,n-1));
			}
			if(f2!=x){
				sol.push_back(mp(n-1,n));
			}
			cout<<sol.size()<<endl;;
			for(int i=0;i<sol.size();i++){
				cout<<sol[i].x<<" "<<sol[i].y<<endl;
			}
		}

	}

return 0;
}


#include <iostream>
#include <cmath>
#include <utility>
#include <vector>

using namespace std;

typedef pair<int,int> pii;
typedef long long ll;
#define mp make_pair
#define x first
#define y second

vector<pii> sol;

int main () {
	int t;
	cin>>t;
	while(t--){
		int n;
		cin>>n;
		char grid[203][203];
		for(int i=1;i<=n;i++){
			for(int j=1;j<=n;j++){
				cin>>grid[i][j];
			}
		}
		int s1=int(grid[1][2])-48;
		int s2=int(grid[2][1])-48;
		int f1=int(grid[n][n-1])-48;
		int f2=int(grid[n-1][n])-48;
		if(s1==s2){
			int x=(s1+1)%2;
			if(f1!=x){
				sol.push_back(mp(n,n-1));
			}
			if(f2!=x){
				sol.push_back(mp(n-1,n));
			}
			cout<<sol.size()<<endl;
			for(int i=0;i<sol.size();i++){
				cout<<sol[i].x<<" "<<sol[i].y<<endl;
			}
			sol.clear();
		}
		else if(f1==f2){
			int x=(f1+1)%2;
			if(s1!=x){
				sol.push_back(mp(1,2));
			}
			if(s2!=x){
				sol.push_back(mp(2,1));
			}
			cout<<sol.size()<<endl;
			for(int i=0;i<sol.size();i++){
				cout<<sol[i].x<<" "<<sol[i].y<<endl;
			}
			sol.clear();
		}
		else{
			int x=(s1+1)%2;
			sol.push_back(mp(2,1));
			if(f1!=x){
				sol.push_back(mp(n,n-1));
			}
			if(f2!=x){
				sol.push_back(mp(n-1,n));
			}
			cout<<sol.size()<<endl;
			for(int i=0;i<sol.size();i++){
				cout<<sol[i].x<<" "<<sol[i].y<<endl;
			}
			sol.clear();
		}
	}

return 0;
}


#include <iostream>
#include <cmath>
#include <utility>
#include <vector>

using namespace std;

typedef pair<int,int> pii;
typedef long long ll;
#define mp make_pair
#define x first
#define y second

int main () {
	int t;
	cin>>t;
	while(t--){
		int n;
		cin>>n;
		char grid[203][203];
		for(int i=1;i<=n;i++){
			for(int j=1;j<=n;j++){
				cin>>grid[i][j];
			}
		}
		int s1=int(grid[1][2])-48;
		int s2=int(grid[2][1])-48;
		int f1=int(grid[n][n-1])-48;
		int f2=int(grid[n-1][n])-48;
		vector<pii> sol;
		if(s1==s2){
			int x=(s1+1)%2;
			if(f1!=x){
				sol.push_back(mp(n,n-1));
			}
			if(f2!=x){
				sol.push_back(mp(n-1,n));
			}
			cout<<sol.size()<<endl;
			for(int i=0;i<sol.size();i++){
				cout<<sol[i].x<<" "<<sol[i].y<<endl;
			}
			sol.clear();
		}
		else if(f1==f2){
			int x=(s1+1)%2;
			if(s1!=x){
				sol.push_back(mp(1,2));
			}
			if(s2!=x){
				sol.push_back(mp(2,1));
			}
			cout<<sol.size()<<endl;
			for(int i=0;i<sol.size();i++){
				cout<<sol[i].x<<" "<<sol[i].y<<endl;
			}
			sol.clear();
		}
		else{
			int x=(s1+1)%2;
			sol.push_back(mp(2,1));
			if(f1!=x){
				sol.push_back(mp(n,n-1));
			}
			if(f2!=x){
				sol.push_back(mp(n-1,n));
			}
			cout<<sol.size()<<endl;
			for(int i=0;i<sol.size();i++){
				cout<<sol[i].x<<" "<<sol[i].y<<endl;
			}
			sol.clear();
		}
	}

return 0;
}