RT
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<cmath>
#include<map>
#include<unordered_map>
#include<vector>
#include<queue>
#include<set>
#include<ctime>
#include<random>
#define x1 xx1
#define y1 yy1
#define IOS ios::sync_with_stdio(false)
#define ITIE cin.tie(0);
#define OTIE cout.tie(0);
#define PY puts("Yes")
#define PN puts("No")
#define popcount __builtin_popcount
#define pii pair<int,int>
#define mp make_pair
#define int long long
using namespace std;
inline int R(){
int x=0,f=1;char ch=getchar();
while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
while(isdigit(ch)){x=x*10+ch-48;ch=getchar();}return x*f;
}
inline void write(int x){
if(x<0){x=-x;putchar('-');}
int y=0;char z[70];
while(x||!y){z[y++]=x%10+48;x/=10;}
while(y--)putchar(z[y]);
}
inline void writesp(int x){
write(x);putchar(32);
}
inline void writeln(int x){
write(x);putchar(10);
}
#define rep(a,b,c) for(int a=b;a<=c;a++)
#define per(a,b,c) for(int a=b;a>=c;a--)
#define reprange(a,b,c,d) for(int a=b;a<=c;a+=d)
#define perrange(a,b,c,d) for(int a=b;a>=c;a-=d)
#define graph(i,j,k) for(int i=head[j];i;i=k[i].nxt)
const int maxn=1e5+5,maxm=3e5+5;
int n,m,ans=0x7fffffffffffffff,sum;
struct edge{
int to,nxt,w;
}a[maxn<<1];
int head[maxn],edges;
void add(int x,int y,int z){
a[++edges]=(edge){y,head[x],z};
head[x]=edges;
}
struct node{
int u,v,w;
bool ontree;
bool operator<(const node &x)const{return w<x.w;}
}e[maxm];
namespace MST{
int f[maxn];
int getf(int x){
return f[x]==x?x:f[x]=getf(f[x]);
}
void kruscal(){
sort(e+1,e+m+1);
rep(i,1,n)f[i]=i;
int tmp=0;
rep(i,1,m){
int g1=getf(e[i].u),g2=getf(e[i].v);
if(g1!=g2){
f[g1]=g2;
tmp++;
sum+=e[i].w;
e[i].ontree=1;
add(e[i].u,e[i].v,e[i].w);
add(e[i].v,e[i].u,e[i].w);
if(tmp==n-1) return;
}
}
}
}
int f[maxn][25],dep[maxn];
namespace LCA{
int lg[maxn];
void init(){
rep(i,1,n) lg[i]==(1<<lg[i-1])==i?lg[i-1]+1:lg[i-1];
}
void dfs(int x,int y){
f[x][0]=y,dep[x]=dep[y]+1;
rep(i,1,lg[dep[x]]) f[x][i]=f[f[x][i-1]][i-1];
graph(i,x,a){
int u=a[i].to;
if(u==y) continue;
dfs(u,x);
}
}
int getlca(int x,int y){
if(dep[x]<dep[y]) swap(x,y);
while(dep[x]>dep[y]) x=f[x][lg[dep[x]-dep[y]]-1];
if(x==y) return x;
per(i,lg[dep[x]]-1,0)
if(f[x][i]!=f[y][i])
x=f[x][i],y=f[y][i];
return f[x][0];
}
}
namespace BL{
int g[maxn][25][2];
void dfs(int x,int y){
graph(i,x,a){
int u=a[i].to;
if(u==y) continue;
g[u][0][0]=a[i].w;
dfs(u,x);
}
}
void init(){
dfs(1,0);
rep(j,1,17){
rep(i,1,n){
if(g[f[i][j-1]][j-1][0]>g[i][j][0]) g[i][j][1]=g[i][j][0],g[i][j][0]=g[f[i][j-1]][j-1][0];
if(g[f[i][j-1]][j-1][0]<g[i][j][0]&&g[f[i][j-1]][j-1][0]>g[i][j][1]) g[i][j][1]=g[f[i][j-1]][j-1][0];
if(g[f[i][j-1]][j-1][1]>g[i][j][1]) g[i][j][1]=g[f[i][j-1]][j-1][1];
}
}
}
int solve(int x,int lca,int w){
int res=0;
per(i,17,0){
if(x==lca) break;
if(dep[f[x][i]]>=dep[lca]){
if(g[x][i][0]==w) res=max(res,g[x][i][1]);
else res=max(res,g[x][i][0]);
x=f[x][i];
}
}
return res;
}
}
signed main(){
n=R(),m=R();
rep(i,1,m){
int x=R(),y=R(),z=R();
e[i]=(node){x,y,z,0};
}
MST::kruscal();LCA::init();
LCA::dfs(1,0);BL::init();
rep(i,1,m){
if(e[i].ontree) continue;
int lca=LCA::getlca(e[i].u,e[i].v);
int mx=max(BL::solve(e[i].u,lca,e[i].w),BL::solve(e[i].v,lca,e[i].w));
ans=min(ans,sum+e[i].w-mx);
}
write(ans);
}