#include <iostream>
#include <vector>
#include <algorithm>
#include <cmath>

using namespace std;

class UnionFindTree{

private:
  // indexÌÌem[h
  vector<int> par;
  // indexðªÆ·éØÌN
  vector<int> rank;
  // ØÌÅål
  int treeSize;
  
public:
  UnionFindTree(int initTreeSize = 1000){
     // øÅ^¦çê½lðÅåi[Æ·éUnionFindTreeÌì¬
    treeSize = initTreeSize;
    init();
  }
  
  
  void init(){
    
    for(int i = 0; i < treeSize; i++){
      par.push_back(i);
      rank.push_back(0);
    }
    
  }

  // ^¦çê½ªi[³êÄ¢éØÌ[gðTõ
  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[y] == rank[x]){
	rank[x]++;
      }
    }
  }

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

};

class edge{
public:
	int u,v,cost;

	bool operator<(const edge &e)const{
		return e.cost>this->cost;
	}
};
edge es[10001];
int V,E;
int s,d;

int kruskal(){
	sort(es,es+E);
	UnionFindTree uft(V);
	int res=0;
	for(int k = 0; k < E; k++){
		edge &e=es[k];
		// 2ÂÈãÌM¹ðêÂÌssÉÂÈ°éÌÍ³Ê
		if(e.u>=s&&e.v<s){
			int netu=e.v;
			bool isc=false;
			for(int j = 0; j < s; j++){
				if(uft.same(j,e.u)){
					isc=true;
					break;
				}
			}
			if(isc){
				continue;
			}
		}
		else if(e.v>=s&&e.u<s){
			int netu=e.u;
			bool isc=false;
			for(int j = 0; j < s; j++){
				if(uft.same(j,e.v)){
					isc=true;
					break;
				}
			}
			if(isc){
				continue;
			}
		}
		// ¼ûÌssª¢¸ê©ÌM¹ÆqªÁÄ¢éê
		else{
			bool isc=false;
			for(int j = 0; j < s; j++){
				if(uft.same(j,e.v)){
					isc=true;
					break;
				}
			}
			bool isc2=false;
			for(int j = 0; j < s; j++){
				if(uft.same(j,e.u)){
					isc2=true;
					break;
				}
			}
			if(isc&&isc2)
				continue;
		}

		if(!uft.same(e.u,e.v)){
			uft.unite(e.u,e.v);
			res+=e.cost;
			bool f=true;
			for(int i = 0; i < d; i++){
				bool isc=false;
				for(int j = 0; j < s; j++){
					if(uft.same(j,i+s)){
						isc=true;
						break;
					}
				}
				if(!isc){
					f=false;
					break;
				}
			}
			if(f)
				break;
		}
	}
	return res;
}

int main(){
	
	while(cin>>s>>d&&!(s==0&&d==0)){

		E=V=0;
		V=s+d;
		for(int i = 0; i < s; i++){
			edge e;
			e.u=i;
			for(int j = 0; j < d; j++){
				e.v=j+s;
				cin>>e.cost;
				if(e.cost!=0){
					es[E]=e;
					E++;
				}
			}
		}
		for(int i = 0; i < d-1; i++){
			edge e;
			e.u=i+s;
			for(int j = i+1; j < d; j++){
				e.v=j+s;
				cin>>e.cost;
				if(e.cost!=0){
					es[E]=e;
					E++;
				}
			}
		}
		cout<<kruskal()<<endl;
	}
  
	return 0;
}