#include <bits/stdc++.h>
#define INF 1000000000
#define MAX_N 100
using namespace std;
typedef pair<int, int> P;
struct edge {
	int to, cost;
	edge(int to_, int cost_) : to(to_), cost(cost_) {}
};

int n;
vector<edge> G[MAX_N];

int Prim() {
	int res = 0;
	vector<bool> used(n, false);
	priority_queue<P, vector<P>, greater<P>> que;
	que.push(P(0, 0));
	while (!que.empty()) {
		P p = que.top(); que.pop();
		int v = p.second;
		if (used[v]) continue;
		used[v] = true;
		res += p.first;
		for (int i = 0; i < G[v].size(); i++) {
			edge e = G[v][i];
			que.push(P(e.cost, e.to));
		}
	}
	return res;
}

int main()
{
	cin >> n;
	for (int i = 0, c; i < n; i++) {
		for (int j = 0; j < n; j++) {
			cin >> c;
			if (c != -1)
				G[i].push_back(edge(j, c));
		}
	}
	cout << Prim() << endl;
	return 0;
}
#include <algorithm>
#include <iostream>
using namespace std;

int P[10010];
void init(int N){
  for (int i=0; i<N; i++) P[i] = i;
}
int root (int a){
  if (P[a] == a) return a;
  else {
    P[a] = root(P[a]);
    return P[a];
  }
}
bool is_same_set(int a, int b){
  return root(a) == root(b);
}
void unite(int a, int b){
  P[root(a)] = root(b);
}

int main(){
  int N;
  cin >> N;
  pair <int, int> edge[10010];
  for (int i=0; i<N; i++){
    for (int j=0; j<N; j++){
      cin >> edge[i*N+j].first;
      edge[i*N+j].second = i*N+j;
    }
  }
  sort(edge, edge+N*N);
  init(N);
  int ans = 0;
  int b = 0;
  for (int k=0; k<N*N; k++){
    while(edge[k].first < 0) k++;
    int i = edge[k].second / N;
    int j = edge[k].second % N;
    if (is_same_set(i,j)){}
    else{
      unite(i,j);
      ans += edge[k].first;
    }
  }
  cout << ans << endl;
}