#include < iostream >
using namespace std;
#define MAXN 250
#define INF 2110000000
#define MIN(x,y) (x<y?x:y)
int map[MAXN][MAXN];
int K,C,M,n;
int s,t;
int dis[MAXN][MAXN];
int mat[MAXN][MAXN];
void floyd()
{
int i,j,k;
for (k = 1 ;k <= n;k ++ )
{
for (i = 1 ;i <= n;i ++ )
{
for (j = 1 ;j <= n;j ++ )
{
if (dis[i][j] > dis[i][k] + dis[k][j])
dis[i][j] = dis[i][k] + dis[k][j];
}
}
}
}
void inti( int mindis)
{
int i,j;
memset(mat, 0 , sizeof (mat));
for (i = K + 1 ;i <= n;i ++ )
mat[s][i] = 1 ;
for (i = 1 ;i <= K;i ++ )
mat[i][t] = M;
for (i = K + 1 ;i <= n;i ++ )
{
for (j = 1 ;j <= K;j ++ )
{
if (mindis >= dis[i][j])
mat[i][j] = 1 ;
}
}
}
int max_flow( int num, int map[][MAXN], int source, int sink) // 参数含义:结点数量 网络 源点 汇点
{
int my_queue[MAXN],queue_first,queue_end; // 数组做队列 实现BFS搜索路径
int pre[MAXN],min_flow[MAXN]; // 记录结点的父节点 当前路径中最小的一段的值,也即限制值
int flow[MAXN][MAXN]; // 记录当前网络中的流
int ans = 0 ; // 最终结果
memset(flow, 0 , sizeof (flow));
while ( 1 ) // 一直循环,直到不存在增广路径
{
queue_first = 0 ; // 初始化队列
queue_end = 0 ;
my_queue[queue_end ++ ] = source;
memset(pre, - 1 , sizeof (pre));
min_flow[source] = INF;
pre[source] =- 2 ; // 源点的父节点需特殊标示
while (queue_first < queue_end) // BFS寻找增广路径
{
int temp = my_queue[queue_first ++ ]; // 出队列
for ( int i = 0 ;i < num;i ++ ) // 由结点temp往外扩展
{
if (pre[i] ==- 1 && flow[temp][i] < map[temp][i]) // 当结点i还未被探索到,并且还有可用流量
{
my_queue[queue_end ++ ] = i; // 加入队列
pre[i] = temp; // 标示父节点
min_flow[i] = MIN(min_flow[temp],(map[temp][i] - flow[temp][i])); // 求得min_flow
}
}
if (pre[sink] !=- 1 ) // sink的父节点不为初始值,说明BFS已经找到了一条路径
{
int k = sink;
while (pre[k] >= 0 )
{
flow[pre[k]][k] += min_flow[sink]; // 将新的流量加入flow
flow[k][pre[k]] =- flow[pre[k]][k];
k = pre[k];
}
break ;
}
}
if (pre[sink] ==- 1 ) return ans; // 不存在增广路径,返回
else ans += min_flow[sink];
}
return ans;
}
int main()
{
int i,j;
while (scanf( " %d%d%d " , & K, & C, & M) != EOF)
{
n = K + C;
for (i = 1 ;i <= n;i ++ )
{
for (j = 1 ;j <= n;j ++ )
{
scanf( " %d " , & dis[i][j]);
if (dis[i][j] == 0 ) dis[i][j] = 999999999 ;
}
}
floyd();
s = 0 ;
t = n + 1 ;
int left = 0 ,right = 10000 ,mid;
while (left < right)
{
mid = (left + right) / 2 ;
inti(mid);
int temp = max_flow(n + 2 ,mat,s,t);
if (temp >= C) right = mid;
else left = mid + 1 ;
}
printf( " %d\n " ,right);
}
return 0 ;
}