#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <map>
using namespace std;

int par[51];
int rank[51];
int d, n;

struct edge{int u, v, cost; };

bool comp(const edge& e1, const edge& e2){
  return e1.cost < e2.cost;
}

vector<edge> es;
int V, E;

void init(){
  for(int i = 0 ; i < 51 ; i++){
    par[i] = i;
    rank[i] = 0;
  }
}

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

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]++;
  }
}

bool same(int x, int y){
  return find(x) == find(y);
}

int kruskal(){
  sort(es.begin(), es.end(), comp);
  init();
  int res = 0;
  bool f1, f2;
  for(int i = 0 ; i < es.size() ; i++){
    edge e = es[i];
    if(!same(e.u, e.v)){
      f1 = f2 = false;
      for(int j = 0 ; j < d ; j++){
	if(!f1 && same(j, e.u)) f1 = true;
	if(!f2 && same(j, e.v)) f2 = true;
      }
      if(!f1 || !f2){
      unite(e.u, e.v);
      res += e.cost;
      }
    }
  }
  return res;
}

int main(){

  while(cin >> d >> n, d|n){
    edge e;
    for(int i = 0 ; i < d ; i++){
      for(int j = 0 ; j < n ; j++){
	e.u = i, e.v = d+j;
	cin >> e.cost;	
	if(e.cost != 0) es.push_back(e);
      }
    }
    
    for(int i = 0 ; i < n-1 ; i++){
      for(int j = i+1 ; j < n ; j++){
	e.u = d+i, e.v = d+j;
	cin >> e.cost;
	if(e.cost != 0) es.push_back(e);
      }
    }
    cout << kruskal() << endl;
  }  
  return 0;
}