#include <iostream>
#include <vector>
#include <queue>
#include <algorithm>
using namespace std;
const int MAXN = 3005;
const long long INF = 1e18;
int A[MAXN][MAXN];
long long dist_tree[MAXN];
int min_edge[MAXN];
int parent[MAXN];
bool vis[MAXN];
vector<pair<int, int>> adj[MAXN];
int N;
bool verify(int root) {
for (int i = 1; i <= N; ++i) dist_tree[i] = -1;
queue<int> q;
q.push(root);
dist_tree[root] = 0;
while (!q.empty()) {
int u = q.front();
q.pop();
if (dist_tree[u] != A[root][u]) return false;
for (auto& edge : adj[u]) {
int v = edge.first;
int w = edge.second;
if (dist_tree[v] == -1) {
dist_tree[v] = dist_tree[u] + w;
q.push(v);
}
}
}
for(int i = 1; i <= N; ++i) {
if(dist_tree[i] == -1) return false;
}
return true;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
if (!(cin >> N)) return 0;
for (int i = 1; i < N; ++i) {
for (int j = i + 1; j <= N; ++j) {
cin >> A[i][j];
A[j][i] = A[i][j];
}
}
for (int i = 1; i <= N; ++i) {
min_edge[i] = 20000;
vis[i] = false;
}
min_edge[1] = 0;
for (int i = 0; i < N; ++i) {
int u = -1;
for (int j = 1; j <= N; ++j) {
if (!vis[j] && (u == -1 || min_edge[j] < min_edge[u])) {
u = j;
}
}
if (u == -1 || min_edge[u] == 20000 && i > 0) {
cout << "No" << endl;
return 0;
}
vis[u] = true;
if (parent[u] != 0) {
adj[parent[u]].push_back({u, min_edge[u]});
adj[u].push_back({parent[u], min_edge[u]});
}
for (int v = 1; v <= N; ++v) {
if (!vis[v] && A[u][v] < min_edge[v]) {
min_edge[v] = A[u][v];
parent[v] = u;
}
}
}
for (int i = 1; i <= N; ++i) {
if (!verify(i)) {
cout << "No" << endl;
return 0;
}
}
cout << "Yes" << endl;
return 0;
}