1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
#include <bits/stdc++.h>
using namespace std;
#define st first
#define nd second
#define pb push_back
#define all(x) (x).begin(), (x).end()
#define BOOST ios_base::sync_with_stdio(0), cin.tie(0)
template<typename T>
using vc = vector<T>;
using ll = long long;
using ld = long double;
using ii = pair<int, int>;

const int N = 3e5 + 5;

int main(){
	BOOST;
	int n, m, k;
	cin >> n >> m >> k;

	vc<ll> dc;
	vc<vc<ll>> ac;
	vc<vc<ll>> suf;
	vc<vc<ll>> pref;
	for(int i=0; i<n; i++){
		vc<ll> t(m);
		for(int j=0; j<m; j++){
			cin >> t[j];
		}
		if(t.front() >= t.back()){
			for(int j=0; j<m; j++){
				dc.pb(t[j]);
			}
		}
		else{
			for(int j=1; j<m; j++){
				t[j] += t[j-1];
			}
			ac.pb(t);
		}
	}
	sort(all(ac), [](const vc<ll> &a, const vc<ll> &b){
		return a.back() > b.back();	
	}); sort(all(dc), greater<ll>());
	pref = suf = ac;

	int acs = ac.size();
	for(int i=acs-1; i>=0; i--){
		for(int j=0; j<m; j++){
			if(i < acs-1){
				suf[i][j] = max(suf[i][j], suf[i+1][j]);
			}
		}
	}
	for(int i=0; i<acs; i++){
		for(int j=0; j<m; j++){
			pref[i][j] -= ac[i][m-1];
			if(i) pref[i][j] = max(pref[i][j], pref[i-1][j]);
		}
	}
	suf.pb(vc<ll>(m));

	ll ans = 0, cur = 0;

	int pa = 0;

	auto calc = [&]() -> void{
		if(k){
			ans = max(ans, cur + suf[pa][min(k-1, m-1)]);

			// if(ans == 3309){
				// cout << "pa  = " << pa << "\n";
				// cout << "cur = " << cur << "\n";
				// cout << "k   = " << k << "\n";
				// cout << "suf = " << suf[pa][0] << "\n";
				// cout << "ac[pa] = " << ac[pa][0] << "\n";
				// cout << "ac[pa+1] = " << ac[pa+1][0] << "\n";
				// cout << "ac[pa+2] = " << ac[pa+2][0] << "\n";

				// exit(0);
			// }

			if(pa){
				ll best_sub = pref[pa-1][min(k-1, m-1)];
				ll best_nxt = 0;
				if(pa < acs) best_nxt = ac[pa].back();
				ans = max(ans, cur + best_sub + best_nxt);
			}
		}
		ans = max(ans, cur);
	};

	for(; pa<acs && k >= m; pa++){
		cur += ac[pa].back();
		k -= m;
	}
	calc();

	for(int i=0; i<(int)dc.size(); i++){
		cur += dc[i];
		k--;

		if(k < 0){
			pa--;
			if(pa < 0) break;
			cur -= ac[pa].back();
			k += m;
		}
		calc();
	}

	cout << ans << "\n";
}