#include<stdio.h>
#include<algorithm>
using namespace std;
int UF[110];
int FIND(int a){
	if(UF[a]<0)return a;
	return UF[a]=FIND(UF[a]);
}
void UNION(int a,int b){
	a=FIND(a);b=FIND(b);if(a==b)return;
	UF[a]+=UF[b];UF[b]=a;
}
pair<int,pair<int,int> > edge[50000];
int main(){
	int a,b;
	while(scanf("%d%d",&a,&b),a+b){
		for(int i=0;i<a+b;i++)UF[i]=-1;
		int sz=0;
		for(int i=0;i<a;i++)for(int j=0;j<b;j++){
			int p;scanf("%d",&p);
			if(p==0)continue;
			edge[sz++]=make_pair(p,make_pair(i,j+a));
		}
		for(int i=0;i<b;i++)for(int j=i+1;j<b;j++){
			int p;scanf("%d",&p);
			if(p==0)continue;
			edge[sz++]=make_pair(p,make_pair(i+a,j+a));
		}
		std::sort(edge,edge+sz);
		int ret=0;
		for(int i=0;i<sz;i++){
			bool ok=true;
			int s=-1;
			int t=-1;
			for(int j=0;j<a;j++){
				if(FIND(edge[i].second.first)==FIND(j))s=j;
				if(FIND(j)==FIND(edge[i].second.second))t=j;
			}
			if(~s&&~t)continue;
			if(!ok)continue;
			if(FIND(edge[i].second.first)!=FIND(edge[i].second.second)){
				ret+=edge[i].first;
				UNION(edge[i].second.first,edge[i].second.second);
			}
		}
		printf("%d\n",ret);
	}
}