//Dipta Das CUET CSE-11

#include <cstdio>
#include <cstring>
#include <cmath>
#include <limits>
#include <iostream>
#include <algorithm>
#include <sstream>
#include <string>
#include <vector>
#include <stack>
#include <queue>
#include <map>

#define LL long long
#define Pi acos(-1.0)
#define EPS 1e-11
#define Mod 100000007
#define mset(a, s) memset(a, s, sizeof (a))
#define NN 100005
#define Inf 1000000000

using namespace std;

int par[NN],adj[505][505],cnt;
bool vis[100005];

vector<int> e[100005];

void dfs(int n)
{
    cnt++;
    vis[n]=1;
    for(int i=0; i<e[n].size(); i++)
    {
        if(vis[e[n][i]]==0) dfs(e[n][i]);
    }
}

int main()
{
    int n,m,u,v,x,k,k1[505],k2=1,k3=0;

    scanf("%d%d%d",&n,&m,&k);

    for(int i=1; i<=k; i++)
    {
        scanf("%d",&k1[i]);
        k3++;
        for(int j=0; j<k1[i]; j++)
        {
            par[k2]=k3;
            k2++;
        }
    }

    for(int i=1; i<=k; i++)
    {
        for(int j=1; j<=k; j++) adj[i][j]=Inf;
        adj[i][i]=0;
    }

    bool flg=0;

    for(int i=0; i<m; i++)
    {
        scanf("%d%d%d",&u,&v,&x);
        adj[par[u]][par[v]]=adj[par[v]][par[u]]=min(adj[par[u]][par[v]],x);
        if(par[u]==par[v] && x==0)
        {
            e[u].push_back(v);
            e[v].push_back(u);
        }
//        else if(x==0) flg=1;
    }

//    if(flg)
//    {
//        printf("No");
//        return 0;
//    }

    int z=1;
    k1[0]=0;

    for(int i=1; i<=k; i++)
    {
        z=z+k1[i-1];
        cnt=0;
        dfs(z);
        if(cnt!=k1[i])
        {
            printf("No");
            return 0;
        }
    }

    for(int l=1; l<=k; l++)
    {
        for(int i=1; i<=k; i++)
        {
            for(int j=1; j<=k; j++)
            {
                adj[i][j]=min(adj[i][j],adj[i][l]+adj[l][j]);
            }
        }
    }

    printf("Yes\n");
    for(int i=1; i<=k; i++)
    {
        for(int j=1; j<=k; j++)
        {
            if(j!=1) printf(" ");
            if(adj[i][j]==Inf) adj[i][j]=-1;
            printf("%d",adj[i][j]);
        }
        puts("");
    }

    return 0;
}


//Dipta Das CUET CSE-11

#include <cstdio>
#include <cstring>
#include <cmath>
#include <limits>
#include <iostream>
#include <algorithm>
#include <sstream>
#include <string>
#include <vector>
#include <stack>
#include <queue>
#include <map>

#define LL long long
#define Pi acos(-1.0)
#define EPS 1e-11
#define Mod 100000007
#define mset(a, s) memset(a, s, sizeof (a))
#define NN 100005
#define Inf 1000000000

using namespace std;

int par[NN],adj[505][505],cnt,check;
bool vis[100005];

vector<int> e[100005];

void dfs(int n)
{
    if(par[n]==check) cnt++;
    vis[n]=1;
    for(int i=0; i<e[n].size(); i++)
    {
        if(vis[e[n][i]]==0) dfs(e[n][i]);
    }
}

