import java.io.BufferedReader
import java.io.InputStreamReader
import java.io.StreamTokenizer
import java.util.*

fun main(args: Array<String> ) {
    val st = StreamTokenizer( BufferedReader( InputStreamReader( System.`in` ) ) )
    val n = st.nextInt()
    val e = Array( n, { IntArray( n ) } )
    val queue = PriorityQueue<Edge>( n * n / 2 )
    for ( i in 0 until n ) {
        for ( j in 0 until n ) {
            e[i][j] = st.nextInt()
            if ( i < j ) queue.add( Edge( i, j, e[i][j] ) )
        }
    }
    val dist = Array( n, { LongArray( n, { Long.MAX_VALUE / 4 } ) } )
    for ( i in 0 until n ) dist[i][i] = 0
    var r = 0L
    while ( queue.isNotEmpty() ) {
        val edge = queue.poll()
        if ( dist[edge.u][edge.v] < edge.d ) {
            println( -1 )
            return
        }
        if ( dist[edge.u][edge.v] > edge.d ) {
            r += edge.d
            for ( i in 0 until n ) {
                for ( j in 0 until n ) {
                    dist[i][j] = Math.min( dist[i][j],
                            Math.min(
                                    dist[i][edge.u] + edge.d + dist[edge.v][j],
                                    dist[i][edge.v] + edge.d + dist[edge.u][j]
                            )
                    )
                }
            }
        }
    }
    for ( i in 0 until n ) {
        for ( j in 0 until n ) {
            if ( e[i][j].toLong() != dist[i][j] ) {
                println( -1 )
                return
            }
        }
    }
    println( r )
}

data class Edge( val u: Int, val v: Int, val d: Int ) : Comparable<Edge> {
    override fun compareTo( e: Edge ): Int {
        if ( d != e.d ) return Integer.compare( d, e.d )
        if ( u != e.u ) return Integer.compare( u, e.u )
        return Integer.compare( v, e.v )
    }
}

private fun StreamTokenizer.nextInt(): Int {
    nextToken()
    return nval.toInt()
}
