#include <iostream>
#include <vector>
#include <map>
#include <set>
#include <queue>
#include <algorithm>
using namespace std;

int N, M, h[201];
bool f[1000001];

// Union-Find
struct union_find{
	vector<int> par, rank;
	
	// コンストラクタで初期化
	union_find(int n){
		par = vector<int>( n );
		rank = vector<int>( n , 0 );
		for(int i=0 ; i < n ; i++ ){
			par[i] = i;
		}
	}
	// x の root を返す
	int find(int x){
		return ( par[x] == x )? x : (par[x] = find(par[x]) ) ;
	}
	// x と y の属する集合を併合する
	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]++;
		}
	}
	// x と y が同じ集合に属するかどうか
	bool same(int x, int y){
		return find(x) == find(y);
	}
	// 集合の数を返す
	int size(){
		set<int> s;
		for(int i=0 ; i < par.size() ; i++ ){
			s.insert( this->find(i) );
		}
		return s.size();
	}
};

struct edge{
	int cost, u, v;
	edge(){}
	edge(int cost_, int u_, int v_){
		cost= cost_; u = u_; v = v_;
	}
};
bool operator<(const edge &a, const edge &b){
	return a.cost < b.cost;
}

int main(){
	while( cin >> N >> M , N ){
		// min_time := 一番最初に島が沈む時刻
		// max_time := 一番最後に島が沈む時刻
		int min_time = 1e+8, max_time = 0;
		fill(f, f + 1000001, false);
		vector<edge> e;
		
		for(int i = 0 ; i < N ; i++ ){
			cin >> h[i];
			f[h[i]] = true;
			min_time = min(min_time, h[i]);
			max_time = max(max_time, h[i]);
		}
		for(int i = 0 ; i < M ; i++ ){
			int a, b, c;
			cin >> a >> b >> c;
			a--; b--;
			e.push_back(edge(c, a, b));
		}
		
		vector<int> v;
		f[0] = true;
		for(int t = 1000000 ; t >= 0 ; t-- ){
			if( f[t] ) v.push_back( t );
		}
		
		// 時刻の遅い順に連結かどうか調べる
		union_find uf(N);
		int time = max_time;
		for(int i = 0 ; i < v.size() ; i++ ){
			int t = v[i];
			for(int j = 0 ; j < e.size() ; j++ ){
				int u = e[j].u, v = e[j].v;
				if( t < h[u] && t < h[v] ){
					uf.unite(u, v);
				}
			}
			
			// V := 沈んでない頂点数
			// vv := 沈んでない頂点の集合
			int V = 0, cnt = 0;
			vector<int> vv;
			for(int v = 0 ; v < N ; v++ ){
				if( t < h[v] ){
					V++;
					vv.push_back(v);
				}
			}
			if( vv.size() == 0 ) continue;
			
			for(int j = 0 ; j < vv.size() ; j++ ){
				int v = vv[j];
				if( uf.find(v) == uf.find(vv[0]) ) cnt++;
			}
			// 時刻 t で沈んでいない頂点で全域木を構成できない(連結にできない)			
			if( V != cnt ) time = t;
		}
		
		// 最初から連結にできないので解は0 
		if( time == 0 ){
			cout << 0 << endl;
			continue;
		}
		
		sort(e.begin(), e.end());
		// 時刻 time で残っている頂点でMSTを構成する
		time--;
		int res = 0;
		union_find tr(N);
		for(int i = 0 ; i < e.size() ; i++ ){
			int cost = e[i].cost, u = e[i].u, v = e[i].v;
			if( time < h[u] && time < h[v] ){
				if( !tr.same(u, v) ){
					res += cost;
					tr.unite(u, v);
				}
			}
		}
		int k = 0;
		time++;
		for(int i = 0 ; i < v.size() ; i++ ){
			if( v[i] == time ){
				k = i;
				break;
			}
		}
		// 時刻 v[k] から時間の逆順に辿っていき橋をかけていく
		for(int i = k ; i < v.size() ; i++ ){
			int t = v[i];
			for(int j = 0 ; j < e.size() ; j++ ){
				int cost = e[j].cost, u = e[j].u, v = e[j].v;
				if( t < h[u] && t < h[v] ){
					if( !tr.same(u, v) ){
						res += cost;
						tr.unite(u, v);
					}
				}
			}
		}
		cout << res << endl;
	}
}

Measured memory_bytes: 2684