#include <iostream>
#include <vector>
#include <unordered_map>
#include <algorithm>
#include <random>

using namespace std;

typedef long long ll;

struct Edge {
    int from;
    int to;
    ll weight;
};

bool cmp( const Edge& fst, const Edge& snd ) {
    return fst.weight < snd.weight;
}

int find( int x, vector<int>& p ) {
    if( p[x] == x ) {
        return x;
    }
    int root = find( p[x], p );
    p[x] = root;
    return root;
}

bool add( int from, int to, vector<int>& p ) {
    int fst = find( from, p );
    int snd = find( to, p );
    if( fst == snd ) {
        return false;
    }
    if( rand() % 2 == 0 ) {
        p[fst] = snd;
    } else {
        p[snd] = fst;
    }

    return true;
}

int main() {
    ios_base::sync_with_stdio( false );
    cin.tie( nullptr );
    cout.tie( nullptr );

    int n, m;
    cin >> n >> m;

    vector<pair<ll, int>> a( n );
    for( int i = 0; i < n; ++i ) {
        cin >> a[i].first;
        a[i].second = i;
    }
    sort( a.begin(), a.end() );

    vector<int> p( n );
    for( int i = 0; i < n; ++i ) {
        p[i] = i;
    }

    vector<Edge> edges( m );
    for( auto& x : edges ) {
        cin >> x.from >> x.to >> x.weight;
        --x.from; --x.to;
    }
    sort( edges.begin(), edges.end(), cmp );

    ll ans = 0;
    int ind = 1;
    int indE = 0;
    int cnt = 0;
    while( cnt < n - 1 ) {
        bool added;
        if( indE == edges.size() || a[0].first + a[ind].first < edges[indE].weight ) {
            added = add( a[0].second, a[ind].second, p );
            if( added ) {
                ans += a[0].first + a[ind].first;
                ++cnt;
            }
            ++ind;
        } else {
            added = add( edges[indE].from, edges[indE].to, p );
            if( added ) {
                ans += edges[indE].weight;
                ++cnt;
            }
            ++indE;
        }
    }

    cout << ans << endl;

    return 0;
}


#include <iostream>
#include <vector>
#include <unordered_map>
#include <algorithm>

using namespace std;

typedef long long ll;

struct Edge {
    int from;
    int to;
    ll weight;
};

bool cmp( const Edge& fst, const Edge& snd ) {
    return fst.weight < snd.weight;
}

int find( int x, vector<int>& p ) {
    if( p[x] == x ) {
        return x;
    }
    int root = find( p[x], p );
    p[x] = root;
    return root;
}

bool add( int from, int to, vector<int>& p ) {
    int fst = find( from, p );
    int snd = find( to, p );
    if( fst == snd ) {
        return false;
    }
    p[fst] = snd;
    return true;
}

int main() {
    ios_base::sync_with_stdio( false );
    cin.tie( nullptr );
    cout.tie( nullptr );

    int n, m;
    cin >> n >> m;

    vector<pair<int, int>> a( n );
    for( int i = 0; i < n; ++i ) {
        cin >> a[i].first;
        a[i].second = i;
    }
    sort( a.begin(), a.end() );

    vector<int> p( n );
    for( int i = 0; i < n; ++i ) {
        p[i] = i;
    }

    vector<Edge> edges( m );
    for( auto& x : edges ) {
        cin >> x.from >> x.to >> x.weight;
        --x.from; --x.to;
    }
    sort( edges.begin(), edges.end(), cmp );

    ll ans = 0;
    int ind = 1;
    int cnt = 0;
    while( cnt < n - 1 ) {
        bool added;
        if( edges.empty() || a[0].first + a[ind].first < edges.begin()->weight ) {
            added = add( a[0].second, a[ind].second, p );
            if( added ) {
                ans += a[0].first + a[ind].first;
                ++cnt;
            }
            ++ind;
        } else {
            added = add( edges.begin()->from, edges.begin()->to, p );
            if( added ) {
                ans += edges.begin()->weight;
                ++cnt;
            }
            edges.erase( edges.begin() );
        }
    }

    cout << ans << endl;

    return 0;
}


#include <iostream>
#include <vector>
#include <unordered_map>
#include <algorithm>

using namespace std;

typedef long long ll;

struct Edge {
    int from;
    int to;
    ll weight;
};

bool cmp( const Edge& fst, const Edge& snd ) {
    return fst.weight < snd.weight;
}

int find( int x, vector<int>& p ) {
    if( p[x] == x ) {
        return x;
    }
    int root = find( p[x], p );
    p[x] = root;
    return root;
}

bool add( int from, int to, vector<int>& p ) {
    int fst = find( from, p );
    int snd = find( to, p );
    if( fst == snd ) {
        return false;
    }
    p[fst] = snd;
    return true;
}

int main() {
    ios_base::sync_with_stdio( false );
    cin.tie( nullptr );
    cout.tie( nullptr );

    int n, m;
    cin >> n >> m;

    vector<pair<ll, int>> a( n );
    for( int i = 0; i < n; ++i ) {
        cin >> a[i].first;
        a[i].second = i;
    }
    sort( a.begin(), a.end() );

    vector<int> p( n );
    for( int i = 0; i < n; ++i ) {
        p[i] = i;
    }

    vector<Edge> edges( m );
    for( auto& x : edges ) {
        cin >> x.from >> x.to >> x.weight;
        --x.from; --x.to;
    }
    sort( edges.begin(), edges.end(), cmp );

    ll ans = 0;
    int ind = 1;
    int cnt = 0;
    while( cnt < n - 1 ) {
        bool added;
        if( edges.empty() || a[0].first + a[ind].first < edges.begin()->weight ) {
            added = add( a[0].second, a[ind].second, p );
            if( added ) {
                ans += a[0].first + a[ind].first;
                ++cnt;
            }
            ++ind;
        } else {
            added = add( edges.begin()->from, edges.begin()->to, p );
            if( added ) {
                ans += edges.begin()->weight;
                ++cnt;
            }
            edges.erase( edges.begin() );
        }
    }

    cout << ans << endl;

    return 0;
}


#include <iostream>
#include <vector>
#include <unordered_map>
#include <algorithm>
#include <random>

using namespace std;

typedef long long ll;

struct Edge {
    int from;
    int to;
    ll weight;
};

bool cmp( const Edge& fst, const Edge& snd ) {
    return fst.weight < snd.weight;
}

int find( int x, vector<int>& p ) {
    if( p[x] == x ) {
        return x;
    }
    int root = find( p[x], p );
    p[x] = root;
    return root;
}

bool add( int from, int to, vector<int>& p ) {
    int fst = find( from, p );
    int snd = find( to, p );
    if( fst == snd ) {
        return false;
    }
    if( rand() % 2 == 0 ) {
        p[fst] = snd;
    } else {
        p[snd] = fst;
    }

    return true;
}

int main() {
    ios_base::sync_with_stdio( false );
    cin.tie( nullptr );
    cout.tie( nullptr );

    int n, m;
    cin >> n >> m;

    vector<pair<ll, int>> a( n );
    for( int i = 0; i < n; ++i ) {
        cin >> a[i].first;
        a[i].second = i;
    }
    sort( a.begin(), a.end() );

    vector<int> p( n );
    for( int i = 0; i < n; ++i ) {
        p[i] = i;
    }

    vector<Edge> edges( m );
    for( auto& x : edges ) {
        cin >> x.from >> x.to >> x.weight;
        --x.from; --x.to;
    }
    sort( edges.begin(), edges.end(), cmp );

    ll ans = 0;
    int ind = 1;
    int indE = 0;
    int cnt = 0;
    while( cnt < n - 1 ) {
        bool added;
        if( indE < edges.size() || a[0].first + a[ind].first < edges[indE].weight ) {
            added = add( a[0].second, a[ind].second, p );
            if( added ) {
                ans += a[0].first + a[ind].first;
                ++cnt;
            }
            ++ind;
        } else {
            added = add( edges[indE].from, edges[indE].to, p );
            if( added ) {
                ans += edges[indE].weight;
                ++cnt;
            }
            ++indE;
        }
    }

    cout << ans << endl;

    return 0;
}


#include <iostream>
#include <vector>
#include <unordered_map>
#include <algorithm>
#include <random>

using namespace std;

typedef long long ll;

struct Edge {
    int from;
    int to;
    ll weight;
};

bool cmp( const Edge& fst, const Edge& snd ) {
    return fst.weight < snd.weight;
}

int find( int x, vector<int>& p ) {
    if( p[x] == x ) {
        return x;
    }
    int root = find( p[x], p );
    p[x] = root;
    return root;
}

bool add( int from, int to, vector<int>& p ) {
    int fst = find( from, p );
    int snd = find( to, p );
    if( fst == snd ) {
        return false;
    }
    p[snd] = fst;

    return true;
}

int main() {
    ios_base::sync_with_stdio( false );
    cin.tie( nullptr );
    cout.tie( nullptr );

    int n, m;
    cin >> n >> m;

    vector<pair<ll, int>> a( n );
    for( int i = 0; i < n; ++i ) {
        cin >> a[i].first;
        a[i].second = i;
    }
    sort( a.begin(), a.end() );

    vector<int> p( n );
    for( int i = 0; i < n; ++i ) {
        p[i] = i;
    }

    vector<Edge> edges( m );
    for( auto& x : edges ) {
        cin >> x.from >> x.to >> x.weight;
        --x.from; --x.to;
    }
    sort( edges.begin(), edges.end(), cmp );

    ll ans = 0;
    int ind = 1;
    int indE = 0;
    int cnt = 0;
    while( cnt < n - 1 ) {
        bool added;
        if( indE == edges.size() || a[0].first + a[ind].first < edges[indE].weight ) {
            added = add( a[0].second, a[ind].second, p );
            if( added ) {
                ans += a[0].first + a[ind].first;
                ++cnt;
            }
            ++ind;
        } else {
            added = add( edges[indE].from, edges[indE].to, p );
            if( added ) {
                ans += edges[indE].weight;
                ++cnt;
            }
            ++indE;
        }
    }

    cout << ans << endl;

    return 0;
}


#include <iostream>
#include <vector>
#include <unordered_map>
#include <algorithm>
#include <random>

using namespace std;

typedef long long ll;

struct Edge {
    int from;
    int to;
    ll weight;
};

bool cmp( const Edge& fst, const Edge& snd ) {
    return fst.weight < snd.weight;
}

int find( int x, vector<int>& p ) {
    if( p[x] == x ) {
        return x;
    }
    int root = find( p[x], p );
    p[x] = root;
    return root;
}

bool add( int from, int to, vector<int>& p ) {
    int fst = find( from, p );
    int snd = find( to, p );
    if( fst == snd ) {
        return false;
    }
    if( rand() % 2 == 0 ) {
        p[fst] = snd;
    } else {
        p[snd] = fst;
    }

    return true;
}

int main() {
    ios_base::sync_with_stdio( false );
    cin.tie( nullptr );
    cout.tie( nullptr );

    int n, m;
    cin >> n >> m;

    vector<pair<ll, int>> a( n );
    for( int i = 0; i < n; ++i ) {
        cin >> a[i].first;
        a[i].second = i;
    }
    sort( a.begin(), a.end() );

    vector<int> p( n );
    for( int i = 0; i < n; ++i ) {
        p[i] = i;
    }

    vector<Edge> edges( m );
    for( auto& x : edges ) {
        cin >> x.from >> x.to >> x.weight;
        --x.from; --x.to;
    }
    sort( edges.begin(), edges.end(), cmp );

    ll ans = 0;
    int ind = 1;
    int cnt = 0;
    while( cnt < n - 1 ) {
        bool added;
        if( edges.empty() || a[0].first + a[ind].first < edges.begin()->weight ) {
            added = add( a[0].second, a[ind].second, p );
            if( added ) {
                ans += a[0].first + a[ind].first;
                ++cnt;
            }
            ++ind;
        } else {
            added = add( edges.begin()->from, edges.begin()->to, p );
            if( added ) {
                ans += edges.begin()->weight;
                ++cnt;
            }
            edges.erase( edges.begin() );
        }
    }

    cout << ans << endl;

    return 0;
}


#include <bits/stdc++.h>
#include <vector>
#define pb push_back
#define sc second
#define fr first
#define mk make_pair
#define ii pair<int,int>
typedef long long intt;
using namespace std;
int p[200004];
int findd(int x)
{
    if(x==p[x])
        return x;
    return x=findd(p[x]);
}
int main()
{
  ios::sync_with_stdio(false);
  cin.tie();
  cout.tie();
  int n,m,i;
  cin>>n>>m;
   vector <pair<intt,ii> > op;
    intt a[n+2];
    intt minn=1e14;
    intt idx=-1;
   for(i=1;i<=n;i++)
   {
       cin>>a[i];
       if(a[i]<minn)
       {
           minn=a[i];
           idx=i;
       }
   }
   for(i=1;i<=n;i++)
   {
       if(i!=idx)
       {
           op.push_back(mk(a[idx]+a[i],mk(idx,i)));
       }
   }

    for(i=0;i<m;i++)
    {
        intt x,y,z;
        cin>>x>>y>>z;
        op.pb(mk(z,mk(x,y)));
    }
    sort(op.begin(),op.end());
    intt res=0;
    for(i=0;i<op.size();i++)
    {
        int x=findd(op[i].sc.fr);
        int y=findd(op[i].sc.sc);
        if(x!=y)
        {
            p[x]=y;
            res+=op[i].fr;
        }
    }
    cout<<res;
    return 0;
}


