#include <fstream>
#include <iostream>
#include <vector>
#include <algorithm>
#define mp make_pair

using namespace std;

ifstream in("inverse_the_problem.in");
ofstream out("inverse_the_problem.out");

const int Nmax = 2000;

int l;
vector<int> A[Nmax];
vector<int> dad(Nmax);
vector<int> viz(Nmax);
vector<vector<int>> d(Nmax, vector<int>(Nmax));
vector<vector<int>> init(Nmax, vector<int>(Nmax));
vector<vector<int>> cost(Nmax, vector<int>(Nmax));

struct nod
{
    int x;
    int y;
    int c;
}v[Nmax];

bool cmp (nod a, nod b)
{
    return a.c < b.c;
}

int Find (int x)
{
    if (dad[x] == x) return x;
    return dad[x] = Find (dad[x]);
}

void Union (int x, int y)
{
    dad[x] = y;
}

void DFS (int x, int cnt, int dist)
{
    viz[x] = l;

    for (auto i = 0; i < A[x].size(); i++)
    {
        int w = A[x][i];

        if (viz[w] == 1 - l)
        {
            d[cnt][w] = dist + cost[x][w];
            int rez = d[cnt][w];
            DFS(w, cnt, d[cnt][w]);
        }
    }
}

int main()
{
    int n, nr = 0;
    cin >> n;

    for (int i = 1; i <= n; i++)
    {
        dad[i] = i;

        for (int j = 1; j <= n; j++)
        {
            int c;
            cin >> init[i][j];
            c = init[i][j];

            nr++;
            v[nr].x = i;
            v[nr].y = j;
            v[nr].c = c;
        }
    }

    sort (v + 1, v + n * n + 1, cmp);

    for (int i = 1; i <= n * n; i++)
    {
        int x = v[i].x;
        int y = v[i].y;
        int c = v[i].c;

        int xx = Find(x);
        int yy = Find(y);

        if (xx != yy)
        {
            Union(xx, yy);

            A[x].push_back(y);
            A[y].push_back(x);

            cost[x][y] = c;
            cost[y][x] = c;

            if (c == 0)
            {
                cout << "NO";
                return 0;
            }
        }
    }

    for (int i = 1; i <= n; i++)
    {
        l = 1 - l;
        DFS(i, i, 0);
    }

    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= n; j++)
        {
            if (d[i][j] != init[i][j])
            {
                cout << "NO";
                return 0;
            }
        }

    cout << "YES";
    return 0;
}


#include <iostream>
#include <vector>
#include <queue>

using namespace std;

const int Nmax = 2000;

int i, l;
int dad[Nmax], viz[Nmax];
int cost[Nmax][Nmax], v[Nmax][Nmax], d[Nmax][Nmax];

struct Nod
{
    int x;
    int y;
    int c;
};

struct comp
{
    bool operator()(Nod X, Nod Y)
    {
        return X.c > Y.c;
    }
};

priority_queue <Nod,  vector<Nod>, comp> Q;
vector <int> A[Nmax];

int Find (int x)
{
    if (dad[x] == x) return x;
    return dad[x] = Find(dad[x]);
}

void Union (int x, int y)
{
    dad[x] = y;
}

void DFS (int x)
{

    viz[x] = l;
    for (auto j = 0; j < A[x].size(); j++)
    {
        int w = A[x][j];
        if (viz[w] == 1 - l)
        {
            d[i][w] = d[i][x] + cost[x][w];
            DFS(w);
        }
    }
}

int main()
{
    int n;
    cin >> n;

    for (int i = 1; i <= n; i++)
    {
        if (v[i - 1][i - 1] != 0)
        {
            cout << "NO";
            return 0;
        }
        dad[i] = i;
            for (int j = 1; j <= n; j++)
        {
            cin >> v[i][j];

            int c = v[i][j];
            Nod nod;

            nod.x = i;
            nod.y = j;
            nod.c = c;

            Q.push(nod);
        }
    }

    if (v[n][n] != 0)
    {
        cout << "NO";
        return 0;
    }

    while (!Q.empty())
    {
        int x = Q.top().x;
        int y = Q.top().y;
        int c = Q.top().c;

        int xx = Find(x);
        int yy = Find(y);

        if (xx != yy)
        {
            Union(xx, yy);

            A[x].push_back(y);
            A[y].push_back(x);

            cost[x][y] = c;
            cost[y][x] = c;

            if (c == 0)
            {
                cout << "NO";
                return 0;
            }
        }

        Q.pop();
    }

    for (i = 1; i <= n; i++)
    {
        l = 1 - l;
        DFS(i);
    }

    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= n; j++)
        {
            if (d[i][j] != v[i][j])
            {
                cout << "NO";
                return 0;
            }
        }

    cout << "YES";
    return 0;
}


#include <iostream>
#include <vector>
#include <queue>
#define mp make_pair

using namespace std;

const int Nmax = 2000;

int i, l;
int dad[Nmax], viz[Nmax];
int v[Nmax][Nmax], d[Nmax][Nmax];

struct Nod
{
    int x;
    int y;
    int c;
};

struct comp
{
    bool operator()(Nod X, Nod Y)
    {
        return X.c > Y.c;
    }
};

priority_queue <Nod,  vector<Nod>, comp> Q;
vector <pair<int, int>> A[Nmax];

int Find (int x)
{
    if (dad[x] == x) return x;
    return dad[x] = Find(dad[x]);
}

void Union (int x, int y)
{
    dad[x] = y;
}

void DFS (int x)
{

    viz[x] = l;
    for (auto j = 0; j < A[x].size(); j++)
    {
        int w = A[x][j].first;
        int q = A[x][j].second;

        if (viz[w] == 1 - l)
        {
            d[i][w] = d[i][x] + q;
            DFS(w);
        }
    }
}

int main()
{
    int n;
    cin >> n;

    for (int i = 1; i <= n; i++)
    {
        dad[i] = i;
            for (int j = 1; j <= n; j++)
        {
            cin >> v[i][j];

            Nod nod;
            nod.x = i;
            nod.y = j;
            nod.c = v[i][j];

            Q.push(nod);
        }
    }

    while (!Q.empty())
    {
        int x = Q.top().x;
        int y = Q.top().y;
        int c = Q.top().c;

        int xx = Find(x);
        int yy = Find(y);

        if (xx != yy)
        {
            Union(xx, yy);

            A[x].push_back(mp(y, c));
            A[y].push_back(mp(x, c));

            if (c == 0)
            {
                cout << "NO";
                return 0;
            }
        }

        Q.pop();
    }

    for (i = 1; i <= n; i++)
    {
        l = 1 - l;
        DFS(i);
    }

    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= n; j++)
        {
            if (d[i][j] != v[i][j])
            {
                cout << "NO";
                return 0;
            }
        }

    cout << "YES";
    return 0;
}


#include <iostream>
#include <vector>
#include <algorithm>
#define mp make_pair

using namespace std;

const int Nmax = 2000;

vector<pair<int, int>> A[Nmax];

struct nod
{
    int x;
    int y;
    int c;
}v[Nmax * Nmax];

bool cmp (nod a, nod b)
{
    return a.c < b.c;
}

int Find (int x, vector<int>&dad)
{
    if (dad[x] == x) return x;
    return dad[x] = Find (dad[x], dad);
}

void Union (int x, int y, vector<int>&dad)
{
    dad[x] = y;
}

void DFS (int x, int cnt, int &l, vector<int>&viz, vector<vector<int>>&d)
{
    viz[x] = l;

    for (auto i = 0; i < A[x].size(); i++)
    {
        int w = A[x][i].first;
        int q = A[x][i].second;

        if (viz[w] == 1 - l)
        {
            d[cnt][w] = d[cnt][x] + q;
            DFS(w, cnt, l, viz, d);
        }
    }
}

int main()
{
    int n, l = 0, nr = 0;
    vector<int> viz(Nmax);
    vector<int> dad(Nmax);
    vector<vector<int>> d(Nmax, vector<int>(Nmax));
    vector<vector<int>> init(Nmax, vector<int>(Nmax));

    cin.sync_with_stdio(false);
    cin >> n;

    for (int i = 1; i <= n; i++)
    {
        dad[i] = i;

        for (int j = 1; j <= n; j++)
        {
            cin >> init[i][j];
            int c = init[i][j];

            nr++;
            v[nr].x = i;
            v[nr].y = j;
            v[nr].c = c;
        }
    }

    sort (v + 1, v + n * n + 1, cmp);

    for (int i = 1; i <= n * n; i++)
    {
        int x = v[i].x;
        int y = v[i].y;
        int c = v[i].c;

        int xx = Find(x, dad);
        int yy = Find(y, dad);

        if (xx != yy)
        {
            Union(xx, yy, dad);

            A[x].push_back(mp(y, c));
            A[y].push_back(mp(x, c));

            if (c == 0)
            {
                cout << "NO";
                return 0;
            }
        }
    }

    for (int i = 1; i <= n; i++)
    {
        l = 1 - l;
        DFS(i, i, l, viz, d);
    }

    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= n; j++)
        {
            if (d[i][j] != init[i][j])
            {
                cout << "NO";
                return 0;
            }
        }

    cout << "YES";
    return 0;
}


#include <iostream>
#include <vector>
#include <algorithm>
#define mp make_pair

using namespace std;

const int Nmax = 2000;

vector<pair<int, int>> A[Nmax];

struct nod
{
    int x;
    int y;
    int c;
}v[Nmax * Nmax];

bool cmp (nod a, nod b)
{
    return a.c < b.c;
}

int Find (int x, vector<int>&dad)
{
    if (dad[x] == x) return x;
    return dad[x] = Find (dad[x], dad);
}

void Union (int x, int y, vector<int>&dad)
{
    dad[x] = y;
}

void DFS (int x, int cnt, int &l, bool &OK, vector<int>&viz, vector<vector<int>>&d, vector<vector<int>>&init)
{
    viz[x] = l;

    for (auto i = 0; i < A[x].size(); i++)
    {
        int w = A[x][i].first;
        int q = A[x][i].second;

        if (viz[w] == 1 - l)
        {
            d[cnt][w] = d[cnt][x] + q;
            if (d[cnt][w] != init[cnt][w])
                OK = false;

            DFS(w, cnt, l, OK, viz, d, init);
        }
    }
}

int main()
{
    bool OK = true;
    int n, l = 0, nr = 0;
    vector<int> viz(Nmax);
    vector<int> dad(Nmax);
    vector<vector<int>> d(Nmax, vector<int>(Nmax));
    vector<vector<int>> init(Nmax, vector<int>(Nmax));

    cin >> n;

    for (int i = 1; i <= n; i++)
    {
        dad[i] = i;

        if (init[i - 1][i - 1] != 0)
        {
            cout << "NO";
            return 0;
        }

        for (int j = 1; j <= n; j++)
        {
            cin >> init[i][j];
            int c = init[i][j];

            nr++;
            v[nr].x = i;
            v[nr].y = j;
            v[nr].c = c;
        }
    }

    if (init[n][n] != 0)
    {
        cout << "NO";
        return 0;
    }

    sort (v + 1, v + n * n + 1, cmp);

    for (int i = 1; i <= n * n; i++)
    {
        int x = v[i].x;
        int y = v[i].y;
        int c = v[i].c;

        int xx = Find(x, dad);
        int yy = Find(y, dad);

        if (xx != yy)
        {
            Union(xx, yy, dad);

            A[x].push_back(mp(y, c));
            A[y].push_back(mp(x, c));

            if (c == 0)
            {
                cout << "NO";
                return 0;
            }
        }
    }

    for (int i = 1; i <= n; i++)
    {
        l = 1 - l;
        DFS(i, i, l, OK, viz, d, init);

        if (OK == false)
        {
            cout << "NO";
            return 0;
        }
    }

    cout << "YES";
    return 0;
}


#include <iostream>
#include <fstream>
#include <vector>
#include <queue>
#define mp make_pair

using namespace std;

ifstream in("inverse_the_problem.in");
ofstream out("inverse_the_problem.out");

const int Nmax = 2000;

int dad[Nmax];
int cost[Nmax][Nmax], v[Nmax][Nmax];
bool OK = true;

struct Nod
{
    int x;
    int y;
    int c;
};

struct comp
{
    bool operator()(Nod X, Nod Y)
    {
        return X.c > Y.c;
    }
};

priority_queue <Nod,  vector<Nod>, comp> Q;
vector <int> A[Nmax];

int Find (int x)
{
    if (dad[x] == x) return x;
    return dad[x] = Find(dad[x]);
}

void Union (int x, int y)
{
    dad[x] = y;
}

void DFS (int x, int cnt, vector<int> viz, vector<int> d)
{
    if (OK == true)
    {
        viz[x] = 1;

        for (auto i = 0; i < A[x].size(); i++)
        {
            int w = A[x][i];

            if (viz[w] == 0)
            {
                d[w] = d[x] + cost[x][w];

                if (v[cnt][w] != d[w])
                {
                    OK = false;
                    return;
                }

                DFS(w, cnt, viz, d);
            }
        }
    }
}

int main()
{
    int n;
    in >> n;

    for (int i = 1; i <= n; i++)
    {
        if (v[i - 1][i - 1] != 0)
        {
            out << "NO";
            return 0;
        }

        dad[i] = i;
            for (int j = 1; j <= n; j++)
        {
            in >> v[i][j];

            int c = v[i][j];
            Nod nod;

            nod.x = i;
            nod.y = j;
            nod.c = c;

            Q.push(nod);
        }
    }

    if (v[n][n] != 0)
    {
        out << "NO";
        return 0;
    }

    while (!Q.empty())
    {
        int x = Q.top().x;
        int y = Q.top().y;
        int c = Q.top().c;

        int xx = Find(x);
        int yy = Find(y);

        if (xx != yy)
        {
            Union(xx, yy);

            A[x].push_back(y);
            A[y].push_back(x);

            cost[x][y] = c;
            cost[y][x] = c;

            if (c == 0)
            {
                out << "NO";
                return 0;
            }
        }

        Q.pop();
    }

    for (int i = 1; i <= n; i++)
    {
        vector <int> viz(Nmax), d(Nmax);
        DFS(i, i, viz, d);

        if (OK == false)
        {
            out << "NO";
            return 0;
        }
    }

    out << "YES";
    return 0;
}


#include <iostream>
#include <fstream>
#include <vector>
#include <algorithm>

using namespace std;

ifstream in("inverse_the_problem.in");
ofstream out("inverse_the_problem.out");

const int Nmax = 2005;

vector<pair<int, int> > A[Nmax];

struct muchie
{
    int x;
    int y;
    int c;
};

bool cmp (muchie A, muchie B)
{
    return A.c < B.c;
}

int Find (int x, vector<int>&Father)
{
    if (Father[x] == x) return x;
    return Father[x] = Find(Father[x], Father);
}

void Union (int x, int y, vector<int>&Father)
{
    Father[x] = y;
}

