#include <bits/stdc++.h>
using namespace std;
template <typename TYPE>
inline TYPE sqr(const TYPE& a) {
  return (a) * (a);
}
const int INF = 1000 * 1000 * 1000;
const long double EPS = 1e-9;
const long double PI = 2 * acos(0.0);
const int N = 2100;
int n;
int d[N][N];
int e[N][N];
vector<pair<int, int> > g[N];
vector<pair<int, int> > ch[N];
inline void check(bool condition) {
  if (condition) return;
  puts("NO");
  exit(0);
}
inline void add_e(int fm, int to, bool yes) {
  int val = yes ? 1 : -1;
  if (e[fm][to])
    check(e[fm][to] == val);
  else {
    e[fm][to] = val;
    e[to][fm] = val;
  }
}
void go(int v, vector<pair<int, int> >& vs) {
  int m = (int)vs.size();
  int adj = 0;
  for (int i = 0; i < int(m); ++i) {
    int dist = vs[i].first;
    int dest = vs[i].second;
    if (dest == v) continue;
    bool flag = true;
    for (int j = 0; j < int(adj); ++j) {
      int t = vs[j].second;
      if (dist == vs[j].first + d[t][dest]) {
        ch[vs[j].second].push_back(pair<int, int>(d[t][dest], dest));
        flag = false;
        break;
      }
    }
    add_e(v, dest, flag);
    if (flag) {
      vs[adj++] = vs[i];
    }
  }
  for (int i = 0; i < int(adj); ++i) {
    int t = vs[i].second;
    sort((ch[t]).begin(), (ch[t]).end());
    go(t, ch[t]);
  }
}
int visited;
bool used[N];
void test(int v, int prev) {
  if (used[v]) return;
  used[v] = true;
  visited++;
  int dif = d[v][prev];
  for (int i = 0; i < int(n); ++i) {
    if (i != prev) {
      check(d[v][i] == d[prev][i] - dif || d[v][i] == d[prev][i] + dif);
      if (e[v][i] > 0) test(i, v);
    }
  }
}
int main() {
  scanf("%d", &n);
  for (int i = 0; i < int(n); ++i) {
    for (int j = 0; j < int(n); ++j) {
      scanf("%d", &d[i][j]);
      if (d[i][j]) g[i].push_back(pair<int, int>(d[i][j], j));
    }
    sort((g[i]).begin(), (g[i]).end());
  }
  for (int i = 0; i < int(n); ++i) {
    check(d[i][i] == 0);
    for (int j = i + 1; j < n; ++j) check(d[i][j] == d[j][i]);
  }
  vector<pair<int, int> > vs;
  for (int i = 0; i < int(g[0].size()); ++i) vs.push_back(g[0][i]);
  go(0, vs);
  ++visited;
  used[0] = true;
  for (int i = 0; i < int(n); ++i)
    if (e[0][i] > 0) test(i, 0);
  check(visited == n);
  puts("YES");
  return 0;
}