#include <bits/stdc++.h>
#include <vector>
#define pb push_back
#define sc second
#define fr first
#define mk make_pair
#define ii pair<int,int>
typedef long long intt;
using namespace std;
int p[200004];
int findd(int x)
{
    if(x==p[x])
        return x;
    return x=findd(p[x]);
}
int main()
{
  ios::sync_with_stdio(false);
  cin.tie();
  cout.tie();
  int n,m,i;
  cin>>n>>m;
  priority_queue <pair<int,ii>,vector <pair<int,ii> >,greater <pair<int,ii> > >op;
   vector <pair<int,int> > d;
   for(i=1;i<=n;i++)
   {
       int x;
       cin>>x;
       p[i]=i;
       d.pb(mk(x,i));
   }
   sort(d.begin(),d.end());
   for(i=1;i<d.size();i++)
    op.push(mk(d[0].fr+d[i].fr,mk(d[0].sc,d[i].sc)));
    for(i=0;i<m;i++)
    {
        int x,y,z;
        cin>>x>>y>>z;
        op.push(mk(z,mk(x,y)));
    }
    intt res=0;
    while(!op.empty())
    {
        pair<int,ii> f=op.top();
        op.pop();
        int x=findd(f.sc.fr);
        int y=findd(f.sc.sc);
        if(x!=y)
        {
            p[x]=y;
            res+=f.fr;
        }
    }
    cout<<res;
    return 0;
}


#include <bits/stdc++.h>
#include <vector>
#define pb push_back
#define sc second
#define fr first
#define mk make_pair
#define ii pair<int,int>
typedef long long intt;
using namespace std;
int p[200004];
int findd(int x)
{
    if(x==p[x])
        return x;
    return x=findd(p[x]);
}
int main()
{
  ios::sync_with_stdio(false);
  cin.tie();
  cout.tie();
  int n,m,i;
  cin>>n>>m;
   vector <pair<intt,ii> > op;
    intt a[n+2];
    intt minn=1e14;
    intt idx=-1;
   for(i=1;i<=n;i++)
   {
       cin>>a[i];
       p[i]=i;
       if(a[i]<minn)
       {
           minn=a[i];
           idx=i;
       }
   }
   for(i=1;i<=n;i++)
   {
       if(i!=idx)
       {
           op.push_back(mk(a[idx]+a[i],mk(idx,i)));
       }
   }

    for(i=0;i<m;i++)
    {
        intt x,y,z;
        cin>>x>>y>>z;
        op.pb(mk(z,mk(x,y)));
    }
    sort(op.begin(),op.end());
    intt res=0;
    for(i=0;i<op.size();i++)
    {
        int x=findd(op[i].sc.fr);
        int y=findd(op[i].sc.sc);
        if(x!=y)
        {
            p[x]=y;
            res+=op[i].fr;
        }
    }
    cout<<res;
    return 0;
}


#include <bits/stdc++.h>
#include <vector>
#define pb push_back
#define sc second
#define fr first
#define mk make_pair
#define ii pair<int,int>
typedef long long intt;
using namespace std;
int p[200004];
int findd(int x)
{
    if(x==p[x])
        return x;
    return x=findd(p[x]);
}
int main()
{
  ios::sync_with_stdio(false);
  cin.tie();
  cout.tie();
  int n,m,i;
  cin>>n>>m;
   vector <pair<intt,ii> > op;
   vector <pair<intt,int> > d;
   for(i=1;i<=n;i++)
   {
       intt x;
       cin>>x;
       p[i]=i;
       d.pb(mk(x,i));
   }
   sort(d.begin(),d.end());
   for(i=1;i<d.size();i++)
    op.pb(mk(d[0].fr+d[i].fr,mk(d[0].sc,d[i].sc)));
    for(i=0;i<m;i++)
    {
        intt x,y,z;
        cin>>x>>y>>z;
        op.pb(mk(z,mk(x,y)));
    }
    sort(op.begin(),op.end());
    intt res=0;
    for(i=0;i<op.size();i++)
    {
        int x=findd(op[i].sc.fr);
        int y=findd(op[i].sc.sc);
        if(x!=y)
        {
            p[x]=y;
            res+=op[i].fr;
        }
    }
    cout<<res;
    return 0;
}


#include <bits/stdc++.h>
#include <vector>
#define pb push_back
#define sc second
#define fr first
#define mk make_pair
#define ii pair<int,int>
typedef long long intt;
using namespace std;
int p[200004];
int findd(int x)
{
    if(x==p[x])
        return x;
    return x=findd(p[x]);
}
int main()
{
  ios::sync_with_stdio(false);
  cin.tie();
  cout.tie();
  int n,m,i;
  cin>>n>>m;
  priority_queue <pair<intt,ii>,vector <pair<intt,ii> >,greater <pair<intt,ii> > >op;
   vector <pair<intt,int> > d;
   for(i=1;i<=n;i++)
   {
       intt x;
       cin>>x;
       p[i]=i;
       d.pb(mk(x,i));
   }
   sort(d.begin(),d.end());
   for(i=1;i<d.size();i++)
    op.push(mk(d[0].fr+d[i].fr,mk(d[0].sc,d[i].sc)));
    for(i=0;i<m;i++)
    {
        intt x,y,z;
        cin>>x>>y>>z;
        op.push(mk(z,mk(x,y)));
    }
    intt res=0;
    while(!op.empty())
    {
        pair<intt,ii> f=op.top();
        op.pop();
        int x=findd(f.sc.fr);
        int y=findd(f.sc.sc);
        if(x!=y)
        {
            p[x]=y;
            res+=f.fr;
        }
    }
    cout<<res;
    return 0;
}


#include <bits/stdc++.h>
#include <vector>
#define pb push_back
#define sc second
#define fr first
#define mk make_pair
#define ii pair<int,int>
typedef long long intt;
using namespace std;
int p[200004];
int findd(int x)
{
    if(x==p[x])
        return x;
    return p[x]=findd(p[x]);
}
int main()
{
  ios::sync_with_stdio(false);
  cin.tie();
  cout.tie();
  int n,m,i;
  cin>>n>>m;
   vector <pair<intt,ii> > op;
    intt a[n+2];
    intt minn=1e14;
    intt idx=-1;
   for(i=1;i<=n;i++)
   {
       cin>>a[i];
       p[i]=i;
       if(a[i]<minn)
       {
           minn=a[i];
           idx=i;
       }
   }
   for(i=1;i<=n;i++)
   {
       if(i!=idx)
       {
           op.push_back(mk(a[idx]+a[i],mk(idx,i)));
       }
   }

    for(i=0;i<m;i++)
    {
        intt x,y,z;
        cin>>x>>y>>z;
        op.pb(mk(z,mk(x,y)));
    }
    sort(op.begin(),op.end());
    intt res=0;
    for(i=0;i<op.size();i++)
    {
        int x=findd(op[i].sc.fr);
        int y=findd(op[i].sc.sc);
        if(x!=y)
        {
            p[x]=y;
            res+=op[i].fr;
        }
    }
    cout<<res;
    return 0;
}


#include <bits/stdc++.h>
#include <vector>
#define pb push_back
#define sc second
#define fr first
#define mk make_pair
#define ii pair<int,int>
typedef long long intt;
using namespace std;
int p[200004];
int findd(int x)
{
    if(x==p[x])
        return x;
    return x=findd(p[x]);
}
int main()
{
  int n,m,i;
  cin>>n>>m;
  priority_queue <pair<int,ii>,vector <pair<int,ii> >,greater <pair<int,ii> > >op;
   vector <pair<int,int> > d;
   for(i=1;i<=n;i++)
   {
       int x;
       cin>>x;
       p[i]=i;
       d.pb(mk(x,i));
   }
   sort(d.begin(),d.end());
   for(i=1;i<d.size();i++)
    op.push(mk(d[0].fr+d[i].fr,mk(d[0].sc,d[i].sc)));
    for(i=0;i<m;i++)
    {
        int x,y,z;
        cin>>x>>y>>z;
        op.push(mk(z,mk(x,y)));
    }
    intt res=0;
    while(!op.empty())
    {
        pair<int,ii> f=op.top();
        op.pop();
        int x=findd(f.sc.fr);
        int y=findd(f.sc.sc);
        if(x!=y)
        {
            p[x]=y;
            res+=f.fr;
        }
    }
    cout<<res;
    return 0;
}


#include<bits/stdc++.h>
// #include <ext/pb_ds/assoc_container.hpp>
// #include <ext/pb_ds/tree_policy.hpp>

#define int  long long
#define rep(i,begin,end) for(__typeof(end)i=(begin)-((begin)>(end));i!=(end)-((begin)>(end));i+=1-2*((begin)>(end)))
#define F first
#define S second
#define sz(x) ((int)x.size())
#define pii pair<int,int>
#define vi vector<int>
#define vii vector<pii>
#define pb push_back
#define pf push_front
#define eb emplace_back //FASTER THAN PUSH BACK!
#define all(v) (v).begin(), (v).end()
#define mod 1000000007
#define mi multiset<int>
#define mii multiset<pii>
#define what_is(x) cerr << #x << " is " << x <<"\n";
#define sortA(v) sort(v.begin(), v.end())
#define sortD(v) sort(v.rbegin(), v.rend())
#define PI 3.14159265358979323846
#define vout(a) for(auto x:a) cout<<x<<" ";
#define INF 10000000000000

// #define ordered_set tree<ll, null_type, less<ll>, rb_tree_tag, tree_order_statistics_node_update>

// using namespace __gnu_pbds;
using namespace std;

int lcm(int a,int b) {return (a*(b/__gcd(a,b)));}

struct Edge
{
    int u, v, weight;
    bool operator<(Edge const& other) {
        return weight < other.weight;
    }
};

const int maxn=100005;
vi Union(maxn),Size(maxn),value(maxn);
vector<Edge> edge(maxn),mst;
map<int,int> vis;
int cost=0;

void initialize(int N)
{
    for(int i=1;i<=N;i++)
    {
        Union[i]=i;
        Size[i]=1;
    }
}

int root(int i)
{
    while(Union[i]!=i)
    {
        Union[i]=Union[Union[i]] ;
        i=Union[i];
    }
    return i;
}

void weightedUnion(int A,int B)
{
    int root_A=root(A);
    int root_B=root(B);
    if(root_A==root_B)
    {
        return;
    }
    if(Size[root_A]<Size[root_B])
    {
        Union[root_A]=Union[root_B];
        Size[root_B]+=Size[root_A];
    }
    else
    {
        Union[root_B]=Union[root_A];
        Size[root_A]+=Size[root_B];
    }
}

bool find(int A,int B)
{
    if(root(A)==root(B))
    {
        return true;
    }
    else
    {
          return false;
    }
}

void kruskal()
{
    sort(all(edge));
    for(Edge e:edge)
    {
        if(!find(e.u,e.v))
        {
            weightedUnion(e.u,e.v);
            mst.pb(e);
            vis[e.u]++;
            vis[e.v]++;
            cost+=e.weight;
        }
    }
}

void solve()
{
    int t,n,m,i,k,r,l,u,v,w,j,s,sum=0,pos,flag=0,count=0;
    string S,T,U;
    int y,x;
    cin>>n>>m;
    value.resize(n+1);
    value[0]=INF;
    rep(i,1,n+1) cin>>value[i];
    int mn=*min_element(all(value));
    rep(i,1,n+1) if(value[i]==mn) {pos=i;break;}
    initialize(n+1);
    edge.resize(m);
    i=0;
    while(m--)
    {
        cin>>edge[i].u>>edge[i].v>>edge[i].weight;
        edge[i].weight=min(edge[i].weight,value[edge[i].u]+value[edge[i].v]);
        i++;
    }
    rep(i,1,n+1)
    {
        if(value[i]!=mn)
        {
            Edge e;
            e.u=i;
            e.v=pos;
            e.weight=mn+value[i];
            edge.pb(e);
        }
        else
        {
            if(i!=pos)
            {
                Edge e;
                e.u=i;
                e.v=i;
                e.weight=2*mn;
                edge.pb(e);
            }
        }
    }
    kruskal();
    rep(i,1,n+1)
    {
        if(!vis[i])
        {
            cost+=mn+value[i];
        }
    }
    cout<<cost;
}

signed main()
{
    #ifndef ONLINE_JUDGE
       freopen("input.txt","r",stdin);
       freopen("output.txt","w",stdout);
    #endif
    ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);
    int t=1;
    // cin>>t;
    while(t--)
    {
        solve();
        if(t)cout<<"\n";
    }
    return 0;
}


#include<bits/stdc++.h>
// #include <ext/pb_ds/assoc_container.hpp>
// #include <ext/pb_ds/tree_policy.hpp>

#define int  long long
#define rep(i,begin,end) for(__typeof(end)i=(begin)-((begin)>(end));i!=(end)-((begin)>(end));i+=1-2*((begin)>(end)))
#define F first
#define S second
#define sz(x) ((int)x.size())
#define pii pair<int,int>
#define vi vector<int>
#define vii vector<pii>
#define pb push_back
#define pf push_front
#define eb emplace_back
#define all(v) (v).begin(), (v).end()
#define mod 1000000007
#define mi multiset<int>
#define mii multiset<pii>
#define what_is(x) cerr << #x << " is " << x <<"\n";
#define sortA(v) sort(v.begin(), v.end())
#define sortD(v) sort(v.rbegin(), v.rend())
#define PI 3.14159265358979323846
#define vout(a) for(auto x:a) cout<<x<<" ";
#define INF 1000000000000000

// #define ordered_set tree<ll, null_type, less<ll>, rb_tree_tag, tree_order_statistics_node_update>

// using namespace __gnu_pbds;
using namespace std;

int lcm(int a,int b) {return (a*(b/__gcd(a,b)));}

struct Edge
{
    int u, v, weight;
    bool operator<(Edge const& other) {
        return weight < other.weight;
    }
};

const int maxn=200005;
vi Union(maxn),Size(maxn),value(maxn);
vector<Edge> edge(2*maxn),mst;
map<int,int> vis;
int cost=0;

void initialize(int N)
{
    for(int i=1;i<=N;i++)
    {
        Union[i]=i;
        Size[i]=1;
    }
}

int root(int i)
{
    while(Union[i]!=i)
    {
        Union[i]=Union[Union[i]] ;
        i=Union[i];
    }
    return i;
}

void weightedUnion(int A,int B)
{
    int root_A=root(A);
    int root_B=root(B);
    if(root_A==root_B)
    {
        return;
    }
    if(Size[root_A]<Size[root_B])
    {
        Union[root_A]=Union[root_B];
        Size[root_B]+=Size[root_A];
    }
    else
    {
        Union[root_B]=Union[root_A];
        Size[root_A]+=Size[root_B];
    }
}

