/*
题意:求严格次小生成树(就是不能等于)
思路:先求一个最小生成树 枚举每条非树边 若连入则一定会成环
那么在这个环中 删去最大的边(除非树边) 就是一个次小生成树
但是如果那个最大边和非树边的值相等 有可能次小生成树的值就和最小生成树一样
显然是不成立的 所以应该记录一下次大值 最大值不满足就用次大值
注意:在dfs中转移的顺序
*/
#include<bits/stdc++.h>
using namespace std;
#define N 100005
#define ll long long
struct node{
int x,y,in; int w;
}a[N*3];
int fa[N],head[N<<1],nex[N<<1],to[N<<1],tot=0,f[N][22],dep[N];
int d1[N][22],d2[N][22],w[N<<1],mn=0x7f7f7f;
bool cmp(const node &a,const node &b) { return a.w<b.w; }
int get(int x)
{
if(x==fa[x]) return x;
return fa[x]=get(fa[x]);
}
void add(int a,int b,int ww){ to[++tot]=b; nex[tot]=head[a]; head[a]=tot; w[tot]=ww;}
void dfs(int u,int father)
{//倍增的初始化一定要在for的外面!!
for(int i=1;i<=20;i++){
f[u][i]=f[f[u][i-1]][i-1];
//d1是最大值 d2是次大值
d1[u][i]=max(d1[u][i-1],d1[f[u][i-1]][i-1]);
if(d1[u][i-1]==d1[f[u][i-1]][i-1])//最大值相等 次大值就是从两段的次大值转移过来
d2[u][i]=max(d2[u][i-1],d2[f[u][i-1]][i-1]);
else{//不相等就可能由两段最大值中的较小值 或 两段次大值 转移过来
d2[u][i]=min(d1[u][i-1],d1[f[u][i-1]][i-1]);
d2[u][i]=max(d2[u][i],d2[u][i-1]);
d2[u][i]=max(d2[u][i],d2[f[u][i-1]][i-1]);
}
}
for(int j=head[u];j;j=nex[j]){
int v=to[j];
if(v==father) continue;
dep[v]=dep[u]+1; f[v][0]=u; d1[v][0]=w[j];
dfs(v,u);
}
}
int lca(int x,int y)
{
if(dep[x]<dep[y]) swap(x,y);
for(int i=20;i>=0;i--)
if(dep[f[x][i]]>=dep[y]) x=f[x][i];
if(x==y) return x;
for(int i=20;i>=0;i--)
if(f[x][i]!=f[y][i]) x=f[x][i],y=f[y][i];
return f[x][0];
}//求路径的最大值和次大值
void solve(int x,int y,int v)
{
int mx1=0,mx2=0;
int t=dep[x]-dep[y];//深度差 是i的范围
for(int i=0;i<=20;i++)
if(t&(1<<i)){//如果还可以跳
if(d1[x][i]>mx1) mx2=mx1,mx1=d1[x][i];
else mx2=max(mx2,d1[x][i]);
mx2=max(mx2,d2[x][i]);
x=f[x][i];
}
if(mx1!=v) mn=min(mn,v-mx1);
else mn=min(mn,v-mx2);
}
void work(int x,int y,int ww)
{
int lc=lca(x,y);
solve(x,lc,ww); solve(y,lc,ww);
}
ll ans=0;
int main()
{
int n,m,cnt=0;
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++) scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].w);
sort(a+1,a+1+m,cmp);
for(int i=1;i<=n;i++) fa[i]=i;
for(int i=1;i<=m;i++){
int f1=get(a[i].x),f2=get(a[i].y);
if(f1!=f2){
cnt++;
ans+=a[i].w;
a[i].in=1;
fa[f1]=f2;
add(a[i].x,a[i].y,a[i].w); add(a[i].y,a[i].x,a[i].w);
}
if(cnt==n-1) break;
}
dfs(1,0);
for(int i=1;i<=m;i++) if(!a[i].in) work(a[i].x,a[i].y,a[i].w);
printf("%lld
",ans+mn);
}
/*
5 6
1 2 1
1 3 2
2 4 3
3 5 4
3 4 3
4 5 6
*/