#include <bits/stdc++.h>
using namespace std;
int n, a[2001][2001], d[2001], mark[2001], cha[2001], u, v, U, V;
vector<pair<int, pair<int, int> > > edge;
queue<int> q;
vector<pair<int, int> > data[2001];
bool check(int u) {
  memset(mark, 0, sizeof(mark));
  memset(d, 0, sizeof(d));
  d[u] = 0;
  q.push(u);
  mark[u] = true;
  while (!q.empty()) {
    int uu = q.front();
    for (int i = 0; i < data[uu].size(); i++) {
      int v = data[uu][i].first;
      if (!mark[v]) {
        mark[v] = true;
        q.push(v);
        d[v] = d[uu] + data[uu][i].second;
      }
    }
    q.pop();
  }
  for (int i = 1; i <= n; i++) {
    if (d[i] != a[u][i]) return false;
  }
  return true;
}
int getroof(int x) {
  if (cha[x] == x)
    return x;
  else {
    cha[x] = getroof(cha[x]);
    return cha[x];
  }
}
int main() {
  scanf("%d", &n);
  for (int i = 1; i <= n; i++) {
    for (int j = 1; j <= n; j++) {
      scanf("%d", &a[i][j]);
    }
  }
  for (int i = 1; i <= n; i++) {
    for (int j = i + 1; j <= n; j++) {
      edge.push_back(pair<int, pair<int, int> >(a[i][j], pair<int, int>(i, j)));
    }
  }
  sort(edge.begin(), edge.end());
  int dem = 0;
  for (int i = 1; i <= n; i++) cha[i] = i;
  for (int i = 0; i < edge.size(); i++) {
    if (edge[i].first == 0) {
      puts("NO");
      return 0;
    }
    u = edge[i].second.first;
    v = edge[i].second.second;
    U = getroof(u);
    V = getroof(v);
    if (U != V) {
      dem++;
      cha[U] = V;
      data[u].push_back(pair<int, int>(v, edge[i].first));
      data[v].push_back(pair<int, int>(u, edge[i].first));
    }
    if (dem == n - 1) break;
  }
  for (int i = 1; i <= n; i++) {
    if (!check(i)) {
      puts("NO");
      return 0;
    }
  }
  puts("YES");
  return 0;
}
