#define _USE_MATH_DEFINES

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <cmath>
#include <algorithm>
#include <vector>
#include <queue>
#include <map>
#include <list>

using namespace std;

long long int INF = 1e18;
long long int MOD = 1e9 + 7;

typedef pair<long long int, long long int> P;

#define MAX_V 1000

long long int cost[MAX_V][MAX_V]; // cost[u][v] は頂点uからvへのコスト
long long int mincost[MAX_V];
bool used[MAX_V];

long long int prim(int V){
	
	for(int i = 0; i < V; i++){
		mincost[i] = INF;
		used[i] = false;
	}
	
	mincost[0] = 0;
	
	long long int total = 0;
	
	while(true){
		
		int add_v = -1;
		
		for(int u = 0; u < V; u++){
			if(!used[u] && (add_v == -1 || mincost[u] < mincost[add_v])){
				add_v = u;
			}
		} // 追加する頂点を決定
		
		if(add_v == -1){
			break;
		} // 更新する頂点がない場合、終了
		used[add_v] = true;
		total += mincost[add_v];
		
		for(int u = 0; u < V; u++){
			mincost[u] = min(mincost[u], cost[add_v][u]);
		} // 集合の外の頂点への最小コストを更新
	}
	return total;
}

int main(){
	
	while(true){
		int P, V;
		cin >> P >> V;
		if(P == 0){
			break;
		}
		long long int num[1000];
		for(int i = 0; i < V; i++){
			num[i] = INF;
		}
		for(int i = 0; i < P; i++){
			for(int j = 0; j < V; j++){
				long long int C;
				cin >> C;
				if(C){
					num[j] = min(num[j], C);
				}
			}
		}
		for(int i = 0; i < V; i++){
			cost[i][i] = 0;
		}
		for(int i = 0; i < V; i++){
			cost[0][i + 1] = cost[i + 1][0] = num[i];
		}
		
		for(int i = 1; i <= V; i++){
			for(int j = i + 1; j <= V; j++){
				long long int C;
				cin >> C;
				if(C == 0){
					C = INF;
				}
				cost[j][i] = cost[i][j] = C;
			}
		}
		V++;
		cout << prim(V) << endl;
	}
	return 0;
}

