#include <bits/stdc++.h>
using std::cin;
using std::complex;
using std::cout;
using std::endl;
using std::fixed;
using std::greater;
using std::ios_base;
using std::lower_bound;
using std::make_pair;
using std::map;
using std::max;
using std::min;
using std::multiset;
using std::next_permutation;
using std::ostream;
using std::pair;
using std::prev_permutation;
using std::random_shuffle;
using std::reverse;
using std::set;
using std::setprecision;
using std::sort;
using std::string;
using std::swap;
using std::upper_bound;
using std::vector;
template <class C>
void mini(C& a4, C b4) {
  a4 = min(a4, b4);
}
template <class C>
void maxi(C& a4, C b4) {
  a4 = max(a4, b4);
}
template <class T1, class T2>
ostream& operator<<(ostream& out, pair<T1, T2> pair) {
  return out << "(" << pair.first << ", " << pair.second << ")";
}
const long long N = 2e3 + 5;
vector<pair<long long, long long> > slo[N];
long long rep[N];
long long Find(long long v) {
  if (rep[v] == v) {
    return v;
  }
  rep[v] = Find(rep[v]);
  return rep[v];
}
bool Union(long long a, long long b) {
  a = Find(a);
  b = Find(b);
  if (a == b) {
    return false;
  }
  rep[b] = a;
  return true;
}
long long dis[N][N];
int want_dis[N][N];
int act_dis[N];
void Dfs(int v, int root) {
  dis[v][root] = act_dis[v];
  for (auto p : slo[v]) {
    int nei = p.first;
    int e = p.second;
    if (act_dis[nei] == -1) {
      act_dis[nei] = act_dis[v] + e;
      Dfs(nei, root);
    }
  }
}
pair<int, pair<long long, long long> > vec[N * N];
int main() {
  cout << fixed << setprecision(10);
  double beg_clock = 1.0 * clock() / CLOCKS_PER_SEC;
  long long dupa = 0;
  long long n;
  cin >> n;
  ;
  for (long long i = (1); i <= (n); ++i) {
    rep[i] = i;
    for (long long j = (1); j <= (n); ++j) {
      scanf("%d", &want_dis[i][j]);
      dupa++;
      vec[dupa] = (make_pair(want_dis[i][j], make_pair(i, j)));
      if (want_dis[i][j] == 0 && i != j) {
        cout << "NO\n";
        return 0;
      }
    }
  }
  sort(vec + 1, vec + dupa + 1);
  for (long long i = (1); i <= (dupa); ++i) {
    auto p = vec[i];
    long long a = p.second.first;
    long long b = p.second.second;
    if (Union(a, b)) {
      slo[a].push_back(make_pair(b, p.first));
      slo[b].push_back(make_pair(a, p.first));
    }
  }
  for (long long i = (1); i <= (n); ++i) {
    for (long long j = (1); j <= (n); ++j) {
      act_dis[j] = -1;
    }
    act_dis[i] = 0;
    Dfs(i, i);
  }
  for (long long i = (1); i <= (n); ++i) {
    for (long long j = (1); j <= (n); ++j) {
      if (dis[i][j] != want_dis[i][j]) {
        cout << "NO\n";
        return 0;
      }
    }
  }
  cout << "YES\n";
  return 0;
}
