#include <bits/stdc++.h>
using namespace std;
const long long int INF = (long long int)1e9 + 10;
const long long int INFLL = (long long int)1e18 + 10;
const long double EPS = 1e-8;
const long double EPSLD = 1e-18;
const long long int MOD = 1e9 + 7;
template <class T>
T &chmin(T &a, const T &b) {
  return a = min(a, b);
}
template <class T>
T &chmax(T &a, const T &b) {
  return a = max(a, b);
}
struct Unionfind {
  vector<int> size, par;
  Unionfind() {}
  Unionfind(int n) : size(n, 1), par(n) {
    for (long long int i = (0); i < (long long int)(n); i++) par[i] = i;
  }
  void init(int n) {
    size = vector<int>(n, 1);
    par.resize(n);
    for (long long int i = (0); i < (long long int)(n); i++) par[i] = i;
  }
  int find(int x) {
    if (par[x] == x) return x;
    return par[x] = find(par[x]);
  }
  bool unite(int x, int y) {
    x = find(x);
    y = find(y);
    if (x == y) return false;
    if (size[y] < size[x]) swap(x, y);
    par[x] = y;
    size[y] += size[x];
    return true;
  }
  bool same(int x, int y) { return find(x) == find(y); }
};
const long long int MAX_N = 2010;
long long int n;
long long int d[MAX_N][MAX_N];
vector<pair<long long int, pair<long long int, long long int> > > edges;
vector<pair<long long int, long long int> > G[MAX_N];
Unionfind uf;
long long int dist[MAX_N];
int ng() {
  printf("NO\n");
  return 0;
}
void dfs(long long int x, long long int p, long long int d) {
  dist[x] = d;
  for (auto &w : G[x])
    if (w.first != p) dfs(w.first, x, d + w.second);
}
int main() {
  scanf("%lld", &n);
  for (long long int i = (0); i < (long long int)(n); i++)
    for (long long int j = (0); j < (long long int)(n); j++)
      scanf("%lld", &d[i][j]);
  for (long long int i = (0); i < (long long int)(n); i++)
    for (long long int j = (0); j < (long long int)(n); j++)
      if (i != j)
        edges.emplace_back(d[i][j], pair<long long int, long long int>(i, j));
  sort((edges).begin(), (edges).end());
  uf.init(n);
  for (auto &w : edges) {
    if (!uf.same(w.second.first, w.second.second)) {
      if (w.first == 0) return ng();
      uf.unite(w.second.first, w.second.second);
      G[w.second.first].emplace_back(w.second.second, w.first);
      G[w.second.second].emplace_back(w.second.first, w.first);
    }
  }
  for (long long int i = (0); i < (long long int)(n); i++) {
    for (long long int j = (0); j < (long long int)(n); j++) dist[j] = 0;
    dfs(i, -1, 0);
    for (long long int j = (0); j < (long long int)(n); j++)
      if (dist[j] != d[i][j]) return ng();
  }
  printf("YES\n");
  return 0;
}
