// Slower C++ solution:
#include <iostream>

#include<bits/stdc++.h>

using namespace std;

long long int a[1000][1000],b[1000][1000],c[1000][1000];

//char x[1050][150],y[100050][20];



int main()

{

    long long int i,n,m,j,k,x,y;

    long long  int sum=0;

    scanf("%lld",&n);

    //memset(b,1,sizeof(b));

    for(i=1; i<=n; i++)

    {

        for(j=1; j<=n; j++)

        {

            scanf("%lld",&a[i][j]);



        }

    }

    memset(c,0,sizeof(c));

    for(k=1;k<=n;k++)

    {

        for(i=1;i<=n;i++)

        {

            for(j=1;j<=n;j++)

            {

                if(b[i][j]==0)

                {

                    b[i][j]=a[i][j];

                }

                b[i][j]=min(b[i][j],a[i][k]+a[k][j]);

                if((a[i][j]>=a[i][k]+a[k][j])&&(i!=k&&j!=k))

                {

                    c[i][j]=1;

                    b[i][j]=a[i][k]+a[k][j];

                }

            }

        }

    }

    int f=0;

    for(i=1;i<n;i++)

    {

        for(j=i+1;j<=n;j++)

        {

            if(a[i][j]!=b[i][j])

            {

                f=-1;

                break;

            }if((c[i][j]!=1)&&(a[i][j]==b[i][j]))

            {

                sum+=b[i][j];

            }

        }

        if(f==-1)

        {

            break;

        }

    }

    if(f==-1)

    {

        printf("-1");

    }else

    {

        printf("%lld",sum);

    }

    return 0;

}


// Faster C++ solution for the same problem (measured speedup: 9.298872682023838x):
#include<bits/stdc++.h>

#include<iostream>

#include<string>

#include<cmath>

#include<cstdio>

#include<cctype>

#include<cstring>

#include<iomanip>

#include<cstdlib>

#include<ctime>

#include<set>

#include<map>

#include<utility>

#include<queue>

#include<vector>

#include<stack>

#include<sstream>

#include<algorithm>

using namespace std;

typedef long long ll;

typedef unsigned long long ull;

typedef pair<int,int> pii;

typedef pair<pii,pii> piiii;

typedef vector<pii> vii;

typedef vector<int> vi;

typedef queue<int> qi;

typedef queue<char> qc;

typedef queue<string> qs;

typedef vector<char> vc;

typedef vector<string> vs;

typedef map<char,int> mpci;

typedef map<int,int> mpii;

typedef map<string,int> mpsi;

typedef set<int> sei;

typedef set<char> sec;

typedef set<string> ses;

typedef stack<ll> si;

typedef stack<char> sc;

typedef vector<ll> vll;

typedef vector<vi> vvi;

typedef vector<double> vd;

typedef pair<ll,ll> pll;

typedef pair<double,double> pdd;

typedef vector<pll> vpll;

typedef vector<pdd> vdd;

typedef unsigned int uint;

typedef long double ld;

typedef vector<bool> vb;

typedef vector<double> vd;

typedef vector<vi> vvi;

typedef vector<vvi> vvvi;

typedef vector<vii> vvii;

/*=====================================================================*/

#define pb push_back

#define rep(i,n) for(int i=0;i<(int)(n);i++)

#define sz(a) (int)(a.size())

#define len(a) (int)(a.length())

#define all(s) (s).begin(),(s).end()

#define fi first

#define se second

#define be begin

#define en end

#define m_p make_pair

#define repd(i,n) for(int i=n-1;i>=0;i--)

#define forn(i,p,n) for(int i=p;i<=n;i++)

#define ford(i,p,n) for(int i=n-1;i>=p;i--)

#define foreach(i,c) for(__typeof(c.begin())i=(c.begin());i!=(c).end();++i)

#define zero(a) memset(a,0,sizeof(a))

#define number(a,num) memeset(a,num,sizeof(a))



/*=====================================================================*/



inline void read(int &x)

{

	short negative=1;

    x=0;

    char c=getchar();

    while(c<'0' || c>'9')

    {

		if(c=='-')

			negative=-1;

		c=getchar();

	}

    while(c>='0' && c<='9')

        x=(x<<3)+(x<<1)+(c^48),c=getchar();

    x*=negative;

}

inline void write(long long x) {

  static long long sta[35];

  long long top = 0;

  do {

    sta[top++] = x % 10, x /= 10;

  } while (x);

  while (top) putchar(sta[--top] + 48);

  puts("");

}

