#include <bits/stdc++.h>
using namespace std;
using i64 = int64_t;
using vi = vector<i64>;
using vvi = vector<vi>;
struct UnionFind {
  int n, cnt;
  vi par, rank, sz;
  UnionFind(){};
  UnionFind(int n) : n(n), cnt(n), par(n), rank(n), sz(n, 1) {
    iota(par.begin(), par.end(), 0);
  }
  int find(int x) {
    if (x == par[x]) return x;
    return par[x] = find(par[x]);
  }
  bool same(int x, int y) { return find(x) == find(y); }
  int size(int x) { return sz[find(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;
      sz[y] += sz[x];
    } else {
      par[y] = x;
      sz[x] += sz[y];
      if (rank[x] == rank[y]) {
        rank[x]++;
      }
    }
    cnt--;
  }
};
int n;
map<pair<int, int>, i64> es;
vvi adj;
vi as;
UnionFind uf;
i64 boruvka() {
  for (auto it = es.begin(); it != es.end();) {
    if (uf.same(it->first.first, it->first.second)) {
      es.erase(it++);
    } else {
      it++;
    }
  }
  int N = uf.cnt;
  vector<pair<i64, int>> nearest(N, {1e18, -1});
  vector<int> node(N, -1);
  vector<pair<i64, int>> grmin(N, {1e18, -1});
  map<int, int> mp;
  for (int i = 0; i < n; i++) {
    uf.find(i);
  }
  for (int i = 0; i < n; i++) {
    mp[uf.find(i)];
  }
  N = 0;
  for (auto &p : mp) {
    p.second = N++;
  }
  assert(N == uf.cnt);
  for (auto &e : es) {
    i64 w = e.second;
    int a = e.first.first, b = e.first.second;
    int aa = mp[uf.find(a)], bb = mp[uf.find(b)];
    assert(0 <= aa && aa < N && 0 <= bb && bb < N);
    nearest[aa] = min(nearest[aa], {w, bb});
    nearest[bb] = min(nearest[bb], {w, aa});
  }
  for (int i = 0; i < n; i++) {
    node[mp[uf.find(i)]] = i;
    grmin[mp[uf.find(i)]] = min(grmin[mp[uf.find(i)]], {as[i], mp[uf.find(i)]});
  }
  vector<pair<i64, int>> grmin2(grmin);
  sort(grmin.begin(), grmin.end());
  for (int i = 0; i < N; i++) {
    if (grmin[0].second != i) {
      nearest[i] =
          min(nearest[i], {grmin2[i].first + grmin[0].first, grmin[0].second});
    } else {
      nearest[i] =
          min(nearest[i], {grmin2[i].first + grmin[1].first, grmin[1].second});
    }
  }
  i64 cost = 0;
  for (int i = 0; i < N; i++) {
    if (!uf.same(node[i], node[nearest[i].second])) {
      cost += nearest[i].first;
      uf.unite(node[i], node[nearest[i].second]);
    }
  }
  return cost;
}
int main() {
  ios::sync_with_stdio(false);
  cin.tie(nullptr);
  cout.tie(nullptr);
  int m;
  cin >> n >> m;
  adj = vvi(n);
  as = vi(n);
  uf = UnionFind(n);
  for (int i = 0; i < n; i++) {
    cin >> as[i];
  }
  for (int i = 0; i < m; i++) {
    i64 a, b, w;
    cin >> a >> b >> w;
    a--, b--;
    if (es.count({min(a, b), max(a, b)})) {
      es[{min(a, b), max(a, b)}] =
          min({es[{min(a, b), max(a, b)}], as[a] + as[b], w});
    } else {
      es[{min(a, b), max(a, b)}] = min(as[a] + as[b], w);
    }
  }
  i64 cost = 0;
  while (uf.cnt > 1) {
    cost += boruvka();
  }
  cout << cost << endl;
}