bool find(int A,int B)
{
    if(root(A)==root(B))
    {
        return true;
    }
    else
    {
        return false;
    }
}

int ok;

void kruskal()
{
    sort(all(edge));
    for(Edge e:edge)
    {
        if(!find(e.u,e.v))
        {
            weightedUnion(e.u,e.v);
            mst.pb(e);
            ok=e.u;
            vis[e.u]++;
            vis[e.v]++;
            cost+=e.weight;
        }
    }
}

void solve()
{
    int t,n,m,i,k,r,l,u,v,w,j,s,sum=0,pos,flag=0,count=0;
    string S,T,U;
    int y,x;
    cin>>n>>m;
    value.resize(n+1);
    value[0]=INF;
    rep(i,1,n+1)
    {
        cin>>value[i];
    }

    int mn=*min_element(all(value));

    rep(i,1,n+1)
    {
        if(value[i]==mn)
        {
            pos=i;
            break;
        }
    }
    initialize(n+1);
    edge.resize(m);
    i=0;
    while(m--)
    {
        cin>>edge[i].u>>edge[i].v>>edge[i].weight;
        edge[i].weight=min(edge[i].weight,value[edge[i].u]+value[edge[i].v]);
        i++;
    }
    rep(i,1,n+1)
    {
        if(value[i]!=mn)
        {
            Edge e;
            e.u=i;
            e.v=pos;
            e.weight=mn+value[i];
            edge.pb(e);
        }
        else
        {
            if(i!=pos)
            {
                Edge e;
                e.u=i;
                e.v=i;
                e.weight=2*mn;
                edge.pb(e);
            }
        }
    }
    kruskal();
    rep(i,1,n+1)
    {
        if(!find(ok,i)&&i!=pos)
        {
            cost+=mn+value[i];
        }
    }
    cout<<cost;
}

signed main()
{
    #ifndef ONLINE_JUDGE
       freopen("input.txt","r",stdin);
       freopen("output.txt","w",stdout);
    #endif
    ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);
    int t=1;
    // cin>>t;
    while(t--)
    {
        solve();
        if(t)cout<<"\n";
    }
    return 0;
}


#include<bits/stdc++.h>
// #include <ext/pb_ds/assoc_container.hpp>
// #include <ext/pb_ds/tree_policy.hpp>

#define int  long long
#define rep(i,begin,end) for(__typeof(end)i=(begin)-((begin)>(end));i!=(end)-((begin)>(end));i+=1-2*((begin)>(end)))
#define F first
#define S second
#define sz(x) ((int)x.size())
#define pii pair<int,int>
#define vi vector<int>
#define vii vector<pii>
#define pb push_back
#define pf push_front
#define eb emplace_back
#define all(v) (v).begin(), (v).end()
#define mod 1000000007
#define mi multiset<int>
#define mii multiset<pii>
#define what_is(x) cerr << #x << " is " << x <<"\n";
#define sortA(v) sort(v.begin(), v.end())
#define sortD(v) sort(v.rbegin(), v.rend())
#define PI 3.14159265358979323846
#define vout(a) for(auto x:a) cout<<x<<" ";
#define INF 1000000000000000

// #define ordered_set tree<ll, null_type, less<ll>, rb_tree_tag, tree_order_statistics_node_update>

// using namespace __gnu_pbds;
using namespace std;

int lcm(int a,int b) {return (a*(b/__gcd(a,b)));}

struct Edge
{
    int u, v, weight;
    bool operator<(Edge const& other) {
        return weight < other.weight;
    }
};

const int maxn=200005;
vi Union(maxn),Size(maxn),value(maxn);
vector<Edge> edge(2*maxn),mst;
map<int,int> vis;
int cost=0;

void initialize(int N)
{
    for(int i=1;i<=N;i++)
    {
        Union[i]=i;
        Size[i]=1;
    }
}

int root(int i)
{
    while(Union[i]!=i)
    {
        Union[i]=Union[Union[i]] ;
        i=Union[i];
    }
    return i;
}

void weightedUnion(int A,int B)
{
    int root_A=root(A);
    int root_B=root(B);
    if(root_A==root_B)
    {
        return;
    }
    if(Size[root_A]<Size[root_B])
    {
        Union[root_A]=Union[root_B];
        Size[root_B]+=Size[root_A];
    }
    else
    {
        Union[root_B]=Union[root_A];
        Size[root_A]+=Size[root_B];
    }
}

bool find(int A,int B)
{
    if(root(A)==root(B))
    {
        return true;
    }
    else
    {
        return false;
    }
}

void kruskal()
{
    sort(all(edge));
    for(Edge e:edge)
    {
        if(!find(e.u,e.v))
        {
            weightedUnion(e.u,e.v);
            mst.pb(e);
            vis[e.u]++;
            vis[e.v]++;
            cost+=e.weight;
        }
    }
}

void solve()
{
    int t,n,m,i,k,r,l,u,v,w,j,s,sum=0,pos,flag=0,count=0;
    string S,T,U;
    int y,x;
    cin>>n>>m;
    value.resize(n+1);
    value[0]=INF;
    rep(i,1,n+1)
    {
        cin>>value[i];
    }

    int mn=*min_element(all(value));

    rep(i,1,n+1)
    {
        if(value[i]==mn)
        {
            pos=i;
            break;
        }
    }
    initialize(n+1);
    edge.resize(m);
    i=0;
    while(m--)
    {
        cin>>edge[i].u>>edge[i].v>>edge[i].weight;
        edge[i].weight=min(edge[i].weight,value[edge[i].u]+value[edge[i].v]);
        i++;
    }
    rep(i,1,n+1)
    {
        if(value[i]!=mn)
        {
            Edge e;
            e.u=i;
            e.v=pos;
            e.weight=mn+value[i];
            edge.pb(e);
        }
        else
        {
            if(i!=pos)
            {
                Edge e;
                e.u=i;
                e.v=i;
                e.weight=2*mn;
                edge.pb(e);
            }
        }
    }
    kruskal();
    rep(i,1,n+1)
    {
        if(!vis[i]&&i!=pos)
        {
            cost+=mn+value[i];
        }
    }
    cout<<cost;
}

signed main()
{
    #ifndef ONLINE_JUDGE
       freopen("input.txt","r",stdin);
       freopen("output.txt","w",stdout);
    #endif
    ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);
    int t=1;
    // cin>>t;
    while(t--)
    {
        solve();
        if(t)cout<<"\n";
    }
    return 0;
}


#include<bits/stdc++.h>
// #include <ext/pb_ds/assoc_container.hpp>
// #include <ext/pb_ds/tree_policy.hpp>

#define int  long long
#define rep(i,begin,end) for(__typeof(end)i=(begin)-((begin)>(end));i!=(end)-((begin)>(end));i+=1-2*((begin)>(end)))
#define F first
#define S second
#define sz(x) ((int)x.size())
#define pii pair<int,int>
#define vi vector<int>
#define vii vector<pii>
#define pb push_back
#define pf push_front
#define eb emplace_back //FASTER THAN PUSH BACK!
#define all(v) (v).begin(), (v).end()
#define mod 1000000007
#define mi multiset<int>
#define mii multiset<pii>
#define what_is(x) cerr << #x << " is " << x <<"\n";
#define sortA(v) sort(v.begin(), v.end())
#define sortD(v) sort(v.rbegin(), v.rend())
#define PI 3.14159265358979323846
#define vout(a) for(auto x:a) cout<<x<<" ";
#define INF 10000000000000

// #define ordered_set tree<ll, null_type, less<ll>, rb_tree_tag, tree_order_statistics_node_update>

// using namespace __gnu_pbds;
using namespace std;

int lcm(int a,int b) {return (a*(b/__gcd(a,b)));}

struct Edge
{
    int u, v, weight;
    bool operator<(Edge const& other) {
        return weight < other.weight;
    }
};

const int maxn=200005;
vi Union(maxn),Size(maxn),value(maxn);
vector<Edge> edge(maxn),mst;
map<int,int> vis;
int cost=0;

void initialize(int N)
{
    for(int i=1;i<=N;i++)
    {
        Union[i]=i;
        Size[i]=1;
    }
}

int root(int i)
{
    while(Union[i]!=i)
    {
        Union[i]=Union[Union[i]] ;
        i=Union[i];
    }
    return i;
}

void weightedUnion(int A,int B)
{
    int root_A=root(A);
    int root_B=root(B);
    if(root_A==root_B)
    {
        return;
    }
    if(Size[root_A]<Size[root_B])
    {
        Union[root_A]=Union[root_B];
        Size[root_B]+=Size[root_A];
    }
    else
    {
        Union[root_B]=Union[root_A];
        Size[root_A]+=Size[root_B];
    }
}

bool find(int A,int B)
{
    if(root(A)==root(B))
    {
        return true;
    }
    else
    {
          return false;
    }
}

void kruskal()
{
    sort(all(edge));
    for(Edge e:edge)
    {
        if(!find(e.u,e.v))
        {
            weightedUnion(e.u,e.v);
            mst.pb(e);
            vis[e.u]++;
            vis[e.v]++;
            cost+=e.weight;
        }
    }
}

void solve()
{
    int t,n,m,i,k,r,l,u,v,w,j,s,sum=0,pos,flag=0,count=0;
    string S,T,U;
    int y,x;
    cin>>n>>m;
    value.resize(n+1);
    value[0]=INF;
    rep(i,1,n+1) cin>>value[i];
    int mn=*min_element(all(value));
    rep(i,1,n+1) if(value[i]==mn) {pos=i;break;}
    initialize(n+1);
    edge.resize(m);
    i=0;
    while(m--)
    {
        cin>>edge[i].u>>edge[i].v>>edge[i].weight;
        edge[i].weight=min(edge[i].weight,value[edge[i].u]+value[edge[i].v]);
        i++;
    }
    rep(i,1,n+1)
    {
        if(value[i]!=mn)
        {
            Edge e;
            e.u=i;
            e.v=pos;
            e.weight=mn+value[i];
            edge.pb(e);
        }
        else
        {
            if(i!=pos)
            {
                Edge e;
                e.u=i;
                e.v=i;
                e.weight=2*mn;
                edge.pb(e);
            }
        }
    }
    kruskal();
    rep(i,1,n+1)
    {
        if(!vis[i])
        {
            cost+=mn+value[i];
        }
    }
    cout<<cost;
}

signed main()
{
    #ifndef ONLINE_JUDGE
       freopen("input.txt","r",stdin);
       freopen("output.txt","w",stdout);
    #endif
    ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);
    int t=1;
    // cin>>t;
    while(t--)
    {
        solve();
        if(t)cout<<"\n";
    }
    return 0;
}


#include<bits/stdc++.h>
// #include <ext/pb_ds/assoc_container.hpp>
// #include <ext/pb_ds/tree_policy.hpp>

#define int  long long
#define rep(i,begin,end) for(__typeof(end)i=(begin)-((begin)>(end));i!=(end)-((begin)>(end));i+=1-2*((begin)>(end)))
#define F first
#define S second
#define sz(x) ((int)x.size())
#define pii pair<int,int>
#define vi vector<int>
#define vii vector<pii>
#define pb push_back
#define pf push_front
#define eb emplace_back //FASTER THAN PUSH BACK!
#define all(v) (v).begin(), (v).end()
#define mod 1000000007
#define mi multiset<int>
#define mii multiset<pii>
#define what_is(x) cerr << #x << " is " << x <<"\n";
#define sortA(v) sort(v.begin(), v.end())
#define sortD(v) sort(v.rbegin(), v.rend())
#define PI 3.14159265358979323846
#define vout(a) for(auto x:a) cout<<x<<" ";
#define INF 10000000000000

// #define ordered_set tree<ll, null_type, less<ll>, rb_tree_tag, tree_order_statistics_node_update>

// using namespace __gnu_pbds;
using namespace std;

int lcm(int a,int b) {return (a*(b/__gcd(a,b)));}

struct Edge
{
    int u, v, weight;
    bool operator<(Edge const& other) {
        return weight < other.weight;
    }
};

const int maxn=200005;
vi Union(maxn),Size(maxn),value(maxn);
vector<Edge> edge(2*maxn),mst;
map<int,int> vis;
int cost=0;

void initialize(int N)
{
    for(int i=1;i<=N;i++)
    {
        Union[i]=i;
        Size[i]=1;
    }
}

int root(int i)
{
    while(Union[i]!=i)
    {
        Union[i]=Union[Union[i]] ;
        i=Union[i];
    }
    return i;
}

void weightedUnion(int A,int B)
{
    int root_A=root(A);
    int root_B=root(B);
    if(root_A==root_B)
    {
        return;
    }
    if(Size[root_A]<Size[root_B])
    {
        Union[root_A]=Union[root_B];
        Size[root_B]+=Size[root_A];
    }
    else
    {
        Union[root_B]=Union[root_A];
        Size[root_A]+=Size[root_B];
    }
}

bool find(int A,int B)
{
    if(root(A)==root(B))
    {
        return true;
    }
    else
    {
          return false;
    }
}

void kruskal()
{
    sort(all(edge));
    for(Edge e:edge)
    {
        if(!find(e.u,e.v))
        {
            weightedUnion(e.u,e.v);
            mst.pb(e);
            vis[e.u]++;
            vis[e.v]++;
            cost+=e.weight;
        }
    }
}