/*======================================================================*/

bool prime(int n)

{

	if(n==0||n==1)

	  return false;

	for(int i=2;i*i<=n;i++)

	  if(n%i==0)

	    return false;

	return true;

}

const ll power(int n,int k)

{

	ll t=1;

	rep(i,k)

	  t*=n;

	return t;

}

const string turn2(int n)

{

	string s="";

	while(n!=0)

	{

		s+=(char)(n%2+'0');

		n/=2;

	}

	reverse(s.begin(),s.end());

	return s;

}

const string turn16(int n)

{

	string s="";

	while(n!=0)

	{

		if(n%16>9)

		  s+=(char)('A'+n%16-10);

		else

		  s+=(char)('0'+n%16);

		n/=16;

	}

	reverse(s.begin(),s.end());

	return s;

}

const ll quickpower(int n,int k)

{

	if(k==1)

	  return n;

	if(k%2==1)

	  return n*quickpower(n,k/2)*quickpower(n,k/2);

	else

	  return quickpower(n,k/2)*(quickpower(n,k/2));

}

/*

void merge(int a[],int left,int mid,int right)

{

	int n1=mid-left;

	int n2=right-mid;

	for(int i=0;i<n1;i++)

	{

	  l[i]=a[i+left];

    }

	for(int i=0;i<n2;i++)

	{

	  r[i]=a[mid+i];

	}

	r[n2]=l[n1]=INF;

	int i=0;

	int j=0;

	for(int k=left;k<right;k++)

	{

		if(l[i]<=r[j])

		{

			a[k]=l[i++];

		}

		else

		{

			a[k]=r[j++];

		}

	}

}

void mergesort(int a[],int left,int right)

{

	if(left+1<right)

	{

		int mid=(left+right)/2;

		mergesort(a,left,mid);

		mergesort(a,mid,right);

		merge(a,left,mid,right);

	}

}

int binsearch(int x,int v[],int n)

{

	int low=0,high=n-1;

	int mid;

	while(low<=high)

	{

		mid=(low+high)/2;

		if(x<v[mid])

		  high=mid-1;

		else

		  if(x>v[mid])

		    low=mid+1;

		  else

		    return mid+1;

	}

	return -1;

}

int partition(int a[],int left,int right)

{

	int p=a[left];

	int i=left;

	int j=right+1;

	for(;;)

	{

		while(a[++i]<p)

		  if(i>=right)

		    break;

		while(a[j--]>p)

		  if(j<=left)

		    break;

		if(i>=j)

		  break;

		else

		  swap(a[i],a[j]);

	}

	if(j>=left)

	  return j;

	swap(a[left],a[j]);

	return j;

}

void quicksort(int a[],int left,int right)

{

	int q;

	while(right>left)

	{

		q=partition(a,left,right);

	    if(n-q+1==k)

	    {

	        cout<<a[q];

	  		exit(0);

		}

		quicksort(a,left,q-1);

		quicksort(a,q+1,right);

	}

}

void dfs(int n)

{

	if(use[n])

	  return;

	use[n]=true;

	cout<<n<<endl;

	for(int i=0;i<v[n].size();i++)

	  dfs(v[n][i]);

}*/

/*======================================================================*/

const int dx[]={-1,0,1,0};

const int dy[]={0,-1,0,1};

ll a[310][310];

bool p[310][310];

/*======================================================================*/

int main()

{

  /*

	freopen("input.txt","r",stdin);

	freopen("output.txt","w",stdout);

  */

  /*====================================================================*/

    ll n,ans=0;

    cin>>n;

    rep(i,n)

    {

      rep(j,n)

      {

        cin>>a[i][j];

       }

    }

	rep(k,n)   

	{

		rep(i,n)

		{

            rep(j,n)

			{

                if(k!=j&&k!=i&&i!=j)

				{

                    if(a[i][j]==a[i][k]+a[k][j])

                    {

                      p[i][j]=1; 

					}

                    if(a[i][j]>a[i][k]+a[k][j])

					{

                        cout<<"-1"<<endl;  

                        return 0;

                    }

                }

            }

        }

    }

    rep(i,n)

    {

      for(int j=i+1;j<n;j++)

      {

        if(p[i][j]==0)

        {

            ans+=a[i][j]; 

        }

      }

    }

    cout<<ans<<endl;

    return 0;

}