#include <bits/stdc++.h>
using namespace std;
vector<long long> parent(2001, -1);
vector<pair<long long, long long>> adj[2000 + 1];
vector<long long> rnk(2001, 0);
void make_set(long long v) {
  parent[v] = v;
  rnk[v] = 0;
}
long long find_set(long long v) {
  if (v == parent[v])
    return v;
  else
    return parent[v] = find_set(parent[v]);
}
void union_set(long long u, long long v) {
  u = find_set(u);
  v = find_set(v);
  if (u != v) {
    if (rnk[u] < rnk[v]) swap(u, v);
    parent[v] = u;
    if (rnk[u] == rnk[v]) rnk[u]++;
  }
}
int main() {
  long long n;
  scanf("%lld", &n);
  long long arr[n + 1][n + 1];
  for (long long i = 1; i <= n; i++)
    for (long long j = 1; j <= n; j++) scanf("%lld", &arr[i][j]);
  for (long long i = 1; i <= n; i++)
    for (long long j = i; j <= n; j++) {
      if (i == j && arr[i][j] != 0) {
        cout << "NO";
        exit(0);
      }
      if (arr[i][j] != arr[j][i]) {
        cout << "NO";
        exit(0);
      }
      if (i != j && arr[i][j] == 0) {
        cout << "NO";
        exit(0);
      }
    }
  for (long long i = 0; i <= 2000; i++) make_set(i);
  vector<tuple<long long, long long, long long>> edge;
  for (long long i = 1; i <= n; i++)
    for (long long j = i + 1; j <= n; j++)
      edge.push_back(make_tuple(arr[i][j], i, j));
  sort(edge.begin(), edge.end());
  vector<pair<long long, long long>> check[n + 1];
  for (auto x : edge) {
    long long len = get<0>(x);
    long long a = get<1>(x);
    long long b = get<2>(x);
    if (find_set(a) == find_set(b)) {
      check[a].push_back({b, len});
    } else {
      union_set(a, b);
      adj[a].push_back({b, len});
      adj[b].push_back({a, len});
    }
  }
  for (long long i = 1; i <= n; i++) {
    if (check[i].size() == 0) continue;
    vector<bool> used(2001, false);
    used[i] = true;
    vector<long long> d(2001, 1e18);
    d[i] = 0;
    queue<long long> q;
    q.push(i);
    while (!q.empty()) {
      long long v = q.front();
      q.pop();
      for (auto u : adj[v])
        if (!used[u.first]) {
          used[u.first] = true;
          q.push(u.first);
          d[u.first] = d[v] + u.second;
        }
    }
    for (auto x : check[i]) {
      if (d[x.first] != x.second) {
        cout << "NO";
        exit(0);
      }
    }
  }
  cout << "YES";
  return 0;
}
