#include <bits/stdc++.h>
using namespace std;
struct no {
  int u, v, wei;
} edge[2007 * 2007];
bool operator<(no const& a, no const& b) { return a.wei < b.wei; }
int len[2007][2007];
struct node {
  int to, next, w;
} ed[2 * 2007];
int stu[2007];
int tre = 0;
void addtre(int u, int v, int w) {
  ed[tre].w = w;
  ed[tre].to = v;
  ed[tre].next = stu[u];
  stu[u] = tre++;
}
int fa[2007];
int col = 0;
int fin(int x) {
  if (fa[x] == -1) return x;
  int y = fa[x];
  while (fa[y] != -1) {
    fa[x] = fa[y];
    x = y;
    y = fa[y];
  }
  return y;
}
void add(int u, int v, int w) {
  edge[col].u = u;
  edge[col].v = v;
  edge[col++].wei = w;
}
bool kruskal(int n) {
  memset(fa, -1, sizeof(fa));
  int cnt = 0;
  sort(edge, edge + col);
  for (int i = 0; i < col; i++) {
    int u = fin(edge[i].u);
    int v = fin(edge[i].v);
    if (u != v) {
      addtre(edge[i].u, edge[i].v, edge[i].wei);
      addtre(edge[i].v, edge[i].u, edge[i].wei);
      fa[u] = v;
      cnt++;
    }
    if (cnt == n - 1) return true;
  }
  if (cnt < n - 1) return false;
}
bool vis[2007];
int deep[2007];
int d[2007][22];
int dis[2007];
void dfs(int u) {
  vis[u] = true;
  for (int i = stu[u]; i != -1; i = ed[i].next) {
    int v = ed[i].to;
    if (!vis[v]) {
      deep[v] = deep[u] + 1;
      d[v][0] = u;
      dis[v] = dis[u] + ed[i].w;
      dfs(v);
    }
  }
  return;
}
void buid(int n) {
  for (int j = 1; (1 << j) <= n; ++j)
    for (int i = 1; i <= n; ++i)
      if (~d[i][j - 1]) {
        d[i][j] = d[d[i][j - 1]][j - 1];
      }
}
void init_lca(int n) {
  memset(d, -1, sizeof(d));
  dfs(1);
  buid(n);
}
int query(int a, int b) {
  int ans = dis[a] + dis[b];
  int tmp;
  if (deep[a] < deep[b]) swap(a, b);
  for (tmp = 0; (1 << tmp) <= deep[a]; ++tmp)
    ;
  tmp--;
  for (int j = tmp; j >= 0; --j)
    if (deep[a] - deep[b] >= (1 << j)) a = d[a][j];
  if (a == b) return ans - 2 * dis[a];
  for (int j = tmp; j >= 0; j--) {
    if (d[a][j] != -1 && d[a][j] != d[b][j]) a = d[a][j], b = d[b][j];
  }
  ans -= 2 * dis[d[a][0]];
  return ans;
}
int main() {
  memset(stu, -1, sizeof(stu));
  int n;
  scanf("%d", &n);
  for (int i = 1; i <= n; i++) {
    for (int j = 1; j <= n; j++) {
      scanf("%d", &len[i][j]);
      if (i != j && len[i][j] <= 0 || i > j && len[i][j] != len[j][i]) {
        printf("NO\n");
        return 0;
      }
      if (i != j) {
        add(i, j, len[i][j]);
      } else if (i == j && len[i][j] != 0) {
        printf("NO\n");
        return 0;
      }
    }
  }
  if (n == 1) {
    printf("YES\n");
    return 0;
  }
  if (!kruskal(n)) {
    printf("NO\n");
    return 0;
  }
  init_lca(n);
  for (int i = 1; i <= n; ++i)
    for (int j = 1; j <= n; ++j) {
      if (i != j) {
        if (query(i, j) != len[i][j]) {
          printf("NO\n");
          return 0;
        }
      }
    }
  printf("YES\n");
  return 0;
}
