#include <bits/stdc++.h>
using namespace std;
int n;
int d[2001][2001];
int d2[2001][2001];
int fa[2001];
struct Edge {
  int u, v, c;
};
bool operator<(const Edge &a, const Edge &b) { return a.c < b.c; }
vector<Edge> v;
int getfather(int x) { return fa[x] == x ? x : (fa[x] = getfather(fa[x])); }
vector<int> node[2001];
void dfs(int from, int cur, int prev, int c) {
  d2[from][cur] = c;
  for (int i = 0; i < node[cur].size(); ++i)
    if (node[cur][i] != prev)
      dfs(from, node[cur][i], cur, c + d[cur][node[cur][i]]);
}
int main() {
  scanf("%d", &n);
  for (int i = 0; i < n; ++i)
    for (int j = 0; j < n; ++j) scanf("%d", &d[i][j]);
  for (int i = 0; i < n; ++i)
    if (d[i][i] != 0) {
      printf("NO\n");
      return 0;
    }
  for (int i = 0; i < n; ++i)
    for (int j = i + 1; j < n; ++j) {
      if (d[i][j] != d[j][i] || d[i][j] <= 0) {
        printf("NO\n");
        return 0;
      }
      v.push_back({i, j, d[i][j]});
    }
  sort(v.begin(), v.end());
  for (int i = 0; i < n; ++i) fa[i] = i;
  int m = v.size();
  int cnt = 1;
  for (int i = 0; i < m && cnt < n; ++i) {
    int x = getfather(v[i].u), y = getfather(v[i].v);
    if (x == y) continue;
    fa[y] = x;
    node[v[i].u].push_back(v[i].v);
    node[v[i].v].push_back(v[i].u);
    ++cnt;
  }
  memset(d2, -1, sizeof(d2));
  for (int i = 0; i < n; ++i) dfs(i, i, -1, 0);
  for (int i = 0; i < n; ++i)
    for (int j = 0; j < n; ++j)
      if (d[i][j] != d2[i][j]) {
        printf("NO\n");
        return 0;
      }
  printf("YES\n");
  return 0;
}
