import std.algorithm;
import std.array;
import std.conv;
import std.range;
import std.stdio;
import std.string;
import std.traits;
import std.typecons;

enum INF(T) = T.max / 2; //longの場合10^^18くらい

void main()
{
	auto N = readln.chomp.to!size_t;
	auto input = new long[][](N, N);
	foreach (ref r; input)
	{
		r[] = readln.chomp.split(' ').map!(to!long).array;
	}
	long total;
	auto wf = warshallFloyd(input);
	//writefln("i:\n%sw:\n%s", input.fmt, wf.fmt);
	foreach (f; 0 .. N)
		foreach (t; 0 .. N)
		{
			if (wf[f][t] < input[f][t])
			{
				writeln(-1);
				return;
			}
			else
			{
				total += input[f][t];
				foreach (relay; 0 .. N)
				{
					if (f != relay && t != relay && input[f][t] == wf[f][relay] + wf[relay][t])
					{
						total -= input[f][t];
						break;
					}
				}
			}
		}
	writeln(total / 2);

}

/// graphMatrix[from][to] == cost < INF!T
T[][] graphMatrix(T = long)(size_t e)
{
	auto m = new T[][](e, e);
	foreach (ref r; m)
		r[] = INF!T;
	return m;
}
/// デバッグ用。GraphMatrixを見やすい文字列にする
string fmt(T)(T[][] graph)
{
	auto result = "";
	foreach (r; graph)
	{
		result ~= r.map!(n => (n == INF!T) ? "max" : n.to!string).join("\t") ~ "\n";
	}
	return result;
}

/// warshallFloyd[from][to] == shortestCost
T[][] warshallFloyd(T)(T[][] graph)
{
	auto result = new T[][](graph.length, graph.length);
	foreach(i,ref r;result)
		r[] = graph[i];
	foreach (relay; 0 .. graph.length)
		foreach (from; 0 .. graph.length)
			foreach (to; 0 .. graph.length)
				result[from][to] = min(result[from][to], result[from][relay] + result[relay][to]);
	return result;
}
