#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;
}