#include <bits/stdc++.h>
using namespace std;
const int MOD = 1000000007;
const int INF = 2e9;
const long long INFLL = 1e18;
const int MAX_N = 2000;
int N;
int d[MAX_N + 1][MAX_N + 1];
vector<pair<long long, long long> > gp[MAX_N + 1];
vector<pair<int, pair<int, int> > > edge;
int g[MAX_N + 1];
void i_g() {
  for (int i = 1; i <= N; i++) g[i] = i;
}
int f_g(int x) { return (x == g[x]) ? x : g[x] = f_g(g[x]); }
void u_g(int x, int y) {
  x = f_g(x);
  y = f_g(y);
  g[y] = x;
}
long long dist[MAX_N + 1];
bool vst[MAX_N + 1];
void dfs(int x) {
  vst[x] = true;
  for (pair<int, int> j : gp[x]) {
    if (!vst[j.first]) {
      dist[j.first] = dist[x] + j.second;
      dfs(j.first);
    }
  }
}
int main() {
  scanf("%d", &N);
  i_g();
  for (int i = 1; i <= N; i++) {
    for (int j = 1; j <= N; j++) {
      scanf("%d", &d[i][j]);
    }
  }
  for (int i = 1; i <= N; i++) {
    if (d[i][i] != 0) {
      printf("NO");
      return 0;
    }
    for (int j = i + 1; j <= N; j++) {
      if (d[i][j] != d[j][i]) {
        printf("NO");
        return 0;
      }
      if (d[i][j] <= 0) {
        printf("NO");
        return 0;
      }
      edge.push_back({d[i][j], {i, j}});
    }
  }
  sort(edge.begin(), edge.end());
  for (int i = 0; i < edge.size(); i++) {
    int x = edge[i].second.first, y = edge[i].second.second;
    if (f_g(x) != f_g(y)) {
      gp[x].push_back({y, edge[i].first});
      gp[y].push_back({x, edge[i].first});
      u_g(x, y);
    }
  }
  for (int i = 1; i <= N; i++) {
    dfs(i);
    for (int j = 1; j <= N; j++) {
      if (dist[j] != d[i][j]) {
        printf("NO");
        return 0;
      }
      dist[j] = 0;
      vst[j] = false;
    }
  }
  printf("YES");
  return 0;
}