void solve()
{
    int t,n,m,i,k,r,l,u,v,w,j,s,sum=0,pos,flag=0,count=0;
    string S,T,U;
    int y,x;
    cin>>n>>m;
    value.resize(n+1);
    value[0]=INF;
    rep(i,1,n+1)
    {
        cin>>value[i];
    }
    int mn=*min_element(all(value));
    rep(i,1,n+1)
    {
        if(value[i]==mn)
        {
            pos=i;
            break;
        }
    }
    initialize(n+1);
    edge.resize(m);
    i=0;
    while(m--)
    {
        cin>>edge[i].u>>edge[i].v>>edge[i].weight;
        edge[i].weight=min(edge[i].weight,value[edge[i].u]+value[edge[i].v]);
        i++;
    }
    rep(i,1,n+1)
    {
        if(value[i]!=mn)
        {
            Edge e;
            e.u=i;
            e.v=pos;
            e.weight=mn+value[i];
            edge.pb(e);
        }
        else
        {
            if(i!=pos)
            {
                Edge e;
                e.u=i;
                e.v=i;
                e.weight=2*mn;
                edge.pb(e);
            }
        }
    }
    kruskal();
    rep(i,1,n+1)
    {
        if(!vis[i])
        {
            cost+=mn+value[i];
        }
    }
    cout<<cost;
}

signed main()
{
    #ifndef ONLINE_JUDGE
       freopen("input.txt","r",stdin);
       freopen("output.txt","w",stdout);
    #endif
    ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);
    int t=1;
    // cin>>t;
    while(t--)
    {
        solve();
        if(t)cout<<"\n";
    }
    return 0;
}


#include<bits/stdc++.h>
// #include <ext/pb_ds/assoc_container.hpp>
// #include <ext/pb_ds/tree_policy.hpp>

#define int  long long
#define rep(i,begin,end) for(__typeof(end)i=(begin)-((begin)>(end));i!=(end)-((begin)>(end));i+=1-2*((begin)>(end)))
#define F first
#define S second
#define sz(x) ((int)x.size())
#define pii pair<int,int>
#define vi vector<int>
#define vii vector<pii>
#define pb push_back
#define pf push_front
#define eb emplace_back
#define all(v) (v).begin(), (v).end()
#define mod 1000000007
#define mi multiset<int>
#define mii multiset<pii>
#define what_is(x) cerr << #x << " is " << x <<"\n";
#define sortA(v) sort(v.begin(), v.end())
#define sortD(v) sort(v.rbegin(), v.rend())
#define PI 3.14159265358979323846
#define vout(a) for(auto x:a) cout<<x<<" ";
#define INF 1000000000000000

// #define ordered_set tree<ll, null_type, less<ll>, rb_tree_tag, tree_order_statistics_node_update>

// using namespace __gnu_pbds;
using namespace std;

int lcm(int a,int b) {return (a*(b/__gcd(a,b)));}

struct Edge
{
    int u, v, weight;
    bool operator<(Edge const& other) {
        return weight < other.weight;
    }
};

const int maxn=200005;
vi Union(maxn),Size(maxn),value(maxn);
vector<Edge> edge(2*maxn),mst;
map<int,int> vis;
int cost=0;

void initialize(int N)
{
    for(int i=1;i<=N;i++)
    {
        Union[i]=i;
        Size[i]=1;
    }
}

int root(int i)
{
    while(Union[i]!=i)
    {
        Union[i]=Union[Union[i]] ;
        i=Union[i];
    }
    return i;
}

void weightedUnion(int A,int B)
{
    int root_A=root(A);
    int root_B=root(B);
    if(root_A==root_B)
    {
        return;
    }
    if(Size[root_A]<Size[root_B])
    {
        Union[root_A]=Union[root_B];
        Size[root_B]+=Size[root_A];
    }
    else
    {
        Union[root_B]=Union[root_A];
        Size[root_A]+=Size[root_B];
    }
}

bool find(int A,int B)
{
    if(root(A)==root(B))
    {
        return true;
    }
    else
    {
        return false;
    }
}

int ok;

void kruskal()
{
    sort(all(edge));
    for(Edge e:edge)
    {
        if(!find(e.u,e.v))
        {
            weightedUnion(e.u,e.v);
            // cout<<e.u<<" "<<e.v<<" "<<value[e.u]<<" "<<value[e.v]<<" "<<e.weight<<"\n";
            mst.pb(e);
            ok=e.u;
            vis[e.u]++;
            vis[e.v]++;
            cost+=e.weight;
        }
    }
}

void solve()
{
    int t,n,m,i,k,r,l,u,v,w,j,s,sum=0,pos,flag=0,count=0;
    string S,T,U;
    int y,x;
    cin>>n>>m;
    value.resize(n+1);
    value[0]=INF;
    rep(i,1,n+1)
    {
        cin>>value[i];
    }

    int mn=*min_element(all(value));

    rep(i,1,n+1)
    {
        if(value[i]==mn)
        {
            pos=i;
            break;
        }
    }
    initialize(n+1);
    edge.resize(m);
    i=0;
    while(m--)
    {
        cin>>edge[i].u>>edge[i].v>>edge[i].weight;
        edge[i].weight=min(edge[i].weight,value[edge[i].u]+value[edge[i].v]);
        i++;
    }
    rep(i,1,n+1)
    {
        if(value[i]!=mn)
        {
            Edge e;
            e.u=i;
            e.v=pos;
            e.weight=mn+value[i];
            edge.pb(e);
        }
        else
        {
            if(i!=pos)
            {
                Edge e;
                e.u=i;
                e.v=pos;
                e.weight=2*mn;
                edge.pb(e);
            }
        }
    }
    kruskal();
    // rep(i,1,n+1)
    // {
    //     if(!find(ok,i)&&i!=pos)
    //     {
    //         cost+=mn+value[i];
    //     }
    // }
    cout<<cost;
}

signed main()
{
    #ifndef ONLINE_JUDGE
       freopen("input.txt","r",stdin);
       freopen("output.txt","w",stdout);
    #endif
    ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);
    int t=1;
    // cin>>t;
    while(t--)
    {
        solve();
        if(t)cout<<"\n";
    }
    return 0;
}


#include<bits/stdc++.h>
// #include <ext/pb_ds/assoc_container.hpp>
// #include <ext/pb_ds/tree_policy.hpp>

#define int  long long
#define rep(i,begin,end) for(__typeof(end)i=(begin)-((begin)>(end));i!=(end)-((begin)>(end));i+=1-2*((begin)>(end)))
#define F first
#define S second
#define sz(x) ((int)x.size())
#define pii pair<int,int>
#define vi vector<int>
#define vii vector<pii>
#define pb push_back
#define pf push_front
#define eb emplace_back
#define all(v) (v).begin(), (v).end()
#define mod 1000000007
#define mi multiset<int>
#define mii multiset<pii>
#define what_is(x) cerr << #x << " is " << x <<"\n";
#define sortA(v) sort(v.begin(), v.end())
#define sortD(v) sort(v.rbegin(), v.rend())
#define PI 3.14159265358979323846
#define vout(a) for(auto x:a) cout<<x<<" ";
#define INF 1000000000000000

// #define ordered_set tree<ll, null_type, less<ll>, rb_tree_tag, tree_order_statistics_node_update>

// using namespace __gnu_pbds;
using namespace std;

int lcm(int a,int b) {return (a*(b/__gcd(a,b)));}

struct Edge
{
    int u, v, weight;
    bool operator<(Edge const& other) {
        return weight < other.weight;
    }
};

const int maxn=200005;
vi Union(maxn),Size(maxn),value(maxn);
vector<Edge> edge(2*maxn),mst;
map<int,int> vis;
int cost=0;

void initialize(int N)
{
    for(int i=1;i<=N;i++)
    {
        Union[i]=i;
        Size[i]=1;
    }
}

int root(int i)
{
    while(Union[i]!=i)
    {
        Union[i]=Union[Union[i]] ;
        i=Union[i];
    }
    return i;
}

void weightedUnion(int A,int B)
{
    int root_A=root(A);
    int root_B=root(B);
    if(root_A==root_B)
    {
        return;
    }
    if(Size[root_A]<Size[root_B])
    {
        Union[root_A]=Union[root_B];
        Size[root_B]+=Size[root_A];
    }
    else
    {
        Union[root_B]=Union[root_A];
        Size[root_A]+=Size[root_B];
    }
}

bool find(int A,int B)
{
    if(root(A)==root(B))
    {
        return true;
    }
    else
    {
        return false;
    }
}

int ok;

void kruskal()
{
    sort(all(edge));
    for(Edge e:edge)
    {
        if(!find(e.u,e.v))
        {
            weightedUnion(e.u,e.v);
            cout<<e.u<<" "<<e.v<<" "<<value[e.u]<<" "<<value[e.v]<<" "<<e.weight<<"\n";
            mst.pb(e);
            ok=e.u;
            vis[e.u]++;
            vis[e.v]++;
            cost+=e.weight;
        }
    }
}

void solve()
{
    int t,n,m,i,k,r,l,u,v,w,j,s,sum=0,pos,flag=0,count=0;
    string S,T,U;
    int y,x;
    cin>>n>>m;
    value.resize(n+1);
    value[0]=INF;
    rep(i,1,n+1)
    {
        cin>>value[i];
    }

    int mn=*min_element(all(value));

    rep(i,1,n+1)
    {
        if(value[i]==mn)
        {
            pos=i;
            break;
        }
    }
    initialize(n+1);
    edge.resize(m);
    i=0;
    while(m--)
    {
        cin>>edge[i].u>>edge[i].v>>edge[i].weight;
        edge[i].weight=min(edge[i].weight,value[edge[i].u]+value[edge[i].v]);
        i++;
    }
    rep(i,1,n+1)
    {
        if(value[i]!=mn)
        {
            Edge e;
            e.u=i;
            e.v=pos;
            e.weight=mn+value[i];
            edge.pb(e);
        }
        else
        {
            if(i!=pos)
            {
                Edge e;
                e.u=i;
                e.v=pos;
                e.weight=2*mn;
                edge.pb(e);
            }
        }
    }
    kruskal();
    // rep(i,1,n+1)
    // {
    //     if(!find(ok,i)&&i!=pos)
    //     {
    //         cost+=mn+value[i];
    //     }
    // }
    cout<<cost;
}

signed main()
{
    #ifndef ONLINE_JUDGE
       freopen("input.txt","r",stdin);
       freopen("output.txt","w",stdout);
    #endif
    ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);
    int t=1;
    // cin>>t;
    while(t--)
    {
        solve();
        if(t)cout<<"\n";
    }
    return 0;
}


#include<bits/stdc++.h>
// #include <ext/pb_ds/assoc_container.hpp>
// #include <ext/pb_ds/tree_policy.hpp>

#define int  long long
#define rep(i,begin,end) for(__typeof(end)i=(begin)-((begin)>(end));i!=(end)-((begin)>(end));i+=1-2*((begin)>(end)))
#define F first
#define S second
#define sz(x) ((int)x.size())
#define pii pair<int,int>
#define vi vector<int>
#define vii vector<pii>
#define pb push_back
#define pf push_front
#define eb emplace_back
#define all(v) (v).begin(), (v).end()
#define mod 1000000007
#define mi multiset<int>
#define mii multiset<pii>
#define what_is(x) cerr << #x << " is " << x <<"\n";
#define sortA(v) sort(v.begin(), v.end())
#define sortD(v) sort(v.rbegin(), v.rend())
#define PI 3.14159265358979323846
#define vout(a) for(auto x:a) cout<<x<<" ";
#define INF 1000000000000000

// #define ordered_set tree<ll, null_type, less<ll>, rb_tree_tag, tree_order_statistics_node_update>

// using namespace __gnu_pbds;
using namespace std;

int lcm(int a,int b) {return (a*(b/__gcd(a,b)));}

struct Edge
{
    int u, v, weight;
    bool operator<(Edge const& other) {
        return weight < other.weight;
    }
};

const int maxn=200005;
vi Union(maxn),Size(maxn),value(maxn);
vector<Edge> edge(2*maxn),mst;
map<int,int> vis;
int cost=0;

void initialize(int N)
{
    for(int i=1;i<=N;i++)
    {
        Union[i]=i;
        Size[i]=1;
    }
}

int root(int i)
{
    while(Union[i]!=i)
    {
        Union[i]=Union[Union[i]] ;
        i=Union[i];
    }
    return i;
}

void weightedUnion(int A,int B)
{
    int root_A=root(A);
    int root_B=root(B);
    if(root_A==root_B)
    {
        return;
    }
    if(Size[root_A]<Size[root_B])
    {
        Union[root_A]=Union[root_B];
        Size[root_B]+=Size[root_A];
    }
    else
    {
        Union[root_B]=Union[root_A];
        Size[root_A]+=Size[root_B];
    }
}

bool find(int A,int B)
{
    if(root(A)==root(B))
    {
        return true;
    }
    else
    {
        return false;
    }
}

int ok;

void kruskal()
{
    sort(all(edge));
    for(Edge e:edge)
    {
        if(!find(e.u,e.v))
        {
            weightedUnion(e.u,e.v);
            mst.pb(e);
            ok=e.u;
            vis[e.u]++;
            vis[e.v]++;
            cost+=e.weight;
        }
    }
}

void solve()
{
    int t,n,m,i,k,r,l,u,v,w,j,s,sum=0,pos,flag=0,count=0;
    string S,T,U;
    int y,x;
    cin>>n>>m;
    value.resize(n+1);
    value[0]=INF;
    rep(i,1,n+1)
    {
        cin>>value[i];
    }

    int mn=*min_element(all(value));

    rep(i,1,n+1)
    {
        if(value[i]==mn)
        {
            pos=i;
            break;
        }
    }
    initialize(n+1);
    edge.resize(m);
    i=0;
    while(m--)
    {
        cin>>edge[i].u>>edge[i].v>>edge[i].weight;
        edge[i].weight=min(edge[i].weight,value[edge[i].u]+value[edge[i].v]);
        i++;
    }
    rep(i,1,n+1)
    {
        if(value[i]!=mn)
        {
            Edge e;
            e.u=i;
            e.v=pos;
            e.weight=mn+value[i];
            edge.pb(e);
        }
        else
        {
            if(i!=pos)
            {
                Edge e;
                e.u=i;
                e.v=i;
                e.weight=2*mn;
                edge.pb(e);
            }
        }
    }
    kruskal();
    // rep(i,1,n+1)
    // {
    //     if(!find(ok,i)&&i!=pos)
    //     {
    //         cost+=mn+value[i];
    //     }
    // }
    cout<<cost;
}

