#include<iostream>
#include<iomanip>
#include<cstdio>

#include<vector>
#include<queue>
#include<set>
#include<map>
#include<string>

#include<algorithm>
#include<cmath>
#include<numeric>

using namespace std;
typedef long long ll;
template <class T> inline bool chmax(T& a, T b) {if (a < b) {a = b; return 1;} return 0;}
template <class T> inline bool chmin(T& a, T b) {if (a > b) {a = b; return 1;} return 0;}

#ifndef MAX_N
#define MAX_N 300
#endif
int par[MAX_N];
int rk[MAX_N];

//配列が長さnのものとして0で初期化する
void init(int n) {
    for (int i = 0; i < n; i++) {
        par[i] = i;
        rk[i] = 0;
    }
}
//xの親の要素の番号を返す
int find(int x) {
    if (par[x] == x) {
        return x;
    } else {
        return par[x] = find(par[x]);
    }
}
//要素を併合する
//木の高さrankが低いほうを高いほうの親につなげる
void unite(int x, int y){
    x = find(x);
    y = find(y);
    if (x == y) return;

    if (rk[x] < rk[y]) {
        par[x] = y;
    } else {
        par[y] = x;
        if (rk[x] == rk[y]) rk[x]++;
    }
}
//要素が同じ集合に属しているかどうかを返す
bool same(int x, int y) {
    return find(x) == find(y);
}




ll A[300][300], G[300][300], d[300][300];

struct edge{
    ll  u, v, cost;
    edge(ll uu, ll vv, ll cc) {
        u = uu; v = vv; cost = cc;
    }
};
bool comp(edge a, edge b) {
    return a.cost <= b.cost;
}


/*
グラフは連結になる
辺の短いほうから選択していく
最短のA[i][j]　をij間のA[i][j]の辺とする unite(i,j) d[i][j]=A[i][j]

uniteされてたら...
d[i][j] > A[i][j] ならij間に辺を追加 d[i][j] < A[i][j]ならだめ

uniteされてなかったら...
問答無用で追加

いずれも最短路を逐次更新

追加を終えたら、最後にワーシャルフロイドで点検
辺の和を出力

*/

int N;

void update(int u, int v) {
    for (int i = 0; i < N; i++) {
        for (int j = 0; j < N; j++) {
            if (i == j) continue;
            chmin(d[i][j],d[i][u]+G[u][v]+d[v][j]);
            chmin(d[i][j],d[i][v]+G[v][u]+d[u][j]);
        }
    }
}



int main() {

    cin >> N;
    init(N);
    for (int i = 0; i < N; i++) {
        for (int j = 0; j < N; j++) cin >> A[i][j];
    }
    vector<edge> E;
    for (int i = 0; i < N; i++) {
        for (int j = i+1; j < N; j++) {
            E.push_back(edge(i,j,A[i][j]));
        }
    }
    sort(E.begin(),E.end(),comp);

    for (int i = 0; i < N; i++) {
        for (int j = 0; j < N; j++) {
            if (i == j) continue;
            G[i][j] = 1e18;
            d[i][j] = 1e18;
        }
    }
    for (int i = 0; i < E.size(); i++) {
        edge e = E[i];
        ll dist = d[e.u][e.v];
        if (same(e.u,e.v)) {
            if (dist < e.cost) {
                cout << -1 << endl; return 0;
            } else if (dist > e.cost) {
                G[e.u][e.v] = G[e.v][e.u] = e.cost;  
                update(e.u,e.v);
            }
        } else {
            unite(e.u,e.v);
            G[e.u][e.v] = G[e.v][e.u] = e.cost;
            update(e.u,e.v);
        }
    }

    ll res = 0;
    for (int i = 0; i < N; i++) {
        for (int j = i+1; j < N; j++) {
            if (G[i][j] != 1e18) res += G[i][j];
        }
    }
    cout << res << endl;
    
    
    
    
    /*
    for (int i = 0; i < E.size(); i++) {
        edge e = E[i];
        ll d = dist(e.u,e.v,N);
        if (d < e.cost) {
            cout << -1 << endl; return 0;
        } else if (d > e.cost) {
            F[e.u].push_back(make_pair(e.v,e.cost));
            F[e.v].push_back(make_pair(e.u,e.cost));
            
        }
    }*/





}


Measured memory_bytes: 3572