#include <bits/stdc++.h>
using namespace std;
const int N = 300, INF = 0x3f3f3f3f;
int w[N][N], c[N][N];
int minW[N], bestX[N], sum[N];
int n, m, v, minSum = 0, bestW = INF;
struct node
{
int d, cv, cw, lb, rcost;
int x[N];
// 优先级的比较
bool operator < (const node& t) const
{
return lb > t.lb;
}
// 构造函数
node (int d, int cv, int cw, int lb, int rcost)
{
this->d = d, this->cv = cv, this->cw = cw;
this->lb = lb, this->rcost = rcost;
}
};
int main()
{
memset(minW, 0x3f, sizeof minW);
cin >> n >> m >> v;
for(int i = 1; i <= n; i ++)
{
for(int j = 1; j <= m; j ++) cin >> c[i][j];
}
for(int i = 1; i <= n; i ++)
{
for(int j = 1; j <= m; j ++)
{
cin >> w[i][j];
// 记录每个部件的最小重量
minW[i] = min(minW[i], w[i][j]);
}
minSum += minW[i];
}
//for(int i = n; i >= 1; i --) sum[i] = minW[i] + sum[i + 1];
// 根节点
node fa = {0, 0, 0, minSum, minSum};
priority_queue<node> q;
q.push(fa);
while(q.size())
{
fa = q.top();
q.pop();
int d = fa.d + 1;
// 遍历到叶子节点时更新最优解
if(d == n + 1)
{
if(fa.cw < bestW)
{
bestW = fa.cw;
for(int i = 1; i <= n; i ++)
{
bestX[i] = fa.x[i];
}
}
}
else
{
for(int j = 1; j <= m; j ++)
{
int cv = fa.cv + c[d][j];
int cw = fa.cw + w[d][j];
if(cv > v) continue;
int rcost = fa.rcost - minW[d];
int lb = cw + rcost;
//int lb = cw + sum[d + 1];
//cout <<"d: " << d <<" J: " << j <<" cv: " <<cv <<" cw: " << cw << " rcost : " << rcost << " lb: " << lb << endl;
// 扩展子节点
if(lb < bestW)
{
node t = {d, cv, cw, lb, rcost};
// 构造子节点的解向量
for(int i = 1; i < d; i ++) t.x[i] = fa.x[i];
t.x[d] = j;
q.push(t);
}
}
}
}
cout << bestW << endl;
for(int i = 1; i <= n; i ++) cout << bestX[i] << ' ';
cout << endl;
return 0;
}