RT
#include<bits/stdc++.h>
#include<map>
using namespace std;
typedef long long ll;
const ll MAXN=1e5+5,MAXM=2e6+5,INF=0x7f7f7f7f7f;
ll n,m;
struct edge{
ll u,v,w,nxt;
bool operator < (const edge &oth)const{
return w<oth.w;
}
};
edge e[MAXM],tree[MAXM];
ll head_e[MAXN],head_tree[MAXN],e_num,tree_num;
void add_e(ll From,ll To,ll Len){
e_num++;
e[e_num].u=From;
e[e_num].v=To;
e[e_num].w=Len;
e[e_num].nxt=head_e[From];
head_e[From]=e_num;
return;
}
void add_tree(ll From,ll To,ll Len){
tree_num++;
tree[tree_num].u=From;
tree[tree_num].v=To;
tree[tree_num].w=Len;
tree[tree_num].nxt=head_tree[From];
head_tree[From]=tree_num;
return;
}
ll x,y,z;
ll dsu[MAXN];
ll Find(ll qwq){
return dsu[qwq]==qwq?qwq:dsu[qwq]=Find(dsu[qwq]);
}
ll sum_l;
void kruskal(){
sort(e+1,e+1+e_num);
for(int i=1;i<=n;i++)dsu[i]=i;
ll tmp=0;
for(int i=1;i<=e_num&&tmp<n-1;i++){
ll f_u=Find(e[i].u),f_v=Find(e[i].v);
if(f_u==f_v)continue;
dsu[f_u]=f_v;
add_tree(e[i].u,e[i].v,e[i].w);
add_tree(e[i].v,e[i].u,e[i].w);
sum_l+=e[i].w;
tmp++;
}
return;
}
pair<ll,ll> mix(pair<ll,ll> p1,pair<ll,ll> p2){
if(p1.first==-1)return p2;
if(p2.first==-1)return p1;
if(p1.first>=p2.first)return make_pair(p1.first,max(p1.second,p2.first));
else return make_pair(p2.first,max(p2.second,p1.first));
}
struct sgm_t{
ll num1[MAXN<<3],num2[MAXN<<3];
void clear(){
fill(num1,num1+(MAXN<<2)+10,-1);
fill(num1,num1+(MAXN<<2)+10,-1);
return;
}
void push_up(ll id){
if(num1[id<<1]==-1){
num1[id]=num1[id<<1|1];
num2[id]=num2[id<<1|1];
return;
}
if(num1[id<<1|1]==-1){
num1[id]=num1[id<<1];
num2[id]=num2[id<<1];
return;
}
if(num1[id<<1]>=num1[id<<1|1]){
num1[id]=num1[id<<1];
num2[id]=max(num2[id<<1],num1[id<<1|1]);
}
else{
num1[id]=num1[id<<1|1];
num2[id]=max(num2[id<<1|1],num1[id<<1]);
}
return;
}
void update(ll id,ll L,ll R,ll k,ll delta){
if(L>R||k<L||k>R)return;
if(L==R){
if(num1[id]==-1)num1[id]=delta;
else{
if(delta>=num1[id])num1[id]=delta;
else if(delta>=num2[id])num2[id]=delta;
}
return;
}
ll mid=(L+R)>>1;
update(id<<1,L,mid,k,delta);
update(id<<1|1,mid+1,R,k,delta);
push_up(id);
return;
}
pair<ll,ll> query(ll id,ll L,ll R,ll QL,ll QR){
if(R<QL||L>QR)return make_pair(-1,-1);
if(QL<=L&&R<=QR)return make_pair(num1[id],num2[id]);
ll mid=(L+R)>>1;
return mix(query(id<<1,L,mid,QL,QR),query(id<<1|1,mid+1,R,QL,QR));
}
}S;
ll fa[MAXN],deep[MAXN],sz[MAXN],hson[MAXN];
ll Len[MAXN];
void pre(ll now){
sz[now]=1;
for(int i=head_tree[now];i;i=tree[i].nxt){
if(tree[i].v==fa[now])continue;
fa[tree[i].v]=now;
deep[tree[i].v]=deep[now]+1;
Len[tree[i].v]=tree[i].w;
pre(tree[i].v);
sz[now]+=sz[tree[i].v];
if(sz[tree[i].v]>sz[hson[now]])hson[now]=tree[i].v;
}
return;
}
ll dfn[MAXN],rk[MAXN],cnt,top[MAXN];
void cut(ll now,ll rt){
dfn[now]=++cnt;
rk[cnt]=now;
top[now]=rt;
S.update(1,1,n,cnt,Len[now]);
if(hson[now])cut(hson[now],rt);
for(int i=head_tree[now];i;i=tree[i].nxt){
if(tree[i].v==fa[now]||tree[i].v==hson[now])continue;
cut(tree[i].v,tree[i].v);
}
return;
}
pair<ll,ll> max_l(ll X,ll Y){
pair<ll,ll> ans=make_pair(-1,-1);
if(deep[top[X]]<=deep[top[Y]])swap(X,Y);
while(deep[top[X]]>deep[top[Y]])ans=mix(ans,S.query(1,1,n,dfn[top[X]],dfn[X])),X=fa[top[X]];
if(X==Y)return ans;
while(top[X]!=top[Y]){
if(deep[top[X]]>deep[top[Y]])ans=mix(ans,S.query(1,1,n,dfn[top[X]],dfn[X])),X=fa[top[X]];
else ans=mix(ans,S.query(1,1,n,dfn[top[Y]],dfn[Y])),Y=fa[top[Y]];
}
if(dfn[X]>dfn[Y])swap(X,Y);
ans=mix(ans,S.query(1,1,n,dfn[X]+1,dfn[Y]));
return ans;
}
ll reg;
ll Ans=INF;
int main(){
cin>>n>>m;
for(int i=1;i<=m;i++){
cin>>x>>y>>z;
if(x==y)continue;
add_e(x,y,z);
add_e(y,x,z);
}
kruskal();
// cout<<"_______________"<<endl;
// for(int i=1;i<=tree_num;i++)cout<<tree[i].u<<" "<<tree[i].v<<endl;
// cout<<"_______________"<<endl;
S.clear();
pre(1);
cut(1,1);
// for(int i=1;i<=n;i++)cout<<top[i]<<" ";
// cout<<"______"<<endl;
for(int i=1;i<=e_num;i++){
pair<ll,ll> reg=max_l(e[i].u,e[i].v);
if(reg.first==e[i].w&®.second==e[i].w)continue;
if(reg.first==e[i].w)Ans=min(Ans,sum_l-reg.second+e[i].w);
else Ans=min(Ans,sum_l-reg.first+e[i].w);
}
cout<<Ans;
return 0;
}