#include <bits/stdc++.h>
using namespace std;
static const int NEG = -1e9;
static const int MAXM = 100;
vector<signed char> build_pref(const vector<int>& scores, int right_cap, int m) {
vector<bitset<MAXM + 1>> masks(right_cap + 1);
masks[0][0] = 1; // sum 0 with 0 hidden scores
for (int a : scores) {
for (int sum = right_cap; sum >= a; --sum) {
masks[sum] |= (masks[sum - a] << 1);
}
}
vector<signed char> pref((right_cap + 1) * (m + 1), -1);
for (int sum = 0; sum <= right_cap; ++sum) {
int best = -1;
for (int h = 0; h <= m; ++h) {
if (masks[sum][h]) best = h;
pref[sum * (m + 1) + h] = (signed char)best;
}
}
return pref;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int N, M, K;
cin >> N >> M >> K;
vector<vector<int>> scores(N, vector<int>(M));
vector<int> total(N, 0);
for (int i = 0; i < N; ++i) {
for (int j = 0; j < M; ++j) {
cin >> scores[i][j];
total[i] += scores[i][j];
}
}
vector<int> order(N);
iota(order.begin(), order.end(), 0);
sort(order.begin(), order.end(), [&](int x, int y) {
if (total[x] != total[y]) return total[x] > total[y];
return x < y;
});
vector<int> g(N - 1);
for (int i = 0; i + 1 < N; ++i) {
int x = order[i], y = order[i + 1];
g[i] = total[x] - total[y] - (x > y ? 1 : 0);
}
// First contestant: only the uncertainty towards the right matters.
vector<signed char> first_pref = build_pref(scores[order[0]], g[0], M);
vector<int> dp(g[0] + 1, NEG);
for (int a = 0; a <= g[0]; ++a) {
dp[a] = first_pref[a * (M + 1) + M];
}
// Middle contestants.
for (int pos = 1; pos + 1 < N; ++pos) {
int left_cap = g[pos - 1];
int right_cap = g[pos];
vector<signed char> pref = build_pref(scores[order[pos]], right_cap, M);
vector<int> next_dp(right_cap + 1, NEG);
for (int prev_a = 0; prev_a <= left_cap; ++prev_a) {
if (dp[prev_a] <= NEG / 2) continue;
int left_budget = left_cap - prev_a;
int base = dp[prev_a];
for (int cur_a = 0; cur_a <= right_cap; ++cur_a) {
int limit = (cur_a + left_budget) / K;
if (limit > M) limit = M;
int h = pref[cur_a * (M + 1) + limit];
if (h >= 0) {
next_dp[cur_a] = max(next_dp[cur_a], base + h);
}
}
}
dp.swap(next_dp);
}
// Last contestant: only the uncertainty towards the left matters.
int last_cap = g.back();
vector<int> deficits;
deficits.reserve(M);
for (int a : scores[order.back()]) deficits.push_back(K - a);
sort(deficits.begin(), deficits.end());
vector<int> pref_def(M + 1, 0);
for (int i = 0; i < M; ++i) pref_def[i + 1] = pref_def[i] + deficits[i];
vector<int> best_last(last_cap + 1, 0);
int h = 0;
for (int budget = 0; budget <= last_cap; ++budget) {
while (h + 1 <= M && pref_def[h + 1] <= budget) ++h;
best_last[budget] = h;
}
int max_hidden = 0;
for (int prev_a = 0; prev_a <= last_cap; ++prev_a) {
if (dp[prev_a] <= NEG / 2) continue;
max_hidden = max(max_hidden, dp[prev_a] + best_last[last_cap - prev_a]);
}
cout << N * M - max_hidden << '\n';
return 0;
}