#include <bits/stdc++.h>
using namespace std;
const int64_t MOD = 1000000007;
class DisjointSet {
 private:
  vector<int> fa;

 public:
  DisjointSet(int x) {
    fa.resize(x);
    for (int i = 0; i < x; i++) fa[i] = i;
  }
  int find(int x) { return fa[x] == x ? x : fa[x] = find(fa[x]); }
  void merge(int x, int y) { fa[find(x)] = find(y); }
};
vector<vector<int>> getMst(const vector<vector<int>> &adj) {
  int n = adj.size();
  DisjointSet st(n);
  vector<pair<int, int>> edges;
  edges.reserve(n * n);
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < n; j++) {
      edges.push_back(move(pair<int, int>(i, j)));
    }
  }
  sort(edges.begin(), edges.end(),
       [&adj](const pair<int, int> &a, const pair<int, int> &b) {
         return adj[a.first][a.second] < adj[b.first][b.second];
       });
  vector<vector<int>> ret(n);
  for (const auto &edge : edges) {
    int f = edge.first;
    int t = edge.second;
    if (st.find(f) != st.find(t)) {
      st.merge(f, t);
      ret[f].push_back(t);
      ret[t].push_back(f);
    }
  }
  return move(ret);
}
vector<vector<int>> getAdj(const vector<vector<int>> &mst,
                           const vector<vector<int>> &adj) {
  int n = adj.size();
  vector<vector<int>> ret(n, vector<int>(n));
  for (int i = 0; i < n; i++) {
    queue<int> Q;
    vector<bool> visit(n);
    Q.push(i);
    visit[i] = true;
    auto &cost = ret[i];
    while (Q.size()) {
      int now = Q.front();
      Q.pop();
      for (auto next : mst[now]) {
        if (!visit[next]) {
          cost[next] = cost[now] + adj[now][next];
          visit[next] = true;
          Q.push(next);
        }
      }
    }
  }
  return move(ret);
}
int main() {
  int n;
  scanf("%d", &n);
  vector<vector<int>> adj(n, vector<int>(n));
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < n; j++) {
      scanf("%d", &adj[i][j]);
    }
  }
  bool check = true;
  for (int i = 0; i < n; i++) {
    if (adj[i][i] != 0) check = false;
    for (int j = i + 1; j < n; j++) {
      if (adj[i][j] != adj[j][i]) check = false;
      if (adj[i][j] == 0 || adj[j][i] == 0) check = false;
    }
  }
  if (!check) {
    cout << "NO" << endl;
  } else {
    vector<vector<int>> mst = getMst(adj);
    vector<vector<int>> ans = getAdj(mst, adj);
    cout << ((ans == adj) ? "YES" : "NO") << endl;
  }
  return 0;
}