signed main()
{
    #ifndef ONLINE_JUDGE
       freopen("input.txt","r",stdin);
       freopen("output.txt","w",stdout);
    #endif
    ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);
    int t=1;
    // cin>>t;
    while(t--)
    {
        solve();
        if(t)cout<<"\n";
    }
    return 0;
}


//#define INTERACTIVE
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp> // gp_hash_table<int, int> == hash map
#include <ext/pb_ds/tree_policy.hpp>
using namespace std;
using namespace __gnu_pbds;
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef pair<double, double> pdd;
template <typename T> using min_heap = priority_queue<T, vector<T>, greater<T>>;
template <typename T> using max_heap = priority_queue<T, vector<T>, less<T>>;
template <typename T> using ordered_set = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;
template <typename K, typename V> using hashmap = gp_hash_table<K, V>;

template<typename A, typename B> ostream& operator<<(ostream& out, pair<A, B> p) { out << "(" << p.first << ", " << p.second << ")"; return out;}
template<typename T> ostream& operator<<(ostream& out, vector<T> v) { out << "["; for(auto& x : v) out << x << ", "; out << "]";return out;}
template<typename T> ostream& operator<<(ostream& out, set<T> v) { out << "{"; for(auto& x : v) out << x << ", "; out << "}"; return out; }
template<typename K, typename V> ostream& operator<<(ostream& out, map<K, V> m) { out << "{"; for(auto& e : m) out << e.first << " -> " << e.second << ", "; out << "}"; return out; }
template<typename K, typename V> ostream& operator<<(ostream& out, hashmap<K, V> m) { out << "{"; for(auto& e : m) out << e.first << " -> " << e.second << ", "; out << "}"; return out; }

#define FAST_IO ios_base::sync_with_stdio(false); cin.tie(NULL)
#define TESTS(t) int NUMBER_OF_TESTS; cin >> NUMBER_OF_TESTS; for(int t = 1; t <= NUMBER_OF_TESTS; t++)
#define FOR(i, begin, end) for (int i = (begin) - ((begin) > (end)); i != (end) - ((begin) > (end)); i += 1 - 2 * ((begin) > (end)))
#define sgn(a)     ((a) > eps ? 1 : ((a) < -eps ? -1 : 0))
#define precise(x) fixed << setprecision(x)
#define debug(x) cerr << "> " << #x << " = " << x << endl;
#define pb push_back
#define rnd(a, b) (uniform_int_distribution<int>((a), (b))(rng))
#ifndef LOCAL
    #define cerr if(0)cout
    #ifndef INTERACTIVE
        #define endl "\n"
    #endif
#endif
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
clock_t __clock__;
void startTime() {__clock__ = clock();}
void timeit(string msg) {cerr << "> " << msg << ": " << precise(6) << ld(clock()-__clock__)/CLOCKS_PER_SEC << endl;}
template<typename T> inline void maxi(T& a, T b) { a = max(a, b); }
template<typename T> inline void mini(T& a, T b) { a = min(a, b); }
const ld PI = asin(1) * 2;
const ld eps = 1e-12;
const int oo = 2e9;
const ll OO = 2e18;
const ll MOD = 998244353;
const int MAXN = 50000;

int main() {
    FAST_IO;
    startTime();

    int n, m;
    cin >> n >> m;
    vector<pair<ll, int>> a(n);
    FOR(i, 0, n) {
        auto& x = a[i];
        x.second = i;
        cin >> x.first;
    }
    sort(a.begin(), a.end());
    int root = a[0].second;
    vector<ll> W(n);
    ll ans = 0;
    FOR(i, 1, n) {
        ll w = a[i].first + a[0].first;
        ans += w;
        W[a[i].second] = w;
    }

    debug(root);
    debug(a);
    debug(W);
    debug(ans);

    vector<pair<pii, ll>> spec(m);
    vector<pair<ll, pii>> cross;
    for(auto& x : spec) {
        cin >> x.first.first >> x.first.second >> x.second;
        x.first.first--;
        x.first.second--;
        if(x.first.second == root) swap(x.first.second, x.first.first);
        if(x.first.first == root) {
            if(x.second < W[x.first.second]) {
                ans += -W[x.first.second] + x.second;
                W[x.first.second] = x.second;
            }
        } else {
            cross.pb({x.second, x.first});
        }
    }
    debug(ans);
    sort(cross.begin(), cross.end());
    debug(cross);
    for(auto& e : cross) {
        int x = e.second.first;
        int y = e.second.second;
        ll w = e.first;
        if(W[x] == -1 && W[y] == -1) continue;
        if(W[x] == -1 && -W[y]+w < 0) {
            ans += -W[y] + w;
            W[y] = -1;
        } else if(W[y] == -1 && -W[x]+w < 0) {
            ans += -W[x]+w;
            W[x] = -1;
        } else if(W[x] > W[y] && -W[x]+w < 0) {
            ans += -W[x]+w;
            W[x] = -1;
        } else if(W[y] >= W[x] && -W[y]+w < 0){
            ans += -W[y]+w;
            W[y] = -1;
        }
    }
    cout << ans << endl;

    timeit("Finished");
    return 0;
}


//#define INTERACTIVE
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp> // gp_hash_table<int, int> == hash map
#include <ext/pb_ds/tree_policy.hpp>
using namespace std;
using namespace __gnu_pbds;
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef pair<double, double> pdd;
template <typename T> using min_heap = priority_queue<T, vector<T>, greater<T>>;
template <typename T> using max_heap = priority_queue<T, vector<T>, less<T>>;
template <typename T> using ordered_set = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;
template <typename K, typename V> using hashmap = gp_hash_table<K, V>;

template<typename A, typename B> ostream& operator<<(ostream& out, pair<A, B> p) { out << "(" << p.first << ", " << p.second << ")"; return out;}
template<typename T> ostream& operator<<(ostream& out, vector<T> v) { out << "["; for(auto& x : v) out << x << ", "; out << "]";return out;}
template<typename T> ostream& operator<<(ostream& out, set<T> v) { out << "{"; for(auto& x : v) out << x << ", "; out << "}"; return out; }
template<typename K, typename V> ostream& operator<<(ostream& out, map<K, V> m) { out << "{"; for(auto& e : m) out << e.first << " -> " << e.second << ", "; out << "}"; return out; }
template<typename K, typename V> ostream& operator<<(ostream& out, hashmap<K, V> m) { out << "{"; for(auto& e : m) out << e.first << " -> " << e.second << ", "; out << "}"; return out; }

#define FAST_IO ios_base::sync_with_stdio(false); cin.tie(NULL)
#define TESTS(t) int NUMBER_OF_TESTS; cin >> NUMBER_OF_TESTS; for(int t = 1; t <= NUMBER_OF_TESTS; t++)
#define FOR(i, begin, end) for (int i = (begin) - ((begin) > (end)); i != (end) - ((begin) > (end)); i += 1 - 2 * ((begin) > (end)))
#define sgn(a)     ((a) > eps ? 1 : ((a) < -eps ? -1 : 0))
#define precise(x) fixed << setprecision(x)
#define debug(x) cerr << "> " << #x << " = " << x << endl;
#define pb push_back
#define rnd(a, b) (uniform_int_distribution<int>((a), (b))(rng))
#ifndef LOCAL
    #define cerr if(0)cout
    #ifndef INTERACTIVE
        #define endl "\n"
    #endif
#endif
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
clock_t __clock__;
void startTime() {__clock__ = clock();}
void timeit(string msg) {cerr << "> " << msg << ": " << precise(6) << ld(clock()-__clock__)/CLOCKS_PER_SEC << endl;}
template<typename T> inline void maxi(T& a, T b) { a = max(a, b); }
template<typename T> inline void mini(T& a, T b) { a = min(a, b); }
const ld PI = asin(1) * 2;
const ld eps = 1e-12;
const int oo = 2e9;
const ll OO = 2e18;
const ll MOD = 998244353;
const int MAXN = 50000;

vector<int> par;
vector<int> sz;

int find(int a) {
    return par[a] = par[a] == a ? a : find(par[a]);
}

void unite(int a, int b) {
    a = find(a);
    b = find(b);
    if(sz[a] > sz[b]) swap(a, b);
    // sz[a] <= sz[b]
    sz[b] += sz[a];
    par[a] = b;
}

bool same(int a, int b) {
    return find(a) == find(b);
}

int main() {
    FAST_IO;
    startTime();

    int n, m;
    cin >> n >> m;
    vector<ll> a(n);
    sz.assign(n, 1);
    par.resize(n);
    FOR(i, 0, n) par[i] = i;
    int root = 0;
    FOR(i, 0, n) {
        cin >> a[i];
        if(a[i] < a[root]) root = i;
    }
    vector<pair<ll, pii>> edges;
    FOR(i, 0, n) {
        if(i != root) {
            edges.pb({a[root]+a[i], {root, i}});
        }
    }
    FOR(i, 0, m) {
        int x, y;
        ll w;
        cin >> x >> y >> w;
        x--;y--;
        edges.pb({w, {x, y}});
    }
    sort(edges.begin(), edges.end());
    ll ans = 0;
    int cnt = 0;
    for(int i = 0; cnt < n-1; i++) {
        int x = edges[i].second.first;
        int y = edges[i].second.second;
        ll w = edges[i].first;
        if(same(x, y)) continue;
        unite(x, y);
        ans += w;
        cnt++;
    }
    cout << ans << endl;

    timeit("Finished");
    return 0;
}


//#define INTERACTIVE
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp> // gp_hash_table<int, int> == hash map
#include <ext/pb_ds/tree_policy.hpp>
using namespace std;
using namespace __gnu_pbds;
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef pair<double, double> pdd;
template <typename T> using min_heap = priority_queue<T, vector<T>, greater<T>>;
template <typename T> using max_heap = priority_queue<T, vector<T>, less<T>>;
template <typename T> using ordered_set = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;
template <typename K, typename V> using hashmap = gp_hash_table<K, V>;

template<typename A, typename B> ostream& operator<<(ostream& out, pair<A, B> p) { out << "(" << p.first << ", " << p.second << ")"; return out;}
template<typename T> ostream& operator<<(ostream& out, vector<T> v) { out << "["; for(auto& x : v) out << x << ", "; out << "]";return out;}
template<typename T> ostream& operator<<(ostream& out, set<T> v) { out << "{"; for(auto& x : v) out << x << ", "; out << "}"; return out; }
template<typename K, typename V> ostream& operator<<(ostream& out, map<K, V> m) { out << "{"; for(auto& e : m) out << e.first << " -> " << e.second << ", "; out << "}"; return out; }
template<typename K, typename V> ostream& operator<<(ostream& out, hashmap<K, V> m) { out << "{"; for(auto& e : m) out << e.first << " -> " << e.second << ", "; out << "}"; return out; }

#define FAST_IO ios_base::sync_with_stdio(false); cin.tie(NULL)
#define TESTS(t) int NUMBER_OF_TESTS; cin >> NUMBER_OF_TESTS; for(int t = 1; t <= NUMBER_OF_TESTS; t++)
#define FOR(i, begin, end) for (int i = (begin) - ((begin) > (end)); i != (end) - ((begin) > (end)); i += 1 - 2 * ((begin) > (end)))
#define sgn(a)     ((a) > eps ? 1 : ((a) < -eps ? -1 : 0))
#define precise(x) fixed << setprecision(x)
#define debug(x) cerr << "> " << #x << " = " << x << endl;
#define pb push_back
#define rnd(a, b) (uniform_int_distribution<int>((a), (b))(rng))
#ifndef LOCAL
    #define cerr if(0)cout
    #ifndef INTERACTIVE
        #define endl "\n"
    #endif
#endif
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
clock_t __clock__;
void startTime() {__clock__ = clock();}
void timeit(string msg) {cerr << "> " << msg << ": " << precise(6) << ld(clock()-__clock__)/CLOCKS_PER_SEC << endl;}
template<typename T> inline void maxi(T& a, T b) { a = max(a, b); }
template<typename T> inline void mini(T& a, T b) { a = min(a, b); }
const ld PI = asin(1) * 2;
const ld eps = 1e-12;
const int oo = 2e9;
const ll OO = 2e18;
const ll MOD = 998244353;
const int MAXN = 50000;

vector<int> par;
vector<int> sz;
vector<ll> toRoot;

int find(int a) {
    return par[a] = par[a] == a ? a : find(par[a]);
}

void unite(int a, int b) {
    a = find(a);
    b = find(b);
    if(sz[a] > sz[b]) swap(a, b);
    // sz[a] <= sz[b]
    sz[b] += sz[a];
    par[a] = b;
    toRoot[b] = min(toRoot[b], toRoot[a]);
}

int main() {
    FAST_IO;
    startTime();

    int n, m;
    cin >> n >> m;
    vector<pair<ll, int>> a(n);
    sz.assign(n, 1);
    par.resize(n);
    toRoot.resize(n);
    FOR(i, 0, n) par[i] = i;
    FOR(i, 0, n) {
        auto& x = a[i];
        x.second = i;
        cin >> x.first;
    }
    sort(a.begin(), a.end());
    int root = a[0].second;
    vector<ll> W(n);
    ll ans = 0;
    FOR(i, 1, n) {
        ll w = a[i].first + a[0].first;
        ans += w;
        W[a[i].second] = w;
        toRoot[a[i].second] = w;
    }

    debug(root);
    debug(a);
    debug(W);
    debug(ans);

    vector<pair<pii, ll>> spec(m);
    vector<pair<ll, pii>> cross;
    for(auto& x : spec) {
        cin >> x.first.first >> x.first.second >> x.second;
        x.first.first--;
        x.first.second--;
        if(x.first.second == root) swap(x.first.second, x.first.first);
        if(x.first.first == root) {
            if(x.second < W[x.first.second]) {
                ans += -W[x.first.second] + x.second;
                W[x.first.second] = x.second;
            }
        } else {
            cross.pb({x.second, x.first});
        }
    }
    debug(ans);
    sort(cross.begin(), cross.end());
    debug(cross);
    set<pii> seen;
    for(auto& e : cross) {
        int x = e.second.first;
        int y = e.second.second;
        if(seen.find({x, y}) != seen.end()) continue;
        seen.insert({x, y});
        ll w = e.first;
        ll r = max(toRoot[x], toRoot[y]);
        if(w >= r) continue;
        ans += -r+w;
        unite(x, y);
    }
    cout << ans << endl;

    timeit("Finished");
    return 0;
}


