/*
题目大意:给定一个N*N的方格,让你在里面取出一些数使其和最大,要求每一个数不能与其边相邻的4个数同时取出~~
f[i][j]代表前i层状态为j时的最优值
状态转移方称:f[i][j]=max{f[i-1][k]+sum} (sum是第i行状态为j的和,k&j==0)
*/
/*
dp(状态压缩)
f[i][j]代表前i层状态为j时的最优值
状态转移方称:f[i][j]=max{f[i-1][k]+sum} (sum是第i行状态为j的和,k&j==0)
*/
#include <cstdio>
#include<algorithm>
#include<iostream>
using namespace std;
const int N=21;
int n,tot,b[18000],a[N][N];
int f[N][1<<20];
void pre()
{
bool flg;
tot=0;
for (int i=0; i<(1<<20); i++)
{
if ((i<<1)&i)continue;
b[tot++]=i;
}
}
int dp()
{
int i,j,k,sum,t,ans=0;
for (i=1; i<=n; i++)
for (j=0; j<tot&&b[j]<(1<<n); j++)
{
sum=0;
k=1;
t=b[j];
while(t)
{
if(t&1) sum+=a[i][k];
k++;
t>>=1;
}
f[i][j]=0;
for (k=0; k<tot&&b[k]<(1<<n); k++)
{
if ((b[j]&b[k]))continue;
f[i][j]=max(f[i][j],f[i-1][k]+sum);
}
}
for(i=0;i<tot&&b[i]<(1<<n);i++)
ans=max(ans,f[n][i]);
return ans;
}
int main()
{
pre();
while (scanf("%d",&n)!=EOF)
{
for (int i=1; i<=n; i++)
for (int j=1; j<=n; j++)
scanf("%d",&a[i][j]);
printf("%d\n",dp());
}
return 0;
}