#include <bits/stdc++.h>
using namespace std;
int n, m, v, k, ans, fa[10000001];
struct node//定义结构体存图
{
int x, y, z;//z表示x连y的权值
}stu[100001];
int find(int x)//并查集
{
if(x != fa[x])
{
fa[x] = find(fa[x]);
}
return fa[x];
}//查找
void unity(int x, int y)
{
int r1 = find(x);
int r2 = find(y);
fa[r1] = r2;
}//合并
bool cmp(node a, node b)//从小到大结构体排序
{
return a.z < b.z;
}
int main()
{
scanf("%d", &n);
for(int i = 1; i <= n; i++)
{
fa[i] = i;//并查集初始化
}
for(int i = 1; i <= n; i++)
{
for(int j = 1; j <= n; j++)
{
scanf("%d", &v);
if(j > i)//邻接矩阵上下对称,存一半就行了
{
m++;
stu[m].x = i;
stu[m].y = j;
stu[m].z = v;
}
}
}
sort(stu + 1, stu + m + 1, cmp);//排序
for(int i = 1; i <= m; i++)
{
if(find(stu[i].x) != find(stu[i].y))
{
ans += stu[i].z;//加上最小生成树中边的权值
unity(stu[i].x, stu[i].y);//连接起来
k++;//记录边数
if(k == n - 1)//n - 1条边就行了
{
printf("%d", ans);
return 0;
}
}
}
return 0;
}