/*#include<cstdio>
#include<cstdlib>
#include<vector>
#include<queue>
#include<cstring>
using namespace std;
const int MAXN = 210;
const int INF = 1 << 30;
vector <int> graf[MAXN];
int c[MAXN][MAXN], f[MAXN][MAXN], tt[MAXN], cost[MAXN][MAXN], dist[MAXN];
bool viz[MAXN];
int N, S, D;
bool ok = 1;
char *buffer;
inline int minim(int a, int b)
{
if(a > b)
return a;
return b;
}
int BF()
{
queue <int> Q;
vector <int> :: iterator it;
int nod, fm = INF, i;
//memset(dist, INF, sizeof(dist));
//memset(viz, 0, sizeof(viz));
for(i = 0; i <= D; ++i){
dist[i] = INF;
viz[i] = 0;
tt[i] = -1;
}
Q.push(S);
//viz[S] = 1;
dist[S] = 0;
while(!Q.empty()){
nod = Q.front();
Q.pop();
viz[nod] = 0;
for(it = graf[nod].begin(); it != graf[nod].end(); ++it){
if(c[nod][*it] > f[nod][*it])
continue;
if(dist[nod] + cost[nod][*it] < dist[*it]){
dist[*it] = dist[nod] + cost[nod][*it];
tt[*it] = nod;
if(!viz[*it]){
Q.push(*it);
viz[*it] = 1;
}
}
}
}
if(dist[D] != INF){
ok = 1;
fm = INF;
fprintf(stderr, "a");
for(i = D; i != S; i = tt[i])
fm = minim(fm, c[ tt[i] ][i] - f[ tt[i] ][i]);
//if(!fm)
//return 0;
for(i = D; i != S; i = tt[i]){
f[ tt[i] ][i] += fm;
f[i][ tt[i] ] -= fm;
}
return (fm * dist[D]);
}
if(tt[D] != -1)
return 0;
}
int flux()
{
int sol = 0;
while(ok){
ok = 0;
sol += BF();
}
return sol;
}
void flux()
{
int i;
while(BF()){
for(i = D; i != S; i = tt[i]){
++f[ tt[i] ][i];
--f[i][ tt[i] ];
}
}
}
void read(int &x)
{
while(*buffer < '0' || *buffer > '9')
++buffer;
x = 0;
while(*buffer >= '0' && *buffer <= '9'){
x = (x * 10) + (*buffer - '0');
++buffer;
}
}
int main()
{
int fs, i, j, x, sol = 0;
freopen("cc.in", "r", stdin);
freopen("cc.out", "w", stdout);
fseek(stdin, 0, SEEK_END);
fs = ftell(stdin);
buffer = (char*) malloc(fs);
rewind(stdin);
fread(buffer, 1, fs, stdin);
read(N);
S = 0;
D = (N << 1) + 1;
for(i = 1; i <= N; ++i)
for(j = 1; j <= N; ++j){
read(x);
graf[i].push_back(j + N);
graf[j + N].push_back(i);
cost[i][j + N] = x;
cost[j + N][i] = (-x);
c[i][j + N] = 1;
}
for(i = 1; i <= N; ++i){
graf[S].push_back(i);
graf[i].push_back(S);
c[0][S] = 1;
graf[i + N].push_back(D);
graf[D].push_back(i + N);
c[i + N][D] = 1;
}
//printf("%d", flux());
flux();
for(i = 1; i <= N; ++i)
for(j = 1; j <= N; ++j)
if(f[i][j + N])
sol += cost[i][j + N];
printf("%d", sol);
return 0;
}*/
#include<cstdio>
#include<cstdlib>
#include<queue>
using namespace std;
const int MAXN = 210;
const int INF = 1 << 30;
int c[MAXN][MAXN], f[MAXN][MAXN], tt[MAXN], cost[MAXN][MAXN], dist[MAXN];
bool viz[MAXN];
int N, S, D;
char *buffer;
inline int minim(int a, int b)
{
if(a > b)
return a;
return b;
}
void read(int &x)
{
while(*buffer < '0' || *buffer > '9')
++buffer;
x = 0;
while(*buffer >= '0' && *buffer <= '9'){
x = (x * 10) + (*buffer - '0');
++buffer;
}
}
bool BF()
{
queue <int> Q;
int i, nod;
for(i = 0; i <= D + 1; ++i){
dist[i] = INF;
tt[i] = (-1);
viz[i] = 0;
}
Q.push(S);
viz[S] = 1;
tt[S] = S;
dist[S] = 0;
while(!Q.empty()){
nod = Q.front();
Q.pop();
viz[nod] = 0;
for(i = 1; i <= D; ++i)
if(f[nod][i] < c[nod][i] && dist[i] > dist[nod] + cost[nod][i]){
dist[i] = dist[nod] + cost[nod][i];
tt[i] = nod;
if(!viz[i]){
Q.push(i);
viz[i] = 1;
}
}
}
if(tt[D] != (-1))
return 1;
return 0;
}
int flux()
{
int i, j, sol = 0;
while(BF()){
for(i = D; i != S; i = tt[i]){
++f[ tt[i] ][i];
--f[i][ tt[i] ];
}
}
for(i = 1; i <= N; ++i)
for(j = 1; j <= N; ++j)
if(f[i][j + N])
sol += cost[i][j + N];
return sol;
}
int main()
{
int fs, i, j, x;
freopen("cc.in", "r", stdin);
freopen("cc.out", "w", stdout);
fseek(stdin, 0, SEEK_END);
fs = ftell(stdin);
buffer = (char*) malloc(fs);
rewind(stdin);
fread(buffer, 1, fs, stdin);
read(N);
S = 0; D = (N << 1) + 1;
for(i = 1; i <= N; ++i)
for(j = 1; j <= N; ++j){
read(x);
cost[i][j + N] = x;
cost[j + N][i] = (-x);
c[i][j + N] = 1;
}
for(i = 1; i <= N; ++i){
c[0][i] = 1;
c[i + N][D] = 1;
}
printf("%d", flux());
return 0;
}