/*
ID: niepeng1
LANG: C++
TASK:agrinet
*/
#include <iostream>
#include <algorithm>
#include <functional>
#include <vector>
using namespace std;
#define Max1 101
int map[Max1][Max1];
struct Node{
int fro;
int to;
int val;
};
Node edge[Max1*Max1];
int cond[Max1];
int num,knum;
int total=0;
int cmp(const Node & a,const Node & b){return a.val>b.val;}
void Krustal()
{
int i,k,j;
int start=0,tem;
for(k=0;k<num-1;k++){
make_heap(edge+start,edge+knum,cmp);
for(i=start;i<knum;i++){
if( cond[edge[i].fro] != cond[edge[i].to] || (cond[edge[i].fro]==-1 && cond[edge[i].to]==-1))
break;
}
total+=edge[i].val;
if(edge[i].fro > edge[i].to)//fro 大 将被覆盖
{
tem=cond[edge[i].fro];
if(cond[edge[i].to]==-1)
cond[edge[i].to]=edge[i].to;
cond[edge[i].fro]=cond[edge[i].to];
if(tem != -1)
for(j=0;j<num;j++)
{
if(cond[j] == tem)
cond[j]=cond[edge[i].to];
}
}
else
{
tem=cond[edge[i].to];//to是较大的
if(cond[edge[i].fro]==-1)
cond[edge[i].fro]=edge[i].fro;
cond[edge[i].to]=cond[edge[i].fro];
if(tem != -1)
for(j=0;j<num;j++)
{
if(cond[j]==tem)
cond[j]=cond[edge[i].fro];
}
}
start=i+1;
}
}
int main()
{
FILE *in,*out;
int i,j,tem;
in=fopen("agrinet.in","r");
out=fopen("agrinet.out","w");
knum=0;
fscanf(in,"%d",&num);
for(i=0;i<num;i++)
for(j=0;j<num;j++){
fscanf(in,"%d",&tem);
map[i][j]=tem;
if( tem!=0)
{
edge[knum].fro=i;
edge[knum].to=j;
edge[knum].val=tem;
knum++;
}
cond[i]=-1;
}
Krustal();
fprintf(out,"%d/n",total);
// for(i=0;i<k;i++)
// cout<<edge[i].val<<' ';
fclose(in);
fclose(out);
return 0;
}