void DFS (int cnt, int nod, int k, vector<bool>&viz, vector<vector<int> >&dist)
{
    viz[nod] = k;
    for (auto i = 0; i < A[nod].size(); i++)
    {
        int nod_curent = A[nod][i].first;
        int pret_curent = A[nod][i].second;

        if (viz[nod_curent] != k)
        {
            dist[cnt][nod_curent] = dist[cnt][nod] + pret_curent;
            DFS(cnt, nod_curent, k, viz, dist);
        }
    }
}

int main()
{
    int n, l = 0;

    cin.sync_with_stdio(false);
    cin >> n;

    vector<muchie> v;
    vector<bool> viz(n + 1);
    vector<int> Father(n + 1);
    vector<vector<int> > init(n + 1, vector<int>(n + 1));
    vector<vector<int> > dist(n + 1, vector<int>(n + 1));

    for (int i = 1; i <= n; i++)
    {
        Father[i] = i;
        for (int j = 1; j <= n; j++)
        {
            cin >> init[i][j];
            v.push_back({i, j, init[i][j]});
        }
    }

    sort(v.begin(), v.end(), cmp);

    for (int i = 0; i < v.size(); i++)
    {
        int x = v[i].x;
        int y = v[i].y;
        int c = v[i].c;

        int xx = Find(x, Father);
        int yy = Find(y, Father);

        if (xx != yy)
        {
            Union(xx, yy, Father);

            A[x].push_back(make_pair(y, c));
            A[y].push_back(make_pair(x, c));

            if (c == 0)
            {
                cout << "NO";
                return 0;
            }
        }
    }

    for (int i = 1; i <= n; i++)
    {
        DFS(i, i, 1 - l, viz, dist);
        l = 1 - l;
    }

    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= n; j++)
            if (init[i][j] != dist[i][j])
            {
                cout << "NO";
                return 0;
            }

    cout << "YES";
    return 0;
}


#include <iostream>
#include <vector>
#include <algorithm>
#define mp make_pair

using namespace std;

const int Nmax = 2000;

vector<pair<int, int>> A[Nmax];

struct nod
{
    int x;
    int y;
    int c;
}v[Nmax * Nmax];

bool cmp (nod a, nod b)
{
    return a.c < b.c;
}

int Find (int x, vector<int>&dad)
{
    if (dad[x] == x) return x;
    return dad[x] = Find (dad[x], dad);
}

void Union (int x, int y, vector<int>&dad)
{
    dad[x] = y;
}

void DFS (int x, int &l, int cnt, vector<int>&viz, vector<vector<int>>&d)
{
    viz[x] = l;

    for (auto i = 0; i < A[x].size(); i++)
    {
        int w = A[x][i].first;
        int q = A[x][i].second;

        if (viz[w] == 1 - l)
        {
            d[cnt][w] = d[cnt][x] + q;
            DFS(w, l, cnt, viz, d);
        }
    }
}

int main()
{
    int n, l = 0, nr = 0;
    vector<int> viz(Nmax);
    vector<int> dad(Nmax);
    vector<vector<int>> d(Nmax, vector<int>(Nmax));
    vector<vector<int>> init(Nmax, vector<int>(Nmax));

    cin >> n;

    for (int i = 1; i <= n; i++)
    {
        dad[i] = i;

        for (int j = 1; j <= n; j++)
        {
            int c;
            cin >> init[i][j];
            c = init[i][j];

            nr++;
            v[nr].x = i;
            v[nr].y = j;
            v[nr].c = c;
        }
    }

    sort (v + 1, v + n * n + 1, cmp);

    for (int i = 1; i <= n * n; i++)
    {
        int x = v[i].x;
        int y = v[i].y;
        int c = v[i].c;

        int xx = Find(x, dad);
        int yy = Find(y, dad);

        if (xx != yy)
        {
            Union(xx, yy, dad);

            A[x].push_back(mp(y, c));
            A[y].push_back(mp(x, c));

            if (c == 0)
            {
                cout << "NO";
                return 0;
            }
        }
    }

    for (int i = 1; i <= n; i++)
    {
        l = 1 - l;
        DFS(i, l, i, viz, d);
    }

    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= n; j++)
        {
            if (d[i][j] != init[i][j])
            {
                cout << "NO";
                return 0;
            }
        }

    cout << "YES";
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define pb push_back
#define pii pair<int,int>
#define mp make_pair
#define in insert
#define x first
#define y second
#define inf INT_MAX
#define mx 100007
#define mod 1000000007
ll bigmod(ll a,ll b,ll m)
{
    if(b==0)
        return 1%m;
    ll x=bigmod(a,b/2,m);
    x=(x*x)%m;
    if(b%2==1)
        x=(x*a)%m;
    return x;
}
int fx[]= {0,0,-1,1,-1,1,-1,1};
int fy[]= {1,-1,0,0,1,1,-1,-1};

int mat[2001][2001];

