

#include<bits/stdc++.h> using namespace std; const int N=300+10;//左集的个数,右集的个数 const int INF=0x3f3f3f3f; int match[N],v[N][N],lv[N],rv[N],visx[N],visy[N],minz,n; vector<int>g[N]; bool dfs(int u){ visx[u]=1; for(int i=1;i<=n;i++){ if(visy[i]) continue; int t=lv[u]+rv[i]-v[u][i]; if(t==0){ visy[i]=1; if(match[i]==-1||dfs(match[i])){ match[i]=u; return true; } } else if(t>0){ if(minz>t) minz=t; } } return false; } void km(){ memset(match,-1,sizeof(match)); for(int i=1;i<=n;i++){ while(1){ minz=INF; memset(visx,0,sizeof(visx)); memset(visy,0,sizeof(visy)); if(dfs(i)) break; for(int i=1;i<=n;i++) if(visx[i]) lv[i]-=minz; for(int i=1;i<=n;i++) if(visy[i]) rv[i]+=minz; } } } int main(){ while(~scanf("%d",&n)){ int l,r; memset(lv,0,sizeof(lv)); memset(rv,0,sizeof(rv)); for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) scanf("%d",&v[i][j]); for(int i=1;i<=n;i++){ int max_=0; for(int j=1;j<=n;j++) max_=max(max_,v[i][j]); lv[i]=max_; } km();int ans=0; for(int i=1;i<=n;i++){ ans+=v[match[i]][i]; } printf("%d\n",ans); } return 0; }