//#define INTERACTIVE
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp> // gp_hash_table<int, int> == hash map
#include <ext/pb_ds/tree_policy.hpp>
using namespace std;
using namespace __gnu_pbds;
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef pair<double, double> pdd;
template <typename T> using min_heap = priority_queue<T, vector<T>, greater<T>>;
template <typename T> using max_heap = priority_queue<T, vector<T>, less<T>>;
template <typename T> using ordered_set = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;
template <typename K, typename V> using hashmap = gp_hash_table<K, V>;

template<typename A, typename B> ostream& operator<<(ostream& out, pair<A, B> p) { out << "(" << p.first << ", " << p.second << ")"; return out;}
template<typename T> ostream& operator<<(ostream& out, vector<T> v) { out << "["; for(auto& x : v) out << x << ", "; out << "]";return out;}
template<typename T> ostream& operator<<(ostream& out, set<T> v) { out << "{"; for(auto& x : v) out << x << ", "; out << "}"; return out; }
template<typename K, typename V> ostream& operator<<(ostream& out, map<K, V> m) { out << "{"; for(auto& e : m) out << e.first << " -> " << e.second << ", "; out << "}"; return out; }
template<typename K, typename V> ostream& operator<<(ostream& out, hashmap<K, V> m) { out << "{"; for(auto& e : m) out << e.first << " -> " << e.second << ", "; out << "}"; return out; }

#define FAST_IO ios_base::sync_with_stdio(false); cin.tie(NULL)
#define TESTS(t) int NUMBER_OF_TESTS; cin >> NUMBER_OF_TESTS; for(int t = 1; t <= NUMBER_OF_TESTS; t++)
#define FOR(i, begin, end) for (int i = (begin) - ((begin) > (end)); i != (end) - ((begin) > (end)); i += 1 - 2 * ((begin) > (end)))
#define sgn(a)     ((a) > eps ? 1 : ((a) < -eps ? -1 : 0))
#define precise(x) fixed << setprecision(x)
#define debug(x) cerr << "> " << #x << " = " << x << endl;
#define pb push_back
#define rnd(a, b) (uniform_int_distribution<int>((a), (b))(rng))
#ifndef LOCAL
    #define cerr if(0)cout
    #ifndef INTERACTIVE
        #define endl "\n"
    #endif
#endif
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
clock_t __clock__;
void startTime() {__clock__ = clock();}
void timeit(string msg) {cerr << "> " << msg << ": " << precise(6) << ld(clock()-__clock__)/CLOCKS_PER_SEC << endl;}
template<typename T> inline void maxi(T& a, T b) { a = max(a, b); }
template<typename T> inline void mini(T& a, T b) { a = min(a, b); }
const ld PI = asin(1) * 2;
const ld eps = 1e-12;
const int oo = 2e9;
const ll OO = 2e18;
const ll MOD = 998244353;
const int MAXN = 50000;

int main() {
    FAST_IO;
    startTime();

    int n, m;
    cin >> n >> m;
    vector<pair<ll, int>> a(n);
    FOR(i, 0, n) {
        auto& x = a[i];
        x.second = i;
        cin >> x.first;
    }
    sort(a.begin(), a.end());
    int root = a[0].second;
    vector<ll> W(n);
    ll ans = 0;
    FOR(i, 1, n) {
        ll w = a[i].first + a[0].first;
        ans += w;
        W[a[i].second] = w;
    }

    debug(root);
    debug(a);
    debug(W);
    debug(ans);

    vector<pair<pii, ll>> spec(m);
    vector<pair<ll, pii>> cross;
    for(auto& x : spec) {
        cin >> x.first.first >> x.first.second >> x.second;
        x.first.first--;
        x.first.second--;
        if(x.first.second == root) swap(x.first.second, x.first.first);
        if(x.first.first == root) {
            if(x.second < W[x.first.second]) {
                ans += -W[x.first.second] + x.second;
                W[x.first.second] = x.second;
            }
        } else {
            cross.pb({x.second, x.first});
        }
    }
    for(auto& e : cross) {
        int x = e.second.first;
        int y = e.second.second;
        ll w = e.first;
        if(W[x] == -1 && W[y] == -1) continue;
        if(W[x] == -1) {
            ans += -W[y] + w;
            W[y] = -1;
        } else if(W[y] == -1) {
            ans += -W[x]+w;
            W[x] = -1;
        } else if(W[x] > W[y] && -W[x]+w < 0) {
            ans += -W[x]+w;
            W[x] = -1;
        } else if(W[y] >= W[x] && -W[y]+w < 0){
            ans += -W[y]+w;
            W[y] = -1;
        }
    }
    cout << ans << endl;

    timeit("Finished");
    return 0;
}


//#define INTERACTIVE
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp> // gp_hash_table<int, int> == hash map
#include <ext/pb_ds/tree_policy.hpp>
using namespace std;
using namespace __gnu_pbds;
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef pair<double, double> pdd;
template <typename T> using min_heap = priority_queue<T, vector<T>, greater<T>>;
template <typename T> using max_heap = priority_queue<T, vector<T>, less<T>>;
template <typename T> using ordered_set = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;
template <typename K, typename V> using hashmap = gp_hash_table<K, V>;

template<typename A, typename B> ostream& operator<<(ostream& out, pair<A, B> p) { out << "(" << p.first << ", " << p.second << ")"; return out;}
template<typename T> ostream& operator<<(ostream& out, vector<T> v) { out << "["; for(auto& x : v) out << x << ", "; out << "]";return out;}
template<typename T> ostream& operator<<(ostream& out, set<T> v) { out << "{"; for(auto& x : v) out << x << ", "; out << "}"; return out; }
template<typename K, typename V> ostream& operator<<(ostream& out, map<K, V> m) { out << "{"; for(auto& e : m) out << e.first << " -> " << e.second << ", "; out << "}"; return out; }
template<typename K, typename V> ostream& operator<<(ostream& out, hashmap<K, V> m) { out << "{"; for(auto& e : m) out << e.first << " -> " << e.second << ", "; out << "}"; return out; }

#define FAST_IO ios_base::sync_with_stdio(false); cin.tie(NULL)
#define TESTS(t) int NUMBER_OF_TESTS; cin >> NUMBER_OF_TESTS; for(int t = 1; t <= NUMBER_OF_TESTS; t++)
#define FOR(i, begin, end) for (int i = (begin) - ((begin) > (end)); i != (end) - ((begin) > (end)); i += 1 - 2 * ((begin) > (end)))
#define sgn(a)     ((a) > eps ? 1 : ((a) < -eps ? -1 : 0))
#define precise(x) fixed << setprecision(x)
#define debug(x) cerr << "> " << #x << " = " << x << endl;
#define pb push_back
#define rnd(a, b) (uniform_int_distribution<int>((a), (b))(rng))
#ifndef LOCAL
    #define cerr if(0)cout
    #ifndef INTERACTIVE
        #define endl "\n"
    #endif
#endif
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
clock_t __clock__;
void startTime() {__clock__ = clock();}
void timeit(string msg) {cerr << "> " << msg << ": " << precise(6) << ld(clock()-__clock__)/CLOCKS_PER_SEC << endl;}
template<typename T> inline void maxi(T& a, T b) { a = max(a, b); }
template<typename T> inline void mini(T& a, T b) { a = min(a, b); }
const ld PI = asin(1) * 2;
const ld eps = 1e-12;
const int oo = 2e9;
const ll OO = 2e18;
const ll MOD = 998244353;
const int MAXN = 50000;

int main() {
    FAST_IO;
    startTime();

    int n, m;
    cin >> n >> m;
    vector<pair<ll, int>> a(n);
    FOR(i, 0, n) {
        auto& x = a[i];
        x.second = i;
        cin >> x.first;
    }
    sort(a.begin(), a.end());
    int root = a[0].second;
    vector<ll> W(n);
    ll ans = 0;
    FOR(i, 1, n) {
        ll w = a[i].first + a[0].first;
        ans += w;
        W[a[i].second] = w;
    }

    debug(root);
    debug(a);
    debug(W);
    debug(ans);

    vector<pair<pii, ll>> spec(m);
    vector<pair<ll, pii>> cross;
    for(auto& x : spec) {
        cin >> x.first.first >> x.first.second >> x.second;
        x.first.first--;
        x.first.second--;
        if(x.first.second == root) swap(x.first.second, x.first.first);
        if(x.first.first == root) {
            if(x.second < W[x.first.second]) {
                ans += -W[x.first.second] + x.second;
                W[x.first.second] = x.second;
            }
        } else {
            cross.pb({x.second, x.first});
        }
    }
    debug(ans);
    sort(cross.begin(), cross.end());
    debug(cross);
    set<pii> seen;
    for(auto& e : cross) {
        int x = e.second.first;
        int y = e.second.second;
        if(seen.find({x, y}) != seen.end()) continue;
        seen.insert({x, y});
        ll w = e.first;
        if(W[x] > W[y] && -W[x]+w < 0) {
            ans += -W[x]+w;
            W[x] = W[y];
        } else if(W[y] >= W[x] && -W[y]+w < 0){
            ans += -W[y]+w;
            W[y] = W[x];
        }
    }
    cout << ans << endl;

    timeit("Finished");
    return 0;
}


//#define INTERACTIVE
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp> // gp_hash_table<int, int> == hash map
#include <ext/pb_ds/tree_policy.hpp>
using namespace std;
using namespace __gnu_pbds;
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef pair<double, double> pdd;
template <typename T> using min_heap = priority_queue<T, vector<T>, greater<T>>;
template <typename T> using max_heap = priority_queue<T, vector<T>, less<T>>;
template <typename T> using ordered_set = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;
template <typename K, typename V> using hashmap = gp_hash_table<K, V>;

template<typename A, typename B> ostream& operator<<(ostream& out, pair<A, B> p) { out << "(" << p.first << ", " << p.second << ")"; return out;}
template<typename T> ostream& operator<<(ostream& out, vector<T> v) { out << "["; for(auto& x : v) out << x << ", "; out << "]";return out;}
template<typename T> ostream& operator<<(ostream& out, set<T> v) { out << "{"; for(auto& x : v) out << x << ", "; out << "}"; return out; }
template<typename K, typename V> ostream& operator<<(ostream& out, map<K, V> m) { out << "{"; for(auto& e : m) out << e.first << " -> " << e.second << ", "; out << "}"; return out; }
template<typename K, typename V> ostream& operator<<(ostream& out, hashmap<K, V> m) { out << "{"; for(auto& e : m) out << e.first << " -> " << e.second << ", "; out << "}"; return out; }

#define FAST_IO ios_base::sync_with_stdio(false); cin.tie(NULL)
#define TESTS(t) int NUMBER_OF_TESTS; cin >> NUMBER_OF_TESTS; for(int t = 1; t <= NUMBER_OF_TESTS; t++)
#define FOR(i, begin, end) for (int i = (begin) - ((begin) > (end)); i != (end) - ((begin) > (end)); i += 1 - 2 * ((begin) > (end)))
#define sgn(a)     ((a) > eps ? 1 : ((a) < -eps ? -1 : 0))
#define precise(x) fixed << setprecision(x)
#define debug(x) cerr << "> " << #x << " = " << x << endl;
#define pb push_back
#define rnd(a, b) (uniform_int_distribution<int>((a), (b))(rng))
#ifndef LOCAL
    #define cerr if(0)cout
    #ifndef INTERACTIVE
        #define endl "\n"
    #endif
#endif
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
clock_t __clock__;
void startTime() {__clock__ = clock();}
void timeit(string msg) {cerr << "> " << msg << ": " << precise(6) << ld(clock()-__clock__)/CLOCKS_PER_SEC << endl;}
template<typename T> inline void maxi(T& a, T b) { a = max(a, b); }
template<typename T> inline void mini(T& a, T b) { a = min(a, b); }
const ld PI = asin(1) * 2;
const ld eps = 1e-12;
const int oo = 2e9;
const ll OO = 2e18;
const ll MOD = 998244353;
const int MAXN = 50000;

int main() {
    FAST_IO;
    startTime();

    int n, m;
    cin >> n >> m;
    vector<pair<ll, int>> a(n);
    FOR(i, 0, n) {
        auto& x = a[i];
        x.second = i;
        cin >> x.first;
    }
    sort(a.begin(), a.end());
    int root = a[0].second;
    vector<ll> W(n);
    ll ans = 0;
    FOR(i, 0, n) {
        if(i == root) continue;
        ll w = a[i].first + a[root].first;
        ans += w;
        W[i] = w;
    }

    debug(root);
    debug(W);

    vector<pair<pii, ll>> spec(m);
    vector<pair<ll, pii>> cross;
    for(auto& x : spec) {
        cin >> x.first.first >> x.first.second >> x.second;
        x.first.first--;
        x.first.second--;
        if(x.first.second == root) swap(x.first.second, x.first.first);
        if(x.first.first == root) {
            if(x.second < W[x.first.second]) {
                ans += -W[x.first.second] + x.second;
                W[x.first.second] = x.second;
            }
        } else {
            cross.pb({x.second, x.first});
        }
    }
    for(auto& e : cross) {
        int x = e.second.first;
        int y = e.second.second;
        ll w = e.first;
        if(W[x] == -1 && W[y] == -1) continue;
        if(W[x] == -1) {
            ans += -W[y] + w;
            W[y] = -1;
        } else if(W[y] == -1) {
            ans += -W[x]+w;
            W[x] = -1;
        } else if(W[x] > W[y] && -W[x]+w < 0) {
            ans += -W[x]+w;
            W[x] = -1;
        } else if(W[y] >= W[x] && -W[y]+w < 0){
            ans += -W[y]+w;
            W[y] = -1;
        }
    }
    cout << ans << endl;

    timeit("Finished");
    return 0;
}