int main()
{
    ios::sync_with_stdio(false);
    int n;
    cin>>n;

    int i,j,k;
    for(i=0;i<n;i++)
    {
        for(j=0;j<n;j++)
        {
            cin>>mat[i][j];
            if(i==j)
            {
                if(mat[i][j]==0)
                {
                    cout<<"NO"<<endl;
                }
            }
        }
    }
    for(k=0;k<n;k++)
    {
        for(i=0;i<n;i++)
        {
            for(j=0;j<n;j++)
            {

                 if(mat[i][j]>mat[i][k]+mat[k][j])
                 {
                    cout<<"NO"<<endl;
                    return 0;
                 }
            }
        }
    }
    cout<<"YES"<<endl;

    return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define pb push_back
#define pii pair<int,int>
#define mp make_pair
#define in insert
#define x first
#define y second
#define inf INT_MAX
#define mx 100007
#define mod 1000000007
ll bigmod(ll a,ll b,ll m)
{
    if(b==0)
        return 1%m;
    ll x=bigmod(a,b/2,m);
    x=(x*x)%m;
    if(b%2==1)
        x=(x*a)%m;
    return x;
}
int fx[]= {0,0,-1,1,-1,1,-1,1};
int fy[]= {1,-1,0,0,1,1,-1,-1};

int mat[2001][2001];

int main()
{
    ios::sync_with_stdio(false);
    int n;
    cin>>n;

    int i,j,k;
    for(i=0;i<n;i++)
    {
        for(j=0;j<n;j++)
        {
            cin>>mat[i][j];
            if(i==j)
            {
                if(mat[i][j])
                {
                    cout<<"NO"<<endl;
                    return 0;
                }
            }
        }
    }
    for(k=0;k<n;k++)
    {
        for(i=0;i<n;i++)
        {
            for(j=0;j<n;j++)
            {

                 if(mat[i][j]!=mat[j][i])
                 {
                     cout<<"NO"<<endl;
                     return 0;
                 }
                 if(mat[i][j]>mat[i][k]+mat[k][j])
                 {
                    cout<<"NO"<<endl;
                    return 0;
                 }
            }
        }
    }
    cout<<"YES"<<endl;

    return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define pb push_back
#define pii pair<int,int>
#define mp make_pair
#define in insert
#define x first
#define y second
#define inf INT_MAX
#define mx 100007
#define mod 1000000007
ll bigmod(ll a,ll b,ll m)
{
    if(b==0)
        return 1%m;
    ll x=bigmod(a,b/2,m);
    x=(x*x)%m;
    if(b%2==1)
        x=(x*a)%m;
    return x;
}
int fx[]= {0,0,-1,1,-1,1,-1,1};
int fy[]= {1,-1,0,0,1,1,-1,-1};

int mat[2001][2001];

int main()
{
    ios::sync_with_stdio(false);
    int n;
    cin>>n;

    int i,j,k;
    for(i=0;i<n;i++)
    {
        for(j=0;j<n;j++)
        {
            cin>>mat[i][j];
            if(i==j)
            {
                if(mat[i][j])
                {
                    cout<<"NO"<<endl;
                    return 0;
                }
            }
        }
    }
    for(k=0;k<n;k++)
    {
        for(i=0;i<n;i++)
        {
            for(j=0;j<n;j++)
            {

                 if(mat[i][j]!=mat[j][i])
                 {
                     cout<<"NO"<<endl;
                     return 0;
                 }
                 if(mat[i][j]!=mat[i][k]+mat[k][j])
                 {
                    cout<<"NO"<<endl;
                    return 0;
                 }
            }
        }
    }
    cout<<"YES"<<endl;

    return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define pb push_back
#define pii pair<int,int>
#define mp make_pair
#define in insert
#define x first
#define y second
#define inf INT_MAX
#define mx 100007
#define mod 1000000007
ll bigmod(ll a,ll b,ll m)
{
    if(b==0)
        return 1%m;
    ll x=bigmod(a,b/2,m);
    x=(x*x)%m;
    if(b%2==1)
        x=(x*a)%m;
    return x;
}
int fx[]= {0,0,-1,1,-1,1,-1,1};
int fy[]= {1,-1,0,0,1,1,-1,-1};

//***************************************************//
#define ed pair<int,pii>
int mat[2001][2001];
vector<ed>edge;
vector<pii>g[2001];
bool vis[2001];
int par[2001],n,s;
int Find(int r)
{
    if(par[r]==r)
        return r;
    else
        return par[r]=Find(par[r]);
}
bool Union(int a,int b)
{
    int x=Find(a);
    int y=Find(b);
    if(x!=y)
    {
        par[x]=y;
        return true;
    }
    return false;
}
void kruskal()
{
    int i,u,v,c=0;
    for(i=0; i<edge.size(); i++)
    {
        u=edge[i].y.x;
        v=edge[i].y.y;
        if(Union(u,v))
        {
            c++;
            g[u].pb(mp(v,edge[i].x));
            g[v].pb(mp(u,edge[i].x));
        }
        if(c==n-1)
            return;
    }
}

int dfs(int u,int c=0)
{
    vis[u]=true;
    if(mat[s][u]!=c)
        return 0;
    int i;
    int r=1;
    pii v;
    for(i=0;i<g[u].size();i++)
    {
        v=g[u][i];
        if(!vis[v.x])
        {
            r=r&dfs(v.x,c+v.y);
        }

    }
    return r;
}
int main()
{
    ios::sync_with_stdio(false);
    cin>>n;
    int i,j;
    for(i=1; i<=n; i++)
    {
        par[i]=i;
        for(j=1; j<=n; j++)
        {
            cin>>mat[i][j];
            if(i==j)
            {
                if(mat[i][j])
                {
                    cout<<"NO"<<endl;
                    return 0;
                }
            }
            else
            {
                if(!mat[i][j])
                {
                    cout<<"NO"<<endl;
                    return 0;
                }
            }
        }
    }
    for(i=1; i<=n; i++)
    {
        for(j=1; j<=n; j++)
        {
            if(mat[i][j]!=mat[j][i])
            {
                cout<<"NO"<<endl;
                return 0;
            }
            else
            {
                edge.pb(mp(mat[i][j],mp(i,j)));
            }
        }
    }
    sort(edge.begin(),edge.end());
    kruskal();

    for(i=1;i<=n;i++)
    {
        memset(vis,false,sizeof(vis));
        s=i;
        if(!dfs(i))
        {
            cout<<"NO"<<endl;
            return 0;
        }
    }
    cout<<"YES"<<endl;

    return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define pb push_back
#define pii pair<int,int>
#define mp make_pair
#define in insert
#define x first
#define y second
#define inf INT_MAX
#define mx 100007
#define mod 1000000007
ll bigmod(ll a,ll b,ll m)
{
    if(b==0)
        return 1%m;
    ll x=bigmod(a,b/2,m);
    x=(x*x)%m;
    if(b%2==1)
        x=(x*a)%m;
    return x;
}
int fx[]= {0,0,-1,1,-1,1,-1,1};
int fy[]= {1,-1,0,0,1,1,-1,-1};

int mat[2001][2001];

int main()
{
    ios::sync_with_stdio(false);
    int n;
    cin>>n;

    int i,j,k;
    for(i=0;i<n;i++)
    {
        for(j=0;j<n;j++)
        {
            cin>>mat[i][j];
            if(i==j)
            {
                if(mat[i][j])
                {
                    cout<<"NO"<<endl;
                    return 0;
                }
            }
        }
    }
    for(k=0;k<n;k++)
    {
        for(i=0;i<n;i++)
        {
            for(j=0;j<n;j++)
            {

                 if(mat[i][j]>mat[i][k]+mat[k][j])
                 {
                    cout<<"NO"<<endl;
                    return 0;
                 }
            }
        }
    }
    cout<<"YES"<<endl;

    return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define pb push_back
#define pii pair<int,int>
#define mp make_pair
#define in insert
#define x first
#define y second
#define inf INT_MAX
#define mx 100007
#define mod 1000000007
ll bigmod(ll a,ll b,ll m)
{
    if(b==0)
        return 1%m;
    ll x=bigmod(a,b/2,m);
    x=(x*x)%m;
    if(b%2==1)
        x=(x*a)%m;
    return x;
}
int fx[]= {0,0,-1,1,-1,1,-1,1};
int fy[]= {1,-1,0,0,1,1,-1,-1};

int mat[2001][2001];

int main()
{
    ios::sync_with_stdio(false);
    int n;
    cin>>n;

    int i,j,k;
    for(i=0;i<n;i++)
    {
        for(j=0;j<n;j++)
        {
            cin>>mat[i][j];
            if(i==j)
            {
                if(mat[i][j]==0)
                {
                    cout<<"NO"<<endl;
                    return 0;
                }
            }
        }
    }
    for(k=0;k<n;k++)
    {
        for(i=0;i<n;i++)
        {
            for(j=0;j<n;j++)
            {

                 if(mat[i][j]>mat[i][k]+mat[k][j])
                 {
                    cout<<"NO"<<endl;
                    return 0;
                 }
            }
        }
    }
    cout<<"YES"<<endl;

    return 0;
}


#include "bits/stdc++.h"
#include<stdio.h>
#include <sstream>
#define pi 3.141592653589793238462
#define limit 100005
#define mo 1000000007;
typedef long long int lli;
typedef unsigned long long int ulli;
const lli mod=9999999999999983;
lli primes[6]={1125899906842597,1495921043,1005985879,1495921043,1005985879,1495921043};
using namespace std;
vector< pair<lli,lli> >adj[2005];
vector< pair<lli,pair<lli,lli> > >vect;
lli siz[200005];
lli arr[2005][2005];
lli parent[200005];
lli vis[200005];
lli dist[2005][2005];

void initialize()
{
    lli i;
    for(i=1;i<=2005;i++)
    {
        parent[i]=i;
        siz[i]=1;
    }
}

lli root(lli a)
{
    while(parent[a]!=a)
    {
        a=parent[parent[a]];
    }
    return a;
}

void make_union(lli a,lli b)
{
    lli root_a,root_b;
    root_a=root(a);
    root_b=root(b);

    if(root_a!=root_b)
    {
        if(siz[root_a]<siz[root_b])
        {
           parent[root_a]=root_b;
           siz[root_b]+=siz[root_a];
        }
        else
        {
           parent[root_b]=root_a;
           siz[root_a]+=siz[root_b];
        }
    }
}

void dfs(lli val,lli fixe)
{
    lli i;
    vis[val]=1;
    for(i=0;i<adj[val].size();i++)
    {
        if(vis[adj[val][i].first]==0)
        {
           dist[fixe][adj[val][i].first]+=dist[fixe][val]+adj[val][i].second;
           dfs(adj[val][i].first,fixe);
        }
    }
}

int main()
{
    int start_s = clock();
    ios_base::sync_with_stdio(false);
    cin.tie(NULL); cout.tie(NULL);

    initialize();
    lli i,j,k,n,m,wei,root_a,root_b,flag=0;
    cin>>n;

    for(i=1;i<=n;i++)
    {
        for(j=1;j<=n;j++)
        {
           cin>>wei;
           vect.push_back({wei,{i,j}});
        }
    }

    sort(vect.begin(),vect.end());

    for(k=0;k<vect.size();k++)
    {
           wei=vect[k].first;
           i=vect[k].second.first;
           j=vect[k].second.second;

           arr[i][j]=wei;
           root_a=root(i);
           root_b=root(j);
           if(root_a!=root_b)
           {
              make_union(i,j);
              adj[i].push_back({j,wei});
              adj[j].push_back({i,wei});
           }
    }

    for(i=1;i<=n;i++)
    {
        //cout<<"i="<<i<<"size="<<adj[i].size()<<endl;
    }

    for(i=1;i<=n;i++)
    {
        dfs(i,i);
        memset(vis,0,sizeof(vis));
    }

    /*
    for(i=1;i<=n;i++)
    {
        for(j=1;j<=n;j++)
        {
            cout<<"i="<<i<<" "<<"j="<<j<<" "<<"dist="<<dist[i][j]<<endl;
        }
    }
    */

    for(i=1;i<=n;i++)
    {
        for(j=1;j<=n;j++)
        {
           // cout<<"i="<<i<<" "<<"j="<<j<<" "<<"dist="<<dist[i][j]<<endl;
            if(arr[i][j]!=dist[i][j]||(arr[i][j]==0&&i!=j))
            {
                flag=1;
                break;
            }
        }
    }

    if(flag==1)
        cout<<"NO"<<endl;
    else
        cout<<"YES"<<endl;
}


#include "bits/stdc++.h"
#include<stdio.h>
#include <sstream>
#define pi 3.141592653589793238462
#define limit 100005
#define mo 1000000007;
typedef long long int lli;
typedef unsigned long long int ulli;
const lli mod=9999999999999983;
lli primes[6]={1125899906842597,1495921043,1005985879,1495921043,1005985879,1495921043};
using namespace std;
vector< pair<lli,lli> >adj[2005];
lli siz[200005];
lli arr[2005][2005];
lli parent[200005];
lli vis[200005];
lli dist[2005][2005];

void initialize()
{
    lli i;
    for(i=1;i<=2005;i++)
    {
        parent[i]=i;
        siz[i]=1;
    }
}

lli root(lli a)
{
    while(parent[a]!=a)
    {
        a=parent[parent[a]];
    }
    return a;
}

void make_union(lli a,lli b)
{
    lli root_a,root_b;
    root_a=root(a);
    root_b=root(b);

    if(root_a!=root_b)
    {
        if(siz[root_a]<siz[root_b])
        {
           parent[root_a]=root_b;
           siz[root_b]+=siz[root_a];
        }
        else
        {
           parent[root_b]=root_a;
           siz[root_a]+=siz[root_b];
        }
    }
}

void dfs(lli val,lli fixe)
{
    lli i;
    vis[val]=1;
    for(i=0;i<adj[val].size();i++)
    {
        if(vis[adj[val][i].first]==0)
        {
           dist[fixe][adj[val][i].first]+=dist[fixe][val]+adj[val][i].second;
           dfs(adj[val][i].first,fixe);
        }
    }
}

int main()
{
    int start_s = clock();
    ios_base::sync_with_stdio(false);
    cin.tie(NULL); cout.tie(NULL);

    initialize();
    lli i,j,k,n,m,wei,root_a,root_b,flag=0;
    cin>>n;

    for(i=1;i<=n;i++)
    {
        for(j=1;j<=n;j++)
        {
           cin>>wei;
           arr[i][j]=wei;
           root_a=root(i);
           root_b=root(j);
           if(root_a!=root_b)
           {
              make_union(i,j);
              adj[i].push_back({j,wei});
              adj[j].push_back({i,wei});
           }
        }
    }

    for(i=1;i<=n;i++)
    {
        //cout<<"i="<<i<<"size="<<adj[i].size()<<endl;
    }

    for(i=1;i<=n;i++)
    {
        dfs(i,i);
        memset(vis,0,sizeof(vis));
    }

    /*
    for(i=1;i<=n;i++)
    {
        for(j=1;j<=n;j++)
        {
            cout<<"i="<<i<<" "<<"j="<<j<<" "<<"dist="<<dist[i][j]<<endl;
        }
    }
    */

    for(i=1;i<=n;i++)
    {
        for(j=1;j<=n;j++)
        {
           // cout<<"i="<<i<<" "<<"j="<<j<<" "<<"dist="<<dist[i][j]<<endl;
            if(arr[i][j]!=dist[i][j]||(arr[i][j]==0&&i!=j))
            {
                flag=1;
                break;
            }
        }
    }

    if(flag==1)
        cout<<"NO"<<endl;
    else
        cout<<"YES"<<endl;
}


#include "bits/stdc++.h"
#include<stdio.h>
#include <sstream>
#define pi 3.141592653589793238462
#define limit 100005
#define mo 1000000007;
typedef long long int lli;
typedef unsigned long long int ulli;
const lli mod=9999999999999983;
lli primes[6]={1125899906842597,1495921043,1005985879,1495921043,1005985879,1495921043};
using namespace std;
vector< pair<lli,lli> >adj[2005];
vector< pair<lli,pair<lli,lli> > >vect;
lli siz[200005];
lli arr[2005][2005];
lli parent[200005];
lli vis[2005][2005];
lli dist[2005][2005];

void initialize()
{
    lli i;
    for(i=1;i<=2005;i++)
    {
        parent[i]=i,siz[i]=1;
    }
}

lli root(lli a)
{
    while(parent[a]!=a)
    {
        a=parent[parent[a]];
    }
    return a;
}

void make_union(lli a,lli b)
{
    lli root_a,root_b;
    root_a=root(a),root_b=root(b);

    if(root_a!=root_b)
    {
        if(siz[root_a]<siz[root_b])
        {
           parent[root_a]=root_b,siz[root_b]+=siz[root_a];
        }
        else
        {
           parent[root_b]=root_a,siz[root_a]+=siz[root_b];
        }
    }
}

void dfs(lli val,lli fixe)
{
    lli i;
    vis[fixe][val]=1;
    for(i=0;i<adj[val].size();i++)
    {
        if(vis[fixe][adj[val][i].first]==0)
        {
           dist[fixe][adj[val][i].first]=dist[fixe][val]+adj[val][i].second;
           dfs(adj[val][i].first,fixe);
        }
    }
}

int main()
{
    int start_s = clock();
    ios_base::sync_with_stdio(false);
    cin.tie(NULL); cout.tie(NULL);

    initialize();
    lli i,j,k,n,m,wei,root_a,root_b,flag=0;
    cin>>n;

    for(i=1;i<=n;i++)
    {
        for(j=1;j<=n;j++)
        {
           cin>>wei;
           if(i!=j&&wei==0)
            flag=1;
           vect.push_back({wei,{i,j}});
        }
    }

    if(flag==1)
    {
        cout<<"NO\n";
        return 0;
    }

    sort(vect.begin(),vect.end());

    for(k=0;k<vect.size();k++)
    {
           //wei=vect[k].first,i=vect[k].second.first,j=vect[k].second.second;

           arr[vect[k].second.first][vect[k].second.second]=vect[k].first,root_a=root(vect[k].second.first),root_b=root(vect[k].second.second);

           if(root_a!=root_b)
           {
              make_union(vect[k].second.first,vect[k].second.second);
              adj[vect[k].second.first].push_back({vect[k].second.second,vect[k].first});
              adj[vect[k].second.second].push_back({vect[k].second.first,vect[k].first});
           }
    }

    for(i=1;i<=n;i++)
        dfs(i,i);

    for(i=1;i<=n;i++)
    {
        for(j=1;j<=n;j++)
        {
            if(arr[i][j]!=dist[i][j])
            {
               cout<<"NO\n";
               return 0;
            }
        }
    }
        cout<<"YES\n";
}


#include "bits/stdc++.h"
#include<stdio.h>
#include <sstream>
#define pi 3.141592653589793238462
#define limit 100005
#define mo 1000000007;
typedef long long int lli;
typedef unsigned long long int ulli;
const lli mod=9999999999999983;
lli primes[6]={1125899906842597,1495921043,1005985879,1495921043,1005985879,1495921043};
using namespace std;
vector< pair<lli,lli> >adj[2005];
vector< pair<lli,pair<lli,lli> > >vect;
lli siz[200005];
lli arr[2005][2005];
lli parent[200005];
lli vis[2005][2005];
lli dist[2005][2005];

void initialize()
{
    lli i;
    for(i=1;i<=2005;i++)
    {
        parent[i]=i,siz[i]=1;
    }
}

lli root(lli a)
{
    while(parent[a]!=a)
    {
        a=parent[parent[a]];
    }
    return a;
}

void make_union(lli a,lli b)
{
    lli root_a,root_b;
    root_a=root(a),root_b=root(b);

    if(root_a!=root_b)
    {
        if(siz[root_a]<siz[root_b])
        {
           parent[root_a]=root_b,siz[root_b]+=siz[root_a];
        }
        else
        {
           parent[root_b]=root_a,siz[root_a]+=siz[root_b];
        }
    }
}

void dfs(lli val,lli fixe)
{
    lli i;
    vis[fixe][val]=1;
    for(i=0;i<adj[val].size();i++)
    {
        if(vis[fixe][adj[val][i].first]==0)
        {
           dist[fixe][adj[val][i].first]+=dist[fixe][val]+adj[val][i].second;
           dfs(adj[val][i].first,fixe);
        }
    }
}

int main()
{
    int start_s = clock();
    ios_base::sync_with_stdio(false);
    cin.tie(NULL); cout.tie(NULL);

    initialize();
    lli i,j,k,n,m,wei,root_a,root_b,flag=0;
    cin>>n;

    for(i=1;i<=n;i++)
    {
        for(j=1;j<=n;j++)
        {
           cin>>wei;
           if(i!=j&&wei==0)
            flag=1;
           vect.push_back({wei,{i,j}});
        }
    }

    if(flag==1)
    {
        cout<<"NO\n";
        return 0;
    }

    sort(vect.begin(),vect.end());

    for(k=0;k<vect.size();k++)
    {
           wei=vect[k].first,i=vect[k].second.first,j=vect[k].second.second;

           arr[i][j]=wei,root_a=root(i),root_b=root(j);

           if(root_a!=root_b)
           {
              make_union(i,j),adj[i].push_back({j,wei}),adj[j].push_back({i,wei});
           }
    }

    for(i=1;i<=n;i++)
        dfs(i,i);

    for(i=1;i<=n;i++)
    {
        for(j=1;j<=n;j++)
        {
            if(arr[i][j]!=dist[i][j])
            {
               cout<<"NO\n";
               return 0;
            }
        }
    }
        cout<<"YES\n";
}


#include "bits/stdc++.h"
#include<stdio.h>
#include <sstream>
#define pi 3.141592653589793238462
#define limit 100005
#define mo 1000000007;
typedef long long int lli;
typedef unsigned long long int ulli;
const lli mod=9999999999999983;
lli primes[6]={1125899906842597,1495921043,1005985879,1495921043,1005985879,1495921043};
using namespace std;
vector< pair<lli,lli> >adj[2005];
vector< pair<lli,pair<lli,lli> > >vect;
lli siz[200005];
lli arr[2005][2005];
lli parent[200005];
lli vis[2005][2005];
lli dist[2005][2005];
lli flag=0;

void initialize()
{
    lli i;
    for(i=1;i<=2005;i++)
    {
        parent[i]=i,siz[i]=1;
    }
}

lli root(lli a)
{
    while(parent[a]!=a)
    {
        a=parent[parent[a]];
    }
    return a;
}

void make_union(lli a,lli b)
{
    lli root_a,root_b;
    root_a=root(a),root_b=root(b);

    if(root_a!=root_b)
    {
        if(siz[root_a]<siz[root_b])
        {
           parent[root_a]=root_b,siz[root_b]+=siz[root_a];
        }
        else
        {
           parent[root_b]=root_a,siz[root_a]+=siz[root_b];
        }
    }
}

void dfs(lli val,lli fixe)
{
    lli i;
    vis[fixe][val]=1;
    for(i=0;i<adj[val].size();i++)
    {
        if(vis[fixe][adj[val][i].first]==0)
        {
           dist[fixe][adj[val][i].first]=dist[fixe][val]+adj[val][i].second;
          // cout<<"dist="<<dist[fixe][adj[val][i].first]<<"arr="<<arr[fixe][adj[val][i].first]<<endl;
           if(dist[fixe][adj[val][i].first]!=arr[fixe][adj[val][i].first])
            flag=1;
           dfs(adj[val][i].first,fixe);
        }
    }
}

int main()
{
    int start_s = clock();
    ios_base::sync_with_stdio(false);
    cin.tie(NULL); cout.tie(NULL);

    initialize();
    lli i,j,k,n,m,wei,root_a,root_b;
    cin>>n;

    for(i=1;i<=n;i++)
    {
        for(j=1;j<=n;j++)
        {
           cin>>wei;
           if((i!=j&&wei==0)||(i==j&&wei!=0))
            flag=1;
           vect.push_back({wei,{i,j}});
        }
    }

    if(flag==1)
    {
        cout<<"NO\n";
        return 0;
    }

    sort(vect.begin(),vect.end());

    for(k=0;k<vect.size();k++)
    {
           //wei=vect[k].first,i=vect[k].second.first,j=vect[k].second.second;

           arr[vect[k].second.first][vect[k].second.second]=vect[k].first,root_a=root(vect[k].second.first),root_b=root(vect[k].second.second);

           if(root_a!=root_b)
           {
              make_union(vect[k].second.first,vect[k].second.second);
              adj[vect[k].second.first].push_back({vect[k].second.second,vect[k].first});
              adj[vect[k].second.second].push_back({vect[k].second.first,vect[k].first});
           }
    }

    for(i=1;i<=n;i++)
    {
         dfs(i,i);
         if(flag==1)
         {
           cout<<"NO\n";
           return 0;
         }
    }

/*
    for(i=1;i<=n;i++)
    {
        for(j=1;j<=n;j++)
        {
            if(arr[i][j]!=dist[i][j])
            {
               cout<<"NO\n";
               return 0;
            }
        }
    }
    */
        cout<<"YES\n";
}


#include "bits/stdc++.h"
#include<stdio.h>
#include <sstream>
#define pi 3.141592653589793238462
#define limit 100005
#define mo 1000000007;
typedef long long int lli;
typedef unsigned long long int ulli;
const lli mod=9999999999999983;
lli primes[6]={1125899906842597,1495921043,1005985879,1495921043,1005985879,1495921043};
using namespace std;
vector< pair<lli,lli> >adj[2005];
vector< pair<lli,pair<lli,lli> > >vect;
lli siz[200005];
lli arr[2005][2005];
lli parent[200005];
lli vis[2005][2005];
lli dist[2005][2005];
lli flag=0;

void initialize()
{
    lli i;
    for(i=1;i<=2005;i++)
    {
        parent[i]=i,siz[i]=1;
    }
}

lli root(lli a)
{
    while(parent[a]!=a)
    {
        a=parent[parent[a]];
    }
    return a;
}

void make_union(lli a,lli b)
{
    lli root_a,root_b;
    root_a=root(a),root_b=root(b);

    if(root_a!=root_b)
    {
        if(siz[root_a]<siz[root_b])
        {
           parent[root_a]=root_b,siz[root_b]+=siz[root_a];
        }
        else
        {
           parent[root_b]=root_a,siz[root_a]+=siz[root_b];
        }
    }
}

void dfs(lli val,lli fixe)
{
    lli i;
    vis[fixe][val]=1;
    for(i=0;i<adj[val].size();i++)
    {
        if(vis[fixe][adj[val][i].first]==0)
        {
           dist[fixe][adj[val][i].first]=dist[fixe][val]+adj[val][i].second;
           if(dist[fixe][adj[val][i].first]!=arr[fixe][adj[val][i].first])
           {
            cout<<"NO";
            exit(0);
           }
           dfs(adj[val][i].first,fixe);
        }
    }
}

int main()
{
    int start_s = clock();
    ios_base::sync_with_stdio(false);
    cin.tie(NULL); cout.tie(NULL);

    initialize();
    lli i,j,k,n,m,wei,root_a,root_b;
    cin>>n;

    for(i=1;i<=n;i++)
    {
        for(j=1;j<=n;j++)
        {
           cin>>wei;
           arr[i][j]=wei;
           if((i!=j&&wei==0)||(i==j&&wei!=0))
           {
              cout<<"NO\n";
              return 0;
           }
           if(i<j)
           vect.push_back({wei,{i,j}});
        }
    }

    for(i=1;i<=n;i++)
    {
        for(j=1;j<=n;j++)
        {
            if(arr[i][j]!=arr[j][i])
            {
               cout<<"NO\n";
               return 0;
            }
        }
    }

    sort(vect.begin(),vect.end());

    for(k=0;k<vect.size();k++)
    {

           arr[vect[k].second.first][vect[k].second.second]=vect[k].first;
           root_a=root(vect[k].second.first);
           root_b=root(vect[k].second.second);

           if(root_a!=root_b)
           {
              make_union(vect[k].second.first,vect[k].second.second);
              adj[vect[k].second.first].push_back({vect[k].second.second,vect[k].first});
              adj[vect[k].second.second].push_back({vect[k].second.first,vect[k].first});
           }
    }

    for(i=1;i<=n;i++)
         dfs(i,i);

        cout<<"YES";
}


#include "bits/stdc++.h"
#include<stdio.h>
#include <sstream>
#define pi 3.141592653589793238462
#define limit 100005
#define mo 1000000007;
typedef long long int lli;
typedef unsigned long long int ulli;
const lli mod=9999999999999983;
lli primes[6]={1125899906842597,1495921043,1005985879,1495921043,1005985879,1495921043};
using namespace std;
vector< pair<lli,lli> >adj[2005];
vector< pair<lli,pair<lli,lli> > >vect;
lli siz[200005];
lli arr[2005][2005];
lli parent[200005];
lli vis[2005][2005];
lli dist[2005][2005];

void initialize()
{
    lli i;
    for(i=1;i<=2005;i++)
    {
        parent[i]=i,siz[i]=1;
    }
}

lli root(lli a)
{
    while(parent[a]!=a)
    {
        a=parent[parent[a]];
    }
    return a;
}

/*
void make_union(lli a,lli b)
{
    lli root_a,root_b;
    root_a=root(a),root_b=root(b);

    if(root_a!=root_b)
    {
        if(siz[root_a]<siz[root_b])
        {
           parent[root_a]=root_b,siz[root_b]+=siz[root_a];
        }
        else
        {
           parent[root_b]=root_a,siz[root_a]+=siz[root_b];
        }
    }
}
*/

void dfs(lli val,lli fixe)
{
    lli i;
    vis[fixe][val]=1;
    for(i=0;i<adj[val].size();i++)
    {
        if(vis[fixe][adj[val][i].first]==0)
        {
           dist[fixe][adj[val][i].first]+=dist[fixe][val]+adj[val][i].second;
           dfs(adj[val][i].first,fixe);
        }
    }
}

int main()
{
    int start_s = clock();
    ios_base::sync_with_stdio(false);
    cin.tie(NULL); cout.tie(NULL);

    initialize();
    lli i,j,k,n,m,wei,root_a,root_b,flag=0;
    cin>>n;

    for(i=1;i<=n;i++)
    {
        for(j=1;j<=n;j++)
        {
           cin>>wei;
           if(i!=j&&wei==0)
            flag=1;
           vect.push_back({wei,{i,j}});
        }
    }

    if(flag==1)
    {
        cout<<"NO\n";
        return 0;
    }

    sort(vect.begin(),vect.end());

    for(k=0;k<vect.size();k++)
    {
           wei=vect[k].first,i=vect[k].second.first,j=vect[k].second.second;

           arr[i][j]=wei,root_a=root(i),root_b=root(j);

           if(root_a!=root_b)
           {
             // make_union(i,j);
              parent[root_b]=root_a;
              adj[i].push_back({j,wei}),adj[j].push_back({i,wei});
           }
    }

    for(i=1;i<=n;i++)
        dfs(i,i);

    for(i=1;i<=n;i++)
    {
        for(j=1;j<=n;j++)
        {
            if(arr[i][j]!=dist[i][j])
            {
               cout<<"NO\n";
               return 0;
            }
        }
    }
        cout<<"YES\n";
}


#include "bits/stdc++.h"
#include<stdio.h>
#include <sstream>
#define pi 3.141592653589793238462
#define limit 100005
#define mo 1000000007;
typedef long long int lli;
typedef unsigned long long int ulli;
const lli mod=9999999999999983;
lli primes[6]={1125899906842597,1495921043,1005985879,1495921043,1005985879,1495921043};
using namespace std;
vector< pair<lli,lli> >adj[2005];
vector< pair<lli,pair<lli,lli> > >vect;
lli siz[200005];
lli arr[2005][2005];
lli parent[200005];
lli vis[200005];
lli dist[2005][2005];

void initialize()
{
    lli i;
    for(i=1;i<=2005;i++)
    {
        parent[i]=i;
        siz[i]=1;
    }
}

lli root(lli a)
{
    while(parent[a]!=a)
    {
        a=parent[parent[a]];
    }
    return a;
}

void make_union(lli a,lli b)
{
    lli root_a,root_b;
    root_a=root(a);
    root_b=root(b);

    if(root_a!=root_b)
    {
        if(siz[root_a]<siz[root_b])
        {
           parent[root_a]=root_b;
           siz[root_b]+=siz[root_a];
        }
        else
        {
           parent[root_b]=root_a;
           siz[root_a]+=siz[root_b];
        }
    }
}

void dfs(lli val,lli fixe)
{
    lli i;
    vis[val]=1;
    for(i=0;i<adj[val].size();i++)
    {
        if(vis[adj[val][i].first]==0)
        {
           dist[fixe][adj[val][i].first]+=dist[fixe][val]+adj[val][i].second;
           dfs(adj[val][i].first,fixe);
        }
    }
}

int main()
{
    int start_s = clock();
    ios_base::sync_with_stdio(false);
    cin.tie(NULL); cout.tie(NULL);

    initialize();
    lli i,j,k,n,m,wei,root_a,root_b,flag=0;
    cin>>n;

    for(i=1;i<=n;i++)
    {
        for(j=1;j<=n;j++)
        {
           cin>>wei;
           if(i!=j&&wei==0)
            flag=1;
           vect.push_back({wei,{i,j}});
        }
    }

    if(flag==1)
    {
        cout<<"NO\n";
        return 0;
    }

    sort(vect.begin(),vect.end());

    for(k=0;k<vect.size();k++)
    {
           wei=vect[k].first;
           i=vect[k].second.first;
           j=vect[k].second.second;

           arr[i][j]=wei;
           root_a=root(i);
           root_b=root(j);
           if(root_a!=root_b)
           {
              make_union(i,j);
              adj[i].push_back({j,wei});
              adj[j].push_back({i,wei});
           }
    }

    for(i=1;i<=n;i++)
    {
       // lli vis[2005]={0};
        dfs(i,i);
        memset(vis,0,sizeof(vis));
    }

    for(i=1;i<=n;i++)
    {
        for(j=1;j<=n;j++)
        {
            if(arr[i][j]!=dist[i][j])
            {
               cout<<"NO\n";
               return 0;
            }
        }
    }
        cout<<"YES\n";
}


#include "bits/stdc++.h"
#include<stdio.h>
#include <sstream>
#define pi 3.141592653589793238462
#define limit 100005
#define mo 1000000007;
typedef long long int lli;
typedef unsigned long long int ulli;
const lli mod=9999999999999983;
lli primes[6]={1125899906842597,1495921043,1005985879,1495921043,1005985879,1495921043};
using namespace std;
vector< pair<lli,lli> >adj[2005];
vector< pair<lli,pair<lli,lli> > >vect;
lli siz[200005];
lli arr[2005][2005];
lli parent[200005];
lli vis[2005][2005];
lli dist[2005][2005];

void initialize()
{
    lli i;
    for(i=1;i<=2005;i++)
    {
        parent[i]=i,siz[i]=1;
    }
}

lli root(lli a)
{
    while(parent[a]!=a)
    {
        a=parent[parent[a]];
    }
    return a;
}

void make_union(lli a,lli b)
{
    lli root_a,root_b;
    root_a=root(a),root_b=root(b);

    if(root_a!=root_b)
    {
        if(siz[root_a]<siz[root_b])
        {
           parent[root_a]=root_b,siz[root_b]+=siz[root_a];
        }
        else
        {
           parent[root_b]=root_a,siz[root_a]+=siz[root_b];
        }
    }
}

void dfs(lli val,lli fixe)
{
    lli i;
    vis[fixe][val]=1;
    for(i=0;i<adj[val].size();i++)
    {
        if(vis[fixe][adj[val][i].first]==0)
        {
           dist[fixe][adj[val][i].first]+=dist[fixe][val]+adj[val][i].second;
           dfs(adj[val][i].first,fixe);
        }
    }
}

int main()
{
    int start_s = clock();
    ios_base::sync_with_stdio(false);
    cin.tie(NULL); cout.tie(NULL);

    initialize();
    lli i,j,k,n,m,wei,root_a,root_b,flag=0;
    cin>>n;

    for(i=1;i<=n;i++)
    {
        for(j=1;j<=n;j++)
        {
           cin>>wei;
           if(i!=j&&wei==0)
            flag=1;
           vect.push_back({wei,{i,j}});
        }
    }

    if(flag==1)
    {
        cout<<"NO\n";
        return 0;
    }

    sort(vect.begin(),vect.end());

    for(k=0;k<vect.size();k++)
    {
           //wei=vect[k].first,i=vect[k].second.first,j=vect[k].second.second;

           arr[i][j]=vect[k].first,root_a=root(vect[k].second.first),root_b=root(vect[k].second.second);

           if(root_a!=root_b)
           {
              make_union(vect[k].second.first,vect[k].second.second);
              adj[vect[k].second.first].push_back({vect[k].second.second,vect[k].first});
              adj[vect[k].second.second].push_back({vect[k].second.first,vect[k].first});
           }
    }

    for(i=1;i<=n;i++)
        dfs(i,i);

    for(i=1;i<=n;i++)
    {
        for(j=1;j<=n;j++)
        {
            if(arr[i][j]!=dist[i][j])
            {
               cout<<"NO\n";
               return 0;
            }
        }
    }
        cout<<"YES\n";
}


#include "bits/stdc++.h"
#include<stdio.h>
#include <sstream>
#define pi 3.141592653589793238462
#define limit 100005
#define mo 1000000007;
typedef long long int lli;
typedef unsigned long long int ulli;
const lli mod=9999999999999983;
lli primes[6]={1125899906842597,1495921043,1005985879,1495921043,1005985879,1495921043};
using namespace std;
vector< pair<lli,lli> >adj[2005];
vector< pair<lli,pair<lli,lli> > >vect;
lli siz[200005];
lli arr[2005][2005];
lli parent[200005];
lli vis[2005][2005];
lli dist[2005][2005];

void initialize()
{
    lli i;
    for(i=1;i<=2005;i++)
    {
        parent[i]=i;
        siz[i]=1;
    }
}

lli root(lli a)
{
    while(parent[a]!=a)
    {
        a=parent[parent[a]];
    }
    return a;
}

void make_union(lli a,lli b)
{
    lli root_a,root_b;
    root_a=root(a);
    root_b=root(b);

    if(root_a!=root_b)
    {
        if(siz[root_a]<siz[root_b])
        {
           parent[root_a]=root_b;
           siz[root_b]+=siz[root_a];
        }
        else
        {
           parent[root_b]=root_a;
           siz[root_a]+=siz[root_b];
        }
    }
}

void dfs(lli val,lli fixe)
{
    lli i;
    vis[fixe][val]=1;
    for(i=0;i<adj[val].size();i++)
    {
        if(vis[fixe][adj[val][i].first]==0)
        {
           dist[fixe][adj[val][i].first]+=dist[fixe][val]+adj[val][i].second;
           dfs(adj[val][i].first,fixe);
        }
    }
}

int main()
{
    int start_s = clock();
    ios_base::sync_with_stdio(false);
    cin.tie(NULL); cout.tie(NULL);

    initialize();
    lli i,j,k,n,m,wei,root_a,root_b,flag=0;
    cin>>n;

    for(i=1;i<=n;i++)
    {
        for(j=1;j<=n;j++)
        {
           cin>>wei;
           if(i!=j&&wei==0)
            flag=1;
           vect.push_back({wei,{i,j}});
        }
    }

    if(flag==1)
    {
        cout<<"NO\n";
        return 0;
    }

    sort(vect.begin(),vect.end());

    for(k=0;k<vect.size();k++)
    {
           wei=vect[k].first;
           i=vect[k].second.first;
           j=vect[k].second.second;

           arr[i][j]=wei;
           root_a=root(i);
           root_b=root(j);
           if(root_a!=root_b)
           {
              make_union(i,j);
              adj[i].push_back({j,wei});
              adj[j].push_back({i,wei});
           }
    }

    for(i=1;i<=n;i++)
    {
       // lli vis[2005]={0};
        dfs(i,i);
        //memset(vis,0,sizeof(vis));
    }

    for(i=1;i<=n;i++)
    {
        for(j=1;j<=n;j++)
        {
            if(arr[i][j]!=dist[i][j])
            {
               cout<<"NO\n";
               return 0;
            }
        }
    }
        cout<<"YES\n";
}


#include "bits/stdc++.h"
#include<stdio.h>
#include <sstream>
#define pi 3.141592653589793238462
#define limit 100005
#define mo 1000000007;
typedef long long int lli;
typedef unsigned long long int ulli;
const lli mod=9999999999999983;
lli primes[6]={1125899906842597,1495921043,1005985879,1495921043,1005985879,1495921043};
using namespace std;
vector< pair<lli,lli> >adj[2005];
vector< pair<lli,pair<lli,lli> > >vect;
lli siz[200005];
lli arr[2005][2005];
lli parent[200005];
lli vis[2005][2005];
lli dist[2005][2005];

void initialize()
{
    lli i;
    for(i=1;i<=2005;i++)
    {
        parent[i]=i,siz[i]=1;
    }
}

lli root(lli a)
{
    while(parent[a]!=a)
    {
        a=parent[parent[a]];
    }
    return a;
}

void make_union(lli a,lli b)
{
    lli root_a,root_b;
    root_a=root(a),root_b=root(b);

    if(root_a!=root_b)
    {
        if(siz[root_a]<siz[root_b])
        {
           parent[root_a]=root_b,siz[root_b]+=siz[root_a];
        }
        else
        {
           parent[root_b]=root_a,siz[root_a]+=siz[root_b];
        }
    }
}

void dfs(lli val,lli fixe)
{
    lli i;
    vis[fixe][val]=1;
    for(i=0;i<adj[val].size();i++)
    {
        if(vis[fixe][adj[val][i].first]==0)
        {
           dist[fixe][adj[val][i].first]+=dist[fixe][val]+adj[val][i].second;
           dfs(adj[val][i].first,fixe);
        }
    }
}

int main()
{
    int start_s = clock();
    ios_base::sync_with_stdio(false);
    cin.tie(NULL); cout.tie(NULL);

    initialize();
    lli i,j,k,n,m,wei,root_a,root_b,flag=0;
    cin>>n;

    for(i=1;i<=n;i++)
    {
        for(j=1;j<=n;j++)
        {
           cin>>wei;
           if(i!=j&&wei==0)
            flag=1;
           vect.push_back({wei,{i,j}});
        }
    }

    if(flag==1)
    {
        cout<<"NO\n";
        return 0;
    }

    sort(vect.begin(),vect.end());

    for(k=0;k<vect.size();k++)
    {
           //wei=vect[k].first,i=vect[k].second.first,j=vect[k].second.second;

           arr[vect[k].second.first][vect[k].second.second]=vect[k].first,root_a=root(vect[k].second.first),root_b=root(vect[k].second.second);

           if(root_a!=root_b)
           {
              make_union(vect[k].second.first,vect[k].second.second);
              adj[vect[k].second.first].push_back({vect[k].second.second,vect[k].first});
              adj[vect[k].second.second].push_back({vect[k].second.first,vect[k].first});
           }
    }

    for(i=1;i<=n;i++)
        dfs(i,i);

    for(i=1;i<=n;i++)
    {
        for(j=1;j<=n;j++)
        {
            if(arr[i][j]!=dist[i][j])
            {
               cout<<"NO\n";
               return 0;
            }
        }
    }
        cout<<"YES\n";
}


// https://codeforces.com/problemset/problem/472/D
#include <bits/stdc++.h>
using namespace std;
typedef long long int ll;
typedef pair<int, int> ii;
typedef vector<int> vi;
typedef vector<string> vs;
typedef vector<bool> vb;
typedef vector<ii> vii;
#define pb push_back
#define mp make_pair
#define fi first
#define se second
class DSU
{
private:
	vi par, rank;
	int n;
public:
	DSU(int a)
	{
		n = a;
		par.assign(n, 0);
		rank.assign(n, 0);
		for(int i = 1; i < n; i++) par[i] = i;
	}
	int find_set(int i) { return (par[i] == i) ? i : par[i] = find_set(par[i]); }
	bool is_same(int i, int j) { return find_set(i) == find_set(j); }
	void Union(int i, int j)
	{
		int x = par[i], y = par[j];
		if(rank[x] > rank[y]) par[y] = par[x];
		else
		{
			par[x] = par[y];
			if(rank[x] == rank[y]) rank[y]++;
		}
	}
};
class LCA
{
private:
	vector<vii > v;
	vector<vi > dp;
	vector<vi> dist;
	vi tin, tout;
	int n, m, tim;
public:
	LCA(int a) { n = a; v.assign(n, vii(0, mp(0, 0)));}
	void add_edge(int a, int b, int c) { v[a].pb(mp(b, c)); v[b].pb(mp(a, c)); }
	void dfs(int idx, int par, int w)
	{
		tin[idx] = tim++;
		dp[idx][0] = par;
		dist[idx][0] = w;
		for(int i = 1; i <= m; i++) dp[idx][i] = dp[dp[idx][i - 1]][i - 1];
		for(int i = 1; i <= m; i++) dist[idx][i] = dist[idx][i - 1] + dist[dp[idx][i - 1]][i - 1];
		for(int i = 0; i < v[idx].size(); i++)
		{
			ii nxt = v[idx][i];
			if(nxt.fi == par) continue;
			dfs(nxt.fi, idx, nxt.se);
		}
		tout[idx] = tim++;
	}
	bool is_ancestor(int u, int v) { return tin[u] <= tin[v] && tout[v] <= tout[u]; }
	ll lca(int u, int v)
	{
		ll ans = 0;
		if(u == v) return 0;
		if(is_ancestor(u, v))
		{
			swap(u, v);
			for(int i = m; i >= 0; i--)
			{
				if(!is_ancestor(dp[u][i], v))
				{
					ans+=dist[u][i];
					u = dp[u][i];
				}
			}
			ans+=(ll)dist[u][0];
			return ans;
		}
		if(is_ancestor(v, u))
		{
			for(int i = m; i >= 0; i--)
			{
				if(!is_ancestor(dp[u][i], i))
				{
					ans+=dist[u][i];
					u = dp[u][i];
				}
			}
			ans+=(ll)dist[u][0];
			return ans;
		}
		for(int i = m; i >= 0; i--)
		{
			if(!is_ancestor(dp[u][i], v))
			{
				ans+=dist[u][i];
				u = dp[u][i];
			}
		}
		ans+=(ll)dist[u][0];
		swap(u, v);
		for(int i = m; i >= 0; i--)
		{
			if(!is_ancestor(dp[u][i], v))
			{
				ans+=dist[u][i];
				u = dp[u][i];
			}
		}
		ans+=(ll)dist[u][0];
		return ans;
	}
	void print()
	{
		for(int i = 1; i < n; i++)
		{
			cout << i << " -> ";
			for(int j = 0; j < v[i].size(); j++) cout << "( " << v[i][j].fi << ", " << v[i][j].se << ") ";
			cout << endl;
		}
	}
	void build()
	{
		m = ceil(log2(n));
		dp.assign(n, vi(m + 1, 0));
		dist.assign(n, vi(m + 1, 0));
		tin.assign(n, 0);
		tout.assign(n, 0);
		tim = 0;
		dfs(1, 1, 0);
	}
};
int main()
{
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);
	cout.tie(NULL);
	int n, val, a, b, c;
	cin >> n;
	vector<vi > adj(n + 1, vi(n + 1, 0));
	for(int i = 1; i <= n; i++)
	{
		for(int j = 1; j <= n; j++) cin >> adj[i][j];
	}
	bool flag = true;
	vector<pair<int, ii> > edg;
	for(int i = 1; i <= n; i++)
	{
		for(int j = 1; j <= n; j++)
		{
			if(adj[i][j] != adj[j][i]) flag = false;
			if(i != j && adj[i][j] == 0) flag = false;
			edg.pb(mp(adj[i][j], mp(i, j)));
		}
	}
	if(!flag) { cout << "NO \n"; return 0; }
	DSU u(n + 1);
	LCA g(n + 1);
	sort(edg.begin(), edg.end());
	for(int i = 0; i < edg.size(); i++)
	{
		a = edg[i].se.fi, b = edg[i].se.se, c = edg[i].fi;
		if(u.is_same(a, b)) continue;
		u.Union(a, b);
		g.add_edge(a, b, c);
	}
	g.build();
	// g.print();
	for(int i = 1; i <= n; i++)
	{
		for(int j = 1; j <= n; j++) if(g.lca(i, j) != (ll)adj[i][j]) flag = false;
	}
	if(!flag) cout << "NO\n";
	else cout << "YES\n";
}


// https://codeforces.com/problemset/problem/472/D
#include <bits/stdc++.h>
using namespace std;
typedef long long int ll;
typedef pair<ll, ll> ii;
typedef vector<ll> vi;
typedef vector<string> vs;
typedef vector<bool> vb;
typedef vector<ii> vii;
#define pb push_back
#define mp make_pair
#define fi first
#define se second
class DSU
{
private:
	vi par, rank;
	ll n;
public:
	DSU(ll a)
	{
		n = a;
		par.assign(n, 0);
		rank.assign(n, 0);
		for(ll i = 1; i < n; i++) par[i] = i;
	}
	ll find_set(ll i) { return (par[i] == i) ? i : par[i] = find_set(par[i]); }
	bool is_same(ll i, ll j) { return find_set(i) == find_set(j); }
	void Union(ll i, ll j)
	{
		ll x = par[i], y = par[j];
		if(rank[x] > rank[y]) par[y] = par[x];
		else
		{
			par[x] = par[y];
			if(rank[x] == rank[y]) rank[y]++;
		}
	}
};
class LCA
{
private:
	vector<vii > v;
	vector<vi > dp;
	vector<vi> dist;
	vi tin, tout;
	ll n, m, tim;
public:
	LCA(ll a) { n = a; v.assign(n, vii(0, mp(0, 0)));}
	void add_edge(ll a, ll b, ll c) { v[a].pb(mp(b, c)); v[b].pb(mp(a, c)); }
	void dfs(ll idx, ll par, ll w)
	{
		tin[idx] = tim++;
		dp[idx][0] = par;
		dist[idx][0] = w;
		for(ll i = 1; i <= m; i++) dp[idx][i] = dp[dp[idx][i - 1]][i - 1];
		for(ll i = 1; i <= m; i++) dist[idx][i] = dist[idx][i - 1] + dist[dp[idx][i - 1]][i - 1];
		for(ll i = 0; i < v[idx].size(); i++)
		{
			ii nxt = v[idx][i];
			if(nxt.fi == par) continue;
			dfs(nxt.fi, idx, nxt.se);
		}
		tout[idx] = tim++;
	}
	bool is_ancestor(ll u, ll v) { return tin[u] <= tin[v] && tout[v] <= tout[u]; }
	ll lca(ll u, ll v)
	{
		ll ans = (ll)0;
		if(u == v) return ans;
		if(is_ancestor(u, v))
		{
			swap(u, v);
			for(ll i = m; i >= 0; i--)
			{
				if(!is_ancestor(dp[u][i], v))
				{
					ans+=dist[u][i];
					u = dp[u][i];
				}
			}
			ans+=dist[u][0];
			return ans;
		}
		if(is_ancestor(v, u))
		{
			for(ll i = m; i >= 0; i--)
			{
				if(!is_ancestor(dp[u][i], i))
				{
					ans+=dist[u][i];
					u = dp[u][i];
				}
			}
			ans+=dist[u][0];
			return ans;
		}
		for(ll i = m; i >= 0; i--)
		{
			if(!is_ancestor(dp[u][i], v))
			{
				ans+=dist[u][i];
				u = dp[u][i];
			}
		}
		ans+=dist[u][0];
		swap(u, v);
		for(ll i = m; i >= 0; i--)
		{
			if(!is_ancestor(dp[u][i], v))
			{
				ans+=dist[u][i];
				u = dp[u][i];
			}
		}
		ans+=dist[u][0];
		return ans;
	}
	void build()
	{
		m = ceil(log2(n));
		dp.assign(n, vi(m + 1, 0));
		dist.assign(n, vi(m + 1, 0));
		tin.assign(n, 0);
		tout.assign(n, 0);
		tim = 0;
		dfs(1, 1, 0);
	}
};
int main()
{
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);
	cout.tie(NULL);
	ll n, val, a, b, c;
	cin >> n;
	vector<vi > adj(n + 1, vi(n + 1, 0));
	for(ll i = 1; i <= n; i++)
	{
		for(ll j = 1; j <= n; j++) cin >> adj[i][j];
	}
	bool flag = true;
	vector<pair<ll, ii> > edg;
	for(ll i = 1; i <= n && flag; i++)
	{
		for(ll j = 1; j <= n && flag; j++)
		{
			if(adj[i][j] != adj[j][i]) flag = false;
			if(i != j && adj[i][j] == (ll)0) flag = false;
			if(i == j && adj[i][j] != 0) flag = false;
			edg.pb(mp(adj[i][j], mp(i, j)));
		}
	}
	if(!flag) { cout << "NO \n"; return 0; }
	DSU u(n + 1);
	LCA g(n + 1);
	sort(edg.begin(), edg.end());
	for(ll i = 0; i < edg.size(); i++)
	{
		a = edg[i].se.fi, b = edg[i].se.se, c = edg[i].fi;
		if(u.is_same(a, b)) continue;
		u.Union(a, b);
		g.add_edge(a, b, c);
	}
	g.build();
	for(ll i = 1; i <= n && flag; i++)
	{
		for(ll j = i; j <= n && flag; j++) if(g.lca(i, j) != adj[i][j]) flag = false;
	}
	if(!flag) cout << "NO\n";
	else cout << "YES\n";
}


// https://codeforces.com/problemset/problem/472/D
#include <bits/stdc++.h>
using namespace std;
typedef long long int ll;
typedef pair<ll, ll> ii;
typedef vector<ll> vi;
typedef vector<string> vs;
typedef vector<bool> vb;
typedef vector<ii> vii;
#define pb push_back
#define mp make_pair
#define fi first
#define se second
class DSU
{
private:
	vi par, rank;
	ll n;
public:
	DSU(ll a)
	{
		n = a;
		par.assign(n, 0);
		rank.assign(n, 0);
		for(ll i = 1; i < n; i++) par[i] = i;
	}
	ll find_set(ll i) { return (par[i] == i) ? i : par[i] = find_set(par[i]); }
	bool is_same(ll i, ll j) { return find_set(i) == find_set(j); }
	void Union(ll i, ll j)
	{
		ll x = par[i], y = par[j];
		if(rank[x] > rank[y]) par[y] = par[x];
		else
		{
			par[x] = par[y];
			if(rank[x] == rank[y]) rank[y]++;
		}
	}
};
class LCA
{
private:
	vector<vii > v;
	vector<vi > dp;
	vector<vi> dist;
	vi tin, tout;
	ll n, m, tim;
public:
	LCA(ll a) { n = a; v.assign(n, vii(0, mp(0, 0)));}
	void add_edge(ll a, ll b, ll c) { v[a].pb(mp(b, c)); v[b].pb(mp(a, c)); }
	void dfs(ll idx, ll par, ll w)
	{
		tin[idx] = tim++;
		dp[idx][0] = par;
		dist[idx][0] = w;
		for(ll i = 1; i <= m; i++) dp[idx][i] = dp[dp[idx][i - 1]][i - 1];
		for(ll i = 1; i <= m; i++) dist[idx][i] = dist[idx][i - 1] + dist[dp[idx][i - 1]][i - 1];
		for(ll i = 0; i < v[idx].size(); i++)
		{
			ii nxt = v[idx][i];
			if(nxt.fi == par) continue;
			dfs(nxt.fi, idx, nxt.se);
		}
		tout[idx] = tim++;
	}
	bool is_ancestor(ll u, ll v) { return tin[u] <= tin[v] && tout[v] <= tout[u]; }
	ll lca(ll u, ll v)
	{
		ll ans = (ll)0;
		if(u == v) return ans;
		if(is_ancestor(u, v))
		{
			swap(u, v);
			for(ll i = m; i >= 0; i--)
			{
				if(!is_ancestor(dp[u][i], v))
				{
					ans+=dist[u][i];
					u = dp[u][i];
				}
			}
			ans+=dist[u][0];
			return ans;
		}
		if(is_ancestor(v, u))
		{
			for(ll i = m; i >= 0; i--)
			{
				if(!is_ancestor(dp[u][i], i))
				{
					ans+=dist[u][i];
					u = dp[u][i];
				}
			}
			ans+=dist[u][0];
			return ans;
		}
		for(ll i = m; i >= 0; i--)
		{
			if(!is_ancestor(dp[u][i], v))
			{
				ans+=dist[u][i];
				u = dp[u][i];
			}
		}
		ans+=dist[u][0];
		swap(u, v);
		for(ll i = m; i >= 0; i--)
		{
			if(!is_ancestor(dp[u][i], v))
			{
				ans+=dist[u][i];
				u = dp[u][i];
			}
		}
		ans+=dist[u][0];
		return ans;
	}
	void build()
	{
		m = ceil(log2(n));
		dp.assign(n, vi(m + 1, 0));
		dist.assign(n, vi(m + 1, 0));
		tin.assign(n, 0);
		tout.assign(n, 0);
		tim = 0;
		dfs(1, 1, 0);
	}
};
int main()
{
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);
	cout.tie(NULL);
	ll n, val, a, b, c;
	cin >> n;
	vector<vi > adj(n + 1, vi(n + 1, 0));
	for(ll i = 1; i <= n; i++)
	{
		for(ll j = 1; j <= n; j++) cin >> adj[i][j];
	}
	bool flag = true;
	vector<pair<ll, ii> > edg;
	for(ll i = 1; i <= n && flag; i++)
	{
		for(ll j = i; j <= n && flag; j++)
		{
			if(i == j && adj[i][j] != 0) flag = false;
			if(adj[i][j] != adj[j][i]) flag = false;
			if(i != j && adj[i][j] == (ll)0) flag = false;
			edg.pb(mp(adj[i][j], mp(i, j)));
		}
	}
	if(!flag) { cout << "NO \n"; return 0; }
	DSU u(n + 1);
	LCA g(n + 1);
	sort(edg.begin(), edg.end());
	for(ll i = 0; i < (ll)edg.size(); i++)
	{
		a = edg[i].se.fi, b = edg[i].se.se, c = edg[i].fi;
		if(u.is_same(a, b)) continue;
		u.Union(a, b);
		g.add_edge(a, b, c);
	}
	g.build();
	for(ll i = 1; i <= n && flag; i++)
	{
		for(ll j = i; j <= n && flag; j++) if(g.lca(i, j) != adj[i][j]) flag = false;
	}
	if(!flag) cout << "NO\n";
	else cout << "YES\n";
}


// https://codeforces.com/problemset/problem/472/D
#include <bits/stdc++.h>
using namespace std;
typedef long long int ll;
typedef pair<ll, ll> ii;
typedef vector<ll> vi;
typedef vector<string> vs;
typedef vector<bool> vb;
typedef vector<ii> vii;
#define pb push_back
#define mp make_pair
#define fi first
#define se second
bool comp(pair<int, ii> a, pair<int, ii> b){ return a.fi < b.fi; }
class DSU
{
private:
	vi par, rank;
	ll n;
public:
	DSU(ll a)
	{
		n = a;
		par.assign(n, 0);
		rank.assign(n, 0);
		for(ll i = 1; i < n; i++) par[i] = i;
	}
	ll find_set(ll i) { return (par[i] == i) ? i : par[i] = find_set(par[i]); }
	bool is_same(ll i, ll j) { return find_set(i) == find_set(j); }
	void Union(ll i, ll j)
	{
		ll x = par[i], y = par[j];
		if(rank[x] > rank[y]) par[y] = par[x];
		else
		{
			par[x] = par[y];
			if(rank[x] == rank[y]) rank[y]++;
		}
	}
};
class LCA
{
private:
	vector<vii > v;
	vector<vi > dp;
	vector<vi> dist;
	vi tin, tout;
	ll n, m, tim;
public:
	LCA(ll a) { n = a; v.assign(n, vii(0, mp(0, 0)));}
	void add_edge(ll a, ll b, ll c) { v[a].pb(mp(b, c)); v[b].pb(mp(a, c)); }
	void dfs(ll idx, ll par, ll w)
	{
		tin[idx] = tim++;
		dp[idx][0] = par;
		dist[idx][0] = w;
		for(ll i = 1; i <= m; i++) dp[idx][i] = dp[dp[idx][i - 1]][i - 1];
		for(ll i = 1; i <= m; i++) dist[idx][i] = dist[idx][i - 1] + dist[dp[idx][i - 1]][i - 1];
		for(ll i = 0; i < v[idx].size(); i++)
		{
			ii nxt = v[idx][i];
			if(nxt.fi == par) continue;
			dfs(nxt.fi, idx, nxt.se);
		}
		tout[idx] = tim++;
	}
	bool is_ancestor(ll u, ll v) { return tin[u] <= tin[v] && tout[v] <= tout[u]; }
	ll lca(ll u, ll v)
	{
		ll ans = (ll)0;
		if(u == v) return ans;
		if(is_ancestor(u, v))
		{
			swap(u, v);
			for(ll i = m; i >= 0; i--)
			{
				if(!is_ancestor(dp[u][i], v))
				{
					ans+=dist[u][i];
					u = dp[u][i];
				}
			}
			ans+=dist[u][0];
			return ans;
		}
		if(is_ancestor(v, u))
		{
			for(ll i = m; i >= 0; i--)
			{
				if(!is_ancestor(dp[u][i], v))
				{
					ans+=dist[u][i];
					u = dp[u][i];
				}
			}
			ans+=dist[u][0];
			return ans;
		}
		for(ll i = m; i >= 0; i--)
		{
			if(!is_ancestor(dp[u][i], v))
			{
				ans+=dist[u][i];
				u = dp[u][i];
			}
		}
		ans+=dist[u][0];
		swap(u, v);
		for(ll i = m; i >= 0; i--)
		{
			if(!is_ancestor(dp[u][i], v))
			{
				ans+=dist[u][i];
				u = dp[u][i];
			}
		}
		ans+=dist[u][0];
		return ans;
	}
	void build()
	{
		m = ceil(log2(n));
		dp.assign(n, vi(m + 1, 0));
		dist.assign(n, vi(m + 1, 0));
		tin.assign(n, 0);
		tout.assign(n, 0);
		tim = 0;
		dfs(1, 1, 0);
	}
};
int main()
{
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);
	cout.tie(NULL);
	ll n, val, a, b, c;
	cin >> n;
	vector<vi > adj(n + 1, vi(n + 1, 0));
	for(ll i = 1; i <= n; i++)
	{
		for(ll j = 1; j <= n; j++) cin >> adj[i][j];
	}
	bool flag = true;
	vector<pair<ll, ii> > edg;
	for(ll i = 1; i <= n && flag; i++)
	{
		for(ll j = i; j <= n && flag; j++)
		{
			if(i == j && adj[i][j] != 0) flag = false;
			if(adj[i][j] != adj[j][i]) flag = false;
			if(i != j && adj[i][j] == (ll)0) flag = false;
			edg.pb(mp(adj[i][j], mp(i, j)));
		}
	}
	if(!flag) { cout << "NO \n"; return 0; }
	DSU u(n + 1);
	LCA g(n + 1);
	sort(edg.begin(), edg.end(), comp);
	for(ll i = 0; i < (ll)edg.size(); i++)
	{
		a = edg[i].se.fi, b = edg[i].se.se, c = edg[i].fi;
		if(u.is_same(a, b)) continue;
		u.Union(a, b);
		g.add_edge(a, b, c);
	}
	g.build();
	for(ll i = 1; i <= n && flag; i++)
	{
		for(ll j = i; j <= n && flag; j++) if(g.lca(i, j) != adj[i][j]) flag = false;
	}
	if(!flag) cout << "NO\n";
	else cout << "YES\n";
}


// https://codeforces.com/problemset/problem/472/D
#include <bits/stdc++.h>
using namespace std;
typedef long long int ll;
typedef pair<ll, ll> ii;
typedef vector<ll> vi;
typedef vector<string> vs;
typedef vector<bool> vb;
typedef vector<ii> vii;
#define pb push_back
#define mp make_pair
#define fi first
#define se second
class DSU
{
private:
	vi par, rank;
	ll n;
public:
	DSU(ll a)
	{
		n = a;
		par.assign(n, 0);
		rank.assign(n, 0);
		for(ll i = 1; i < n; i++) par[i] = i;
	}
	ll find_set(ll i) { return (par[i] == i) ? i : par[i] = find_set(par[i]); }
	bool is_same(ll i, ll j) { return find_set(i) == find_set(j); }
	void Union(ll i, ll j)
	{
		ll x = par[i], y = par[j];
		if(rank[x] > rank[y]) par[y] = par[x];
		else
		{
			par[x] = par[y];
			if(rank[x] == rank[y]) rank[y]++;
		}
	}
};
class LCA
{
private:
	vector<vii > v;
	vector<vi > dp;
	vector<vi> dist;
	vi tin, tout;
	ll n, m, tim;
public:
	LCA(ll a) { n = a; v.assign(n, vii(0, mp(0, 0)));}
	void add_edge(ll a, ll b, ll c) { v[a].pb(mp(b, c)); v[b].pb(mp(a, c)); }
	void dfs(ll idx, ll par, ll w)
	{
		tin[idx] = tim++;
		dp[idx][0] = par;
		dist[idx][0] = w;
		for(ll i = 1; i <= m; i++) dp[idx][i] = dp[dp[idx][i - 1]][i - 1];
		for(ll i = 1; i <= m; i++) dist[idx][i] = dist[idx][i - 1] + dist[dp[idx][i - 1]][i - 1];
		for(ll i = 0; i < v[idx].size(); i++)
		{
			ii nxt = v[idx][i];
			if(nxt.fi == par) continue;
			dfs(nxt.fi, idx, nxt.se);
		}
		tout[idx] = tim++;
	}
	bool is_ancestor(ll u, ll v) { return tin[u] <= tin[v] && tout[v] <= tout[u]; }
	ll lca(ll u, ll v)
	{
		ll ans = 0;
		if(u == v) return 0;
		if(is_ancestor(u, v))
		{
			swap(u, v);
			for(ll i = m; i >= 0; i--)
			{
				if(!is_ancestor(dp[u][i], v))
				{
					ans+=dist[u][i];
					u = dp[u][i];
				}
			}
			ans+=dist[u][0];
			return ans;
		}
		if(is_ancestor(v, u))
		{
			for(ll i = m; i >= 0; i--)
			{
				if(!is_ancestor(dp[u][i], i))
				{
					ans+=dist[u][i];
					u = dp[u][i];
				}
			}
			ans+=dist[u][0];
			return ans;
		}
		for(ll i = m; i >= 0; i--)
		{
			if(!is_ancestor(dp[u][i], v))
			{
				ans+=dist[u][i];
				u = dp[u][i];
			}
		}
		ans+=dist[u][0];
		swap(u, v);
		for(ll i = m; i >= 0; i--)
		{
			if(!is_ancestor(dp[u][i], v))
			{
				ans+=dist[u][i];
				u = dp[u][i];
			}
		}
		ans+=dist[u][0];
		return ans;
	}
	void build()
	{
		m = ceil(log2(n));
		dp.assign(n, vi(m + 1, 0));
		dist.assign(n, vi(m + 1, 0));
		tin.assign(n, 0);
		tout.assign(n, 0);
		tim = 0;
		dfs(1, 1, 0);
	}
};
int main()
{
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);
	cout.tie(NULL);
	ll n, val, a, b, c;
	cin >> n;
	vector<vi > adj(n + 1, vi(n + 1, 0));
	for(ll i = 1; i <= n; i++)
	{
		for(ll j = 1; j <= n; j++) cin >> adj[i][j];
	}
	bool flag = true;
	vector<pair<ll, ii> > edg;
	for(ll i = 1; i <= n; i++)
	{
		for(ll j = 1; j <= n; j++)
		{
			if(adj[i][j] != adj[j][i]) flag = false;
			if(i != j && adj[i][j] == 0) flag = false;
			edg.pb(mp(adj[i][j], mp(i, j)));
		}
	}
	if(!flag) { cout << "NO \n"; return 0; }
	DSU u(n + 1);
	LCA g(n + 1);
	sort(edg.begin(), edg.end());
	for(ll i = 0; i < edg.size(); i++)
	{
		a = edg[i].se.fi, b = edg[i].se.se, c = edg[i].fi;
		if(u.is_same(a, b)) continue;
		u.Union(a, b);
		g.add_edge(a, b, c);
	}
	g.build();
	for(ll i = 1; i <= n; i++)
	{
		for(ll j = 1; j <= n; j++) if(g.lca(i, j) != adj[i][j]) flag = false;
	}
	if(!flag) cout << "NO\n";
	else cout << "YES\n";
}


