#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
using namespace std;
int map[1001][1003];
bool visited[1003];
int dis[1003];
int res;
void prim(int n,int x) //每次找到最小边
{
//初始化 从起点开始
for(int i = 0;i < n;i++)
{
dis[i] = map[x][i];
}
visited[x] = true;
int k;
for(int i = 1;i < n;i++) //找到n-1条边
{
int min = 100000;
for(int j = 0;j < n;j++) //每次找最小边
{
if(!visited[j] && min > dis[j])
{
min = dis[j];
k = j;
}
}
res += min;
visited[k] = true;
for(int j = 0;j < n;j++) //更新数组保存的最小边
{
if(!visited[j] && map[k][j] < dis[j])
{
dis[j] = map[k][j];
}
}
}
}
int main()
{
// freopen("c.txt","r", stdin);
int n;
cin>>n;
res = 0;
for(int i = 0;i < n;i++)
{
for(int j = 0;j < n;j++)
{
scanf("%d",&map[i][j]);
map[j][i] = map[i][j];
}
}
prim(n,0);
printf("%d\n",res);
return 0;
}
}
visited[x] = true;
int k;
for(int i = 1;i < n;i++) //找到n-1条边
{
int min = 100000;
for(int j = 0;j < n;j++) //每次找最小边
{
if(!visited[j] && min > dis[j])
{
min = dis[j];
k = j;
}
}
res += min;
visited[k] = true;
for(int j = 0;j < n;j++) //更新数组保存的最小边
{
if(!visited[j] && map[k][j] < dis[j])
{
dis[j] = map[k][j];
}
}
}
}
int main()
{
// freopen("c.txt","r", stdin);
int n;
cin>>n;
res = 0;
for(int i = 0;i < n;i++)
{
for(int j = 0;j < n;j++)
{
scanf("%d",&map[i][j]);
map[j][i] = map[i][j];
}
}
prim(n,0);
printf("%d\n",res);
return 0;
}