//#define INTERACTIVE
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp> // gp_hash_table<int, int> == hash map
#include <ext/pb_ds/tree_policy.hpp>
using namespace std;
using namespace __gnu_pbds;
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef pair<double, double> pdd;
template <typename T> using min_heap = priority_queue<T, vector<T>, greater<T>>;
template <typename T> using max_heap = priority_queue<T, vector<T>, less<T>>;
template <typename T> using ordered_set = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;
template <typename K, typename V> using hashmap = gp_hash_table<K, V>;

template<typename A, typename B> ostream& operator<<(ostream& out, pair<A, B> p) { out << "(" << p.first << ", " << p.second << ")"; return out;}
template<typename T> ostream& operator<<(ostream& out, vector<T> v) { out << "["; for(auto& x : v) out << x << ", "; out << "]";return out;}
template<typename T> ostream& operator<<(ostream& out, set<T> v) { out << "{"; for(auto& x : v) out << x << ", "; out << "}"; return out; }
template<typename K, typename V> ostream& operator<<(ostream& out, map<K, V> m) { out << "{"; for(auto& e : m) out << e.first << " -> " << e.second << ", "; out << "}"; return out; }
template<typename K, typename V> ostream& operator<<(ostream& out, hashmap<K, V> m) { out << "{"; for(auto& e : m) out << e.first << " -> " << e.second << ", "; out << "}"; return out; }

#define FAST_IO ios_base::sync_with_stdio(false); cin.tie(NULL)
#define TESTS(t) int NUMBER_OF_TESTS; cin >> NUMBER_OF_TESTS; for(int t = 1; t <= NUMBER_OF_TESTS; t++)
#define FOR(i, begin, end) for (int i = (begin) - ((begin) > (end)); i != (end) - ((begin) > (end)); i += 1 - 2 * ((begin) > (end)))
#define sgn(a)     ((a) > eps ? 1 : ((a) < -eps ? -1 : 0))
#define precise(x) fixed << setprecision(x)
#define debug(x) cerr << "> " << #x << " = " << x << endl;
#define pb push_back
#define rnd(a, b) (uniform_int_distribution<int>((a), (b))(rng))
#ifndef LOCAL
    #define cerr if(0)cout
    #ifndef INTERACTIVE
        #define endl "\n"
    #endif
#endif
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
clock_t __clock__;
void startTime() {__clock__ = clock();}
void timeit(string msg) {cerr << "> " << msg << ": " << precise(6) << ld(clock()-__clock__)/CLOCKS_PER_SEC << endl;}
template<typename T> inline void maxi(T& a, T b) { a = max(a, b); }
template<typename T> inline void mini(T& a, T b) { a = min(a, b); }
const ld PI = asin(1) * 2;
const ld eps = 1e-12;
const int oo = 2e9;
const ll OO = 2e18;
const ll MOD = 998244353;
const int MAXN = 50000;

vector<int> par;
vector<int> sz;
vector<ll> toRoot;

int find(int a) {
    return par[a] = par[a] == a ? a : find(par[a]);
}

void unite(int a, int b) {
    a = find(a);
    b = find(b);
    if(sz[a] > sz[b]) swap(a, b);
    // sz[a] <= sz[b]
    sz[b] += sz[a];
    par[a] = b;
    toRoot[b] = min(toRoot[b], toRoot[a]);
}

bool same(int a, int b) {
    return find(a) == find(b);
}

int main() {
    FAST_IO;
    startTime();

    int n, m;
    cin >> n >> m;
    vector<pair<ll, int>> a(n);
    sz.assign(n, 1);
    par.resize(n);
    toRoot.resize(n);
    FOR(i, 0, n) par[i] = i;
    FOR(i, 0, n) {
        auto& x = a[i];
        x.second = i;
        cin >> x.first;
    }
    sort(a.begin(), a.end());
    int root = a[0].second;
    vector<ll> W(n);
    ll ans = 0;
    FOR(i, 1, n) {
        ll w = a[i].first + a[0].first;
        ans += w;
        W[a[i].second] = w;
        toRoot[a[i].second] = w;
    }

    vector<pair<pii, ll>> spec(m);
    vector<pair<ll, pii>> cross;
    map<int, ll> down;
    for(auto& x : spec) {
        cin >> x.first.first >> x.first.second >> x.second;
        x.first.first--;
        x.first.second--;
        if(x.first.second == root) swap(x.first.second, x.first.first);
        if(x.first.first == root) {
            if(x.second < W[x.first.second]) {
                if(down.find(x.first.second) == down.end()) {
                    down[x.first.second] = x.second;
                }
                mini(down[x.first.second], x.second);
            }
        } else {
            cross.pb({x.second, x.first});
        }
    }
    debug(down);
    for(auto& e : down) {
        int j = e.first;
        ll w = e.second;
        if(w < toRoot[j]) {
            ans += -toRoot[j]+w;
            toRoot[j] = w;
        }
    }
    debug(ans);
    sort(cross.begin(), cross.end());
    debug(cross);
    for(auto& e : cross) {
        int x = find(e.second.first);
        int y = find(e.second.second);
        if(x == y) continue;
        ll w = e.first;
        ll r = max(toRoot[x], toRoot[y]);
        if(w >= r) continue;
        ans += -r+w;
        unite(x, y);
    }
    cout << ans << endl;

    timeit("Finished");
    return 0;
}


//#define INTERACTIVE
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp> // gp_hash_table<int, int> == hash map
#include <ext/pb_ds/tree_policy.hpp>
using namespace std;
using namespace __gnu_pbds;
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef pair<double, double> pdd;
template <typename T> using min_heap = priority_queue<T, vector<T>, greater<T>>;
template <typename T> using max_heap = priority_queue<T, vector<T>, less<T>>;
template <typename T> using ordered_set = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;
template <typename K, typename V> using hashmap = gp_hash_table<K, V>;

template<typename A, typename B> ostream& operator<<(ostream& out, pair<A, B> p) { out << "(" << p.first << ", " << p.second << ")"; return out;}
template<typename T> ostream& operator<<(ostream& out, vector<T> v) { out << "["; for(auto& x : v) out << x << ", "; out << "]";return out;}
template<typename T> ostream& operator<<(ostream& out, set<T> v) { out << "{"; for(auto& x : v) out << x << ", "; out << "}"; return out; }
template<typename K, typename V> ostream& operator<<(ostream& out, map<K, V> m) { out << "{"; for(auto& e : m) out << e.first << " -> " << e.second << ", "; out << "}"; return out; }
template<typename K, typename V> ostream& operator<<(ostream& out, hashmap<K, V> m) { out << "{"; for(auto& e : m) out << e.first << " -> " << e.second << ", "; out << "}"; return out; }

#define FAST_IO ios_base::sync_with_stdio(false); cin.tie(NULL)
#define TESTS(t) int NUMBER_OF_TESTS; cin >> NUMBER_OF_TESTS; for(int t = 1; t <= NUMBER_OF_TESTS; t++)
#define FOR(i, begin, end) for (int i = (begin) - ((begin) > (end)); i != (end) - ((begin) > (end)); i += 1 - 2 * ((begin) > (end)))
#define sgn(a)     ((a) > eps ? 1 : ((a) < -eps ? -1 : 0))
#define precise(x) fixed << setprecision(x)
#define debug(x) cerr << "> " << #x << " = " << x << endl;
#define pb push_back
#define rnd(a, b) (uniform_int_distribution<int>((a), (b))(rng))
#ifndef LOCAL
    #define cerr if(0)cout
    #ifndef INTERACTIVE
        #define endl "\n"
    #endif
#endif
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
clock_t __clock__;
void startTime() {__clock__ = clock();}
void timeit(string msg) {cerr << "> " << msg << ": " << precise(6) << ld(clock()-__clock__)/CLOCKS_PER_SEC << endl;}
template<typename T> inline void maxi(T& a, T b) { a = max(a, b); }
template<typename T> inline void mini(T& a, T b) { a = min(a, b); }
const ld PI = asin(1) * 2;
const ld eps = 1e-12;
const int oo = 2e9;
const ll OO = 2e18;
const ll MOD = 998244353;
const int MAXN = 50000;

vector<int> par;
vector<int> sz;
vector<ll> toRoot;

int find(int a) {
    return par[a] = par[a] == a ? a : find(par[a]);
}

void unite(int a, int b) {
    a = find(a);
    b = find(b);
    if(sz[a] > sz[b]) swap(a, b);
    // sz[a] <= sz[b]
    sz[b] += sz[a];
    par[a] = b;
    toRoot[b] = min(toRoot[b], toRoot[a]);
}

bool same(int a, int b) {
    return find(a) == find(b);
}

int main() {
    FAST_IO;
    startTime();

    int n, m;
    cin >> n >> m;
    vector<pair<ll, int>> a(n);
    sz.assign(n, 1);
    par.resize(n);
    toRoot.resize(n);
    FOR(i, 0, n) par[i] = i;
    FOR(i, 0, n) {
        auto& x = a[i];
        x.second = i;
        cin >> x.first;
    }
    sort(a.begin(), a.end());
    int root = a[0].second;
    vector<ll> W(n);
    ll ans = 0;
    FOR(i, 1, n) {
        ll w = a[i].first + a[0].first;
        ans += w;
        W[a[i].second] = w;
        toRoot[a[i].second] = w;
    }

    debug(root);
    debug(a);
    debug(W);
    debug(ans);

    vector<pair<pii, ll>> spec(m);
    vector<pair<ll, pii>> cross;
    for(auto& x : spec) {
        cin >> x.first.first >> x.first.second >> x.second;
        x.first.first--;
        x.first.second--;
        if(x.first.second == root) swap(x.first.second, x.first.first);
        if(x.first.first == root) {
            if(x.second < W[x.first.second]) {
                ans += -W[x.first.second] + x.second;
                W[x.first.second] = x.second;
            }
        } else {
            cross.pb({x.second, x.first});
        }
    }
    debug(ans);
    sort(cross.begin(), cross.end());
    debug(cross);
    for(auto& e : cross) {
        int x = find(e.second.first);
        int y = find(e.second.second);
        if(x == y) continue;
        ll w = e.first;
        ll r = max(toRoot[x], toRoot[y]);
        if(w >= r) continue;
        ans += -r+w;
        unite(x, y);
    }
    cout << ans << endl;

    timeit("Finished");
    return 0;
}


//#define INTERACTIVE
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp> // gp_hash_table<int, int> == hash map
#include <ext/pb_ds/tree_policy.hpp>
using namespace std;
using namespace __gnu_pbds;
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef pair<double, double> pdd;
template <typename T> using min_heap = priority_queue<T, vector<T>, greater<T>>;
template <typename T> using max_heap = priority_queue<T, vector<T>, less<T>>;
template <typename T> using ordered_set = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;
template <typename K, typename V> using hashmap = gp_hash_table<K, V>;

template<typename A, typename B> ostream& operator<<(ostream& out, pair<A, B> p) { out << "(" << p.first << ", " << p.second << ")"; return out;}
template<typename T> ostream& operator<<(ostream& out, vector<T> v) { out << "["; for(auto& x : v) out << x << ", "; out << "]";return out;}
template<typename T> ostream& operator<<(ostream& out, set<T> v) { out << "{"; for(auto& x : v) out << x << ", "; out << "}"; return out; }
template<typename K, typename V> ostream& operator<<(ostream& out, map<K, V> m) { out << "{"; for(auto& e : m) out << e.first << " -> " << e.second << ", "; out << "}"; return out; }
template<typename K, typename V> ostream& operator<<(ostream& out, hashmap<K, V> m) { out << "{"; for(auto& e : m) out << e.first << " -> " << e.second << ", "; out << "}"; return out; }

#define FAST_IO ios_base::sync_with_stdio(false); cin.tie(NULL)
#define TESTS(t) int NUMBER_OF_TESTS; cin >> NUMBER_OF_TESTS; for(int t = 1; t <= NUMBER_OF_TESTS; t++)
#define FOR(i, begin, end) for (int i = (begin) - ((begin) > (end)); i != (end) - ((begin) > (end)); i += 1 - 2 * ((begin) > (end)))
#define sgn(a)     ((a) > eps ? 1 : ((a) < -eps ? -1 : 0))
#define precise(x) fixed << setprecision(x)
#define debug(x) cerr << "> " << #x << " = " << x << endl;
#define pb push_back
#define rnd(a, b) (uniform_int_distribution<int>((a), (b))(rng))
#ifndef LOCAL
    #define cerr if(0)cout
    #ifndef INTERACTIVE
        #define endl "\n"
    #endif
#endif
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
clock_t __clock__;
void startTime() {__clock__ = clock();}
void timeit(string msg) {cerr << "> " << msg << ": " << precise(6) << ld(clock()-__clock__)/CLOCKS_PER_SEC << endl;}
template<typename T> inline void maxi(T& a, T b) { a = max(a, b); }
template<typename T> inline void mini(T& a, T b) { a = min(a, b); }
const ld PI = asin(1) * 2;
const ld eps = 1e-12;
const int oo = 2e9;
const ll OO = 2e18;
const ll MOD = 998244353;
const int MAXN = 50000;

vector<int> par;
vector<int> sz;

int find(int a) {
    return par[a] = par[a] == a ? a : find(par[a]);
}

void unite(int a, int b) {
    a = find(a);
    b = find(b);
    if(sz[a] > sz[b]) swap(a, b);
    // sz[a] <= sz[b]
    sz[b] += sz[a];
    par[a] = b;
}

bool same(int a, int b) {
    return find(a) == find(b);
}

