#include <bits/stdc++.h>
using namespace std;
const int maxn = 2007;
int G[maxn][maxn];
int dis[maxn][maxn] = {0};
struct Edge {
  int u, v, dist;
  Edge() {}
  Edge(int b, int a, int d) {
    u = b;
    v = a;
    dist = d;
  }
};
bool cmp(Edge a, Edge b) { return a.dist < b.dist; }
vector<int> ufs;
vector<int> g[maxn];
int Find(int x) {
  if (ufs[x] < 0) return x;
  return ufs[x] = Find(ufs[x]);
}
void init(int n) { ufs.assign(n, -1); }
bool U(int a, int b) {
  if ((a = Find(a)) == (b = Find(b))) return true;
  ufs[a] += ufs[b];
  ufs[b] = a;
  return false;
}
bool has_one(int a, int b) {
  if ((a = Find(a)) == (b = Find(b))) return true;
  return false;
}
int getNum(int a) { return -ufs[a]; }
Edge e[maxn * maxn];
int vis[maxn];
long long dis2[maxn] = {0};
void dfs(int u, int fa, int sum) {
  dis2[u] = sum;
  for (int i = 0; i < g[u].size(); i++) {
    if (g[u][i] != fa) {
      dfs(g[u][i], u, sum + dis[g[u][i]][u]);
    }
  }
}
int ans;
int main() {
  int n;
  while (~scanf("%d", &n)) {
    ans = 1;
    for (int i = 1; i <= n; i++) {
      for (int j = 1; j <= n; j++) {
        scanf("%d", &G[i][j]);
      }
    }
    for (int i = 1; i <= n; i++) {
      for (int j = i + 1; j <= n; j++) {
        if (G[i][j] != G[j][i] || G[i][j] <= 0) {
          ans = 0;
          break;
        }
      }
      if (!ans) break;
    }
    if (ans)
      for (int i = 1; i <= n; i++) {
        if (G[i][i] != 0) {
          ans = 0;
          break;
        }
      }
    if (ans) {
      int num = 0;
      for (int i = 1; i <= n; i++) {
        for (int j = i + 1; j <= n; j++) {
          e[num++] = Edge(i, j, G[i][j]);
        }
      }
      sort(e, e + num, cmp);
      init(n + 7);
      for (int i = 0; i <= n; i++) g[i].clear();
      memset(dis, 0, sizeof(dis));
      for (int i = 0; i < num; i++) {
        Edge t = e[i];
        if (!U(t.u, t.v)) {
          g[t.u].push_back(t.v);
          g[t.v].push_back(t.u);
          dis[t.u][t.v] = dis[t.v][t.u] = t.dist;
        }
      }
      for (int i = 1; i <= n; i++) {
        dfs(i, 0, 0);
        for (int j = 1; j <= n; j++) {
          if (i == j) continue;
          if (dis2[j] != G[i][j]) {
            ans = 0;
            break;
          }
        }
        if (!ans) break;
      }
    }
    if (ans)
      printf("YES\n");
    else
      printf("NO\n");
  }
  return 0;
}
