#include "tickets.h"
#include <bits/stdc++.h>
#define fi first
#define se second
#define sz(x) (int)x.size()
#define cmin(a, b) a=min(a, b)
#define cmax(a, b) a=max(a, b)
#define all(x) (x).begin(),(x).end()
#define rall(x) (x).rbegin(),(x).rend()
#define pb push_back
#define int long long
using namespace std;
int n, m, k;
vector<vector<int>> a;
int find_maximum(signed K, vector<vector<signed>> x) {
n=sz(x), m=sz(x[0]), k=K;
a.resize(n, vector<int>(m));
for (int i=0; i<n; i++) for (int j=0; j<m; j++) a[i][j]=x[i][j];
vector<int> cnt(n), cur(n);
int res=0;
if (k==m) {
vector<pair<int, int>> vec; for (int i=0; i<n; i++) for (int j=0; j<m; j++) vec.pb({x[i][j], i});
sort(all(vec));
for (int i=0; i<sz(vec); i++) {
if (i<sz(vec)/2) res-=vec[i].fi, cnt[vec[i].se]++;
else res+=vec[i].fi;
}
} else {
for (int i=0; i<n/2; i++) {
cnt[i]=k;
for (int j=0; j<k; j++) res-=a[i][j];
}
for (int i=n/2; i<n; i++) {
cnt[i]=0;
for (int j=0; j<k; j++) res+=a[i][m-j-1];
}
set<pair<int, int>> add, rem;
for (int i=0; i<n/2; i++) add.insert({a[i][m-1]+a[i][k-1], i});
for (int i=n/2; i<n; i++) rem.insert({a[i][m-k]+a[i][0], i});
while (1) {
auto toadd=*add.rbegin(), torem=*rem.begin();
if (toadd.fi<=torem.fi) break;
res+=toadd.fi-torem.fi;
add.erase(toadd), rem.erase(torem);
int idxadd=toadd.se, idxrem=torem.se;
if (cnt[idxadd]<k) rem.erase({a[idxadd][m-(k-cnt[idxadd])]+a[idxadd][cnt[idxadd]], idxadd});
if (cnt[idxrem]>0) add.erase({a[idxrem][m-(k-cnt[idxrem])-1]+a[idxrem][cnt[idxrem]-1], idxrem});
cnt[idxadd]--, cnt[idxrem]++;
if (cnt[idxadd]>0) add.insert({a[idxadd][m-(k-cnt[idxadd])-1]+a[idxadd][cnt[idxadd]-1], idxadd});
if (cnt[idxadd]<k) rem.insert({a[idxadd][m-(k-cnt[idxadd])]+a[idxadd][cnt[idxadd]], idxadd});
if (cnt[idxrem]>0) add.insert({a[idxrem][m-(k-cnt[idxrem])-1]+a[idxrem][cnt[idxrem]-1], idxrem});
if (cnt[idxrem]<k) rem.insert({a[idxrem][m-(k-cnt[idxrem])]+a[idxrem][cnt[idxrem]], idxrem});
}
}
vector<pair<int, int>> order; for (int i=0; i<n; i++) order.pb({cnt[i], i});
vector<vector<signed>> ans(n, vector<signed>(m, -1));
for (int i=0; i<k; i++) {
sort(rall(order));
for (int j=0; j<n/2; j++) {
ans[order[j].se][cur[order[j].se]++]=i;
order[j].fi--;
}
for (int j=n/2; j<n; j++) {
int idx=order[j].se;
ans[idx][sz(a[idx])-1]=i;
a[idx].pop_back();
}
}
allocate_tickets(ans);
return res;
}