#include <bits/stdc++.h>
using namespace std;
int n;
int nu[2006][2006];
int fa[2006];
int ct = 0;
struct edge {
  int x, y, w;
  edge(int x = 0, int y = 0, int w = 0) : x(x), y(y), w(w) {}
  bool operator<(const edge &rhs) const { return w < rhs.w; }
} eg[2006 * 2006];
vector<int> g[2006];
int find(int x) {
  if (x == fa[x])
    return x;
  else
    return fa[x] = find(fa[x]);
}
int node;
int flag = 0;
int kruskal() {
  sort(eg, eg + ct);
  for (int i = 0; i < n; i++) fa[i] = i;
  for (int i = 0; i < ct; i++) {
    int tx = find(eg[i].x);
    int ty = find(eg[i].y);
    if (tx != ty) {
      fa[tx] = ty;
      g[eg[i].x].push_back(eg[i].y);
      g[eg[i].y].push_back(eg[i].x);
    }
  }
}
int dfs(int v, int now, int fa) {
  for (int i = 0; i < g[v].size(); i++) {
    int t = g[v][i];
    if (t == fa) continue;
    int wt = nu[v][t] + now;
    if (nu[node][t] != wt) {
      flag = 1;
      return -1;
    } else
      dfs(t, wt, v);
  }
  return 0;
}
int main() {
  scanf("%d", &n);
  int num;
  for (int i = 0; i < n; i++) g[i].clear();
  for (int i = 0; i < n; i++)
    for (int j = 0; j < n; j++) {
      scanf("%d", &num);
      nu[i][j] = num;
      if (i > j) {
        eg[ct].x = i;
        eg[ct].y = j;
        eg[ct++].w = num;
      }
      if (nu[i][j] != 0 && i == j) flag = 1;
      if (j < i && nu[i][j] != nu[j][i]) flag = 1;
      if (nu[i][j] == 0 && i != j) flag = 1;
    }
  if (flag != 1) {
    kruskal();
    for (int i = 0; i < n; i++) {
      node = i;
      if (dfs(i, 0, -1) == -1) {
        flag = 1;
        break;
      }
    }
  }
  if (flag == 1)
    puts("NO");
  else
    puts("YES");
  return 0;
}