// https://codeforces.com/problemset/problem/472/D
#include <bits/stdc++.h>
using namespace std;
typedef long long int ll;
typedef pair<ll, ll> ii;
typedef vector<ll> vi;
typedef vector<string> vs;
typedef vector<bool> vb;
typedef vector<ii> vii;
#define pb push_back
#define mp make_pair
#define fi first
#define se second
bool comp(pair<int, ii> a, pair<int, ii> b){ return a.fi < b.fi; }
class DSU
{
private:
	vi par, rank;
	ll n;
public:
	DSU(ll a)
	{
		n = a;
		par.assign(n, 0);
		rank.assign(n, 0);
		for(ll i = 1; i < n; i++) par[i] = i;
	}
	ll find_set(ll i) { return (par[i] == i) ? i : par[i] = find_set(par[i]); }
	bool is_same(ll i, ll j) { return find_set(i) == find_set(j); }
	void Union(ll i, ll j)
	{
		ll x = par[i], y = par[j];
		if(rank[x] > rank[y]) par[y] = par[x];
		else
		{
			par[x] = par[y];
			if(rank[x] == rank[y]) rank[y]++;
		}
	}
};
class LCA
{
private:
	vector<vii > v;
	vector<vi > dp;
	vector<vi> dist;
	vi tin, tout;
	ll n, m, tim;
public:
	LCA(ll a) { n = a; v.assign(n, vii(0, mp(0, 0)));}
	void add_edge(ll a, ll b, ll c) { v[a].pb(mp(b, c)); v[b].pb(mp(a, c)); }
	void dfs(ll idx, ll par, ll w)
	{
		tin[idx] = tim++;
		dp[idx][0] = par;
		dist[idx][0] = w;
		for(ll i = 1; i <= m; i++) dp[idx][i] = dp[dp[idx][i - 1]][i - 1];
		for(ll i = 1; i <= m; i++) dist[idx][i] = dist[idx][i - 1] + dist[dp[idx][i - 1]][i - 1];
		for(ll i = 0; i < v[idx].size(); i++)
		{
			ii nxt = v[idx][i];
			if(nxt.fi == par) continue;
			dfs(nxt.fi, idx, nxt.se);
		}
		tout[idx] = tim++;
	}
	bool is_ancestor(ll u, ll v) { return tin[u] <= tin[v] && tout[v] <= tout[u]; }
	ll lca(ll u, ll v)
	{
		ll ans = (ll)0;
		if(u == v) return ans;
		if(is_ancestor(u, v))
		{
			swap(u, v);
			for(ll i = m; i >= 0; i--)
			{
				if(!is_ancestor(dp[u][i], v))
				{
					ans+=dist[u][i];
					u = dp[u][i];
				}
			}
			ans+=dist[u][0];
			return ans;
		}
		if(is_ancestor(v, u))
		{
			for(ll i = m; i >= 0; i--)
			{
				if(!is_ancestor(dp[u][i], i))
				{
					ans+=dist[u][i];
					u = dp[u][i];
				}
			}
			ans+=dist[u][0];
			return ans;
		}
		for(ll i = m; i >= 0; i--)
		{
			if(!is_ancestor(dp[u][i], v))
			{
				ans+=dist[u][i];
				u = dp[u][i];
			}
		}
		ans+=dist[u][0];
		swap(u, v);
		for(ll i = m; i >= 0; i--)
		{
			if(!is_ancestor(dp[u][i], v))
			{
				ans+=dist[u][i];
				u = dp[u][i];
			}
		}
		ans+=dist[u][0];
		return ans;
	}
	void build()
	{
		m = ceil(log2(n));
		dp.assign(n, vi(m + 1, 0));
		dist.assign(n, vi(m + 1, 0));
		tin.assign(n, 0);
		tout.assign(n, 0);
		tim = 0;
		dfs(1, 1, 0);
	}
};
int main()
{
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);
	cout.tie(NULL);
	ll n, val, a, b, c;
	cin >> n;
	vector<vi > adj(n + 1, vi(n + 1, 0));
	for(ll i = 1; i <= n; i++)
	{
		for(ll j = 1; j <= n; j++) cin >> adj[i][j];
	}
	bool flag = true;
	vector<pair<ll, ii> > edg;
	for(ll i = 1; i <= n && flag; i++)
	{
		for(ll j = i; j <= n && flag; j++)
		{
			if(i == j && adj[i][j] != 0) flag = false;
			if(adj[i][j] != adj[j][i]) flag = false;
			if(i != j && adj[i][j] == (ll)0) flag = false;
			edg.pb(mp(adj[i][j], mp(i, j)));
		}
	}
	if(!flag) { cout << "NO \n"; return 0; }
	DSU u(n + 1);
	LCA g(n + 1);
	sort(edg.begin(), edg.end(), comp);
	for(ll i = 0; i < (ll)edg.size(); i++)
	{
		a = edg[i].se.fi, b = edg[i].se.se, c = edg[i].fi;
		if(u.is_same(a, b)) continue;
		u.Union(a, b);
		g.add_edge(a, b, c);
	}
	g.build();
	for(ll i = 1; i <= n && flag; i++)
	{
		for(ll j = i; j <= n && flag; j++) if(g.lca(i, j) != adj[i][j]) flag = false;
	}
	if(!flag) cout << "NO\n";
	else cout << "YES\n";
}


