#include<iostream>
using namespace std;
#define MAX 101
#define INF 99999999
struct stuNodes
{
int nFrom;
int nCost;
int nTo;
};
void vInput(int nArry[][MAX],int nN);
int nGetMin(int nArry[][MAX],int nN);
stuNodes nFindMinCost(bool bF[],bool bT[],int nArry[][MAX],int nN);
void vOut(int nRet);
int main()
{
int nNUM;
int nNodes[MAX][MAX];
int nAns;
while(1==scanf("%d",&nNUM))
{
vInput(nNodes,nNUM);
nAns=nGetMin(nNodes,nNUM);
vOut(nAns);
}
return 0;
}
void vInput(int nArry[][MAX],int nN)
{
int i;
int j;
for(i=1;i<=nN;i++)
{
for(j=1;j<=nN;j++)
{
scanf("%d",&nArry[i][j]);
}
}
}
int nGetMin(int nArry[][MAX],int nN)
{
int nAns;
int i;
bool bFrom[MAX],bTo[MAX];
stuNodes stuMin;
int nCount;
for(i=1;i<=nN;i++)
{
bFrom[i]=false;
bTo[i]=true;
}
nCount=1;
bFrom[nCount]=true;
bTo[nCount]=false;
nAns=0;
while(nCount<nN)
{
stuMin=nFindMinCost(bFrom,bTo,nArry,nN);
bFrom[stuMin.nTo]=true;
bTo[stuMin.nTo]=false;
nAns+=stuMin.nCost;
nCount++;
}
return nAns;
}
stuNodes nFindMinCost(bool bF[],bool bT[],int nArry[][MAX],int nN)
{
stuNodes nRet;
int i;
int j;
int nF,nT;
int nTemp;
nTemp=INF;
nF=1;
nT=1;
for(i=1;i<=nN;i++)
{
if(bF[i])
{
for(j=1;j<=nN;j++)
{
if(bT[j])
{
if(nTemp>nArry[i][j])
{
nTemp=nArry[i][j];
nF=i;
nT=j;
}
}
}
}
}
nRet.nCost=nTemp;
nRet.nFrom=nF;
nRet.nTo=nT;
return nRet;
}
void vOut(int nRet)
{
printf("%d\n",nRet);
}
using namespace std;
#define MAX 101
#define INF 99999999
struct stuNodes
{
int nFrom;
int nCost;
int nTo;
};
void vInput(int nArry[][MAX],int nN);
int nGetMin(int nArry[][MAX],int nN);
stuNodes nFindMinCost(bool bF[],bool bT[],int nArry[][MAX],int nN);
void vOut(int nRet);
int main()
{
int nNUM;
int nNodes[MAX][MAX];
int nAns;
while(1==scanf("%d",&nNUM))
{
vInput(nNodes,nNUM);
nAns=nGetMin(nNodes,nNUM);
vOut(nAns);
}
return 0;
}
void vInput(int nArry[][MAX],int nN)
{
int i;
int j;
for(i=1;i<=nN;i++)
{
for(j=1;j<=nN;j++)
{
scanf("%d",&nArry[i][j]);
}
}
}
int nGetMin(int nArry[][MAX],int nN)
{
int nAns;
int i;
bool bFrom[MAX],bTo[MAX];
stuNodes stuMin;
int nCount;
for(i=1;i<=nN;i++)
{
bFrom[i]=false;
bTo[i]=true;
}
nCount=1;
bFrom[nCount]=true;
bTo[nCount]=false;
nAns=0;
while(nCount<nN)
{
stuMin=nFindMinCost(bFrom,bTo,nArry,nN);
bFrom[stuMin.nTo]=true;
bTo[stuMin.nTo]=false;
nAns+=stuMin.nCost;
nCount++;
}
return nAns;
}
stuNodes nFindMinCost(bool bF[],bool bT[],int nArry[][MAX],int nN)
{
stuNodes nRet;
int i;
int j;
int nF,nT;
int nTemp;
nTemp=INF;
nF=1;
nT=1;
for(i=1;i<=nN;i++)
{
if(bF[i])
{
for(j=1;j<=nN;j++)
{
if(bT[j])
{
if(nTemp>nArry[i][j])
{
nTemp=nArry[i][j];
nF=i;
nT=j;
}
}
}
}
}
nRet.nCost=nTemp;
nRet.nFrom=nF;
nRet.nTo=nT;
return nRet;
}
void vOut(int nRet)
{
printf("%d\n",nRet);
}