#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
const int MAXN=20;
const int INF=0x3f3f3f3f;
int dis[MAXN][MAXN];
int dp[1<<MAXN][MAXN];
int n;
void floyd()
{
for(int k=0;k<=n;k++)
for(int i=0;i<=n;i++)
for(int j=0;j<=n;j++)
if(dis[i][j]>(dis[i][k]+dis[k][j]))
dis[i][j]=dis[i][k]+dis[k][j];
}
void DP()
{
for(int i=0;i< (1<<n);i++) //枚舉所有的狀態
{
for(int j=1;j<=n;j++)
if(i==(1<<(j-1))) //狀態i中只走過城市j
dp[i][j]=dis[0][j];
else
{
if(i&(1<<(j-1))) //狀態i中走過城市j和其他城市
{
dp[i][j]=INF;
for(int k=1;k<=n;k++)
{
if(j!=k && (i&(1<<(k-1)))) //枚舉不是城市j的其他城市
//在沒經過城市j的狀態中,尋找合適的中間點k使得距離更短
dp[i][j]=min(dp[i][j],dp[i^(1<<(j-1))][k]+dis[k][j]);
}
}
}
}
int ans=INF;
for(int i=1;i<=n;i++) //枚舉走完所有城市的狀態,求回到原點的最短的距離
ans=min(ans,dp[(1<<n)-1][i]+dis[i][0]);
cout<<ans<<endl;
}
int main()
{
while(cin>>n&&n)
{
for(int i=0;i<=n;i++)
for(int j=0;j<=n;j++)
cin>>dis[i][j];
floyd();
DP();
}
return 0;
}