int main()
{
    int n,m,u,v,x,k,k1[505],k2=1,k3=0;

    scanf("%d%d%d",&n,&m,&k);

    for(int i=1; i<=k; i++)
    {
        scanf("%d",&k1[i]);
        k3++;
        for(int j=0; j<k1[i]; j++)
        {
            par[k2]=k3;
            k2++;
        }
    }

    for(int i=1; i<=k; i++)
    {
        for(int j=1; j<=k; j++) adj[i][j]=Inf;
        adj[i][i]=0;
    }

    bool flg=0;

    for(int i=0; i<m; i++)
    {
        scanf("%d%d%d",&u,&v,&x);
        adj[par[u]][par[v]]=adj[par[v]][par[u]]=min(adj[par[u]][par[v]],x);
        if(x==0)
        {
            e[u].push_back(v);
            e[v].push_back(u);
        }
//        else if(x==0) flg=1;
    }

//    if(flg)
//    {
//        printf("No");
//        return 0;
//    }

    int z=1;
    k1[0]=0;

    for(int i=1; i<=k; i++)
    {
        mset(vis,0);
        z=z+k1[i-1];
        check=par[z];
        cnt=0;
        dfs(z);
        if(cnt!=k1[i])
        {
            printf("No");
            return 0;
        }
    }

    for(int l=1; l<=k; l++)
    {
        for(int i=1; i<=k; i++)
        {
            for(int j=1; j<=k; j++)
            {
                adj[i][j]=min(adj[i][j],adj[i][l]+adj[l][j]);
            }
        }
    }

    printf("Yes\n");
    for(int i=1; i<=k; i++)
    {
        for(int j=1; j<=k; j++)
        {
            if(j!=1) printf(" ");
            if(adj[i][j]==Inf) adj[i][j]=-1;
            printf("%d",adj[i][j]);
        }
        puts("");
    }

    return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define ll long long
const int mod = 1e9 + 7;
const int nmax = 100005;
const ll inf = 1e9;
const double eps = 1e-6;
const ll pw = 31;
int col[nmax];
int s[nmax];
int a[nmax];
int sz[nmax];
int p[nmax];
int d[505][505];
int pp(int a){
    return (a == p[a]? a: p[a] = pp(p[a]));
}
void merg(int a, int b){
    a = pp(a);
    b = pp(b);
    if (a == b) return;
    if (sz[a] < sz[b]) swap(a, b);
    p[b] = a;
    sz[a] += sz[b];
}
int main(){
    ios_base::sync_with_stdio(0);
    int n, m, k;
    cin >> n >> m >> k;
    for(int i = 0; i < k; ++i){
        cin >> s[i];
    }
    for(int i = 0; i < k; ++i){
        for(int j = 0; j < k; ++j)
            if (i != j) d[i][j] = inf;
    }
    int sum = 0;
    int j = 0;
    for(int i = 0; i < n; ++i){
        p[i] = i;
        sz[i] = 1;
        if (i < sum + s[j]){
            col[i] = j;
        }
        else {
            sum += s[j];
            j++;
            col[i] = j;
        }
    }
    sum = 0;
    j = 0;
    for(int i = 0; i < m; ++i){
        int u, v, len;
        cin >> u >> v >> len;
        u--;
        v--;
        if (u > v) swap(u, v);
        if (col[v] == col[u] && !len){
           merg(u, v);
        }
        else if (col[u] != col[v]){
            d[col[u]][col[v]] = d[col[v]][col[u]] = len;
        }
    }
    for(int i = 0; i < n; i++){
        if (sum + s[j] <= i){
            sum += s[j];
            j++;
        }
        if (pp(i) != sum){
            cout << "NO\n";
            return 0;
        }
    }
    cout << "YES\n";
    for(int fase = 0; fase < k; ++fase){
        for(int i = 0; i < k; ++i){
            for(int j = 0; j < k; ++j){
                d[i][j] = min(d[i][j], d[i][fase] + d[fase][j]);
            }
        }
    }
    for(int i = 0; i < k; ++i){
        for(int j = 0; j < k; ++j){
            if (d[i][j] == inf) d[i][j] = -1;
            cout << d[i][j] << ' ';
        }
        cout << '\n';
    }
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define ll long long
const int mod = 1e9 + 7;
const int nmax = 100005;
const ll inf = 1e9;
const double eps = 1e-6;
const ll pw = 31;
int col[nmax];
int s[nmax];
int a[nmax];
int sz[nmax];
int p[nmax];
int d[505][505];
int pp(int a){
    return (a == p[a]? a: p[a] = pp(p[a]));
}
void merg(int a, int b){
    a = pp(a);
    b = pp(b);
    if (a == b) return;
    if (sz[a] < sz[b]) swap(a, b);
    p[b] = a;
    sz[a] += sz[b];
}
int main(){
    ios_base::sync_with_stdio(0);
    int n, m, k;
    cin >> n >> m >> k;
    for(int i = 0; i < k; ++i){
        cin >> s[i];
    }
    for(int i = 0; i < k; ++i){
        for(int j = 0; j < k; ++j)
            if (i != j) d[i][j] = inf;
    }
    int sum = 0;
    int j = 0;
    for(int i = 0; i < n; ++i){
        p[i] = i;
        sz[i] = 1;
        if (i < sum + s[j]){
            col[i] = j;
        }
        else {
            sum += s[j];
            j++;
            col[i] = j;
        }
    }
    sum = 0;
    j = 0;
    for(int i = 0; i < m; ++i){
        int u, v, len;
        cin >> u >> v >> len;
        u--;
        v--;
        if (u > v) swap(u, v);
        if (col[v] == col[u] && !len){
           merg(u, v);
        }
        else if (col[u] != col[v]){
            d[col[u]][col[v]] = d[col[v]][col[u]] = len;
        }
    }
    for(int i = 0; i < n; i++){
        if (sum + s[j] <= i){
            sum += s[j];
            j++;
        }
        if (pp(i) != sum){
            cout << "No\n";
            return 0;
        }
    }
    cout << "Yes\n";
    for(int fase = 0; fase < k; ++fase){
        for(int i = 0; i < k; ++i){
            for(int j = 0; j < k; ++j){
                d[i][j] = min(d[i][j], d[i][fase] + d[fase][j]);
            }
        }
    }
    for(int i = 0; i < k; ++i){
        for(int j = 0; j < k; ++j){
            if (d[i][j] == inf) d[i][j] = -1;
            cout << d[i][j] << ' ';
        }
        cout << '\n';
    }
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define ll long long
const int mod = 1e9 + 7;
const int nmax = 100005;
const ll inf = 1e9;
const double eps = 1e-6;
const ll pw = 31;
int col[nmax];
int s[nmax];
int a[nmax];
int sz[nmax];
int p[nmax];
int d[505][505];
int pp(int a){
    return (a == p[a]? a: p[a] = pp(p[a]));
}
void merg(int a, int b){
    a = pp(a);
    b = pp(b);
    if (a == b) return;
    if (sz[a] < sz[b]) swap(a, b);
    p[b] = a;
    sz[a] += sz[b];
}
int main(){
    ios_base::sync_with_stdio(0);
    int n, m, k;
    cin >> n >> m >> k;
    for(int i = 0; i < k; ++i){
        cin >> s[i];
    }
    for(int i = 0; i < k; ++i){
        for(int j = 0; j < k; ++j)
            if (i != j) d[i][j] = inf;
    }
    int sum = 0;
    int j = 0;
    for(int i = 0; i < n; ++i){
        p[i] = i;
        sz[i] = 1;
        if (i < sum + s[j]){
            col[i] = j;
        }
        else {
            sum += s[j];
            j++;
            col[i] = j;
        }
    }
    sum = 0;
    j = 0;
    for(int i = 0; i < m; ++i){
        int u, v, len;
        cin >> u >> v >> len;
        u--;
        v--;
        if (u > v) swap(u, v);
        if (!len)
           merg(u, v);
        d[col[u]][col[v]] = d[col[v]][col[u]] = min(len, d[col[u]][col[v]]);
    }
    for(int i = 0; i < n - 1; i++){
        if (col[i] == col[i - 1] && pp(i) != pp(i - 1)){
            cout << "No\n";
            return 0;
        }
    }
    cout << "Yes\n";
    for(int fase = 0; fase < k; ++fase){
        for(int i = 0; i < k; ++i){
            for(int j = 0; j < k; ++j){
                d[i][j] = min(d[i][j], d[i][fase] + d[fase][j]);
            }
        }
    }
    for(int i = 0; i < k; ++i){
        for(int j = 0; j < k; ++j){
            if (d[i][j] == inf) d[i][j] = -1;
            cout << d[i][j] << ' ';
        }
        cout << '\n';
    }
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define ll long long
const int mod = 1e9 + 7;
const int nmax = 100005;
const ll inf = 1e9;
const double eps = 1e-6;
const ll pw = 31;
int col[nmax];
int s[nmax];
int a[nmax];
int sz[nmax];
int p[nmax];
int d[505][505];
int pp(int a){
    return (a == p[a]? a: p[a] = pp(p[a]));
}
void merg(int a, int b){
    a = pp(a);
    b = pp(b);
    if (a == b) return;
    if (sz[a] < sz[b]) swap(a, b);
    p[b] = a;
    sz[a] += sz[b];
}
int main(){
    ios_base::sync_with_stdio(0);
    int n, m, k;
    cin >> n >> m >> k;
    for(int i = 0; i < k; ++i){
        cin >> s[i];
    }
    for(int i = 0; i < k; ++i){
        for(int j = 0; j < k; ++j)
            if (i != j) d[i][j] = inf;
    }
    int sum = 0;
    int j = 0;
    for(int i = 0; i < n; ++i){
        p[i] = i;
        sz[i] = 1;
        if (i < sum + s[j]){
            col[i] = j;
        }
        else {
            sum += s[j];
            j++;
            col[i] = j;
        }
    }
    sum = 0;
    j = 0;
    for(int i = 0; i < m; ++i){
        int u, v, len;
        cin >> u >> v >> len;
        u--;
        v--;
        if (u > v) swap(u, v);
        if (col[v] == col[u] && !len){
           merg(u, v);
        }
        else if (col[u] != col[v]){
            d[col[u]][col[v]] = d[col[v]][col[u]] = len;
        }
    }
    for(int i = 0; i < n; i++){
        if (sum + s[j] == i){
            sum += s[j];
            j++;
        }
        if (pp(i) != sum){
            cout << "No\n";
            return 0;
        }
    }
    cout << "Yes\n";
    for(int fase = 0; fase < k; ++fase){
        for(int i = 0; i < k; ++i){
            for(int j = 0; j < k; ++j){
                d[i][j] = min(d[i][j], d[i][fase] + d[fase][j]);
            }
        }
    }
    for(int i = 0; i < k; ++i){
        for(int j = 0; j < k; ++j){
            if (d[i][j] == inf) d[i][j] = -1;
            cout << d[i][j] << ' ';
        }
        cout << '\n';
    }
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define ll long long
const int mod = 1e9 + 7;
const int nmax = 100005;
const ll inf = 1e9;
const double eps = 1e-6;
const ll pw = 31;
int col[nmax];
int s[nmax];
int a[nmax];
int sz[nmax];
int p[nmax];
int d[505][505];
int pp(int a){
    return (a == p[a]? a: p[a] = pp(p[a]));
}
void merg(int a, int b){
    a = pp(a);
    b = pp(b);
    if (a == b) return;
    if (sz[a] < sz[b]) swap(a, b);
    p[b] = a;
    sz[a] += sz[b];
}
int main(){
    ios_base::sync_with_stdio(0);
    int n, m, k;
    cin >> n >> m >> k;
    for(int i = 0; i < k; ++i){
        cin >> s[i];
    }
    for(int i = 0; i < k; ++i){
        for(int j = 0; j < k; ++j)
            if (i != j) d[i][j] = inf;
    }
    int sum = 0;
    int j = 0;
    for(int i = 0; i < n; ++i){
        p[i] = i;
        sz[i] = 1;
        if (i < sum + s[j]){
            col[i] = j;
        }
        else {
            sum += s[j];
            j++;
            col[i] = j;
        }
    }
    sum = 0;
    j = 0;
    for(int i = 0; i < m; ++i){
        int u, v, len;
        cin >> u >> v >> len;
        u--;
        v--;
        if (u > v) swap(u, v);
        if (!len)
           merg(u, v);
        d[col[u]][col[v]] = d[col[v]][col[u]] = min(len, d[col[u]][col[v]]);
    }
    for(int i = 0; i < n - 1; i++){
        if (col[i] == col[i + 1] && pp(i) != pp(i + 1)){
            cout << "No\n";
            return 0;
        }
    }
    cout << "Yes\n";
    for(int fase = 0; fase < k; ++fase){
        for(int i = 0; i < k; ++i){
            for(int j = 0; j < k; ++j){
                d[i][j] = min(d[i][j], d[i][fase] + d[fase][j]);
            }
        }
    }
    for(int i = 0; i < k; ++i){
        for(int j = 0; j < k; ++j){
            if (d[i][j] == inf) d[i][j] = -1;
            cout << d[i][j] << ' ';
        }
        cout << '\n';
    }
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define ll long long
const int mod = 1e9 + 7;
const int nmax = 100005;
const ll inf = 1e9;
const double eps = 1e-6;
const ll pw = 31;
int col[nmax];
int s[nmax];
int a[nmax];
int sz[nmax];
int p[nmax];
int d[505][505];
int pp(int a){
    return (a == p[a]? a: p[a] = pp(p[a]));
}
void merg(int a, int b){
    a = pp(a);
    b = pp(b);
    if (a == b) return;
    if (sz[a] < sz[b]) swap(a, b);
    p[b] = a;
    sz[a] += sz[b];
}
int main(){
    ios_base::sync_with_stdio(0);
    int n, m, k;
    cin >> n >> m >> k;
    for(int i = 0; i < k; ++i){
        cin >> s[i];
    }
    for(int i = 0; i < k; ++i){
        for(int j = 0; j < k; ++j)
            if (i != j) d[i][j] = inf;
    }
    int sum = 0;
    int j = 0;
    for(int i = 0; i < n; ++i){
        p[i] = i;
        sz[i] = 1;
        if (i < sum + s[j]){
            col[i] = j;
        }
        else {
            sum += s[j];
            j++;
            col[i] = j;
        }
    }
    sum = 0;
    j = 0;
    for(int i = 0; i < m; ++i){
        int u, v, len;
        cin >> u >> v >> len;
        u--;
        v--;
        if (u > v) swap(u, v);
        if (!len)
           merg(u, v);
        d[col[u]][col[v]] = d[col[v]][col[u]] = min(len, d[col[u]][col[v]]);
    }
    for(int i = 0; i < n; i++){
        if (sum + s[j] == i){
            sum += s[j];
            j++;
        }
        if (pp(i) != sum){
            cout << "No\n";
            return 0;
        }
    }
    cout << "Yes\n";
    for(int fase = 0; fase < k; ++fase){
        for(int i = 0; i < k; ++i){
            for(int j = 0; j < k; ++j){
                d[i][j] = min(d[i][j], d[i][fase] + d[fase][j]);
            }
        }
    }
    for(int i = 0; i < k; ++i){
        for(int j = 0; j < k; ++j){
            if (d[i][j] == inf) d[i][j] = -1;
            cout << d[i][j] << ' ';
        }
        cout << '\n';
    }
    return 0;
}


#include <iostream>
#include <fstream>
#include <iomanip>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <bitset>
#include <set>
#include <map>
#include <vector>
#include <string>
#include <cstring>
#include <queue>
#include <math.h>
using namespace std;

#define FOR0(i,n) for( i = 0 ; i < n ; ++i )
#define FOR1(i,n) for( i = 1 ; i <= n ; ++i )
#define sys_p system( "pause" )
#define pb push_back
#define mp make_pair
#define FI first
#define SE second

typedef long long LL ;

const int INF = (int)1e9 ;
const LL MOD = (LL)1e9 + 7 ;

int par[200000], rank[200000] ;

void make_set( LL v )
{
     par[v] = v ;
     rank[v] = 0 ;
}

LL find_set( LL v )
{
     if( v == par[v] ) return v ;
     return par[v] = find_set( par[v] ) ;
}

void union_sets( int a, int b )
{
     a = find_set(a) ; b = find_set(b) ;
     if( a != b )
     {
         if( rank[a] < rank[b] )
           swap(a,b) ;
         par[b] = a ;
         if( rank[a] == rank[b] )
           ++rank[a] ;
     }
}

int n, m, k, cc[600], where[200000], a[200000], b[200000], c[200000], numset[200000], path[600][600], i, j, l, last, x, y ;

main()
{
       cin >> n >> m >> k ;

       FOR1( i, n ) make_set(i) ;

       last = 0 ; FOR1( i, k )
       {
             cin >> cc[i] ;
             for( j = last+1 ; j <= last+cc[i] ; ++j )
               where[j] = i ;
             last += cc[i] ;
       }

       FOR1( i, m )
       {
             cin >> a[i] >> b[i] >> c[i] ;
             if( !c[i] && where[a[i]] == where[b[i]] ) union_sets( a[i], b[i] ) ;
       }

       last = 0 ; FOR1( i, k )
       {
             for( j = last+2 ; j <= last+cc[i] ; ++j )
               if( find_set( last+1 ) != find_set( j ) )
               {
                   cout << "No" << endl ;
                   return 0 ;
               }
             last += cc[i] ;
       }

       last = 0 ; FOR1( i, k )
       {
             for( j = last+1 ; j <= last+cc[i] ; ++j )
               numset[j] = i ;
             last += cc[i] ;
       }

       FOR1( i, k ) FOR1( j, k ) path[i][j] = INF, path[j][j] = 0 ;

       FOR1( i, m )
       {
             x = numset[a[i]] ; y = numset[b[i]] ;
             path[x][y] = min( path[x][y], c[i] ) ;
             path[y][x] = min( path[y][x], c[i] ) ;
       }

       FOR1( l, k ) FOR1( i, k ) FOR1( j, k )
         if( path[i][k] + path[k][j] < path[i][j] )
           path[i][j] = path[i][k] + path[k][j] ;

       cout << "Yes" << endl ;
       FOR1( i, k ) { FOR1( j, k ){ cout << (path[i][j] == INF?-1:path[i][j]) << " " ; } cout << endl ; }
}


#include <iostream>
#include <fstream>
#include <iomanip>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <bitset>
#include <set>
#include <map>
#include <vector>
#include <string>
#include <cstring>
#include <queue>
#include <math.h>
using namespace std;

#define FOR0(i,n) for( i = 0 ; i < n ; ++i )
#define FOR1(i,n) for( i = 1 ; i <= n ; ++i )
#define sys_p system( "pause" )
#define pb push_back
#define mp make_pair
#define FI first
#define SE second

typedef long long LL ;

const int INF = (int)1e9 ;
const LL MOD = (LL)1e9 + 7 ;

LL par[200000], rank[200000] ;

void make_set( LL v )
{
     par[v] = v ;
     rank[v] = 0 ;
}

LL find_set( LL v )
{
     if( v == par[v] ) return v ;
     return par[v] = find_set( par[v] ) ;
}

void union_sets( int a, int b )
{
     a = find_set(a) ; b = find_set(b) ;
     if( a != b )
     {
         if( rank[a] < rank[b] )
           swap(a,b) ;
         par[b] = a ;
         if( rank[a] == rank[b] )
           ++rank[a] ;
     }
}

LL n, m, k, cc[600], where[200000], a[200000], b[200000], c[200000], numset[200000], i, j, last, x, y ;
map < pair < LL, LL >, LL > path ;

main()
{
       cin >> n >> m >> k ;

       FOR1( i, n ) make_set(i) ;

       last = 0 ; FOR1( i, k )
       {
             cin >> cc[i] ;
             for( j = last+1 ; j <= last+cc[i] ; ++j )
               where[j] = i ;
             last += cc[i] ;
       }

       FOR1( i, m )
       {
             cin >> a[i] >> b[i] >> c[i] ;
             if( !c[i] && where[a[i]] == where[b[i]] ) union_sets( a[i], b[i] ) ;
       }

       last = 0 ; FOR1( i, k )
       {
             for( j = last+2 ; j <= last+cc[i] ; ++j )
               if( find_set( last+1 ) != find_set( j ) )
               {
                   cout << "No" << endl ;
                   return 0 ;
               }
             last += cc[i] ;
       }

       last = 0 ; FOR1( i, k )
       {
             numset[i] = find_set(last+1) ;
             last += cc[i] ;
       }

       FOR1( i, k ) FOR1( j, k ) { x = numset[i] ; y = numset[j] ; path[mp(x,y)] = INF ; if( x == y ) path[mp(x,y)] = 0 ; }

       FOR1( i, m )
       {
             a[i] = find_set(a[i]) ; b[i] = find_set(b[i]) ;
             path[mp(a[i],b[i])] = min( path[mp(a[i],b[i])], c[i] ) ;
             path[mp(b[i],a[i])] = min( path[mp(b[i],a[i])], c[i] ) ;
       }

       cout << "Yes" << endl ;
       FOR1( i, k ) { FOR1( j, k ){ x = numset[i] ; y = numset[j] ; cout << (path[mp(x,y)] == INF?-1:path[mp(x,y)]) << " " ; } cout << endl ; }
}


#include <iostream>
#include <fstream>
#include <iomanip>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <bitset>
#include <set>
#include <map>
#include <vector>
#include <string>
#include <cstring>
#include <queue>
#include <math.h>
using namespace std;

#define FOR0(i,n) for( i = 0 ; i < n ; ++i )
#define FOR1(i,n) for( i = 1 ; i <= n ; ++i )
#define sys_p system( "pause" )
#define pb push_back
#define mp make_pair
#define FI first
#define SE second

typedef long long LL ;

const int INF = (int)1e9 ;
const LL MOD = (LL)1e9 + 7 ;

int par[200000], rank[200000] ;

void make_set( LL v )
{
     par[v] = v ;
     rank[v] = 0 ;
}

LL find_set( LL v )
{
     if( v == par[v] ) return v ;
     return par[v] = find_set( par[v] ) ;
}

void union_sets( int a, int b )
{
     a = find_set(a) ; b = find_set(b) ;
     if( a != b )
     {
         if( rank[a] < rank[b] )
           swap(a,b) ;
         par[b] = a ;
         if( rank[a] == rank[b] )
           ++rank[a] ;
     }
}

int n, m, k, cc[600], where[200000], a[200000], b[200000], c[200000], numset[200000], path[600][600], i, j, l, last, x, y ;

main()
{
       cin >> n >> m >> k ;

       FOR1( i, n ) make_set(i) ;

       last = 0 ; FOR1( i, k )
       {
             cin >> cc[i] ;
             for( j = last+1 ; j <= last+cc[i] ; ++j )
               where[j] = i ;
             last += cc[i] ;
       }

       FOR1( i, m )
       {
             cin >> a[i] >> b[i] >> c[i] ;
             if( !c[i] ) union_sets( a[i], b[i] ) ;
       }

       last = 0 ; FOR1( i, k )
       {
             for( j = last+2 ; j <= last+cc[i] ; ++j )
               if( find_set( last+1 ) != find_set( j ) )
               {
                   cout << "No" << endl ;
                   return 0 ;
               }
             last += cc[i] ;
       }

       last = 0 ; FOR1( i, k )
       {
             for( j = last+1 ; j <= last+cc[i] ; ++j )
               numset[j] = i ;
             last += cc[i] ;
       }

       FOR1( i, k ) FOR1( j, k ) path[i][j] = INF, path[j][j] = 0 ;

       FOR1( i, m )
       {
             x = numset[a[i]] ; y = numset[b[i]] ;
             path[x][y] = min( path[x][y], c[i] ) ;
             path[y][x] = min( path[y][x], c[i] ) ;
       }

       FOR1( l, k ) FOR1( i, k ) FOR1( j, k )
         path[i][j] = min( path[i][j], path[i][l] + path[l][j] ) ;

       cout << "Yes" << endl ;
       FOR1( i, k ) { FOR1( j, k ){ cout << (path[i][j] == INF?-1:path[i][j]) << " " ; } cout << endl ; }
}


#include <iostream>
#include <fstream>
#include <iomanip>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <bitset>
#include <set>
#include <map>
#include <vector>
#include <string>
#include <cstring>
#include <queue>
#include <math.h>
using namespace std;

#define FOR0(i,n) for( i = 0 ; i < n ; ++i )
#define FOR1(i,n) for( i = 1 ; i <= n ; ++i )
#define sys_p system( "pause" )
#define pb push_back
#define mp make_pair
#define FI first
#define SE second

typedef long long LL ;

const int INF = (int)1e9 ;
const LL MOD = (LL)1e9 + 7 ;

LL par[200000], rank[200000] ;

void make_set( LL v )
{
     par[v] = v ;
     rank[v] = 0 ;
}

LL find_set( LL v )
{
     if( v == par[v] ) return v ;
     return par[v] = find_set( par[v] ) ;
}

void union_sets( int a, int b )
{
     a = find_set(a) ; b = find_set(b) ;
     if( a != b )
     {
         if( rank[a] < rank[b] )
           swap(a,b) ;
         par[b] = a ;
         if( rank[a] == rank[b] )
           ++rank[a] ;
     }
}

LL n, m, k, cc[600], where[200000], a[200000], b[200000], c[200000], numset[200000], i, j, l, last, x, y ;
map < pair < LL, LL >, LL > path ;

main()
{
       cin >> n >> m >> k ;

       FOR1( i, n ) make_set(i) ;

       last = 0 ; FOR1( i, k )
       {
             cin >> cc[i] ;
             for( j = last+1 ; j <= last+cc[i] ; ++j )
               where[j] = i ;
             last += cc[i] ;
       }

       FOR1( i, m )
       {
             cin >> a[i] >> b[i] >> c[i] ;
             if( !c[i] && where[a[i]] == where[b[i]] ) union_sets( a[i], b[i] ) ;
       }

       last = 0 ; FOR1( i, k )
       {
             for( j = last+2 ; j <= last+cc[i] ; ++j )
               if( find_set( last+1 ) != find_set( j ) )
               {
                   cout << "No" << endl ;
                   return 0 ;
               }
             last += cc[i] ;
       }

       last = 0 ; FOR1( i, k )
       {
             numset[i] = find_set(last+1) ;
             last += cc[i] ;
       }

       FOR1( i, k ) FOR1( j, k ) { x = numset[i] ; y = numset[j] ; path[mp(x,y)] = INF ; if( x == y ) path[mp(x,y)] = 0 ; }

       LL A, B, C ;

       FOR1( l, k )
       {
             B = numset[l] ;
             FOR1( i, k ) FOR1( j, k )
             {
                   A = numset[i] ; C = numset[j] ;
                   path[ mp(A,C) ] = min( path[ mp(A,C) ], path[ mp(A,B) ] + path[ mp(B,C) ] ) ;
             }
       }

       FOR1( i, m )
       {
             a[i] = find_set(a[i]) ; b[i] = find_set(b[i]) ;
             path[mp(a[i],b[i])] = min( path[mp(a[i],b[i])], c[i] ) ;
             path[mp(b[i],a[i])] = min( path[mp(b[i],a[i])], c[i] ) ;
       }

       cout << "Yes" << endl ;
       FOR1( i, k ) { FOR1( j, k ){ x = numset[i] ; y = numset[j] ; cout << (path[mp(x,y)] == INF?-1:path[mp(x,y)]) << " " ; } cout << endl ; }
}


#include <iostream>
#include <fstream>
#include <iomanip>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <bitset>
#include <set>
#include <map>
#include <vector>
#include <string>
#include <cstring>
#include <queue>
#include <math.h>
using namespace std;

#define FOR0(i,n) for( i = 0 ; i < n ; ++i )
#define FOR1(i,n) for( i = 1 ; i <= n ; ++i )
#define sys_p system( "pause" )
#define pb push_back
#define mp make_pair
#define FI first
#define SE second

typedef long long LL ;

const int INF = (int)1e9 ;
const LL MOD = (LL)1e9 + 7 ;

int par[200000], rank[200000] ;

void make_set( LL v )
{
     par[v] = v ;
     rank[v] = 0 ;
}

LL find_set( LL v )
{
     if( v == par[v] ) return v ;
     return par[v] = find_set( par[v] ) ;
}

void union_sets( int a, int b )
{
     a = find_set(a) ; b = find_set(b) ;
     if( a != b )
     {
         if( rank[a] < rank[b] )
           swap(a,b) ;
         par[b] = a ;
         if( rank[a] == rank[b] )
           ++rank[a] ;
     }
}

int n, m, k, cc[600], where[200000], a[200000], b[200000], c[200000], numset[200000], path[600][600], i, j, l, last, x, y ;

main()
{
       cin >> n >> m >> k ;

       FOR1( i, n ) make_set(i) ;

       last = 0 ; FOR1( i, k )
       {
             cin >> cc[i] ;
             for( j = last+1 ; j <= last+cc[i] ; ++j )
               where[j] = i ;
             last += cc[i] ;
       }

       FOR1( i, m )
       {
             cin >> a[i] >> b[i] >> c[i] ;
             if( !c[i] && where[a[i]] == where[b[i]] ) union_sets( a[i], b[i] ) ;
       }

       last = 0 ; FOR1( i, k )
       {
             for( j = last+2 ; j <= last+cc[i] ; ++j )
               if( find_set( last+1 ) != find_set( j ) )
               {
                   cout << "No" << endl ;
                   return 0 ;
               }
             last += cc[i] ;
       }

       last = 0 ; FOR1( i, k )
       {
             for( j = last+1 ; j <= last+cc[i] ; ++j )
               numset[j] = i ;
             last += cc[i] ;
       }

       FOR1( i, k ) FOR1( j, k ) path[i][j] = INF, path[j][j] = 0 ;

       FOR1( i, m )
       {
             x = numset[a[i]] ; y = numset[b[i]] ;
             path[x][y] = min( path[x][y], c[i] ) ;
             path[y][x] = min( path[y][x], c[i] ) ;
       }

       FOR1( l, k ) FOR1( i, k ) FOR1( j, k )
         path[i][j] = min( path[i][j], path[i][l] + path[l][j] ) ;

       cout << "Yes" << endl ;
       FOR1( i, k ) { FOR1( j, k ){ cout << (path[i][j] == INF?-1:path[i][j]) << " " ; } cout << endl ; }
}


#include <iostream>
#include <fstream>
#include <iomanip>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <bitset>
#include <set>
#include <map>
#include <vector>
#include <string>
#include <cstring>
#include <queue>
#include <math.h>
using namespace std;

#define FOR0(i,n) for( i = 0 ; i < n ; ++i )
#define FOR1(i,n) for( i = 1 ; i <= n ; ++i )
#define sys_p system( "pause" )
#define pb push_back
#define mp make_pair
#define FI first
#define SE second

typedef long long LL ;

const int INF = (int)1e9 ;
const LL MOD = (LL)1e9 + 7 ;

LL par[200000], rank[200000] ;

void make_set( LL v )
{
     par[v] = v ;
     rank[v] = 0 ;
}

LL find_set( LL v )
{
     if( v == par[v] ) return v ;
     return par[v] = find_set( par[v] ) ;
}

void union_sets( int a, int b )
{
     a = find_set(a) ; b = find_set(b) ;
     if( a != b )
     {
         if( rank[a] < rank[b] )
           swap(a,b) ;
         par[b] = a ;
         if( rank[a] == rank[b] )
           ++rank[a] ;
     }
}

LL n, m, k, cc[600], where[200000], a[200000], b[200000], c[200000], numset[200000], i, j, l, last, x, y ;
map < pair < LL, LL >, LL > path ;

main()
{
       cin >> n >> m >> k ;

       FOR1( i, n ) make_set(i) ;

       last = 0 ; FOR1( i, k )
       {
             cin >> cc[i] ;
             for( j = last+1 ; j <= last+cc[i] ; ++j )
               where[j] = i ;
             last += cc[i] ;
       }

       FOR1( i, m )
       {
             cin >> a[i] >> b[i] >> c[i] ;
             if( !c[i] && where[a[i]] == where[b[i]] ) union_sets( a[i], b[i] ) ;
       }

       last = 0 ; FOR1( i, k )
       {
             for( j = last+2 ; j <= last+cc[i] ; ++j )
               if( find_set( last+1 ) != find_set( j ) )
               {
                   cout << "No" << endl ;
                   return 0 ;
               }
             last += cc[i] ;
       }

       last = 0 ; FOR1( i, k )
       {
             numset[i] = find_set(last+1) ;
             last += cc[i] ;
       }

       FOR1( i, k ) FOR1( j, k ) { x = numset[i] ; y = numset[j] ; path[mp(x,y)] = INF ; if( x == y ) path[mp(x,y)] = 0 ; }

       FOR1( i, m )
       {
             a[i] = find_set(a[i]) ; b[i] = find_set(b[i]) ;
             path[mp(a[i],b[i])] = min( path[mp(a[i],b[i])], c[i] ) ;
             path[mp(b[i],a[i])] = min( path[mp(b[i],a[i])], c[i] ) ;
       }

       LL A, B, C ;

       FOR1( l, k )
       {
             B = numset[l] ;
             FOR1( i, k ) FOR1( j, k )
             {
                   A = numset[i] ; C = numset[j] ;
                   path[ mp(A,C) ] = min( path[ mp(A,C) ], path[ mp(A,B) ] + path[ mp(B,C) ] ) ;
             }
       }

       cout << "Yes" << endl ;
       FOR1( i, k ) { FOR1( j, k ){ x = numset[i] ; y = numset[j] ; cout << (path[mp(x,y)] == INF?-1:path[mp(x,y)]) << " " ; } cout << endl ; }
}


#define _CRT_SECURE_NO_DEPRECATE

#include <stdio.h>
#include <iostream>
#include <memory.h>
#include <assert.h>
#include <algorithm>
#include <functional>
#include <vector>
#include <string>
#include <map>
#include <set>
#include <deque>
#include <math.h>

#define fo(a,b,c) for( a = ( b ); a < ( c ); ++ a )
#define fr(a,b) fo( a, 0, ( b ) )
#define fi(a) fr( i, ( a ) )
#define fj(a) fr( j, ( a ) )
#define fk(a) fr( k, ( a ) )
#define mp make_pair
#define pb push_back
#define all(v) (v).begin( ), (v).end( )
#define _(a,b) memset( a, b, sizeof( a ) )
using namespace std;

void _ad(int &p){ static int i = 0; p = i++; }
#define fi123(x) for_each (all(x),_ad)
#define outv(x) copy(all(x), ostream_iterator<int>(cout," "))

typedef long long ll;
typedef vector<int> vi;
typedef vector<string> vs;
typedef pair<int,int> pii;
typedef map<string,int> msi;

template<class T> void sort_v (vector<T> &v){ sort (v.begin(),v.end());}
template<class T> void print_v (vector<T> &v,const char* c = " "){	copy(v.begin(),v.end(),ostream_iterator<T>(cout,c)); }
template<class T> void each (vector<T> &v,void (*f)(T&)){ for_each (v.begin(),v.end(),f); }
template<class T> void scanf_v (vector<T> &v,int cnt) { v.resize(cnt);	for (int i = 0; i < cnt; i++) {
		getchar(); 	T a; scanf ("%d",&a); 	v[i] = a; }}

int n, m;
int type[100001] = {0};
int num[100001] = {0};

vector<vector<int> > stm;

int find_set (int v,int id) {
	if (v == stm[id][v])
		return v;
	return stm[id][v] = find_set (stm[id][v],id);
}
void union_sets (int a, int b,int id) {
	a = find_set (a,id);
	b = find_set (b,id);
	if (a != b) {
		if (rand() & 1)
			swap (a, b);
		stm[id][b] = a;
	}
}

int main( )
{
#ifndef ONLINE_JUDGE
	freopen("input.txt", "rt", stdin);
	//freopen("output.txt", "wt", stdout);
#endif
	cin >> n >> m;
	int k;
	cin >> k;
	int i;
	vector<int> c(k);
	int it = 0;
	stm.resize(k);
	fi(k)
	{
		cin >> c[i];
		stm[i].resize(c[i]);
		for (int j = it; j < it + c[i]; j++)
		{
			type[j] = i;
			stm[i][j - it] = j - it;
			num[j] = j - it;
		}
		it += c[i];
	}

	int v,u,x;
	vector<vector<int> > g(k,vector<int>(k,INT_MAX));
	fi(m)
	{
		scanf ("%d%d%d",&v,&u,&x);
		--v;
		--u;
		int id = type[v];
		int id1 = type[u];
		if (id != id1)
		{
			g[id][id1] = x;
			g[id1][id] = x;
		}
		else if(x == 0)
		{
			union_sets (num[v],num[u],id);
		}
	}
	bool ft = true;
	for (int i = 0; i < k; i++)
	{
		int pre = -1;
		for (int j = 0; j < c[i]; j++)
		{
			int vl = find_set (j,i);
			if (pre == -1)
				pre = vl;
			else if (pre != vl)
			{
				ft = false;
				break;
			}
		}

	}
	if (!ft)
	{
		cout << "No";
		return 0;
	}

	for (int k1=0; k1<k; ++k1)
                 g[k1][k1] = 0 ;
	for (int k1=0; k1<k; ++k1)
		for (int i=0; i<k; ++i)
			for (int j=0; j<k; ++j)
				if (g[i][k1] < INT_MAX && g[k1][j] < INT_MAX)
					g[i][j] = min (g[i][j], g[i][k1] + g[k1][j]);

	cout << "Yes" << endl;
	for (int i = 0; i < k; i++)
	{
		for (int j = 0; j < k; j++)
		{
			if (i == j)
				printf ("0 ");
			else
				printf ("%d ",(g[i][j] == INT_MAX ? -1 : g[i][j]));
		}
		printf ("\n");
	}

	return 0;
}


#include <iostream>
#include <fstream>
#include <iomanip>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <bitset>
#include <set>
#include <map>
#include <vector>
#include <string>
#include <cstring>
#include <queue>
#include <math.h>
using namespace std;

#define FOR0(i,n) for( i = 0 ; i < n ; ++i )
#define FOR1(i,n) for( i = 1 ; i <= n ; ++i )
#define sys_p system( "pause" )
#define pb push_back
#define mp make_pair
#define FI first
#define SE second

typedef long long LL ;

const int INF = (int)1e9 ;
const LL MOD = (LL)1e9 + 7 ;

int par[200000], rank[200000] ;

void make_set( LL v )
{
     par[v] = v ;
     rank[v] = 0 ;
}

LL find_set( LL v )
{
     if( v == par[v] ) return v ;
     return par[v] = find_set( par[v] ) ;
}

void union_sets( int a, int b )
{
     a = find_set(a) ; b = find_set(b) ;
     if( a != b )
     {
         if( rank[a] < rank[b] )
           swap(a,b) ;
         par[b] = a ;
         if( rank[a] == rank[b] )
           ++rank[a] ;
     }
}

int n, m, k, cc[600], where[200000], a[200000], b[200000], c[200000], numset[200000], path[600][600], i, j, l, last, x, y ;

main()
{
       cin >> n >> m >> k ;

       FOR1( i, n ) make_set(i) ;

       last = 0 ; FOR1( i, k )
       {
             cin >> cc[i] ;
             for( j = last+1 ; j <= last+cc[i] ; ++j )
               where[j] = i ;
             last += cc[i] ;
       }

       FOR1( i, m )
       {
             cin >> a[i] >> b[i] >> c[i] ;
             if( !c[i] && where[a[i]] == where[b[i]] ) union_sets( a[i], b[i] ) ;
       }

       last = 0 ; FOR1( i, k )
       {
             for( j = last+2 ; j <= last+cc[i] ; ++j )
               if( find_set( last+1 ) != find_set( j ) )
               {
                   cout << "No" << endl ;
                   return 0 ;
               }
             last += cc[i] ;
       }

       last = 0 ; FOR1( i, k )
       {
             for( j = last+1 ; j <= last+cc[i] ; ++j )
               numset[j] = i ;
             last += cc[i] ;
       }

       FOR1( i, k ) FOR1( j, k ) { x = numset[i] ; y = numset[j] ; path[x][y] = INF ; if( x == y ) path[x][y] = 0 ; }

       FOR1( i, m )
       {
             x = find_set(a[i]) ; y = find_set(b[i]) ;
             path[x][y] = min( path[x][y], c[i] ) ;
             path[y][x] = min(path[y][x], c[i] ) ;
       }

       FOR1( l, k ) FOR1( i, k ) FOR1( j, k )
         path[i][j] = min( path[i][j], path[i][k] + path[k][j] ) ;

       cout << "Yes" << endl ;
       FOR1( i, k ) { FOR1( j, k ){ x = numset[i] ; y = numset[j] ; cout << (path[x][y] == INF?-1:path[x][y]) << " " ; } cout << endl ; }
}


#include <iostream>
#include <fstream>
#include <iomanip>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <bitset>
#include <set>
#include <map>
#include <vector>
#include <string>
#include <cstring>
#include <queue>
#include <math.h>
using namespace std;

#define FOR0(i,n) for( i = 0 ; i < n ; ++i )
#define FOR1(i,n) for( i = 1 ; i <= n ; ++i )
#define sys_p system( "pause" )
#define pb push_back
#define mp make_pair
#define FI first
#define SE second

typedef long long LL ;

const LL INF = (LL)1e18 ;
const LL MOD = (LL)1e9 + 7 ;

int par[200000], rank[200000] ;

void make_set( int v )
{
     par[v] = v ;
     rank[v] = 0 ;
}

int find_set( int v )
{
     if( v == par[v] ) return v ;
     return par[v] = find_set( par[v] ) ;
}

void union_sets( int a, int b )
{
     a = find_set(a) ; b = find_set(b) ;
     if( a != b )
     {
         if( rank[a] < rank[b] )
           swap(a,b) ;
         par[b] = a ;
         if( rank[a] == rank[b] )
           ++rank[a] ;
     }
}

int n, m, k, cc[600], where[200000], a[200000], b[200000], c[200000], numset[200000], path[1000][1000], i, j, last, x, y ;

main()
{
       cin >> n >> m >> k ;

       FOR1( i, n ) make_set(i) ;

       last = 0 ; FOR1( i, k )
       {
             cin >> cc[i] ;
             for( j = last+1 ; j <= last+cc[i] ; ++j )
               where[j] = i ;
             last += cc[i] ;
       }

       FOR1( i, m )
       {
             cin >> a[i] >> b[i] >> c[i] ;
             if( !c[i] && where[a[i]] == where[b[i]] ) union_sets( a[i], b[i] ) ;
       }

       last = 0 ; FOR1( i, k )
       {
             for( j = last+2 ; j <= last+cc[i] ; ++j )
               if( find_set( last+1 ) != find_set( j ) )
               {
                   cout << "No" << endl ;
                   return 0 ;
               }
             last += cc[i] ;
       }

       last = 0 ; FOR1( i, k )
       {
             numset[i] = find_set(last+1) ;
             last += cc[i] ;
       }

       FOR0( i, 1000 ) FOR1( j, 1000 ) path[i][j] = (int)1e9, path[j][j] = 0 ;

       FOR1( i, m )
       {
             a[i] = find_set(a[i]) ; b[i] = find_set(b[i]) ;
             path[a[i]][b[i]] = min( path[a[i]][b[i]], c[i] ) ;
             path[b[i]][a[i]] = min( path[b[i]][a[i]], c[i] ) ;
       }

       cout << "Yes" << endl ;
       FOR1( i, k ) { FOR1( j, k ){ x = numset[i] ; y = numset[j] ; cout << (path[x][y] == (int)1e9?-1:path[x][y]) << " " ; } cout << endl ; }
}


#include <iostream>
#include <fstream>
#include <iomanip>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <bitset>
#include <set>
#include <map>
#include <vector>
#include <string>
#include <cstring>
#include <queue>
#include <math.h>
using namespace std;

#define FOR0(i,n) for( i = 0 ; i < n ; ++i )
#define FOR1(i,n) for( i = 1 ; i <= n ; ++i )
#define sys_p system( "pause" )
#define pb push_back
#define mp make_pair
#define FI first
#define SE second

typedef long long LL ;

const int INF = (int)1e9 ;
const LL MOD = (LL)1e9 + 7 ;

int par[200000], rank[200000] ;

void make_set( int v )
{
     par[v] = v ;
     rank[v] = 0 ;
}

int find_set( int v )
{
     if( v == par[v] ) return v ;
     return par[v] = find_set( par[v] ) ;
}

void union_sets( int a, int b )
{
     a = find_set(a) ; b = find_set(b) ;
     if( a != b )
     {
         if( rank[a] < rank[b] )
           swap(a,b) ;
         par[b] = a ;
         if( rank[a] == rank[b] )
           ++rank[a] ;
     }
}

int n, m, k, cc[600], where[200000], a[200000], b[200000], c[200000], numset[200000], i, j, last, x, y ;
map < pair < int, int >, int > path ;

main()
{
       cin >> n >> m >> k ;

       FOR1( i, n ) make_set(i) ;

       last = 0 ; FOR1( i, k )
       {
             cin >> cc[i] ;
             for( j = last+1 ; j <= last+cc[i] ; ++j )
               where[j] = i ;
             last += cc[i] ;
       }

       FOR1( i, m )
       {
             cin >> a[i] >> b[i] >> c[i] ;
             if( !c[i] && where[a[i]] == where[b[i]] ) union_sets( a[i], b[i] ) ;
       }

       last = 0 ; FOR1( i, k )
       {
             for( j = last+2 ; j <= last+cc[i] ; ++j )
               if( find_set( last+1 ) != find_set( j ) )
               {
                   cout << "No" << endl ;
                   return 0 ;
               }
             last += cc[i] ;
       }

       last = 0 ; FOR1( i, k )
       {
             numset[i] = find_set(last+1) ;
             last += cc[i] ;
       }

      FOR1( i, k ) FOR1( j, k ) { x = numset[i] ; y = numset[j] ; path[mp(x,y)] = INF ; if( x == y ) path[mp(x,y)]  = 0 ; }

       FOR1( i, m )
       {
             a[i] = find_set(a[i]) ; b[i] = find_set(b[i]) ;
             path[mp(a[i],b[i])] = min( path[mp(a[i],b[i])], c[i] ) ;
             path[mp(b[i],a[i])] = min( path[mp(b[i],a[i])], c[i] ) ;
       }

       cout << "Yes" << endl ;
       FOR1( i, k ) { FOR1( j, k ){ x = numset[i] ; y = numset[j] ; cout << (path[mp(x,y)] == INF?-1:path[mp(x,y)]) << " " ; } cout << endl ; }
}


/*
PROG:   [p]
ID  :   hewifi
LANG:   C++
*/
#include <cstdio>
#include <cstring>
#include <queue>
#include <algorithm>
const int Inf = 1e9;
const int N = 100000 + 10;
const int M = 500 + 10;
int n, m, K;
int fa[N], c[M];
int u[N], v[N], len[N];

int Find(int x) {
    if (x != fa[x])
        x = Find(fa[x]);
    return fa[x];
}
void Union(int x, int y) {
    x = Find(x);
    y = Find(y);
    fa[x] = y;
}

struct Edge {
    int u, v, nex;
    int len;
    Edge() {
    }
    Edge(int _u, int _v, int _len, int _nex) {
        u = _u, v = _v, len = _len, nex = _nex;
    }
};
struct node {
    int d, u;
    node() {
    }
    node(int _d, int _u) {
        d = _d, u = _u;
    }
    friend bool operator <(const node &a, const node &b) {
        return a.d > b.d;
    }
};
const int E = N + N;
std::priority_queue<node> Q;
Edge eg[E];
int dis[M];
int g[M], idx;
bool vis[M];
void addedge(int u, int v, int len) {
    eg[idx] = Edge(u, v, len, g[u]);
    g[u] = idx++;
}
void dijkstra(int st) {
    for (int i = 1; i <= K; ++i)
        dis[i] = Inf;
    memset(vis, 0, sizeof(vis));
    dis[st] = 0;
    while (!Q.empty())
        Q.pop();
    Q.push(node(0, st));
    while (!Q.empty()) {
        node u = Q.top();
        Q.pop();
        int x = u.u;
        if (vis[x])
            continue;
        vis[x] = true;
        for (int i = g[x]; ~i; i = eg[i].nex)
            if (eg[i].len + dis[x] < dis[eg[i].v]) {
                dis[eg[i].v] = dis[x] + eg[i].len;
                Q.push(node(dis[eg[i].v], eg[i].v));
            }
    }
}
int main() {
    //freopen("[p].in", "r", stdin);
    //freopen("[p].out", "w", stdout);
    scanf("%d%d%d", &n, &m, &K);
    for (int i = 1; i <= n; ++i)
        fa[i] = i;

    c[0] = 0;
    for (int i = 1; i <= K; ++i) {
        scanf("%d", &c[i]);
        c[i] += c[i - 1];
    }

    for (int i = 0; i < m; ++i) {
        scanf("%d%d%d", &u[i], &v[i], &len[i]);
        Union(u[i], v[i]);
    }
    bool f, ans = true;
    int id;
    for (int i = 1; i <= K; ++i) {
        id = Find(c[i - 1] + 1);
        f = true;
        for (int j = 1; j <= c[i] - c[i - 1]; ++j)
            if (Find(c[i - 1] + j) != id) {
                f = false;
                break;
            }
        if (!f) {
            ans = false;
            break;
        }
    }
    if (!ans)
        puts("No");
    else {
        for (int i = 1; i <= K; ++i) {
            g[i] = -1;
            for (int j = 1; j <= c[i] - c[i -1]; ++j)
                fa[c[i - 1] + j] = i;
        }
        idx = 0;
        for (int i = 0; i < m; ++i) {
            u[i] = fa[u[i]];
            v[i] = fa[v[i]];
            addedge(u[i], v[i], len[i]);
            addedge(v[i], u[i], len[i]);
        }
        puts("Yes");
        for (int i = 1; i <= K; ++i) {
            dijkstra(i);
            for (int j = 1; j <= K; ++j) {
                if (j > 1)
                    putchar(' ');
                if (dis[j] == Inf)
                    printf("-1");
                else
                    printf("%d", dis[j]);
            }
            puts("");
        }
    }
    return 0;
}


/*
PROG:   [p]
ID  :   hewifi
LANG:   C++
*/
#include <cstdio>
#include <cstring>
#include <queue>
#include <algorithm>
const int Inf = 1e9;
const int N = 100000 + 10;
const int M = 500 + 10;
int n, m, K;
int fa[N], c[M], w[M][M], mon[N];
int u[N], v[N], len[N];

struct Edge {
    int u, v, nex;
    int len;
    Edge() {
    }
    Edge(int _u, int _v, int _len, int _nex) {
        u = _u, v = _v, len = _len, nex = _nex;
    }
};
struct node {
    int d, u;
    node() {
    }
    node(int _d, int _u) {
        d = _d, u = _u;
    }
    friend bool operator <(const node &a, const node &b) {
        return a.d > b.d;
    }
};
const int E = N + N;
std::priority_queue<node> Q;
Edge eg[E];
int dis[M];
int g[M], idx;
bool vis[M];
void addedge(int u, int v, int len) {
    eg[idx] = Edge(u, v, len, g[u]);
    g[u] = idx++;
}
int queue[M], head, tail;
void spfa(int st) {
    for (int i = 1; i <= K; ++i) {
        vis[i] = false;
        dis[i] = Inf;
    }
    dis[st] = 0;
    head = tail = 0;
    queue[tail ++] = st;
    int x;
    while (tail != head) {
        x = queue[head ++];
        if (head == M)
            head = 0;
        vis[x] = false;
        for (int i = g[x]; ~i; i = eg[i].nex)
            if (eg[i].len + dis[x] < dis[eg[i].v]) {
                dis[eg[i].v] = dis[x] + eg[i].len;
                if (!vis[eg[i].v]) {
                    if (head != tail && dis[queue[head]] > dis[eg[i].v]) {
                        if (-- head < 0)
                            head = M - 1;
                        queue[head] = eg[i].v;
                    } else {
                        queue[tail ++] = eg[i].v;
                        if (tail == M)
                            tail = 0;
                    }
                }
            }
    }
}
void dijkstra(int st) {
    for (int i = 1; i <= K; ++i) {
        vis[i] = false;
        dis[i] = Inf;
    }
    dis[st] = 0;
    Q.push(node(0, st));
    int x;
    while (!Q.empty()) {
        node u = Q.top();
        Q.pop();
        x = u.u;
        if (vis[x])
            continue;
        vis[x] = true;
        for (int i = g[x]; ~i; i = eg[i].nex)
            if (eg[i].len + dis[x] < dis[eg[i].v]) {
                dis[eg[i].v] = dis[x] + eg[i].len;
                Q.push(node(dis[eg[i].v], eg[i].v));
            }
    }
}
int main() {
    //freopen("[p].in", "r", stdin);
    //freopen("[p].out", "w", stdout);
    scanf("%d%d%d", &n, &m, &K);
    for (int i = 1; i <= n; ++i)
        fa[i] = i;
    for (int i = 1; i <= K; ++i) {
            for (int j = 1; j <= c[i] - c[i -1]; ++j)
                mon[c[i - 1] + j] = i;
        }
    c[0] = 0;
    for (int i = 1; i <= K; ++i) {
        scanf("%d", &c[i]);
        c[i] += c[i - 1];
    }

    for (int i = 0; i < m; ++i) {
        scanf("%d%d%d", &u[i], &v[i], &len[i]);
        if (mon[u[i]] != mon[v[i]])
            continue;
        fa[u[i]] = fa[v[i]] = mon[v[i]];
    }
    bool f, ans = true;
    int id;
    for (int i = 1; i <= K; ++i) {
        id = fa[c[i - 1] + 1];
        f = true;
        for (int j = 2; j <= c[i] - c[i - 1]; ++j)
            if (fa[c[i - 1] + j] != id) {
                f = false;
                break;
            }
        if (!f) {
            ans = false;
            break;
        }
    }
    if (!ans)
        puts("No");
    else {
        for (int i = 1; i <= K; ++i) {
            g[i] = -1;
            for (int j = 1; j <= c[i] - c[i -1]; ++j)
                fa[c[i - 1] + j] = i;
        }
        idx = 0;
        for (int i = 1; i <= K; ++i) {
            for (int j = 1; j <= K; ++j)
                w[i][j] = Inf;
            w[i][i] = 0;
        }
        for (int i = 0; i < m; ++i) {
            u[i] = fa[u[i]];
            v[i] = fa[v[i]];
            if (u[i] == v[i]) continue;
            if (w[u[i]][v[i]] > len[i])
                w[u[i]][v[i]] = w[v[i]][u[i]] = len[i];
        }
        for (int i = 1; i <= K; ++i)
            for (int j = 1; j <= K; ++j)
                if (w[i][j] != Inf)
                    addedge(i, j, w[i][j]);
        puts("Yes");
        for (int i = 1; i <= K; ++i) {
            dijkstra(i);
            for (int j = 1; j <= K; ++j) {
                if (j > 1)
                    putchar(' ');
                if (dis[j] == Inf)
                    printf("-1");
                else
                    printf("%d", dis[j]);
            }
            puts("");
        }
    }
    return 0;
}


/*
PROG:   [p]
ID  :   hewifi
LANG:   C++
*/
#include <cstdio>
#include <cstring>
#include <queue>
#include <algorithm>
const int Inf = 1e9;
const int N = 100000 + 10;
const int M = 500 + 10;
int n, m, K;
int fa[N], c[M], w[M][M];
int u[N], v[N], len[N];

int Find(int x) {
    if (x != fa[x])
        x = Find(fa[x]);
    return fa[x];
}
void Union(int x, int y) {
    x = Find(x);
    y = Find(y);
    if (x == y) return ;
    fa[x] = y;
}

struct Edge {
    int u, v, nex;
    int len;
    Edge() {
    }
    Edge(int _u, int _v, int _len, int _nex) {
        u = _u, v = _v, len = _len, nex = _nex;
    }
};
struct node {
    int d, u;
    node() {
    }
    node(int _d, int _u) {
        d = _d, u = _u;
    }
    friend bool operator <(const node &a, const node &b) {
        return a.d > b.d;
    }
};
const int E = N + N;
std::priority_queue<node> Q;
Edge eg[E];
int dis[M];
int g[M], idx;
bool vis[M];
void addedge(int u, int v, int len) {
    eg[idx] = Edge(u, v, len, g[u]);
    g[u] = idx++;
}
int queue[M], head, tail;
void spfa(int st) {
    for (int i = 1; i <= K; ++i) {
        vis[i] = false;
        dis[i] = Inf;
    }
    dis[st] = 0;
    head = tail = 0;
    queue[tail ++] = st;
    int x;
    while (tail != head) {
        x = queue[head ++];
        if (head == M)
            head = 0;
        vis[x] = false;
        for (int i = g[x]; ~i; i = eg[i].nex)
            if (eg[i].len + dis[x] < dis[eg[i].v]) {
                dis[eg[i].v] = dis[x] + eg[i].len;
                if (!vis[eg[i].v]) {
                    if (head != tail && dis[queue[head]] > dis[eg[i].v]) {
                        if (-- head < 0)
                            head = M - 1;
                        queue[head] = eg[i].v;
                    } else {
                        queue[tail ++] = eg[i].v;
                        if (tail == M)
                            tail = 0;
                    }
                }
            }
    }
}
void dijkstra(int st) {
    for (int i = 1; i <= K; ++i) {
        vis[i] = false;
        dis[i] = Inf;
    }
    dis[st] = 0;
    Q.push(node(0, st));
    int x;
    while (!Q.empty()) {
        node u = Q.top();
        Q.pop();
        x = u.u;
        if (vis[x])
            continue;
        vis[x] = true;
        for (int i = g[x]; ~i; i = eg[i].nex)
            if (eg[i].len + dis[x] < dis[eg[i].v]) {
                dis[eg[i].v] = dis[x] + eg[i].len;
                Q.push(node(dis[eg[i].v], eg[i].v));
            }
    }
}
int main() {
    //freopen("[p].in", "r", stdin);
    //freopen("[p].out", "w", stdout);
    scanf("%d%d%d", &n, &m, &K);
    for (int i = 1; i <= n; ++i)
        fa[i] = i;

    c[0] = 0;
    for (int i = 1; i <= K; ++i) {
        scanf("%d", &c[i]);
        c[i] += c[i - 1];
    }

    for (int i = 0; i < m; ++i) {
        scanf("%d%d%d", &u[i], &v[i], &len[i]);
        Union(u[i], v[i]);
    }
    bool f, ans = true;
    int id;
    for (int i = 1; i <= K; ++i) {
        id = Find(c[i - 1] + 1);
        f = true;
        for (int j = 2; j <= c[i] - c[i - 1]; ++j)
            if (Find(c[i - 1] + j) != id) {
                f = false;
                break;
            }
        if (!f) {
            ans = false;
            break;
        }
    }
    if (!ans)
        puts("No");
    else {
        for (int i = 1; i <= K; ++i) {
            g[i] = -1;
            for (int j = 1; j <= c[i] - c[i -1]; ++j)
                fa[c[i - 1] + j] = i;
        }
        idx = 0;
        for (int i = 1; i <= K; ++i) {
            for (int j = 1; j <= K; ++j)
                w[i][j] = Inf;
            w[i][i] = 0;
        }
        for (int i = 0; i < m; ++i) {
            u[i] = fa[u[i]];
            v[i] = fa[v[i]];
            if (u[i] == v[i]) continue;
            if (w[u[i]][v[i]] > len[i])
                w[u[i]][v[i]] = w[v[i]][u[i]] = len[i];
        }
        for (int i = 1; i <= K; ++i)
            for (int j = 1; j <= K; ++j)
                if (w[i][j] != Inf)
                    addedge(i, j, w[i][j]);
        puts("Yes");
        for (int i = 1; i <= K; ++i) {
            spfa(i);
            for (int j = 1; j <= K; ++j) {
                if (j > 1)
                    putchar(' ');
                if (dis[j] == Inf)
                    printf("-1");
                else
                    printf("%d", dis[j]);
            }
            puts("");
        }
    }
    return 0;
}


/*
PROG:   [p]
ID  :   hewifi
LANG:   C++
*/
#include <cstdio>
#include <cstring>
#include <queue>
#include <algorithm>
const int Inf = 1e9;
const int N = 100000 + 10;
const int M = 500 + 10;
int n, m, K;
int fa[N], c[M], w[M][M];
int u[N], v[N], len[N];
int Find(int x) {
	if (x != fa[x])
		x = Find(fa[x]);
	return fa[x];
}
void Union(int x, int y) {
	x = Find(x);
	y = Find(y);
	fa[x] = y;
}
struct Edge {
    int u, v, nex;
    int len;
    Edge() {
    }
    Edge(int _u, int _v, int _len, int _nex) {
        u = _u, v = _v, len = _len, nex = _nex;
    }
};
struct node {
    int d, u;
    node() {
    }
    node(int _d, int _u) {
        d = _d, u = _u;
    }
    friend bool operator <(const node &a, const node &b) {
        return a.d > b.d;
    }
};
const int E = N + N;
std::priority_queue<node> Q;
Edge eg[E];
int dis[M];
int g[M], idx;
bool vis[M];
void addedge(int u, int v, int len) {
    eg[idx] = Edge(u, v, len, g[u]);
    g[u] = idx++;
}
int queue[M], head, tail;
void spfa(int st) {
    for (int i = 1; i <= K; ++i) {
        vis[i] = false;
        dis[i] = Inf;
    }
    dis[st] = 0;
    head = tail = 0;
    queue[tail ++] = st;
    int x;
    while (tail != head) {
        x = queue[head ++];
        if (head == M)
            head = 0;
        vis[x] = false;
        for (int i = g[x]; ~i; i = eg[i].nex)
            if (eg[i].len + dis[x] < dis[eg[i].v]) {
                dis[eg[i].v] = dis[x] + eg[i].len;
                if (!vis[eg[i].v]) {
                    if (head != tail && dis[queue[head]] > dis[eg[i].v]) {
                        if (-- head < 0)
                            head = M - 1;
                        queue[head] = eg[i].v;
                    } else {
                        queue[tail ++] = eg[i].v;
                        if (tail == M)
                            tail = 0;
                    }
                }
            }
    }
}
void dijkstra(int st) {
    for (int i = 1; i <= K; ++i) {
        vis[i] = false;
        dis[i] = Inf;
    }
    dis[st] = 0;
    Q.push(node(0, st));
    int x;
    while (!Q.empty()) {
        node u = Q.top();
        Q.pop();
        x = u.u;
        if (vis[x])
            continue;
        vis[x] = true;
        for (int i = g[x]; ~i; i = eg[i].nex)
            if (eg[i].len + dis[x] < dis[eg[i].v]) {
                dis[eg[i].v] = dis[x] + eg[i].len;
                Q.push(node(dis[eg[i].v], eg[i].v));
            }
    }
}
int main() {
    //freopen("[p].in", "r", stdin);
    //freopen("[p].out", "w", stdout);
    scanf("%d%d%d", &n, &m, &K);
    for (int i = 1; i <= n; ++i)
        fa[i] = i;
    c[0] = 0;
    for (int i = 1; i <= K; ++i) {
        scanf("%d", &c[i]);
        c[i] += c[i - 1];
    }

    for (int i = 0; i < m; ++i) {
        scanf("%d%d%d", &u[i], &v[i], &len[i]);
        if (0 == len[i])
        	Union(u[i], v[i]);
    }
    bool f, ans = true;
    int id;
    for (int i = 1; i <= K; ++i) {
        id = Find(c[i - 1] + 1);
        f = true;
        for (int j = 2; j <= c[i] - c[i - 1]; ++j)
            if (Find(c[i - 1] + j) != id) {
                f = false;
                break;
            }
        if (!f) {
            ans = false;
            break;
        }
    }
    if (!ans)
        puts("No");
    else {
        for (int i = 1; i <= K; ++i) {
            g[i] = -1;
            for (int j = 1; j <= c[i] - c[i -1]; ++j)
                fa[c[i - 1] + j] = i;
        }
        idx = 0;
        for (int i = 1; i <= K; ++i) {
            for (int j = 1; j <= K; ++j)
                w[i][j] = Inf;
            w[i][i] = 0;
        }
        for (int i = 0; i < m; ++i) {
            u[i] = fa[u[i]];
            v[i] = fa[v[i]];
            if (u[i] == v[i]) continue;
            if (w[u[i]][v[i]] > len[i])
                w[u[i]][v[i]] = w[v[i]][u[i]] = len[i];
        }
        for (int i = 1; i <= K; ++i)
            for (int j = 1; j <= K; ++j)
                if (w[i][j] != Inf)
                    addedge(i, j, w[i][j]);
        puts("Yes");
        for (int i = 1; i <= K; ++i) {
            dijkstra(i);
            for (int j = 1; j <= K; ++j) {
                if (j > 1)
                    putchar(' ');
                if (dis[j] == Inf)
                    printf("-1");
                else
                    printf("%d", dis[j]);
            }
            puts("");
        }
    }
    return 0;
}


/*
PROG:   [p]
ID  :   hewifi
LANG:   C++
*/
#include <cstdio>
#include <cstring>
#include <queue>
#include <algorithm>
const int Inf = 1e9;
const int N = 100000 + 10;
const int M = 500 + 10;
int n, m, K;
int fa[N], c[M], w[M][M];
int u[N], v[N], len[N];

int Find(int x) {
    if (x != fa[x])
        x = Find(fa[x]);
    return fa[x];
}
void Union(int x, int y) {
    x = Find(x);
    y = Find(y);
    if (x == y) return ;
    fa[x] = y;
}

struct Edge {
    int u, v, nex;
    int len;
    Edge() {
    }
    Edge(int _u, int _v, int _len, int _nex) {
        u = _u, v = _v, len = _len, nex = _nex;
    }
};
struct node {
    int d, u;
    node() {
    }
    node(int _d, int _u) {
        d = _d, u = _u;
    }
    friend bool operator <(const node &a, const node &b) {
        return a.d > b.d;
    }
};
const int E = N + N;
std::priority_queue<node> Q;
Edge eg[E];
int dis[M];
int g[M], idx;
bool vis[M];
void addedge(int u, int v, int len) {
    eg[idx] = Edge(u, v, len, g[u]);
    g[u] = idx++;
}
int queue[M], head, tail;
void spfa(int st) {
    for (int i = 1; i <= K; ++i) {
        vis[i] = false;
        dis[i] = Inf;
    }
    dis[st] = 0;
    head = tail = 0;
    queue[tail ++] = st;
    int x;
    while (tail != head) {
        x = queue[head ++];
        if (head == M)
            head = 0;
        vis[x] = false;
        for (int i = g[x]; ~i; i = eg[i].nex)
            if (eg[i].len + dis[x] < dis[eg[i].v]) {
                dis[eg[i].v] = dis[x] + eg[i].len;
                if (!vis[eg[i].v]) {
                    if (head != tail && dis[queue[head]] > dis[eg[i].v]) {
                        if (-- head < 0)
                            head = M - 1;
                        queue[head] = eg[i].v;
                    } else {
                        queue[tail ++] = eg[i].v;
                        if (tail == M)
                            tail = 0;
                    }
                }
            }
    }
}
void dijkstra(int st) {
    for (int i = 1; i <= K; ++i) {
        vis[i] = false;
        dis[i] = Inf;
    }
    dis[st] = 0;
    Q.push(node(0, st));
    int x;
    while (!Q.empty()) {
        node u = Q.top();
        Q.pop();
        x = u.u;
        if (vis[x])
            continue;
        vis[x] = true;
        for (int i = g[x]; ~i; i = eg[i].nex)
            if (eg[i].len + dis[x] < dis[eg[i].v]) {
                dis[eg[i].v] = dis[x] + eg[i].len;
                Q.push(node(dis[eg[i].v], eg[i].v));
            }
    }
}
int main() {
    //freopen("[p].in", "r", stdin);
    //freopen("[p].out", "w", stdout);
    scanf("%d%d%d", &n, &m, &K);
    for (int i = 1; i <= n; ++i)
        fa[i] = i;

    c[0] = 0;
    for (int i = 1; i <= K; ++i) {
        scanf("%d", &c[i]);
        c[i] += c[i - 1];
    }

    for (int i = 0; i < m; ++i) {
        scanf("%d%d%d", &u[i], &v[i], &len[i]);
        Union(u[i], v[i]);
    }
    bool f, ans = true;
    int id;
    for (int i = 1; i <= K; ++i) {
        id = Find(c[i - 1] + 1);
        f = true;
        for (int j = 2; j <= c[i] - c[i - 1]; ++j)
            if (Find(c[i - 1] + j) != id) {
                f = false;
                break;
            }
        if (!f) {
            ans = false;
            break;
        }
    }
    if (!ans)
        puts("No");
    else {
        for (int i = 1; i <= K; ++i) {
            g[i] = -1;
            for (int j = 1; j <= c[i] - c[i -1]; ++j)
                fa[c[i - 1] + j] = i;
        }
        idx = 0;
        for (int i = 1; i <= K; ++i) {
            for (int j = 1; j <= K; ++j)
                w[i][j] = Inf;
            w[i][i] = 0;
        }
        for (int i = 0; i < m; ++i) {
            u[i] = fa[u[i]];
            v[i] = fa[v[i]];
            if (u[i] == v[i]) continue;
            if (w[u[i]][v[i]] < len[i])
                w[u[i]][v[i]] = w[v[i]][u[i]] = len[i];
        }
        for (int i = 1; i <= K; ++i)
            for (int j = 1; j <= K; ++j)
                if (w[i][j] != Inf)
                    addedge(i, j, w[i][j]);
        puts("Yes");
        for (int i = 1; i <= K; ++i) {
            dijkstra(i);
            for (int j = 1; j <= K; ++j) {
                if (j > 1)
                    putchar(' ');
                if (dis[j] == Inf)
                    printf("-1");
                else
                    printf("%d", dis[j]);
            }
            puts("");
        }
    }
    return 0;
}


/*
PROG:   [p]
ID  :   hewifi
LANG:   C++
*/
#include <cstdio>
#include <cstring>
#include <queue>
#include <algorithm>
const int Inf = 1e9;
const int N = 1e5 + 10;
const int M = 500 + 10;
int n, m, K;
int fa[N], getId[N], c[M], w[M][M];
int Find(int x) {
    if (x != fa[x])
        fa[x] = Find(fa[x]);
    return fa[x];
}
void Union(int x, int y) {
    x = Find(x);
    y = Find(y);
    if (x == y) return ;
    fa[x] = y;
}

int main() {
    //freopen("[p].in", "r", stdin);
    //freopen("[p].out", "w", stdout);
    scanf("%d%d%d", &n, &m, &K);
    for (int i = 1; i <= n; ++i)
        fa[i] = i;
    for (int i = 1; i <= K; ++i) {
        for (int j = 1; j <= K; ++j)
            w[i][j] = Inf;
        w[i][i] = 0;
    }
    c[0] = 0;
    for (int i = 1; i <= K; ++i) {
        scanf("%d", &c[i]);
        c[i] += c[i - 1];
    }
    for (int i = 1; i <= K; ++i)
        for (int j = c[i - 1] + 1; j <= c[i]; ++j)
            getId[j] = i;

    int u, v, len;
    for (int i = 0; i < m; ++i) {
        scanf("%d%d%d", &u, &v, &len);
        if (0 == len)
            Union(u, v);
        u = getId[u];
        v = getId[v];
        if (w[u][v] > len)
            w[u][v] = w[v][u] = len;
    }
    int id;
    for (int i = 1; i <= K; ++i) {
        id = Find(c[i - 1] + 1);
        for (int j = c[i - 1] + 2; j <= c[i]; ++j) {
            if (Find(j) != id) {
                puts("No");
                return 0;
            }
        }
    }
    for (int k = 1; k <= K; ++k)
        for (int i = 1; i <= K; ++i)
        for (int j = 1; j <= K; ++j)
            if (w[i][j] > w[i][k] + w[k][j])
                w[i][j] = w[i][k] + w[k][j];
    puts("Yes");
    for (int i = 1; i <= K; ++i) {
        for (int j = 1; j <= K; ++j) {
            if (j > 1)
                putchar(' ');
            if (w[i][j] == Inf)
                printf("-1");
            else
                printf("%d", w[i][j]);
        }
        puts("");
    }
    return 0;
}


/*
PROG:   [p]
ID  :   hewifi
LANG:   C++
*/
#include <cstdio>
#include <cstring>
#include <queue>
#include <algorithm>
const int Inf = 1e9;
const int N = 100000 + 10;
const int M = 500 + 10;
int n, m, K;
int fa[N], getId[N], c[M], w[M][M];
int Find(int x) {
    if (x != fa[x])
        x = Find(fa[x]);
    return fa[x];
}
void Union(int x, int y) {
    x = Find(x);
    y = Find(y);
    if (x == y) return ;
    fa[x] = y;
}

struct Edge {
    int u, v, nex;
    int len;
    Edge() {
    }
    Edge(int _u, int _v, int _len, int _nex) {
        u = _u, v = _v, len = _len, nex = _nex;
    }
};
struct node {
    int d, u;
    node() {
    }
    node(int _d, int _u) {
        d = _d, u = _u;
    }
    friend bool operator <(const node &a, const node &b) {
        return a.d > b.d;
    }
};
const int E = N + N;
std::priority_queue<node> Q;
Edge eg[E];
int dis[M];
int g[M], idx;
bool vis[M];
void addedge(int u, int v, int len) {
    eg[idx] = Edge(u, v, len, g[u]);
    g[u] = idx++;
}
int queue[M], head, tail;
void spfa(int st) {
    for (int i = 1; i <= K; ++i) {
        vis[i] = false;
        dis[i] = Inf;
    }
    dis[st] = 0;
    head = tail = 0;
    queue[tail ++] = st;
    int x;
    while (tail != head) {
        x = queue[head ++];
        if (head == M)
            head = 0;
        vis[x] = false;
        for (int i = g[x]; ~i; i = eg[i].nex)
            if (eg[i].len + dis[x] < dis[eg[i].v]) {
                dis[eg[i].v] = dis[x] + eg[i].len;
                if (!vis[eg[i].v]) {
                    if (head != tail && dis[queue[head]] > dis[eg[i].v]) {
                        if (-- head < 0)
                            head = M - 1;
                        queue[head] = eg[i].v;
                    } else {
                        queue[tail ++] = eg[i].v;
                        if (tail == M)
                            tail = 0;
                    }
                }
            }
    }
}
void dijkstra(int st) {
    for (int i = 1; i <= K; ++i) {
        vis[i] = false;
        dis[i] = Inf;
    }
    dis[st] = 0;
    Q.push(node(0, st));
    int x;
    while (!Q.empty()) {
        node u = Q.top();
        Q.pop();
        x = u.u;
        if (vis[x])
            continue;
        vis[x] = true;
        for (int i = g[x]; ~i; i = eg[i].nex)
            if (eg[i].len + dis[x] < dis[eg[i].v]) {
                dis[eg[i].v] = dis[x] + eg[i].len;
                Q.push(node(dis[eg[i].v], eg[i].v));
            }
    }
}

int main() {
    //freopen("[p].in", "r", stdin);
    //freopen("[p].out", "w", stdout);
    scanf("%d%d%d", &n, &m, &K);
    for (int i = 1; i <= n; ++i)
        fa[i] = i;
    idx = 0;
    for (int i = 1; i <= K; ++i) {
        for (int j = 1; j <= K; ++j)
            w[i][j] = Inf;
        w[i][i] = 0;
    }
    c[0] = 0;
    for (int i = 1; i <= K; ++i) {
        scanf("%d", &c[i]);
        c[i] += c[i - 1];
    }
    for (int i = 1; i <= K; ++i)
        for (int j = c[i - 1] + 1; j <= c[i]; ++j)
            getId[j] = i;

    int u, v, len;
    for (int i = 0; i < m; ++i) {
        scanf("%d%d%d", &u, &v, &len);
        if (0 == len)
            Union(u, v);
        u = getId[u];
        v = getId[v];
        if (w[u][v] > len)
            w[u][v] = w[v][u] = len;
    }
    int id;
    for (int i = 1; i <= K; ++i) {
        id = Find(c[i - 1] + 1);
        for (int j = c[i - 1] + 2; j <= c[i]; ++j) {
            if (Find(j) != id) {
                puts("No");
                return 0;
            }
        }
    }
    for (int k = 1; k <= K; ++k)
        for (int i = 1; i <= K; ++i)
        for (int j = 1; j <= K; ++j)
            if (w[i][j] > w[i][k] + w[k][j])
                w[i][j] = w[i][k] + w[k][j];
    puts("Yes");
    for (int i = 1; i <= K; ++i) {
        for (int j = 1; j <= K; ++j) {
            if (j > 1)
                putchar(' ');
            if (w[i][j] == Inf)
                printf("-1");
            else
                printf("%d", w[i][j]);
        }
        puts("");
    }
    return 0;
}


/*
PROG:   [p]
ID  :   hewifi
LANG:   C++
*/
#include <cstdio>
#include <cstring>
#include <queue>
#include <algorithm>
const int Inf = 1e9;
const int N = 100000 + 10;
const int M = 500 + 10;
int n, m, K;
int fa[N], c[M], w[M][M];
int u[N], v[N], len[N];
int Find(int x) {
	if (x != fa[x])
		x = Find(fa[x]);
	return fa[x];
}
inline void Union(int x, int y) {
	x = Find(x);
	y = Find(y);
	if (x == y) return ;
	fa[x] = y;
}
struct Edge {
    int u, v, nex;
    int len;
    Edge() {
    }
    Edge(int _u, int _v, int _len, int _nex) {
        u = _u, v = _v, len = _len, nex = _nex;
    }
};
struct node {
    int d, u;
    node() {
    }
    node(int _d, int _u) {
        d = _d, u = _u;
    }
    friend bool operator <(const node &a, const node &b) {
        return a.d > b.d;
    }
};
const int E = N + N;
std::priority_queue<node> Q;
Edge eg[E];
int dis[M];
int g[M], idx;
bool vis[M];
void addedge(int u, int v, int len) {
    eg[idx] = Edge(u, v, len, g[u]);
    g[u] = idx++;
}
int queue[M], head, tail;
void spfa(int st) {
    for (int i = 1; i <= K; ++i) {
        vis[i] = false;
        dis[i] = Inf;
    }
    dis[st] = 0;
    head = tail = 0;
    queue[tail ++] = st;
    int x;
    while (tail != head) {
        x = queue[head ++];
        if (head == M)
            head = 0;
        vis[x] = false;
        for (int i = g[x]; ~i; i = eg[i].nex)
            if (eg[i].len + dis[x] < dis[eg[i].v]) {
                dis[eg[i].v] = dis[x] + eg[i].len;
                if (!vis[eg[i].v]) {
                    if (head != tail && dis[queue[head]] > dis[eg[i].v]) {
                        if (-- head < 0)
                            head = M - 1;
                        queue[head] = eg[i].v;
                    } else {
                        queue[tail ++] = eg[i].v;
                        if (tail == M)
                            tail = 0;
                    }
                }
            }
    }
}
void dijkstra(int st) {
    for (int i = 1; i <= K; ++i) {
        vis[i] = false;
        dis[i] = Inf;
    }
    dis[st] = 0;
    Q.push(node(0, st));
    int x;
    while (!Q.empty()) {
        node u = Q.top();
        Q.pop();
        x = u.u;
        if (vis[x])
            continue;
        vis[x] = true;
        for (int i = g[x]; ~i; i = eg[i].nex)
            if (eg[i].len + dis[x] < dis[eg[i].v]) {
                dis[eg[i].v] = dis[x] + eg[i].len;
                Q.push(node(dis[eg[i].v], eg[i].v));
            }
    }
}
int main() {
    //freopen("[p].in", "r", stdin);
    //freopen("[p].out", "w", stdout);
    scanf("%d%d%d", &n, &m, &K);
    for (int i = 1; i <= n; ++i)
        fa[i] = i;
    c[0] = 0;
    for (int i = 1; i <= K; ++i) {
        scanf("%d", &c[i]);
        c[i] += c[i - 1];
    }

    for (int i = 0; i < m; ++i) {
        scanf("%d%d%d", &u[i], &v[i], &len[i]);
        if (0 == len[i])
        	Union(u[i], v[i]);
    }
    int id;
    for (int i = 1; i <= K; ++i) {
    	if (1 == c[i] - c[i - 1]) continue;
        id = Find(c[i - 1] + 1);
        for (int j = c[i - 1] + 2; j <= c[i]; ++j)
            if (Find(j) != id) {
                puts("No");
            	return 0;
            }
    }
    for (int i = 1; i <= K; ++i) {
            g[i] = -1;
            for (int j = 1; j <= c[i] - c[i -1]; ++j)
                fa[c[i - 1] + j] = i;
        }
        idx = 0;
        for (int i = 1; i <= K; ++i) {
            for (int j = 1; j <= K; ++j)
                w[i][j] = Inf;
            w[i][i] = 0;
        }
        for (int i = 0; i < m; ++i) {
            u[i] = fa[u[i]];
            v[i] = fa[v[i]];
            if (u[i] == v[i]) continue;
            if (w[u[i]][v[i]] > len[i])
                w[u[i]][v[i]] = w[v[i]][u[i]] = len[i];
        }
        for (int i = 1; i <= K; ++i)
            for (int j = 1; j <= K; ++j)
                if (w[i][j] != Inf)
                    addedge(i, j, w[i][j]);
        puts("Yes");
        for (int i = 1; i <= K; ++i) {
            dijkstra(i);
            for (int j = 1; j <= K; ++j) {
                if (j > 1)
                    putchar(' ');
                if (dis[j] == Inf)
                    printf("-1");
                else
                    printf("%d", dis[j]);
            }
            puts("");
        }
    return 0;
}


/*
PROG:   [p]
ID  :   hewifi
LANG:   C++
*/
#include <cstdio>
#include <cstring>
#include <queue>
#include <algorithm>
const int Inf = 1e9;
const int N = 100000 + 10;
const int M = 500 + 10;
int n, m, K;
int fa[N], c[M];
int u[N], v[N], len[N];

int Find(int x) {
    if (x != fa[x])
        x = Find(fa[x]);
    return fa[x];
}
void Union(int x, int y) {
    x = Find(x);
    y = Find(y);
    if (x == y) return ;
    fa[x] = y;
}

struct Edge {
    int u, v, nex;
    int len;
    Edge() {
    }
    Edge(int _u, int _v, int _len, int _nex) {
        u = _u, v = _v, len = _len, nex = _nex;
    }
};
struct node {
    int d, u;
    node() {
    }
    node(int _d, int _u) {
        d = _d, u = _u;
    }
    friend bool operator <(const node &a, const node &b) {
        return a.d > b.d;
    }
};
const int E = N + N;
std::priority_queue<node> Q;
Edge eg[E];
int dis[M];
int g[M], idx;
bool vis[M];
void addedge(int u, int v, int len) {
    eg[idx] = Edge(u, v, len, g[u]);
    g[u] = idx++;
}
void dijkstra(int st) {
    for (int i = 1; i <= K; ++i) {
        vis[i] = false;
        dis[i] = Inf;
    }
    dis[st] = 0;
    Q.push(node(0, st));
    int x;
    while (!Q.empty()) {
        node u = Q.top();
        Q.pop();
        x = u.u;
        if (vis[x])
            continue;
        vis[x] = true;
        for (int i = g[x]; ~i; i = eg[i].nex)
            if (eg[i].len + dis[x] < dis[eg[i].v]) {
                dis[eg[i].v] = dis[x] + eg[i].len;
                Q.push(node(dis[eg[i].v], eg[i].v));
            }
    }
}
int main() {
    //freopen("[p].in", "r", stdin);
    //freopen("[p].out", "w", stdout);
    scanf("%d%d%d", &n, &m, &K);
    for (int i = 1; i <= n; ++i)
        fa[i] = i;

    c[0] = 0;
    for (int i = 1; i <= K; ++i) {
        scanf("%d", &c[i]);
        c[i] += c[i - 1];
    }

    for (int i = 0; i < m; ++i) {
        scanf("%d%d%d", &u[i], &v[i], &len[i]);
        Union(u[i], v[i]);
    }
    bool f, ans = true;
    int id;
    for (int i = 1; i <= K; ++i) {
        id = Find(c[i - 1] + 1);
        f = true;
        for (int j = 2; j <= c[i] - c[i - 1]; ++j)
            if (Find(c[i - 1] + j) != id) {
                f = false;
                break;
            }
        if (!f) {
            ans = false;
            break;
        }
    }
    if (!ans)
        puts("No");
    else {
        for (int i = 1; i <= K; ++i) {
            g[i] = -1;
            for (int j = 1; j <= c[i] - c[i -1]; ++j)
                fa[c[i - 1] + j] = i;
        }
        idx = 0;
        for (int i = 0; i < m; ++i) {
            u[i] = fa[u[i]];
            v[i] = fa[v[i]];
            if (u[i] == v[i]) continue;
            addedge(u[i], v[i], len[i]);
            addedge(v[i], u[i], len[i]);
        }
        puts("Yes");
        for (int i = 1; i <= K; ++i) {
            dijkstra(i);
            for (int j = 1; j <= K; ++j) {
                if (j > 1)
                    putchar(' ');
                if (dis[j] == Inf)
                    printf("-1");
                else
                    printf("%d", dis[j]);
            }
            puts("");
        }
    }
    return 0;
}


/*
PROG:   [p]
ID  :   hewifi
LANG:   C++
*/
#include <cstdio>
#include <cstring>
#include <queue>
#include <algorithm>
const int Inf = 1e9;
const int N = 100000 + 10;
const int M = 500 + 10;
int n, m, K;
int fa[N], c[M], w[M][M];
int u[N], v[N], len[N];

int Find(int x) {
    if (x != fa[x])
        x = Find(fa[x]);
    return fa[x];
}
void Union(int x, int y) {
    x = Find(x);
    y = Find(y);
    if (x == y) return ;
    fa[x] = y;
}

struct Edge {
    int u, v, nex;
    int len;
    Edge() {
    }
    Edge(int _u, int _v, int _len, int _nex) {
        u = _u, v = _v, len = _len, nex = _nex;
    }
};
struct node {
    int d, u;
    node() {
    }
    node(int _d, int _u) {
        d = _d, u = _u;
    }
    friend bool operator <(const node &a, const node &b) {
        return a.d > b.d;
    }
};
const int E = N + N;
std::priority_queue<node> Q;
Edge eg[E];
int dis[M];
int g[M], idx;
bool vis[M];
void addedge(int u, int v, int len) {
    eg[idx] = Edge(u, v, len, g[u]);
    g[u] = idx++;
}
int queue[M], head, tail;
void spfa(int st) {
    for (int i = 1; i <= K; ++i) {
        vis[i] = false;
        dis[i] = Inf;
    }
    dis[st] = 0;
    head = tail = 0;
    queue[tail ++] = st;
    int x;
    while (tail != head) {
        x = queue[head ++];
        if (head == M)
            head = 0;
        vis[x] = false;
        for (int i = g[x]; ~i; i = eg[i].nex)
            if (eg[i].len + dis[x] < dis[eg[i].v]) {
                dis[eg[i].v] = dis[x] + eg[i].len;
                if (!vis[eg[i].v]) {
                    if (head != tail && dis[queue[head]] > dis[eg[i].v]) {
                        if (-- head < 0)
                            head = M - 1;
                        queue[head] = eg[i].v;
                    } else {
                        queue[tail ++] = eg[i].v;
                        if (tail == M)
                            tail = 0;
                    }
                }
            }
    }
}
void dijkstra(int st) {
    for (int i = 1; i <= K; ++i) {
        vis[i] = false;
        dis[i] = Inf;
    }
    dis[st] = 0;
    Q.push(node(0, st));
    int x;
    while (!Q.empty()) {
        node u = Q.top();
        Q.pop();
        x = u.u;
        if (vis[x])
            continue;
        vis[x] = true;
        for (int i = g[x]; ~i; i = eg[i].nex)
            if (eg[i].len + dis[x] < dis[eg[i].v]) {
                dis[eg[i].v] = dis[x] + eg[i].len;
                Q.push(node(dis[eg[i].v], eg[i].v));
            }
    }
}
int main() {
    //freopen("[p].in", "r", stdin);
    //freopen("[p].out", "w", stdout);
    scanf("%d%d%d", &n, &m, &K);
    for (int i = 1; i <= n; ++i)
        fa[i] = i;

    c[0] = 0;
    for (int i = 1; i <= K; ++i) {
        scanf("%d", &c[i]);
        c[i] += c[i - 1];
    }

    for (int i = 0; i < m; ++i) {
        scanf("%d%d%d", &u[i], &v[i], &len[i]);
        Union(u[i], v[i]);
    }
    bool f, ans = true;
    int id;
    for (int i = 1; i <= K; ++i) {
        id = Find(c[i - 1] + 1);
        f = true;
        for (int j = 2; j <= c[i] - c[i - 1]; ++j)
            if (Find(c[i - 1] + j) != id) {
                f = false;
                break;
            }
        if (!f) {
            ans = false;
            break;
        }
    }
    if (!ans)
        puts("No");
    else {
        for (int i = 1; i <= K; ++i) {
            g[i] = -1;
            for (int j = 1; j <= c[i] - c[i -1]; ++j)
                fa[c[i - 1] + j] = i;
        }
        idx = 0;
        for (int i = 1; i <= K; ++i) {
            for (int j = 1; j <= K; ++j)
                w[i][j] = Inf;
            w[i][i] = 0;
        }
        for (int i = 0; i < m; ++i) {
            u[i] = fa[u[i]];
            v[i] = fa[v[i]];
            if (u[i] == v[i]) continue;
            if (w[u[i]][v[i]] > len[i])
                w[u[i]][v[i]] = w[v[i]][u[i]] = len[i];
        }
        for (int i = 1; i <= K; ++i)
            for (int j = 1; j <= K; ++j)
                if (w[i][j] != Inf)
                    addedge(i, j, w[i][j]);
        puts("Yes");
        for (int i = 1; i <= K; ++i) {
            dijkstra(i);
            for (int j = 1; j <= K; ++j) {
                if (j > 1)
                    putchar(' ');
                if (dis[j] == Inf)
                    printf("-1");
                else
                    printf("%d", dis[j]);
            }
            puts("");
        }
    }
    return 0;
}


/*
PROG:   [p]
ID  :   hewifi
LANG:   C++
*/
#include <cstdio>
#include <cstring>
#include <queue>
#include <algorithm>
const int Inf = 1e9;
const int N = 100000 + 10;
const int M = 500 + 10;
int n, m, K;
int fa[N], c[M], w[M][M];
int u[N], v[N], len[N];
int Find(int x) {
	if (x != fa[x])
		x = Find(fa[x]);
	return fa[x];
}
inline void Union(int x, int y) {
	x = Find(x);
	y = Find(y);
	if (x == y) return ;
	fa[x] = y;
}
struct Edge {
    int u, v, nex;
    int len;
    Edge() {
    }
    Edge(int _u, int _v, int _len, int _nex) {
        u = _u, v = _v, len = _len, nex = _nex;
    }
};
struct node {
    int d, u;
    node() {
    }
    node(int _d, int _u) {
        d = _d, u = _u;
    }
    friend bool operator <(const node &a, const node &b) {
        return a.d > b.d;
    }
};
const int E = N + N;
std::priority_queue<node> Q;
Edge eg[E];
int dis[M];
int g[M], idx;
bool vis[M];
void addedge(int u, int v, int len) {
    eg[idx] = Edge(u, v, len, g[u]);
    g[u] = idx++;
}
int queue[M], head, tail;
void spfa(int st) {
    for (int i = 1; i <= K; ++i) {
        vis[i] = false;
        dis[i] = Inf;
    }
    dis[st] = 0;
    head = tail = 0;
    queue[tail ++] = st;
    int x;
    while (tail != head) {
        x = queue[head ++];
        if (head == M)
            head = 0;
        vis[x] = false;
        for (int i = g[x]; ~i; i = eg[i].nex)
            if (eg[i].len + dis[x] < dis[eg[i].v]) {
                dis[eg[i].v] = dis[x] + eg[i].len;
                if (!vis[eg[i].v]) {
                    if (head != tail && dis[queue[head]] > dis[eg[i].v]) {
                        if (-- head < 0)
                            head = M - 1;
                        queue[head] = eg[i].v;
                    } else {
                        queue[tail ++] = eg[i].v;
                        if (tail == M)
                            tail = 0;
                    }
                }
            }
    }
}
void dijkstra(int st) {
    for (int i = 1; i <= K; ++i) {
        vis[i] = false;
        dis[i] = Inf;
    }
    dis[st] = 0;
    Q.push(node(0, st));
    int x;
    while (!Q.empty()) {
        node u = Q.top();
        Q.pop();
        x = u.u;
        if (vis[x])
            continue;
        vis[x] = true;
        for (int i = g[x]; ~i; i = eg[i].nex)
            if (eg[i].len + dis[x] < dis[eg[i].v]) {
                dis[eg[i].v] = dis[x] + eg[i].len;
                Q.push(node(dis[eg[i].v], eg[i].v));
            }
    }
}
int main() {
    //freopen("[p].in", "r", stdin);
    //freopen("[p].out", "w", stdout);
    scanf("%d%d%d", &n, &m, &K);
    for (int i = 1; i <= n; ++i)
        fa[i] = i;
    c[0] = 0;
    for (int i = 1; i <= K; ++i) {
        scanf("%d", &c[i]);
        c[i] += c[i - 1];
    }

    for (int i = 0; i < m; ++i) {
        scanf("%d%d%d", &u[i], &v[i], &len[i]);
        if (0 == len[i])
        	Union(u[i], v[i]);
    }
    bool f, ans = true;
    int id;
    for (int i = 1; i <= K; ++i) {
        id = Find(c[i - 1] + 1);
        f = true;
        for (int j = 2; j <= c[i] - c[i - 1]; ++j)
            if (Find(c[i - 1] + j) != id) {
                f = false;
                break;
            }
        if (!f) {
            ans = false;
            break;
        }
    }
    if (!ans)
        puts("No");
    else {
        for (int i = 1; i <= K; ++i) {
            g[i] = -1;
            for (int j = 1; j <= c[i] - c[i -1]; ++j)
                fa[c[i - 1] + j] = i;
        }
        idx = 0;
        for (int i = 1; i <= K; ++i) {
            for (int j = 1; j <= K; ++j)
                w[i][j] = Inf;
            w[i][i] = 0;
        }
        for (int i = 0; i < m; ++i) {
            u[i] = fa[u[i]];
            v[i] = fa[v[i]];
            if (u[i] == v[i]) continue;
            if (w[u[i]][v[i]] > len[i])
                w[u[i]][v[i]] = w[v[i]][u[i]] = len[i];
        }
        for (int i = 1; i <= K; ++i)
            for (int j = 1; j <= K; ++j)
                if (w[i][j] != Inf)
                    addedge(i, j, w[i][j]);
        puts("Yes");
        for (int i = 1; i <= K; ++i) {
            dijkstra(i);
            for (int j = 1; j <= K; ++j) {
                if (j > 1)
                    putchar(' ');
                if (dis[j] == Inf)
                    printf("-1");
                else
                    printf("%d", dis[j]);
            }
            puts("");
        }
    }
    return 0;
}


/*
PROG:   [p]
ID  :   hewifi
LANG:   C++
*/
#include <cstdio>
#include <cstring>
#include <queue>
#include <algorithm>
const int Inf = 1e9;
const int N = 100000 + 10;
const int M = 500 + 10;
int n, m, K;
int fa[N], c[M], w[M][M];
int u[N], v[N], len[N];
int Find(int x) {
    if (x != fa[x])
        x = Find(fa[x]);
    return fa[x];
}
inline void Union(int x, int y) {
    x = Find(x);
    y = Find(y);
    if (x == y) return ;
    fa[x] = y;
}
struct Edge {
    int u, v, nex;
    int len;
    Edge() {
    }
    Edge(int _u, int _v, int _len, int _nex) {
        u = _u, v = _v, len = _len, nex = _nex;
    }
};
struct node {
    int d, u;
    node() {
    }
    node(int _d, int _u) {
        d = _d, u = _u;
    }
    friend bool operator <(const node &a, const node &b) {
        return a.d > b.d;
    }
};
const int E = N + N;
std::priority_queue<node> Q;
Edge eg[E];
int dis[M];
int g[M], idx;
bool vis[M];
void addedge(int u, int v, int len) {
    eg[idx] = Edge(u, v, len, g[u]);
    g[u] = idx++;
}
int queue[M], head, tail;
void spfa(int st) {
    for (int i = 1; i <= K; ++i) {
        vis[i] = false;
        dis[i] = Inf;
    }
    dis[st] = 0;
    head = tail = 0;
    queue[tail ++] = st;
    int x;
    while (tail != head) {
        x = queue[head ++];
        if (head == M)
            head = 0;
        vis[x] = false;
        for (int i = g[x]; ~i; i = eg[i].nex)
            if (eg[i].len + dis[x] < dis[eg[i].v]) {
                dis[eg[i].v] = dis[x] + eg[i].len;
                if (!vis[eg[i].v]) {
                    if (head != tail && dis[queue[head]] > dis[eg[i].v]) {
                        if (-- head < 0)
                            head = M - 1;
                        queue[head] = eg[i].v;
                    } else {
                        queue[tail ++] = eg[i].v;
                        if (tail == M)
                            tail = 0;
                    }
                }
            }
    }
}
void dijkstra(int st) {
    for (int i = 1; i <= K; ++i) {
        vis[i] = false;
        dis[i] = Inf;
    }
    dis[st] = 0;
    Q.push(node(0, st));
    int x;
    while (!Q.empty()) {
        node u = Q.top();
        Q.pop();
        x = u.u;
        if (vis[x])
            continue;
        vis[x] = true;
        for (int i = g[x]; ~i; i = eg[i].nex)
            if (eg[i].len + dis[x] < dis[eg[i].v]) {
                dis[eg[i].v] = dis[x] + eg[i].len;
                Q.push(node(dis[eg[i].v], eg[i].v));
            }
    }
}
int main() {
    //freopen("[p].in", "r", stdin);
    //freopen("[p].out", "w", stdout);
    scanf("%d%d%d", &n, &m, &K);
    for (int i = 1; i <= n; ++i)
        fa[i] = i;
    c[0] = 0;
    for (int i = 1; i <= K; ++i) {
        scanf("%d", &c[i]);
        c[i] += c[i - 1];
    }

    for (int i = 0; i < m; ++i) {
        scanf("%d%d%d", &u[i], &v[i], &len[i]);
        if (0 == len[i])
            Union(u[i], v[i]);
    }
    bool f, ans = true;
    int id;
    for (int i = 1; i <= K; ++i) {
        if (1 == c[i] - c[i - 1]) continue;
        id = Find(c[i - 1] + 1);
        f = true;
        for (int j = 2; j <= c[i] - c[i - 1]; ++j)
            if (Find(c[i - 1] + j) != id) {
                f = false;
                break;
            }
        if (!f) {
            ans = false;
            break;
        }
    }
    if (!ans)
        puts("No");
    else {
        for (int i = 1; i <= K; ++i) {
            g[i] = -1;
            for (int j = 1; j <= c[i] - c[i -1]; ++j)
                fa[c[i - 1] + j] = i;
        }
        idx = 0;
        for (int i = 1; i <= K; ++i) {
            for (int j = 1; j <= K; ++j)
                w[i][j] = Inf;
            w[i][i] = 0;
        }
        for (int i = 0; i < m; ++i) {
            u[i] = fa[u[i]];
            v[i] = fa[v[i]];
            if (u[i] == v[i]) continue;
            if (w[u[i]][v[i]] > len[i])
                w[u[i]][v[i]] = w[v[i]][u[i]] = len[i];
        }
        for (int i = 1; i <= K; ++i)
            for (int j = 1; j <= K; ++j)
                if (w[i][j] != Inf)
                    addedge(i, j, w[i][j]);
        puts("Yes");
        for (int i = 1; i <= K; ++i) {
            dijkstra(i);
            for (int j = 1; j <= K; ++j) {
                if (j > 1)
                    putchar(' ');
                if (dis[j] == Inf)
                    printf("-1");
                else
                    printf("%d", dis[j]);
            }
            puts("");
        }
    }
    return 0;
}


/*
PROG:   [p]
ID  :   hewifi
LANG:   C++
*/
#include <cstdio>
#include <cstring>
#include <queue>
#include <algorithm>
const int Inf = 1e9;
const int N = 100000 + 10;
const int M = 500 + 10;
int n, m, K;
int fa[N], c[M], w[M][M], mon[N];
int u[N], v[N], len[N];

int Find(int x) {
    if (x != fa[x])
        x = Find(fa[x]);
    return fa[x];
}
void Union(int x, int y) {
    x = Find(x);
    y = Find(y);
    if (x == y) return ;
    fa[x] = y;
}

struct Edge {
    int u, v, nex;
    int len;
    Edge() {
    }
    Edge(int _u, int _v, int _len, int _nex) {
        u = _u, v = _v, len = _len, nex = _nex;
    }
};
struct node {
    int d, u;
    node() {
    }
    node(int _d, int _u) {
        d = _d, u = _u;
    }
    friend bool operator <(const node &a, const node &b) {
        return a.d > b.d;
    }
};
const int E = N + N;
std::priority_queue<node> Q;
Edge eg[E];
int dis[M];
int g[M], idx;
bool vis[M];
void addedge(int u, int v, int len) {
    eg[idx] = Edge(u, v, len, g[u]);
    g[u] = idx++;
}
int queue[M], head, tail;
void spfa(int st) {
    for (int i = 1; i <= K; ++i) {
        vis[i] = false;
        dis[i] = Inf;
    }
    dis[st] = 0;
    head = tail = 0;
    queue[tail ++] = st;
    int x;
    while (tail != head) {
        x = queue[head ++];
        if (head == M)
            head = 0;
        vis[x] = false;
        for (int i = g[x]; ~i; i = eg[i].nex)
            if (eg[i].len + dis[x] < dis[eg[i].v]) {
                dis[eg[i].v] = dis[x] + eg[i].len;
                if (!vis[eg[i].v]) {
                    if (head != tail && dis[queue[head]] > dis[eg[i].v]) {
                        if (-- head < 0)
                            head = M - 1;
                        queue[head] = eg[i].v;
                    } else {
                        queue[tail ++] = eg[i].v;
                        if (tail == M)
                            tail = 0;
                    }
                }
            }
    }
}
void dijkstra(int st) {
    for (int i = 1; i <= K; ++i) {
        vis[i] = false;
        dis[i] = Inf;
    }
    dis[st] = 0;
    Q.push(node(0, st));
    int x;
    while (!Q.empty()) {
        node u = Q.top();
        Q.pop();
        x = u.u;
        if (vis[x])
            continue;
        vis[x] = true;
        for (int i = g[x]; ~i; i = eg[i].nex)
            if (eg[i].len + dis[x] < dis[eg[i].v]) {
                dis[eg[i].v] = dis[x] + eg[i].len;
                Q.push(node(dis[eg[i].v], eg[i].v));
            }
    }
}
int main() {
    //freopen("[p].in", "r", stdin);
    //freopen("[p].out", "w", stdout);
    scanf("%d%d%d", &n, &m, &K);
    for (int i = 1; i <= n; ++i)
        fa[i] = i;
    for (int i = 1; i <= K; ++i) {
            for (int j = 1; j <= c[i] - c[i -1]; ++j)
                mon[c[i - 1] + j] = i;
        }
    c[0] = 0;
    for (int i = 1; i <= K; ++i) {
        scanf("%d", &c[i]);
        c[i] += c[i - 1];
    }

    for (int i = 0; i < m; ++i) {
        scanf("%d%d%d", &u[i], &v[i], &len[i]);
        if (mon[u[i]] != mon[v[i]])
            continue;
        Union(u[i], v[i]);
    }
    bool f, ans = true;
    int id;
    for (int i = 1; i <= K; ++i) {
        id = Find(c[i - 1] + 1);
        f = true;
        for (int j = 2; j <= c[i] - c[i - 1]; ++j)
            if (Find(c[i - 1] + j) != id) {
                f = false;
                break;
            }
        if (!f) {
            ans = false;
            break;
        }
    }
    if (!ans)
        puts("No");
    else {
        for (int i = 1; i <= K; ++i) {
            g[i] = -1;
            for (int j = 1; j <= c[i] - c[i -1]; ++j)
                fa[c[i - 1] + j] = i;
        }
        idx = 0;
        for (int i = 1; i <= K; ++i) {
            for (int j = 1; j <= K; ++j)
                w[i][j] = Inf;
            w[i][i] = 0;
        }
        for (int i = 0; i < m; ++i) {
            u[i] = fa[u[i]];
            v[i] = fa[v[i]];
            if (u[i] == v[i]) continue;
            if (w[u[i]][v[i]] > len[i])
                w[u[i]][v[i]] = w[v[i]][u[i]] = len[i];
        }
        for (int i = 1; i <= K; ++i)
            for (int j = 1; j <= K; ++j)
                if (w[i][j] != Inf)
                    addedge(i, j, w[i][j]);
        puts("Yes");
        for (int i = 1; i <= K; ++i) {
            spfa(i);
            for (int j = 1; j <= K; ++j) {
                if (j > 1)
                    putchar(' ');
                if (dis[j] == Inf)
                    printf("-1");
                else
                    printf("%d", dis[j]);
            }
            puts("");
        }
    }
    return 0;
}


/*
PROG:   [p]
ID  :   hewifi
LANG:   C++
*/
#include <cstdio>
#include <cstring>
#include <algorithm>
const int Inf = 1e9;
const int N = 100000 + 10;
const int M = 500 + 10;
int w[M][M];
int n, m, K;
int fa[N], c[M];
int u[N], v[N], len[N];

int Find(int x) {
	if (x != fa[x])
		x = Find(fa[x]);
	return fa[x];
}
void Union(int x, int y) {
	x = Find(x);
	y = Find(y);
	fa[x] = y;
}
int main() {
	//freopen("[p].in", "r", stdin);
	//freopen("[p].out", "w", stdout);
	scanf("%d%d%d", &n, &m, &K);
	for (int i = 1; i <= n; ++i)
		fa[i] = i;

	c[0] = 0;
	for (int i = 1; i <= K; ++i) {
		scanf("%d", &c[i]);
		c[i] += c[i - 1];
	}

	for (int i = 0; i < m; ++i) {
		scanf("%d%d%d", &u[i], &v[i], &len[i]);
		Union(u[i], v[i]);
	}
	bool f, ans = true;
	int id;
	for (int i = 1; i <= K; ++i) {
		id = Find(c[i - 1] + 1);
		f = true;
		for (int j = 1; j <= c[i] - c[i - 1]; ++j)
			if (Find(c[i - 1] + j) != id) {
				f = false;
				break;
			}
		if (!f) {
			ans = false;
			break;
		}
	}
	if (!ans)
		puts("No");
	else {
		for (int i = 1; i <= K; ++i)
			for (int j = 1; j <= c[i] - c[i -1]; ++j)
				fa[c[i - 1] + j] = i;

		for (int i = 1; i <= K; ++i) {
			for (int j = 1; j <= K; ++j)
				w[i][j] = Inf;
			w[i][i] = 0;
		}
		for (int i = 0; i < m; ++i) {
			u[i] = fa[u[i]];
			v[i] = fa[v[i]];
			if (w[u[i]][v[i]] > len[i])
				w[u[i]][v[i]] = w[v[i]][u[i]] = len[i];
		}
		for (int k = 1; k <= K; ++k)
			for (int i = 1; i <= K; ++i)
			for (int j = 1; j <= K; ++j)
				if (w[i][k] + w[k][j] < w[i][j])
					w[i][j] = w[i][k] + w[k][j];
		puts("Yes");
		for (int i = 1; i <= K; ++i) {
			for (int j = 1; j <= K; ++j) {
				if (j > 1)
					putchar(' ');
				if (w[i][j] == Inf)
					printf("-1");
				else
					printf("%d", w[i][j]);
			}
			puts("");
		}
	}
	return 0;
}


#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
#define FFF 100005
int set[FFF];
int a[FFF];
int sw[505][505];
int cnt[505];
int vis[FFF];
int n,k,m;

int find(int x)
{
    if(x==set[x])
        return x;
    else return set[x]=find(set[x]);
}

void uion(int x,int y)
{
    int l1=find(x);
    int l2=find(y);
    if(l1==l2)
        return;
    else
        set[l2]=l1;
    return;
}

bool judge()
{
    for(int l=1;l<=k;l++)
    {
        int tmp=-1;
        for(int i=cnt[l-1]+1;i<=cnt[l];i++)
        {
            if(tmp==-1)
                tmp=find(i);
            else
            {
                if(tmp!=find(i))
                    return false;
            }
        }
    }
    return true;
}

void solve()
{
    for(int l=1;l<=k;l++)
    {
        for(int i=1;i<=k;i++)
        {
            if(i!=l)
            {
                for(int j=1;j<=k;j++)
                {
                    if(j!=l&&j!=i)
                    {
                        if(sw[i][l]+sw[l][j]<sw[i][j])
                            sw[i][j]=sw[i][l]+sw[l][j];
                    }
                }
            }
        }
    }
    return;
}

void print()
{
    for(int i=1;i<=k;i++)
    {
        sw[i][i]=0;
        for(int j=1;j<=k;j++)
        {
            if(j==1)
                printf("%d",sw[i][j]);
            else
                printf(" %d",sw[i][j]);
        }
        cout<<endl;
    }
    return;
}

int main()
{
    int i,j,now;
    scanf("%d%d%d",&n,&m,&k);
    for(i=1,now=1;i<=k;i++)
    {
        int x;
        scanf("%d",&x);
        for( j=0;j<x;j++)
        {
            a[j+now]=i;
            set[j+now]=j+now;
        }
        now+=x;
        cnt[i]=now-1;
    }
    memset(sw,-1,sizeof(sw));
    while(m--)
    {
        int x,y,z;
        scanf("%d%d%d",&x,&y,&z);
        if(a[x]==a[y])
        {
            if(z==0)
                uion(x,y);
        }
        else
        {
            if(sw[a[x]][a[y]]==-1)
                sw[a[x]][a[y]]=sw[a[y]][a[x]]=z;
            else if(z<sw[a[x]][a[y]])
                sw[a[x]][a[y]]=sw[a[y]][a[x]]=z;
        }
    }
    if(!judge())
        printf("No\n");
    else
    {
    	printf("Yes\n");
        solve();
        print();
    }
    return 0;
}