#include <iostream>
#include <cstring>
using namespace std;const int MAX_N = 1000;
const int MAX_M = 100000;
struct edge {
int v, next;
int len;
} E[MAX_M];
int p[MAX_N], eid;
bool used[MAX_N];
void init() {
memset(p, -1, sizeof(p));
memset(used, false, sizeof(used));
eid = 0;
}
void insert(int u, int v, int len) {
E[eid].v = v;
E[eid].len = len;
E[eid].next = p[u];
p[u] = eid++;
}
int prim(int n) {
int sum = 0;
int dist[MAX_N];
memset(dist, 0x3f, sizeof(dist));
memset(used, false, sizeof(used));
dist[1] = 0;
for (int i = 0; i < n; ++i) {
int min_v = -1, min_d = 0x3f3f3f3f;
for (int j = 1; j <= n; ++j) {
if (!used[j] && dist[j] < min_d) {
min_d = dist[j];
min_v = j;
}
}
sum += min_d;
used[min_v] = true;
for (int i = p[min_v]; i != -1; i = E[i].next) {
int v = E[i].v;
dist[v] = min(dist[v], E[i].len);
}
}
return sum;
}
int main() {
int n;
cin>>n;
init();
int sqar[n][n];
for(int i=0;i<n;i++){
for(int j=0;j<n;j++)cin>>sqar[i][j];
}
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
if(sqar[i][j]!=0){
insert(i+1,j+1,sqar[i][j]);
insert(j+1,i+1,sqar[i][j]);
}
}
}
cout<<prim(n)<<endl;
return 0;
}