#include <bits/stdc++.h>
using namespace std;
struct Edge {
  int src, dst;
  int weight;
  Edge(int src, int dst, int weight) : src(src), dst(dst), weight(weight) {}
};
bool operator<(const Edge &e, const Edge &f) {
  return e.weight != f.weight ? e.weight > f.weight
         : e.src != f.src     ? e.src < f.src
                              : e.dst < f.dst;
}
struct UnionFind {
  vector<int> data;
  UnionFind(int size) : data(size, -1) {}
  bool unionSet(int x, int y) {
    x = root(x);
    y = root(y);
    if (x != y) {
      if (data[y] < data[x]) swap(x, y);
      data[x] += data[y];
      data[y] = x;
    }
    return x != y;
  }
  bool findSet(int x, int y) { return root(x) == root(y); }
  int root(int x) { return data[x] < 0 ? x : data[x] = root(data[x]); }
  int size(int x) { return -data[root(x)]; }
};
const int MAX_N = 51;
int SP[MAX_N][MAX_N];
int DI[MAX_N][MAX_N];
int T[MAX_N];
int main() {
  int s, d;
  while (cin >> s >> d && s && d) {
    for (int i = 0; i < s; ++i) {
      for (int j = 0; j < d; ++j) {
        cin >> SP[i][j];
      }
    }
    for (int i = 0; i < d - 1; ++i) {
      for (int j = 0; j < d - i - 1; ++j) {
        cin >> DI[j][i + j + 1];
        DI[i + j + 1][j] = DI[j][i + j + 1];
      }
    }
    int res = 0;
    for (int i = 0; i < d; ++i) {
      int minc = INT_MAX;
      int t;
      for (int j = 0; j < s; ++j) {
        if (SP[j][i] == 0) continue;
        if (SP[j][i] < minc) {
          minc = SP[j][i];
          t = j;
        }
      }
      T[i] = t;
      res += SP[t][i];
    }
    priority_queue<Edge, vector<Edge> > Q;
    for (int i = 0; i < d; ++i) {
      for (int j = i + 1; j < d; ++j) {
        if (DI[i][j] == 0) continue;
        Q.push(Edge(i, j, DI[i][j]));
      }
    }
    UnionFind uf(d);
    while (!Q.empty()) {
      Edge e = Q.top();
      Q.pop();
      int a = e.src;
      int b = e.dst;
      if (uf.findSet(a, b)) continue;
      if (uf.data[a] >= 0 || uf.data[b] >= 0) continue;
      int w = e.weight;
      int sa = SP[T[a]][a];
      int sb = SP[T[b]][b];
      if (w < sa || w < sb) {
        if (sa > sb) {
          res -= sa;
          T[a] = T[b];
        } else {
          res -= sb;
          T[b] = T[a];
        }
        res += w;
        uf.unionSet(a, b);
      } else if (w == sa) {
        T[b] = T[a];
        uf.unionSet(a, b);
      } else if (w == sb) {
        T[a] = T[b];
        uf.unionSet(a, b);
      }
    }
    cout << res << endl;
  }
  return 0;
}