#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>

using namespace std;
using namespace __gnu_pbds;

#define maxn 200005
#define ll long long int
#define db(x) cout<<#x<<" -> "<<x<<" "<<endl
#define db2(x,y) cout<<#x<<"-> "<<x<<", "<<#y<<" -> "<<y<<endl
#define db3(x,y,z) cout<<#x<<" -> "<<x<<" , "<<#y<<" -> "<<y<<" , "<<#z<<" -> "<<z<<endl
#define prt(x) for(auto it = x.begin(); it!=x.end(); it++) { cout<<*it<<" "; } cout<<endl
#define IN freopen("input.txt","r",stdin)
const int N = 2005;
int mark[N][N] ;
int edge[N][N];
bool vis[ N ][ N ];
int n;
vector< pair< int, pair< int , int > > > V;
#define f first
#define s second

vector< pair< int, int > > g[ N ];
ll dist[N];

void dfs(int src, int par=-1){
    for(auto to : g[ src ]){
        if(to.first==par){ continue ;}
        int v = to.first ; ll w = to.second;
        dist[ v ] = dist[ src ] + w;
        dfs(v,src);
    }
}

int main(){
    ios_base::sync_with_stdio(false); cin.tie(0);
//    IN ;
    cin>>n;
    for(int i = 1; i <= n; i++){
        for(int j = 1; j <= n; j++){
            int w;
            cin>>w;
            if( i==j && w ){ cout<<"NO"<<endl; return 0 ;}
            if(w!=0){ V.push_back({w,{i,j}}) ; }
            edge[ i ][ j ] = w;
        }
    }
    for(int i = 1; i<=n; i++){
        for(int j = 1; j <= n; j++){
            if(i==j){ continue ; }
            if(edge[ i ][ j ]!=edge[ j ][ i ]){
                cout<<"NO"<<endl; return 0;
            }
        }
    }
    if(V.size()==0){
        cout<<"NO"<<endl;
        return 0;
    }
    sort(V.begin(),V.end());
    for(int i = 0 , tot = 0; tot < (n-1) ; i++){
        int u = V[ i ].s.f;
        int v = V[ i ].s.s;
        int w = V[ i ].f;
        if(vis[u][v]){ continue ;}
        g[ u ].push_back({v,w});
        g[ v ].push_back({u,w});
        vis[ u ][ v ] = vis[ v ][ u ] = true;
        tot++;
    }

    for(int i = 1; i <= n; i++){
        memset(dist,0,sizeof(dist));
        dfs(i,-1);
        for(int j = 1; j<= n; j++){
            mark[i][j] = dist[ j ];
        }
    }
    for(int i = 1; i<=n; i++){
        for(int j = 1; j <= n; j++){
            if(edge[ i ][ j ]!=mark[ i ][ j ]){
                cout<<"NO"<<endl; return 0;
            }
        }
    }
    cout<<"YES"<<endl;
    return 0;
}