int main() {
    FAST_IO;
    startTime();

    int n, m;
    cin >> n >> m;
    vector<ll> a(n);
    sz.assign(n, 1);
    par.resize(n);
    FOR(i, 0, n) par[i] = i;
    int root = 0;
    FOR(i, 0, n) {
        cin >> a[i];
        if(a[i] < a[root]) root = i;
    }
    vector<pair<ll, pii>> edges;
    FOR(i, 0, n) {
        if(i != root) {
            edges.pb({a[root]+a[i], {root, i}});
        }
    }
    FOR(i, 0, m) {
        int x, y, w;
        cin >> x >> y >> w;
        x--;y--;
        edges.pb({w, {x, y}});
    }
    sort(edges.begin(), edges.end());
    ll ans = 0;
    int cnt = 0;
    for(int i = 0; cnt < n-1; i++) {
        int x = edges[i].second.first;
        int y = edges[i].second.second;
        ll w = edges[i].first;
        if(same(x, y)) continue;
        unite(x, y);
        ans += w;
        cnt++;
    }
    cout << ans << endl;

    timeit("Finished");
    return 0;
}


#include <bits/stdc++.h>
#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/tree_policy.hpp>

#define fi first
#define se second
#define p_b push_back
#define pll pair<ll,ll>
#define m_p make_pair
#define all(x) x.begin(),x.end()
#define ld long double
#define sset ordered_set

using namespace std;
using namespace __gnu_pbds;
typedef long long ll;
const ll MAXN = 1123456;

template <typename T>
using ordered_set = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;

template <typename T>
T sqr(T x){
    return x * x;
}

template <typename T>
void vout(T s){
    cout << s << endl;
    exit(0);
}

ll bp(ll a,ll n){
    ll res = 1;
    while(n){
        if(n % 2)res *= a;
        a *= a;
        n >>= 1;
    }
    return res;
}

vector <pll> v[MAXN];

ll p[MAXN], kol[MAXN], mn[MAXN];

ll get(ll x){
    if(p[x] != x)p[x] = get(p[x]);
    return p[x];
}

int main(){
    ios_base :: sync_with_stdio(0);
    cin.tie(0);
    //freopen("input.txt","r",stdin);
    //freopen("output.txt","w",stdout);

    ll n, m;

    cin >> n >> m;

    vector <ll> a(n + 1);
    vector <pll> c(n + 1);

    for(int i = 1; i <= n; i++){
        cin >> a[i];
        p[i] = i;
        c[i].fi = a[i];
        c[i].se = i;
        mn[i] = a[i];
    }

    vector < pair <ll,pll> > b;

    sort(c.begin() + 1, c.end());

    ll val, to;

    val = c[1].fi, to = c[1].se;

    for(int i = 0; i < m; i++){
        ll aa, x, c;
        cin >> aa >> x >> c;
        v[aa].p_b({x, c});
        v[x].p_b({aa, c});
    }

    ll ans = 0;

    for(int i = 2; i <= n; i++){
        ll sc = val + c[i].fi, x = c[i].se;
        for(auto j : v[x])if(get(j.fi) == to)sc = min(sc, j.se);

        ans += sc;
        p[x] = to;

    }

    cout << ans << "\n";

    cerr << "Time execute: " << clock() / (double)CLOCKS_PER_SEC << " sec" << endl;
    return 0;
}


#include <bits/stdc++.h>
#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/tree_policy.hpp>

#define fi first
#define se second
#define p_b push_back
#define pll pair<ll,ll>
#define m_p make_pair
#define all(x) x.begin(),x.end()
#define ld long double
#define sset ordered_set

using namespace std;
using namespace __gnu_pbds;
typedef unsigned long long ll;
const ll MAXN = 1123456;

template <typename T>
using ordered_set = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;

template <typename T>
T sqr(T x){
    return x * x;
}

template <typename T>
void vout(T s){
    cout << s << endl;
    exit(0);
}

ll bp(ll a,ll n){
    ll res = 1;
    while(n){
        if(n % 2)res *= a;
        a *= a;
        n >>= 1;
    }
    return res;
}

vector <pll> v[MAXN];

ll p[MAXN], kol[MAXN], mn[MAXN];

ll get(ll x){
    if(p[x] != x)p[x] = get(p[x]);
    return p[x];
}

int main(){
    ios_base :: sync_with_stdio(0);
    cin.tie(0);
    //freopen("input.txt","r",stdin);
    //freopen("output.txt","w",stdout);

    ll n, m;

    cin >> n >> m;

    vector <ll> a(n + 1);
    vector <pll> c(n + 1);

    set <pll> mb;

    for(int i = 1; i <= n; i++){
        cin >> a[i];
        mn[i] = a[i];
        mb.insert({a[i], i});
        p[i] = i;
        c[i].fi = a[i];
        c[i].se = i;
    }

    sort(c.begin() + 1, c.end());

    ll val, to;

    val = c[1].fi, to = c[1].se;

    vector <pair <ll, pll> > b(m);

    for(int i = 0; i < m; i++){
        cin >> b[i].se.fi >> b[i].se.se >> b[i].fi;
    }

    sort(all(b));

    ll uk = 0;
    ll ans = 0;

    while(uk < m){
        ll ra = get(b[uk].se.fi), rb = get(b[uk].se.se);
        if(ra == rb){
            uk++;
            continue;
        }
        ll value = b[uk].fi;
        mb.erase({mn[ra], ra});

        pll xe = *mb.begin();
        if(mn[ra] + xe.fi < value){
            ans += mn[ra] + xe.fi;
            mn[ra] = min(mn[ra], mn[xe.se]);
            p[get(xe.se)] = ra;
            mb.erase(mb.begin());
            mb.insert({mn[ra], ra});
        }else{
            ans += value;
            mb.erase({mn[rb], rb});
            mn[ra] = min(mn[ra], mn[rb]);
            p[rb] = ra;
            mb.insert({mn[ra], ra});
        }

    }

    ll kol = 0;

    for(int i = 1; i <= n; i++)if(get(c[i].se) != get(to) && get(c[i].se) == c[i].se){
        ans += c[i].fi + val;
    }

    cout << ans << "\n";

    cerr << "Time execute: " << clock() / (double)CLOCKS_PER_SEC << " sec" << endl;
    return 0;
}


#include <bits/stdc++.h>
#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/tree_policy.hpp>

#define fi first
#define se second
#define p_b push_back
#define pll pair<ll,ll>
#define m_p make_pair
#define all(x) x.begin(),x.end()
#define ld long double
#define sset ordered_set

using namespace std;
using namespace __gnu_pbds;
typedef long long ll;
const ll MAXN = 1123456;

template <typename T>
using ordered_set = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;

template <typename T>
T sqr(T x){
    return x * x;
}

template <typename T>
void vout(T s){
    cout << s << endl;
    exit(0);
}

ll bp(ll a,ll n){
    ll res = 1;
    while(n){
        if(n % 2)res *= a;
        a *= a;
        n >>= 1;
    }
    return res;
}

vector <ll> v[MAXN];

ll p[MAXN], kol[MAXN], mn[MAXN];

ll get(ll x){
    if(p[x] != x)p[x] = get(p[x]);
    return p[x];
}

int main(){
    ios_base :: sync_with_stdio(0);
    cin.tie(0);
    //freopen("input.txt","r",stdin);
    //freopen("output.txt","w",stdout);

    ll n, m;

    cin >> n >> m;

    vector <ll> a(n + 1);
    vector <pll> c(n + 1);

    for(int i = 1; i <= n; i++){
        cin >> a[i];
        p[i] = i;
        c[i].fi = a[i];
        c[i].se = i;
        mn[i] = a[i];
    }

    vector < pair <ll,pll> > b;

    sort(c.begin() + 1, c.end());

    ll val, to;

    val = c[1].fi, to = c[1].se;

    for(int i = 0; i < m; i++){
        ll aa, x, c;
        cin >> aa >> x >> c;
        b.p_b({c, {aa, x}});
    }

    ll ans = 0;
    if(!b.empty()){
        sort(all(b));

        for(auto i : b){
            ll ra = get(i.se.fi), rb = get(i.se.se);
            ll sc = 2 * val + mn[ra] + mn[rb];

            if(get(to) == ra)sc -= val + mn[ra];
            if(get(to) == rb)sc -= val + mn[rb];

            if(ra != rb && min(i.fi, mn[ra] + mn[rb]) < sc){
                ans += min(i.fi, mn[ra] + mn[rb]);
                p[ra] = rb;
                mn[rb] = min(mn[ra], mn[rb]);
                mn[ra] = min(mn[ra], mn[rb]);
            }
        }
    }

    for(int i = 1; i <= n; i++)if(get(c[i].se) != get(to)){
        p[get(c[i].se)] = get(to);
        ans += val + c[i].fi;
    }

    cout << ans << "\n";

    cerr << "Time execute: " << clock() / (double)CLOCKS_PER_SEC << " sec" << endl;
    return 0;
}


#include <bits/stdc++.h>
#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/tree_policy.hpp>

#define fi first
#define se second
#define p_b push_back
#define pll pair<ll,ll>
#define m_p make_pair
#define all(x) x.begin(),x.end()
#define ld long double
#define sset ordered_set

using namespace std;
using namespace __gnu_pbds;
typedef long long ll;
const ll MAXN = 1123456;

template <typename T>
using ordered_set = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;

template <typename T>
T sqr(T x){
    return x * x;
}

template <typename T>
void vout(T s){
    cout << s << endl;
    exit(0);
}

ll bp(ll a,ll n){
    ll res = 1;
    while(n){
        if(n % 2)res *= a;
        a *= a;
        n >>= 1;
    }
    return res;
}

ll p[MAXN], kol[MAXN], mn[MAXN];

ll get(ll x){
    if(p[x] != x)p[x] = get(p[x]);
    return p[x];
}

int main(){
    ios_base :: sync_with_stdio(0);
    cin.tie(0);
    //freopen("input.txt","r",stdin);
    //freopen("output.txt","w",stdout);

    ll n, m;

    cin >> n >> m;

    vector <ll> a(n + 1);

    for(int i = 1; i <= n; i++){
        cin >> a[i];
        p[i] = i;
        mn[i] = a[i];
        kol[i] = 1;
    }

    vector < pair <pll,ll> > b(m);

    for(int i = 0; i < m; i++)cin >> b[i].fi.fi >> b[i].fi.se >> b[i].se;

    set <pll> s;

    for(int i = 1; i <= n; i++)s.insert({1ll, i});

    ll ans = 0;

    while(s.size() > 1){
        pll xe = *s.begin();
        ll x = xe.se, val = 1e18, to = 0;

        for(int i = 1; i <= n; i++)if(get(i) == i && i != x){
            ll ra = mn[x] + mn[i];
            if(ra < val){
                val = ra;
                to = i;
            }
        }

        for(int i = 0; i < m; i++){
            ll ra = get(b[i].fi.fi), rb = get(b[i].fi.se), value = b[i].se;
            if(ra != rb && ra == x){
                if(val > value){
                    val = value;
                    to = rb;
                }
            }
            if(ra != rb && rb == x){
                if(val > value){
                    val = value;
                    to = ra;
                }
            }
        }

        s.erase({kol[x], x});
        s.erase({kol[to], to});
        kol[x] += kol[to];

        p[to] = x;

        mn[x] = min(mn[x], mn[to]);
        s.insert({kol[x], x});

        ans += val;

    }

    cout << ans << "\n";

    cerr << "Time execute: " << clock() / (double)CLOCKS_PER_SEC << " sec" << endl;
    return 0;
}


#include <bits/stdc++.h>
#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/tree_policy.hpp>

#define fi first
#define se second
#define p_b push_back
#define pll pair<ll,ll>
#define m_p make_pair
#define all(x) x.begin(),x.end()
#define ld long double
#define sset ordered_set

using namespace std;
using namespace __gnu_pbds;
typedef long long ll;
const ll MAXN = 1123456;

template <typename T>
using ordered_set = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;

template <typename T>
T sqr(T x){
    return x * x;
}

template <typename T>
void vout(T s){
    cout << s << endl;
    exit(0);
}

ll bp(ll a,ll n){
    ll res = 1;
    while(n){
        if(n % 2)res *= a;
        a *= a;
        n >>= 1;
    }
    return res;
}

vector <pll> v[MAXN];

ll p[MAXN], kol[MAXN], mn[MAXN];

ll get(ll x){
    if(p[x] != x)p[x] = get(p[x]);
    return p[x];
}

int main(){
    ios_base :: sync_with_stdio(0);
    cin.tie(0);
    //freopen("input.txt","r",stdin);
    //freopen("output.txt","w",stdout);

    ll n, m;

    cin >> n >> m;

    vector <ll> a(n + 1);
    vector <pll> c(n + 1);

    set <pll> mb;

    for(int i = 1; i <= n; i++){
        cin >> a[i];
        mn[i] = a[i];
        mb.insert({a[i], i});
        p[i] = i;
        c[i].fi = a[i];
        c[i].se = i;
    }

    sort(c.begin() + 1, c.end());

    ll val, to;

    val = c[1].fi, to = c[1].se;

    vector <pair <ll, pll> > b(m);

    for(int i = 0; i < m; i++){
        cin >> b[i].se.fi >> b[i].se.se >> b[i].fi;
    }

    sort(all(b));

    ll uk = 0;
    ll ans = 0;

    while(uk < m){
        ll ra = get(b[uk].se.fi), rb = get(b[uk].se.se);
        if(ra == rb){
            uk++;
            continue;
        }
        ll value = b[uk].fi;
        mb.erase({mn[ra], ra});

        pll xe = *mb.begin();
        if(mn[ra] + xe.fi < value){
            ans += mn[ra] + xe.fi;
            mn[ra] = min(mn[ra], mn[xe.se]);
            p[get(xe.se)] = ra;
            mb.erase(mb.begin());
            mb.insert({mn[ra], ra});
        }else{
            ans += value;
            mb.erase({mn[rb], rb});
            mn[ra] = min(mn[ra], mn[rb]);
            p[rb] = ra;
            mb.insert({mn[ra], ra});
        }

    }

    ll kol = 0;

    for(int i = 1; i <= n; i++)if(get(c[i].se) != get(to) && get(c[i].se) == c[i].se){
        ans += c[i].fi + val;
    }

    cout << ans << "\n";

    cerr << "Time execute: " << clock() / (double)CLOCKS_PER_SEC << " sec" << endl;
    return 0;
}