/**
解题思路:首先预处理出来各个点间的最小距离,然后dp求解。定义状态dp[i][j]代表当前访问过的城市用十进制表示为i,最终停留在j城市所走的最短距离。初始化dp[1][0]=0,状态值i所表示的二进制的2的零次方为1表示城市0被已经经过,状态值代表的二进制的2的m次方为1表示城市m已经经过。
*/
#include<stdio.h>
#include<iostream>
#include<string.h>
#include<algorithm>
using namespace std;
#define INF 0x3f3f3f3f
int d[12][12]; //用以记录两点间的最短距离
int n,top;
int dp[1<<12][12]; //dp[i][j]代表状态值为i时最终停留在j城市的最短距离
void floyd(){
for(int k=0;k<=n;k++){ //枚举断点
for(int i=0;i<=n;i++){
for(int j=0;j<=n;j++){
if(d[i][k]<INF&&d[k][j]<INF) //松弛操作
d[i][j]= d[i][j]<(d[i][k]+d[k][j])?d[i][j]:(d[i][k]+d[k][j]);
}
}
}
}
void DP(){
top=1<<(n+1); //状态值的最大值
memset(dp,-1,sizeof(dp)); //初始化为非法
dp[1][0]=0; //只经过0位置,距离初始化为0
for(int i=0;i<top;i++){ //枚举状态值
i=i|1; //哪种状态都必经过0位置,因为0是起点位置
for(int j=0;j<=n;j++){ //枚举所有城市
if(dp[i][j]!=-1){ //枚举该状态值下到达j城市时的最短距离
for(int k=0;k<=n;k++){
//枚举该状态值下从当前城市j到达其他城市k
if((k!=j)&&(dp[i|(1<<k)][k]==-1||dp[i|(1<<k)][k]>dp[i][j]+d[j][k])){
//如果j和k不冲突,且该城市未访问过,或已访问过但是没有从j到k近
//状态转移。如果状态值并未发生改变,说明最后回到的城市是原状态中包含的城市
dp[i|(1<<k)][k]=dp[i][j]+d[j][k];
}
}
}
}
}
}
int main(){
while(scanf("%d",&n)!=EOF&&n){
for(int i=0;i<=n;i++){
for(int j=0;j<=n;j++){
int tmp;
scanf("%d",&tmp);
d[i][j]=tmp;
}
}
floyd(); //floyd求出各个点间的最短距离
DP();
printf("%d\n",dp[top-1][0]);//top-1代表n个城市都走完的状态,0代表最后回到了pizzeria
}
return 0;
}