#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>

using namespace std;
using namespace __gnu_pbds;

#define maxn 200005
#define ll long long int
#define db(x) cout<<#x<<" -> "<<x<<" "<<endl
#define db2(x,y) cout<<#x<<"-> "<<x<<", "<<#y<<" -> "<<y<<endl
#define db3(x,y,z) cout<<#x<<" -> "<<x<<" , "<<#y<<" -> "<<y<<" , "<<#z<<" -> "<<z<<endl
#define prt(x) for(auto it = x.begin(); it!=x.end(); it++) { cout<<*it<<" "; } cout<<endl
#define IN freopen("input.txt","r",stdin)
const int N = 2005;
int edge[N][N];
bool vis[ N ][ N ];
int n;
vector< pair< int, pair< int , int > > > V;
#define f first
#define s second

vector< pair< int, int > > g[ N ];
int dist[N];

void dfs(int src, int par=-1){
    for(auto to : g[ src ]){
        if(to.first==par){ continue ;}
        int v = to.first ; ll w = to.second;
        dist[ v ] = dist[ src ] + w;
        dfs(v,src);
    }
}

int main(){
    ios_base::sync_with_stdio(false); cin.tie(0);
//    IN ;
    cin>>n;
    for(int i = 1; i <= n; i++){
        for(int j = 1; j <= n; j++){
            int w;
            cin>>w;
            if( i==j && w ){ cout<<"NO"<<endl; return 0 ;}
            if(w!=0){ V.push_back({w,{i,j}}) ; }
            edge[ i ][ j ] = w;
        }
    }
    for(int i = 1; i<=n; i++){
        for(int j = 1; j <= n; j++){
            if(i==j){ continue ; }
            if(edge[ i ][ j ]!=edge[ j ][ i ]){
                cout<<"NO"<<endl; return 0;
            }
        }
    }
    if(n==1){
        if(edge[1][1]){
            cout<<"NO"<<endl; return 0;
        }
        cout<<"YES"<<endl; return 0;
    }
    if(V.size()==0){
        cout<<"NO"<<endl;
        return 0;
    }
    sort(V.begin(),V.end());
    for(int i = 0 , tot = 0; tot < (n-1) ; i++){
        int u = V[ i ].s.f;
        int v = V[ i ].s.s;
        int w = V[ i ].f;
        if(vis[u][v]){ continue ;}
        g[ u ].push_back({v,w});
        g[ v ].push_back({u,w});
        vis[ u ][ v ] = vis[ v ][ u ] = true;
        tot++;
    }
    for(int i = 1; i <= n; i++){
        memset(dist,0,sizeof(dist));
        dfs(i,-1);
        for(int j = 1; j<= n; j++){
            if(dist[ j ]!=edge[ i ][ j ]){
                cout<<"NO"<<endl;
                return 0;
            }
        }
    }
    cout<<"YES"<<endl;
    return 0;
}


