#include<iostream>
#include<cstdio>
#include<algorithm>
#define maxn 100005
#define int long long
using namespace std;
struct Edge
{
int u,v,w;
};
Edge a[maxn<<2];
bool cmp(Edge A,Edge B)
{
return A.w<B.w;
}
struct Eric_cai
{
int to,next,val;
};
Eric_cai EC[maxn<<3];
int head[maxn],cnt;
void add(int u,int v,int w)
{
EC[++cnt].to=v;
EC[cnt].next=head[u];
EC[cnt].val=w;
head[u]=cnt;
}
int fa[maxn][25],Max[maxn][25],Sec[maxn][25],vis[maxn];
int n,m,sz,f[maxn],Min,ans=1e18,dep[maxn];
int get_fa(int x)
{
if(f[x]==x) return x;
return f[x]=get_fa(f[x]);
}
inline void merge(int x,int y)
{
f[get_fa(x)]=get_fa(y);
}
void Kruskal()
{
for(int i=1;i<=n;i++) f[i]=i;
for(int i=1;i<=sz;i++)
{
if(get_fa(a[i].u)!=get_fa(a[i].v))
{
Min+=a[i].w;
merge(a[i].u,a[i].v);
vis[i]=1;
add(a[i].u,a[i].v,a[i].w);
add(a[i].v,a[i].u,a[i].w);
}
}
}
void dfs(int now,int F,int w)
{
fa[now][0]=F;
Max[now][0]=w;
dep[now]=dep[F]+1;
for(int i=1;i<=20;i++)
{
fa[now][i]=fa[fa[now][i-1]][i-1];
Max[now][i]=max(Max[now][i-1],Max[fa[now][i-1]][i-1]);
Sec[now][i]=max(Sec[now][i-1],Sec[fa[now][i-1]][i-1]);
if(Max[now][i-1]!=Max[fa[now][i-1]][i-1])
Sec[now][i]=max(Sec[now][i],min(Max[now][i-1],Max[fa[now][i-1]][i-1]));
}
for(int i=head[now];i!=0;i=EC[i].next)
if(EC[i].to!=F) dfs(EC[i].to,now,EC[i].val);
}
inline void upd(int &u,int x,int w)
{
if(Max[u][x]==w) ans=min(ans,w-Sec[u][x]);
else ans=min(ans,w-Max[u][x]);
u=fa[u][x];
}
void get_ans(int u,int v,int w)
{
if(dep[u]<dep[v]) swap(u,v);
for(int i=20;i>=0;i--)
if(dep[fa[u][i]]>=dep[v]) upd(u,i,w);
if(u==v) return;
for(int i=20;i>=0;i--)
{
if(fa[u][i]!=fa[v][i])
{
upd(u,i,w);
upd(v,i,w);
}
}
upd(u,0,w);
upd(v,0,w);
}
signed main()
{
scanf("%lld%lld",&n,&m);
for(int i=1;i<=m;i++)
{
sz++;
scanf("%lld%lld%lld",&a[sz].u,&a[sz].v,&a[sz].w);
if(a[i].u==a[i].v) sz--;
}
sort(a+1,a+1+sz,cmp);
Kruskal();
dfs(1,0,0);
for(int i=1;i<=sz;i++)
if(vis[i]!=1) get_ans(a[i].u,a[i].v,a[i].w);
printf("%lld\n",ans+Min);
return 0;
}