#include <bits/stdc++.h>
using namespace std;
struct Edge {
  int u, v, cost;
  bool operator<(const Edge& a) const { return cost < a.cost; }
};
struct UnionFind {
  int par[105];
  int rank[105];
  UnionFind(int n) { init(n); }
  void init(int n) {
    for (int(i) = (0); ((i)) < ((n)); ++(i)) {
      par[i] = i;
      rank[i] = 0;
    }
  }
  int find(int x) {
    if (x == par[x]) return x;
    par[x] = find(par[x]);
  }
  int same(int x, int y) { return find(x) == find(y); }
  void unite(int x, int y) {
    x = find(x);
    y = find(y);
    if (x == y) return;
    if (rank[x] < rank[y]) {
      par[x] = y;
    } else {
      par[y] = x;
      if (rank[x] == rank[y]) rank[x]++;
    }
  }
};
int S, D, E;
vector<Edge> es;
int main() {
  while (cin >> S >> D, S) {
    es.clear();
    for (int(i) = (0); ((i)) < ((S)); ++(i))
      for (int(j) = (0); ((j)) < ((D)); ++(j)) {
        int x;
        cin >> x;
        if (!x) continue;
        es.push_back((Edge){i, S + j, x});
      }
    for (int(i) = (0); ((i)) < ((D - 1)); ++(i))
      for (int(j) = (0); ((j)) < ((D - i - 1)); ++(j)) {
        int x;
        cin >> x;
        if (!x) continue;
        es.push_back((Edge){S + i, S + i + j + 1, x});
      }
    UnionFind uf(105);
    sort(es.begin(), es.end());
    int res = 0;
    for (int(i) = (0); ((i)) < ((es.size())); ++(i)) {
      Edge e = es[i];
      if (!uf.same(e.v, e.u)) {
        int f1 = 0, f2 = 0;
        for (int(j) = (0); ((j)) < ((S)); ++(j)) {
          if (!f1 && uf.same(j, e.u)) f1 = 1;
          if (!f2 && uf.same(j, e.v)) f2 = 1;
        }
        if (!f1 || !f2) {
          uf.unite(e.v, e.u);
          res += e.cost;
        }
      }
    }
    cout << res << endl;
  }
  return 0;
}
