#include <bits/stdc++.h>
using namespace std;
string vow = "aeiou";
int month[] = {-1, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
const int dxhorse[] = {-2, -2, -1, -1, 1, 1, 2, 2};
const int dyhorse[] = {1, -1, 2, -2, 2, -2, 1, -1};
const int dx[] = {-1, 0, 1, 0};
const int dy[] = {0, 1, 0, -1};
const long double pie = 3.1415926535897932384626;
const long long mod = 1e9 + 7;
void bad() {
  cout << "NO";
  cout << "\n";
  ;
  exit(0);
}
const int N = 4e6 + 10;
const int M = 2e3 + 3;
long long dis[M][M];
pair<long long, pair<int, int> > ed[N];
int n;
int indx = 0;
void read() {
  cin >> n;
  for (int i = 1; i <= n; i++) {
    for (int j = 1; j <= n; j++) {
      cin >> dis[i][j];
      ed[indx++] = {dis[i][j], {i, j}};
    }
  }
}
void prelim_checks() {
  for (int i = 1; i <= n; i++) {
    for (int j = i + 1; j <= n; j++) {
      if (dis[i][j] != dis[j][i]) bad();
      if (dis[i][j] == 0) bad();
      if (dis[j][i] == 0) bad();
    }
  }
  for (int i = 1; i <= n; i++) {
    if (dis[i][i] != 0) bad();
  }
}
vector<int> parent(M, -1);
vector<pair<long long, int> > g[M];
int edges_included = 0;
bool ok = false;
int find_parent(int node) {
  if (parent[node] < 0) return node;
  return parent[node] = find_parent(parent[node]);
}
void join(pair<long long, pair<int, int> > temp) {
  long long w = temp.first;
  int a = temp.second.first;
  int b = temp.second.second;
  int p1 = find_parent(a);
  int p2 = find_parent(b);
  if (p1 == p2) return;
  g[a].push_back({w, b});
  g[b].push_back({w, a});
  if (parent[p1] > parent[p2]) swap(p1, p2);
  parent[p1] += parent[p2];
  parent[p2] = p1;
  edges_included++;
  if (edges_included == n - 1) ok = 1;
}
void MST() {
  sort(ed, ed + N);
  for (auto &temp : ed) {
    join(temp);
    if (ok) return;
  }
}
const int L = 13;
bool vis[M];
int up[M][L], lev[M];
long long lca_dis[M][L];
void dfs(int node) {
  vis[node] = 1;
  for (auto &temp : g[node]) {
    long long w = temp.first;
    int i = temp.second;
    if (vis[i]) continue;
    ;
    up[i][0] = node;
    lev[i] = 1 + lev[node];
    lca_dis[i][0] = w;
    dfs(i);
  }
}
void fill_data() {
  for (int j = 1; j < L; j++) {
    for (int i = 1; i <= n; i++) {
      up[i][j] = up[up[i][j - 1]][j - 1];
      lca_dis[i][j] = lca_dis[i][j - 1] + lca_dis[up[i][j - 1]][j - 1];
    }
  }
}
int lca(int a, int b) {
  if (lev[a] > lev[b]) swap(a, b);
  int diff = lev[b] - lev[a];
  for (int j = 0; j < L; j++) {
    if ((diff & (1 << j))) b = up[b][j];
  }
  if (a == b) return a;
  for (int j = L - 1; j > -1; j--) {
    if (up[a][j] != up[b][j]) a = up[a][j], b = up[b][j];
  }
  return up[a][0];
}
long long cal(int a, int anc) {
  int diff = lev[a] - lev[anc];
  long long len = 0;
  for (int j = 0; j < L; j++) {
    if ((diff & (1 << j))) {
      len += lca_dis[a][j];
      a = up[a][j];
    }
  }
  return len;
}
void solve(int test_case) {
  read();
  prelim_checks();
  MST();
  dfs(1);
  fill_data();
  for (int i = 1; i <= n; i++) {
    for (int j = i + 1; j <= n; j++) {
      int &a = i, &b = j;
      int anc = lca(a, b);
      long long len = cal(a, anc) + cal(b, anc);
      if (len != dis[i][j]) bad();
    }
  }
  cout << "YES";
  cout << "\n";
  ;
}
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  cout.tie(0);
  int t = 1;
  for (int i = 1; i <= t; i++) solve(i);
  return 0;
}
