#include <bits/stdc++.h>
using namespace std;
const int INF = INT_MAX / 2;
const int MAX_N = (int)(1e5 + 100);
const int MAX_K = 500 + 10;
namespace dset {
int parent[MAX_N], height[MAX_N];
int root(int x) {
  while (parent[x] != -1) x = parent[x];
  return x;
}
void merge(int a, int b) {
  a = root(a);
  b = root(b);
  if (a == b) return;
  if (height[a] < height[b])
    parent[a] = b;
  else {
    parent[b] = a;
    if (height[a] == height[b]) height[a]++;
  }
}
void clear() {
  memset(parent, -1, sizeof(parent));
  memset(height, 0, sizeof(height));
}
}  // namespace dset
int group[MAX_N];
int floyd[MAX_K][MAX_K];
int main() {
  cin.tie(0);
  ios_base::sync_with_stdio(0);
  dset::clear();
  int n, nEdges, nGroups;
  cin >> n >> nEdges >> nGroups;
  {
    int it = 0;
    for (int i = 0; i < nGroups; ++i) {
      fill(floyd[i], floyd[i] + nGroups, INF);
      int size;
      cin >> size;
      while (size--) group[it++] = i;
    }
    int a, b, c;
    while (nEdges--) {
      cin >> a >> b >> c;
      a--;
      b--;
      if (c == 0) dset::merge(a, b);
      a = group[a];
      b = group[b];
      floyd[a][b] = min(floyd[a][b], c);
      floyd[b][a] = floyd[a][b];
    }
  }
  bool valid = true;
  for (int i = 0; i + 1 < n; ++i)
    valid &= (group[i] != group[i + 1] || dset::root(i) == dset::root(i + 1));
  if (!valid) {
    cout << "No\n";
    return 0;
  }
  int i, j, k;
  for (i = 0; i < nGroups; ++i) floyd[i][i] = 0;
  for (k = 0; k < nGroups; ++k)
    for (i = 0; i < nGroups; ++i)
      for (j = 0; j < nGroups; ++j)
        if (floyd[i][j] > floyd[i][k] + floyd[k][j])
          floyd[i][j] = floyd[i][k] + floyd[k][j];
  cout << "Yes\n";
  for (i = 0; i < nGroups; ++i) {
    for (j = 0; j < nGroups; ++j) {
      if (j) cout << ' ';
      cout << (floyd[i][j] == INF ? -1 : floyd[i][j]);
    }
    cout << '\n';
  }
  return 0;
}