#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>

using namespace std;
using namespace __gnu_pbds;

#define maxn 200005
#define ll long long int
#define db(x) cout<<#x<<" -> "<<x<<" "<<endl
#define db2(x,y) cout<<#x<<"-> "<<x<<", "<<#y<<" -> "<<y<<endl
#define db3(x,y,z) cout<<#x<<" -> "<<x<<" , "<<#y<<" -> "<<y<<" , "<<#z<<" -> "<<z<<endl
#define prt(x) for(auto it = x.begin(); it!=x.end(); it++) { cout<<*it<<" "; } cout<<endl
#define IN freopen("input.txt","r",stdin)
const int N = 2005;
int edge[N][N];
bool vis[ N ][ N ];
int n;
int parent[ N ];
vector< pair< int, pair< int , int > > > V;
#define f first
#define s second
int find(int r){
    return (parent[r]==r)?r:find(parent[r]);
}

vector< pair< int, int > > g[ N ];
int lim = (int)1e9;
int dist[N];

void dfs(int src, int par=-1){
    for(auto to : g[ src ]){
        if(to.first==par){ continue ;}
        int v = to.first ; ll w = to.second;
        dist[ v ] = dist[ src ] + w;
        dfs(v,src);
    }
}

int main(){
    ios_base::sync_with_stdio(false); cin.tie(0);
//    IN ;
    cin>>n;
    for(int i = 1; i <= n; i++){
        for(int j = 1; j <= n; j++){
            int w;
            cin>>w;
            if( i==j && w ){ cout<<"NO"<<endl; return 0 ;}
            if(w!=0){ V.push_back({w,{i,j}}) ; }
            edge[ i ][ j ] = w;
        }
    }
    for(int i = 1; i<=n; i++){
        for(int j = 1; j <= n; j++){
            if(i==j){ continue ; }
            if(edge[ i ][ j ]!=edge[ j ][ i ]){
                cout<<"NO"<<endl; return 0;
            }
        }
    }
    if(n==1){
        if(edge[1][1]){
            cout<<"NO"<<endl; return 0;
        }
        cout<<"YES"<<endl; return 0;
    }
    if(V.size()==0){
        cout<<"NO"<<endl;
        return 0;
    }
    sort(V.begin(),V.end());
    for(int i = 1; i <= n; i++){ parent[ i ] = i ; }
    for(int i = 0 , tot = 0; i < V.size() ; i++){
        int u = V[ i ].s.f;
        int v = V[ i ].s.s;
        int w = V[ i ].f;
        int uu = find(u) ; int vv = find(v);
        if(vis[u][v]){ continue ;}
        if(uu==vv){ continue ; }
        parent[ uu ] = vv;
        g[ u ].push_back({v,w});
        g[ v ].push_back({u,w});
        vis[ u ][ v ] = vis[ v ][ u ] = true;
        tot++;
        if(tot==(n-1)){ break ; }
    }

    for(int i = 1; i <= n; i++){
        memset(dist,0,sizeof(dist));
        dfs(i,-1);
        for(int j = 1; j<= n; j++){
            if(dist[ j ]!=edge[ i ][ j ]){
                cout<<"NO"<<endl;
                return 0;
            }
        }
    }
    cout<<"YES"<<endl;
    return 0;
}


#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>

using namespace std;
using namespace __gnu_pbds;

#define maxn 200005
#define ll long long int
#define db(x) cout<<#x<<" -> "<<x<<" "<<endl
#define db2(x,y) cout<<#x<<"-> "<<x<<", "<<#y<<" -> "<<y<<endl
#define db3(x,y,z) cout<<#x<<" -> "<<x<<" , "<<#y<<" -> "<<y<<" , "<<#z<<" -> "<<z<<endl
#define prt(x) for(auto it = x.begin(); it!=x.end(); it++) { cout<<*it<<" "; } cout<<endl
#define IN freopen("input.txt","r",stdin)
const int N = 2005;
int mark[N][N] ;
int edge[N][N];
bool vis[ N ][ N ];
int n;
vector< pair< int, pair< int , int > > > V;
#define f first
#define s second

vector< pair< int, int > > g[ N ];
ll dist[N];

void dfs(int src, int par=-1){
    for(auto to : g[ src ]){
        if(to.first==par){ continue ;}
        int v = to.first ; ll w = to.second;
        dist[ v ] = dist[ src ] + w;
        dfs(v,src);
    }
}

