#include<cstdio>
#include<algorithm>
using namespace std;
typedef long long ll;
struct edge2
{
int to,next,w;
}e[200010];
int head[100010];
void add(int from,int to,int w)
{
static int sum=0;
e[++sum].to=to;
e[sum].next=head[from];
e[sum].w=w;
head[from]=sum;
}
bool vis[100010];
struct edge
{
int from,to,w;
}ed[600010];
int Set[100010];
int Find(int x){
return Set[x]==x ? x : Set[x]=Find(Set[x]);
}
void Union(int a,int b)
{
Set[Find(a)]=Find(b);
}
bool operator<(edge a,edge b)
{
return a.w<b.w;
}
ll min_tree;
void Kruskal(int n,int m)
{
for(int i=1;i<=n;i++)
Set[i]=i;
sort(ed+1,ed+1+m);
for(int i=1;i<=m;i++)
if(Find(ed[i].from)!=Find(ed[i].to))
{
// printf("%d %d\n",i,ed[i].w);
vis[i]=1;
Union(ed[i].from,ed[i].to);
add(ed[i].from,ed[i].to,ed[i].w);
add(ed[i].to,ed[i].from,ed[i].w);
min_tree+=1ll*ed[i].w;
}
}
int l2a1[100010];
void work_log(int n)
{
for(int i=1;i<=n;i++)
l2a1[i]=l2a1[i-1]+(1<<l2a1[i-1]==i);
}
int dep[100010],father[100010][30];
int maxs[100010][30],secs[100010][30];
void pre_dfs(int now,int fath)
{
dep[now]=dep[fath]+1;
father[now][0]=fath;
for(int i=1;i<=l2a1[dep[now]];i++)
{
father[now][i]=father[father[now][i-1]][i-1];
if(maxs[now][i-1]==maxs[father[now][i-1]][i-1])
{
maxs[now][i]=maxs[now][i-1];
secs[now][i]=
max(secs[now][i-1],secs[father[now][i-1]][i-1]);
}
else if(maxs[now][i-1]>maxs[father[now][i-1]][i-1])
{
maxs[now][i]=maxs[now][i-1];
secs[now][i]=max(secs[now][i-1],maxs[father[now][i-1]][i-1]);
}
else
{
maxs[now][i]=maxs[father[now][i-1]][i-1];
secs[now][i]=max(maxs[now][i-1],secs[father[now][i-1]][i-1]);
}
}
for(int i=head[now];i;i=e[i].next)
if(fath!=e[i].to)
{
maxs[e[i].to][0]=e[i].w;
secs[e[i].to][0]=-1;
pre_dfs(e[i].to,now);
}
}
void lca(int a,int b,int& x,int& y)
{
if(dep[a]<dep[b])
{
lca(b,a,x,y);
return ;
}
x=y=-1;
while(dep[a]>dep[b])
{
if(maxs[a][l2a1[dep[a]-dep[b]]-1]>=x)
{
if(maxs[a][l2a1[dep[a]-dep[b]]-1]>x)
y=x;
x=maxs[a][l2a1[dep[a]-dep[b]]-1];
y=max(y,secs[a][l2a1[dep[a]-dep[b]]-1]);
}
else
y=max(y,maxs[a][l2a1[dep[a]-dep[b]]-1]);
a=father[a][l2a1[dep[a]-dep[b]]-1];
}
for(int i=l2a1[dep[a]]-1;i>=0;i--)
{
if(father[a][i]!=father[b][i])
{
if(maxs[a][i]>=x)
{
if(maxs[a][i]>x)
x=maxs[a][i];
x=maxs[a][i];
y=max(y,secs[a][i]);
}
else
y=max(y,maxs[a][i]);
if(maxs[b][i]>=x)
{
if(maxs[b][i]>x)
y=x;
x=maxs[b][i];
y=max(y,secs[b][i]);
}
else
y=max(y,maxs[b][i]);
a=father[a][i];
b=father[b][i];
}
}
if(maxs[a][0]>=x)
{
if(maxs[a][0]>x)
y=x;
x=maxs[a][0];
y=max(y,secs[a][0]);
}
else
y=max(y,maxs[a][0]);
if(maxs[b][0]>=x)
{
if(maxs[b][0]>x)
y=x;
x=maxs[b][0];
y=max(y,secs[b][0]);
}
else
y=max(y,maxs[b][0]);
}
ll work_sec(int m)
{
static ll minn=100000000000000;
for(int i=1;i<=m;i++)
{
if(!vis[i])
{
int maxx,secc;
lca(ed[i].from,ed[i].to,maxx,secc);
// printf("%d %d %d %d %d\n",i,ed[i].from,ed[i].to,maxx,secc);
ll ans=min_tree+ed[i].w-1ll*maxx;
if(ans==min_tree&&secc>0)
ans=min_tree+ed[i].w-1ll*secc;
if(ans<minn&&ans!=min_tree)
minn=ans;
}
}
return minn;
}
int main()
{
int n,m;
scanf("%d%d",&n,&m);
work_log(n);
for(int i=1;i<=m;i++)
{
scanf("%d%d%d",&ed[i].from,&ed[i].to,&ed[i].w);
if(ed[i].from==ed[i].to)
i--,m--;
}
Kruskal(n,m);
pre_dfs(1,0);
// printf("%lld\n",min_tree);
printf("%lld",work_sec(m));
return 0;
}
最后一个测试点RE,求调