#include <stdio.h>
#include <cmath>
#include <algorithm>
#include <cfloat>
#include <stack>
#include <queue>
#include <vector>
#include <string>
#include <iostream>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;


struct Node{
	Node(int arg_from,int arg_to,int arg_length){
		from = arg_from;
		to = arg_to;
		length = arg_length;
	}

	bool operator<(const struct Node &arg) const{
		return length < arg.length;
	};
	int from,to,length;
};

int parent[51],height[51];
int S,D,N;

int getParent(int id){
	if(parent[id] == id)return id;
	else{
		return parent[id] = getParent(parent[id]);
	}
}

bool isSame(int a, int b){
	return getParent(a) == getParent(b);
}

void unite(int a,int b){
	int a_parent = getParent(a);
	int b_parent = getParent(b);

	if(a_parent == b_parent)return;

	if(height[a_parent] > height[b_parent]){
		parent[b_parent] = a_parent;
	}else{
		if(height[a_parent] == height[b_parent])height[b_parent]++;
		parent[a_parent] = b_parent;
	}
}

void init(){
	for(int i = 0; i < N; i++){
		parent[i] = i;
		height[i] = 0;
	}
}

void func(){

	N = S+D;

	init();

	vector<Node> V;

	int tmp_length;

	for(int i = 0; i < S; i++){
		for(int k = 0; k < D; k++){
			scanf("%d",&tmp_length);
			if(tmp_length == 0)continue;
			V.push_back(Node(i,S+k,tmp_length));
		}
	}

	for(int i = 0; i < D-1; i++){
		for(int k = i+1; k < D; k++){
			scanf("%d",&tmp_length);
			if(tmp_length == 0)continue;
			V.push_back(Node(S+i,S+k,tmp_length));
		}
	}

	sort(V.begin(),V.end());

	int ans = 0;

	bool is_connect[N];
	for(int i = 0; i < S; i++)is_connect[i] = true;
	for(int i = S; i < N; i++)is_connect[i] = false;

	int boss;

	for(int i = 0; i < V.size(); i++){
		if(isSame(V[i].from,V[i].to) == false && (is_connect[V[i].from] == false || is_connect[V[i].to] == false)){

			if(is_connect[V[i].from]){
				boss = getParent(V[i].to);

				for(int k = S; k < N; k++){
					if(getParent(k) == boss){
						is_connect[k] = true;
					}
				}
			}else if(is_connect[V[i].to]){
				boss = getParent(V[i].from);

				for(int k = S; k < N; k++){
					if(getParent(k) == boss){
						is_connect[k] = true;
					}
				}
			}

			unite(V[i].from,V[i].to);

			ans += V[i].length;
		}
	}

	printf("%d\n",ans);

}


int main(){

	while(true){
		scanf("%d %d",&S,&D);
		if(S == 0 && D == 0)break;

		func();
	}


	return 0;
}