RT
#include <bits/stdc++.h>
#define pii pair <int,int>
#define int long long
using namespace std;
const int maxn=100005;
const int maxm=300005;
const int logn=25;
const int INF=(int)(1e18)+5;
int n,m,cnt,l,r,ans;
int dp[maxn][logn][2],fa[maxn][logn];
int dep[maxn],fa_[maxn],head[maxn],q[maxn];
bool vis[maxm];
struct edge{
int v,nxt,val;
}a[maxm<<1];
struct sav{
int x,y,val;
}b[maxm];
bool cmp(sav x,sav y){
return x.val<y.val;
}
int get(int x){
return x==fa_[x]?x:fa_[x]=get(fa_[x]);
}
void add(int x,int y,int val){
++cnt;
a[cnt].v =y;
a[cnt].val=val;
a[cnt].nxt=head[x];
head[x]=cnt;
}
pii maxx(int x1,int y1,int x2,int y2){
int x,y;
if(x1==x2){
x=x1;
y=max(y1,y2);
}
if(x1>x2){
x=x1;
y=max(x2,y1);
}
if(x1<x2){
x=x2;
y=max(x1,y2);
}
return make_pair(x,y);
}
inline int read(){
int ret=0,f=1; char ch=getchar();
while(!isdigit(ch)){if(ch=='-')f=-f;ch=getchar();}
while(isdigit(ch)){ret=ret*10+ch-'0';ch=getchar();}
return ret*f;
}
void scan(){
int k;
memset(dp,-1,sizeof(dp));
n=read(); m=read();
for(k=1;k<=m;k++){
int x,y,val;
x=read(); y=read(); val=read();
b[k].x=x; b[k].y=y; b[k].val=val;
}
sort(b+1,b+m+1,cmp);
}
void prim(){
int k;
for(k=1;k<=n;k++) fa_[k]=k;
for(k=1;k<=m;k++){
int x=b[k].x,y=b[k].y,val=b[k].val;
int fx=get(x),fy=get(y);
if(fx==fy) continue;
fa_[fx]=fy; ans+=val; vis[k]=1;
add(x,y,val); add(y,x,val);
}
// printf("最小生成树边权和为%d\n",ans);
}
void dfs(int x,int f){
int k;
fa[x][0]=f; dep[x]=dep[f]+1;
for(k=head[x];k;k=a[k].nxt){
int v=a[k].v,val=a[k].val;
if(v==f) continue;
dfs(v,x);
dp[v][0][0]=val;
}
}
void bfs(){
int k;
q[l=r=1]=1;
while(l<=r){
int x=q[l++];
for(k=head[x];k;k=a[k].nxt){
int v=a[k].v,val=a[k].val;
if(dep[v]<dep[x]) continue;
q[++r]=v;
}
for(k=1;k<logn;k++){
int f=fa[x][k-1];
pii t=maxx(dp[x][k-1][0],dp[x][k-1][1],dp[f][k-1][0],dp[f][k-1][1]);
dp[x][k][0]=t.first;
dp[x][k][1]=t.second;
fa[x][k]=fa[f][k-1];
}
}
}
pii LCA(int x,int y){
int k; int ans1,ans2;
ans1=ans2=-1;
if(dep[y]>dep[x]) swap(x,y);
for(k=logn-1;k>=0;k--){
int f=fa[x][k],a1=dp[x][k][0],b1=dp[x][k][1];
if(dep[f]<=dep[y]){
pii t=maxx(ans1,ans2,a1,b1);
x=f;
ans1=t.first;
ans2=t.second;
}
}
if(x==y) return make_pair(ans1,ans2);
for(k=logn-1;k>=0;k--){
int fx=fa[x][k],fy=fa[y][k];
if(fx!=fy) {
pii t=maxx(dp[x][k][0],dp[x][k][1],dp[y][k][0],dp[y][k][1]);
int a1=t.first,b1=t.second;
t=maxx(a1,b1,ans1,ans2);
x=fx; y=fy;
ans1=t.first;
ans2=t.second;
}
}
return make_pair(ans1,ans2);
}
int calc(){
int k,j,i;
int ans=INF;
for(k=1;k<=m;k++){
if(vis[k]) continue;
int x=b[k].x,y=b[k].y,val=b[k].val;
pii t=LCA(x,y); int x1=t.first,y1=t.second;
int ans1;
if(val!=x1) ans1=val-x1;
else ans1=val-y1;
ans=min(ans,ans1);
}
return ans;
}
void solve(){
ans+=calc();
printf("%lld\n",ans);
}
void prework(){
dep[1]=1; dfs(1,0);
int k,j,i;
bfs();
}
signed main(){
int k,j,i;
// freopen("ex_tree1 (1).in","r",stdin);
scan(); prim(); prework(); solve();
return 0;
}