int main(){
    ios_base::sync_with_stdio(false); cin.tie(0);
//    IN ;
    cin>>n;
    for(int i = 1; i <= n; i++){
        for(int j = 1; j <= n; j++){
            int w;
            cin>>w;
            if( i==j && w ){ cout<<"NO"<<endl; return 0 ;}
            if(w!=0){ V.push_back({w,{i,j}}) ; }
            edge[ i ][ j ] = w;
        }
    }
    for(int i = 1; i<=n; i++){
        for(int j = 1; j <= n; j++){
            if(i==j){ continue ; }
            if(edge[ i ][ j ]!=edge[ j ][ i ]){
                cout<<"NO"<<endl; return 0;
            }
        }
    }
    if(n==1){
        if(edge[1][1]){
            cout<<"NO"<<endl; return 0;
        }
        cout<<"YES"<<endl; return 0;
    }
    if(V.size()==0){
        cout<<"NO"<<endl;
        return 0;
    }
    sort(V.begin(),V.end());
    for(int i = 0 , tot = 0; tot < (n-1) ; i++){
        int u = V[ i ].s.f;
        int v = V[ i ].s.s;
        int w = V[ i ].f;
        if(vis[u][v]){ continue ;}
        g[ u ].push_back({v,w});
        g[ v ].push_back({u,w});
        vis[ u ][ v ] = vis[ v ][ u ] = true;
        tot++;
    }

    for(int i = 1; i <= n; i++){
        memset(dist,0,sizeof(dist));
        dfs(i,-1);
        for(int j = 1; j<= n; j++){
            mark[i][j] = dist[ j ];
        }
    }
    for(int i = 1; i<=n; i++){
        for(int j = 1; j <= n; j++){
            if(edge[ i ][ j ]!=mark[ i ][ j ]){
                cout<<"NO"<<endl; return 0;
            }
        }
    }
    cout<<"YES"<<endl;
    return 0;
}


#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>

using namespace std;
using namespace __gnu_pbds;

#define maxn 200005
#define ll long long int
#define db(x) cout<<#x<<" -> "<<x<<" "<<endl
#define db2(x,y) cout<<#x<<"-> "<<x<<", "<<#y<<" -> "<<y<<endl
#define db3(x,y,z) cout<<#x<<" -> "<<x<<" , "<<#y<<" -> "<<y<<" , "<<#z<<" -> "<<z<<endl
#define prt(x) for(auto it = x.begin(); it!=x.end(); it++) { cout<<*it<<" "; } cout<<endl
#define IN freopen("input.txt","r",stdin)
const int N = 2005;
int edge[N][N];
int n;
int parent[ N ];
vector< pair< int, pair< int , int > > > V;
#define f first
#define s second
int find(int r){
    return (parent[r]==r)?r:find(parent[r]);
}

vector< pair< int, int > > g[ N ];
int lim = (int)1e9;
int dist[N];

void dfs(int src, int par=-1){
    for(auto to : g[ src ]){
        if(to.first==par){ continue ;}
        int v = to.first ; ll w = to.second;
        dist[ v ] = dist[ src ] + w;
        dfs(v,src);
    }
}

int main(){
    ios_base::sync_with_stdio(false); cin.tie(0);
//    IN ;
    cin>>n;
    for(int i = 1; i <= n; i++){
        for(int j = 1; j <= n; j++){
            int w;
            cin>>w;
            if( i==j && w ){ cout<<"NO"<<endl; return 0 ;}
            if(w!=0){ V.push_back({w,{i,j}}) ; }
            edge[ i ][ j ] = w;
        }
    }
    for(int i = 1; i<=n; i++){
        for(int j = 1; j <= n; j++){
            if(i==j){ continue ; }
            if(edge[ i ][ j ]!=edge[ j ][ i ]){
                cout<<"NO"<<endl; return 0;
            }
        }
    }
    if(n==1){
        if(edge[1][1]){
            cout<<"NO"<<endl; return 0;
        }
        cout<<"YES"<<endl; return 0;
    }
    if(V.size()==0){
        cout<<"NO"<<endl;
        return 0;
    }
    sort(V.begin(),V.end());
    for(int i = 1; i <= n; i++){ parent[ i ] = i ; }
    for(int i = 0 , tot = 0; i < V.size() ; i++){
        int u = V[ i ].s.f;
        int v = V[ i ].s.s;
        int w = V[ i ].f;
        int uu = find(u) ; int vv = find(v);
        if(uu==vv){ continue ; }
        parent[ uu ] = vv;
        g[ u ].push_back({v,w});
        g[ v ].push_back({u,w});
        tot++;
        if(tot==(n-1)){ break ; }
    }

    for(int i = 1; i <= n; i++){
        memset(dist,0,sizeof(dist));
        dfs(i,-1);
        for(int j = 1; j<= n; j++){
            if(dist[ j ]!=edge[ i ][ j ]){
                cout<<"NO"<<endl;
                return 0;
            }
        }
    }
    cout<<"YES"<<endl;
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define mp make_pair
#define ll long long
vector< pair < ll,pair <ll,ll> > > g;
vector < pair <ll,ll> > g1[100001];
ll dis[10001]={0};
bool visited[100001];
ll size[100001];
ll c[100001];
void fun(ll n)
{
    for(int i=1;i<=n;i++)
    {
        c[i]=i;
        size[i]=1;
    }
}
ll root1(ll x)
{
    while(c[x]!=x)
    {
        x=c[x];
    }
    return x;
}
void union1(ll x,ll y)
{
    if(size[x]>size[y])
    c[y]=c[x];
    else
        c[x]=c[y];
}
void dfs(ll x)
{
    visited[x]=true;
    for(int i=0;i<g1[x].size();i++)
    {
        if(visited[g1[x][i].first]==false)
        {
            dis[g1[x][i].first]=dis[x] + g1[x][i].second;
            dfs(g1[x][i].first);
        }
    }
}
int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    ll n;
    cin>>n;
    fun(n);
    ll a[n+1][n+1];
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=n;j++)
        {
            cin>>a[i][j];
        }
    }
    for(int i=1;i<=n;i++)
    {
        for(int j=i+1;j<=n;j++)
        {
            g.push_back(mp(a[i][j],mp(i,j)));
        }
    }
    sort(g.begin(),g.end());
    ll k=0;
    for(int i=0;i<g.size();i++)
    {
        if(g[i].first<=0)
        {
            cout<<"NO";
            return 0;
        }
        ll x=g[i].second.first;
        ll y=g[i].second.second;
        ll xx=root1(x);
        ll yy=root1(y);
        if(xx!=yy)
        {
            union1(xx,yy);
            g1[x].push_back(mp(y,g[i].first));
            g1[y].push_back(mp(x,g[i].first));
            k++;
            if(k==n-1)
                break;
        }

    }
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=n;j++)
        {
            visited[j]=0;
            dis[j]=0;
        }
        dfs(i);
        for(int j=1;j<=n;j++)
        {
            if(dis[j]!=a[i][j])
            {
            //    cout<<dis[j]<<" "<<a[i][j]<<endl;
              //  cout<<i<<" "<<j<<endl;
                cout<<"NO";
                return 0;
            }
        }
    }
    cout<<"YES";
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define mp make_pair
#define ll long long
vector< pair < ll,pair <ll,ll> > > g;
vector < pair <ll,ll> > g1[100001];
ll dis[10001]={0};
bool visited[100001];
ll c[100001];
void fun(ll n)
{
    for(int i=1;i<=n;i++)
    {
        c[i]=i;
    }
}
ll root1(ll x)
{
    while(c[x]!=x)
    {
        x=c[x];
    }
    return x;
}
void union1(ll x,ll y)
{
    c[y]=c[x];
}
void dfs(ll x)
{
    visited[x]=true;
    for(int i=0;i<g1[x].size();i++)
    {
        if(visited[g1[x][i].first]==false)
        {
            dis[g1[x][i].first]=dis[x] + g1[x][i].second;
            dfs(g1[x][i].first);
        }
    }
}
int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    ll n;
    cin>>n;
    fun(n);
    ll a[n+1][n+1];
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=n;j++)
        {
            cin>>a[i][j];
        }
    }
    for(int i=1;i<=n;i++)
    {
        for(int j=i+1;j<=n;j++)
        {
            g.push_back(mp(a[i][j],mp(i,j)));
        }
    }
    sort(g.begin(),g.end());
    ll k=0;
    for(int i=0;i<g.size();i++)
    {
        if(g[i].first<=0)
        {
            cout<<"NO";
            return 0;
        }
        ll x=g[i].second.first;
        ll y=g[i].second.second;
        ll xx=root1(x);
        ll yy=root1(y);
        if(xx!=yy)
        {
            union1(xx,yy);
            g1[x].push_back(mp(y,g[i].first));
            g1[y].push_back(mp(x,g[i].first));
            k++;
            if(k==n-1)
                break;
        }

    }
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=n;j++)
        {
            visited[j]=0;
            dis[j]=0;
        }
        dfs(i);
        for(int j=1;j<=n;j++)
        {
            if(dis[j]!=a[i][j])
            {
            //    cout<<dis[j]<<" "<<a[i][j]<<endl;
              //  cout<<i<<" "<<j<<endl;
                cout<<"NO";
                return 0;
            }
        }
    }
    cout<<"YES";
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define mp make_pair
#define ll long long
vector< pair < ll,pair <ll,ll> > > g;
vector < pair <ll,ll> > g1[100001];
ll dis[10001]={0};
bool visited[100001];
void dfs(ll x)
{
    visited[x]=true;
    for(int i=0;i<g1[x].size();i++)
    {
        if(visited[g1[x][i].first]==false)
        {
            dis[g1[x][i].first]=dis[x] + g1[x][i].second;
            dfs(g1[x][i].first);
        }
    }
}
int main()
{
    ll n;
    cin>>n;
    ll a[n+1][n+1];
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=n;j++)
        {
            cin>>a[i][j];
        }
    }
    for(int i=1;i<=n;i++)
    {
        for(int j=i+1;j<=n;j++)
        {
            g.push_back(mp(a[i][j],mp(i,j)));
        }
    }
    sort(g.begin(),g.end());
    for(int i=0;i<n-1;i++)
    {
        if(g[i].first<=0)
        {
            cout<<"NO";
            return 0;
        }
        ll x=g[i].second.first;
        ll y=g[i].second.second;
        g1[x].push_back(mp(y,g[i].first));
        g1[y].push_back(mp(x,g[i].first));
    }
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=n;j++)
        {
            visited[j]=0;
            dis[j]=0;
        }
        dfs(i);
        for(int j=1;j<=n;j++)
        {
            if(dis[j]!=a[i][j])
            {
            //    cout<<dis[j]<<" "<<a[i][j]<<endl;
              //  cout<<i<<" "<<j<<endl;
                cout<<"NO";
                return 0;
            }
        }
    }
    cout<<"YES";
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define mp make_pair
#define ll long long
vector< pair < ll,pair <ll,ll> > > g;
vector < pair <ll,ll> > g1[100001];
ll dis[10001]={0};
bool visited[100001];
ll c[100001];
void fun(ll n)
{
    for(int i=1;i<=n;i++)
    {
        c[i]=i;
        size[i]=1;
    }
}
ll root1(ll x)
{
    while(c[x]!=x)
    {
        x=c[x];
    }
    return x;
}
void union1(ll x,ll y)
{
    if(size[x]>size[y])
    c[y]=c[x];
    else
        c[x]=c[y];
}
void dfs(ll x)
{
    visited[x]=true;
    for(int i=0;i<g1[x].size();i++)
    {
        if(visited[g1[x][i].first]==false)
        {
            dis[g1[x][i].first]=dis[x] + g1[x][i].second;
            dfs(g1[x][i].first);
        }
    }
}
int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    ll n;
    cin>>n;
    fun(n);
    ll a[n+1][n+1];
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=n;j++)
        {
            cin>>a[i][j];
        }
    }
    for(int i=1;i<=n;i++)
    {
        for(int j=i+1;j<=n;j++)
        {
            g.push_back(mp(a[i][j],mp(i,j)));
        }
    }
    sort(g.begin(),g.end());
    ll k=0;
    for(int i=0;i<g.size();i++)
    {
        if(g[i].first<=0)
        {
            cout<<"NO";
            return 0;
        }
        ll x=g[i].second.first;
        ll y=g[i].second.second;
        ll xx=root1(x);
        ll yy=root1(y);
        if(xx!=yy)
        {
            union1(xx,yy);
            g1[x].push_back(mp(y,g[i].first));
            g1[y].push_back(mp(x,g[i].first));
            k++;
            if(k==n-1)
                break;
        }

    }
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=n;j++)
        {
            visited[j]=0;
            dis[j]=0;
        }
        dfs(i);
        for(int j=1;j<=n;j++)
        {
            if(dis[j]!=a[i][j])
            {
            //    cout<<dis[j]<<" "<<a[i][j]<<endl;
              //  cout<<i<<" "<<j<<endl;
                cout<<"NO";
                return 0;
            }
        }
    }
    cout<<"YES";
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define mp make_pair
#define ll long long
vector< pair < ll,pair <ll,ll> > > g;
vector < pair <ll,ll> > g1[100001];
ll dis[10001]={0};
bool visited[100001];
ll size[100001];
ll c[100001];
void fun(ll n)
{
    for(int i=1;i<=n;i++)
    {
        c[i]=i;
        size[i]=1;
    }
}
ll root1(ll x)
{
    while(c[x]!=x)
    {
        x=c[x];
    }
    return x;
}
void union1(ll x,ll y)
{
        c[y]=c[x];
}
void dfs(ll x)
{
    visited[x]=true;
    for(int i=0;i<g1[x].size();i++)
    {
        if(visited[g1[x][i].first]==false)
        {
            dis[g1[x][i].first]=dis[x] + g1[x][i].second;
            dfs(g1[x][i].first);
        }
    }
}
int main()
{
    //ios_base::sync_with_stdio(false);
    //cin.tie(NULL);
    ll n;
    cin>>n;
    fun(n);
    ll a[n+1][n+1];
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=n;j++)
        {
            cin>>a[i][j];
        }
    }
    for(int i=1;i<=n;i++)
    {
        for(int j=i+1;j<=n;j++)
        {
            g.push_back(mp(a[i][j],mp(i,j)));
        }
    }
    sort(g.begin(),g.end());
    ll k=0;
    for(int i=0;i<g.size();i++)
    {
        if(g[i].first<=0)
        {
            cout<<"NO";
            return 0;
        }
        ll x=g[i].second.first;
        ll y=g[i].second.second;
        ll xx=root1(x);
        ll yy=root1(y);
        if(xx!=yy)
        {
            union1(xx,yy);
            g1[x].push_back(mp(y,g[i].first));
            g1[y].push_back(mp(x,g[i].first));
            k++;
            if(k==n-1)
                break;
        }

    }
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=n;j++)
        {
            visited[j]=0;
            dis[j]=0;
        }
        dfs(i);
        for(int j=1;j<=n;j++)
        {
            if(dis[j]!=a[i][j])
            {
            //    cout<<dis[j]<<" "<<a[i][j]<<endl;
              //  cout<<i<<" "<<j<<endl;
                cout<<"NO";
                return 0;
            }
        }
    }
    cout<<"YES";
    return 0;
}