rt,ll开了,数组也往大了开了,#7WA#13RE
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = (int)5e5 + 7;
int read() {
int res = 0, f = 1;
char c = getchar();
while(!isdigit(c)) {
if(c == '-') f = -1;
c = getchar();
}
while(isdigit(c)) {
res = (res << 1) + (res << 3) + c - '0';
c = getchar();
}
return res * f;
}
int n, m, cnt, far[N], top[N], dfn[N], son[N], siz[N], rnk[N], dep[N], cdfn,
wp[N], ans = LLONG_MAX, mstw;
bool vis[N];
struct E {
int u, v, w;
} e[N];
void ins(int u, int v, int w) { e[++cnt] = {u, v, w}; }
vector<pair<int, int>> s[N];
struct dsu {
int pa[N];
void init() {
for(int i = 1; i <= n; ++i) {
pa[i] = i;
}
}
int find(int x) { return x == pa[x] ? x : pa[x] = find(pa[x]); }
void uni(int x, int y) {
x = find(x), y = find(y);
pa[x] = y;
}
} d;
void dfs1(int cur, int fa) {
siz[cur] = 1, dep[cur] = dep[fa] + 1, far[cur] = fa;
for(auto [v, w] : s[cur]) {
if(v == fa) continue;
wp[v] = w;
dfs1(v, cur);
siz[cur] += siz[v];
son[cur] = siz[son[cur]] < siz[v] ? v : son[cur];
}
}
void dfs2(int cur, int tp) {
top[cur] = tp;
dfn[cur] = ++cdfn;
rnk[cdfn] = cur;
if(!son[cur]) return;
dfs2(son[cur], tp);
for(auto [v, _] : s[cur]) {
if(v == far[cur] || v == son[cur]) continue;
dfs2(v, v);
}
}
struct Tree {
int d1[N << 2], d2[N << 2];
int ls(int p) { return p << 1; }
int rs(int p) { return p << 1 | 1; }
void pushup(int p) {
vector<int> v = {d1[ls(p)], d2[ls(p)], d1[rs(p)], d2[rs(p)]};
sort(v.begin(), v.end(), greater<int>());
auto ed = unique(v.begin(), v.end());
if(ed - v.begin() < 3)
d1[p] = v[0], d2[p] = 0;
else
d1[p] = v[0], d2[p] = v[1];
}
void build(int s, int t, int p) {
if(s == t) {
d1[p] = wp[rnk[s]], d2[p] = 0;
return;
}
int m = (s + t) >> 1;
build(s, m, ls(p)), build(m + 1, t, rs(p));
pushup(p);
}
vector<int> query(int l, int r, int s, int t, int p) {
if(l <= s && t <= r) {
return {d1[p], d2[p]};
}
int m = (s + t) >> 1;
vector<int> res;
if(l <= m) {
auto tmp = query(l, r, s, m, ls(p));
res.insert(res.end(), tmp.begin(), tmp.end());
}
if(r > m) {
auto tmp = query(l, r, m + 1, t, rs(p));
res.insert(res.end(), tmp.begin(), tmp.end());
}
sort(res.begin(), res.end(), greater<int>());
auto ed = unique(res.begin(), res.end());
if(ed - res.begin() < 2) return {res[0], 0};
return {res[0], res[1]};
}
} tree;
void krus() {
int cnt1 = 0;
sort(e + 1, e + 1 + m, [](const E &i, const E &j) { return i.w < j.w; });
for(int i = 1; i <= m; ++i) {
auto [u, v, w] = e[i];
if(u == v) continue;
if(d.find(u) == d.find(v)) continue;
s[u].push_back({v, w}), s[v].push_back({u, w});
d.uni(u, v);
vis[i] = 1, mstw += w;
if(++cnt1 == n - 1) break;
}
}
void MST_2() {
for(int i = 1; i <= m; ++i) {
if(vis[i]) continue;
auto [u, v, w] = e[i];
if(u == v) continue;
vector<int> res;
while(top[u] != top[v]) {
if(dep[u] < dep[v]) swap(u, v);
auto tmp = tree.query(dfn[top[u]], dfn[u], 1, n, 1);
res.insert(res.end(), tmp.begin(), tmp.end());
sort(res.begin(), res.end(), greater<int>());
auto ed = unique(res.begin(), res.end());
if(ed - res.begin() == 1) {
while(res.size() != 1) res.pop_back();
res.push_back(0);
} else {
while(res.size() != 2) res.pop_back();
}
u = far[top[u]];
}
if(u != v) {
if(dep[u] > dep[v]) swap(u, v);
auto tmp = tree.query(dfn[u] + 1, dfn[v], 1, n, 1);
res.insert(res.end(), tmp.begin(), tmp.end());
}
sort(res.begin(), res.end(), greater<int>());
auto ed = unique(res.begin(), res.end());
if(ed - res.begin() == 1) {
while(res.size() != 1) res.pop_back();
res.push_back(0);
} else {
while(res.size() != 2) res.pop_back();
}
assert(w >= res[0]);
if(w == res[0]) {
if(res[1])
ans = min(ans, mstw - res[1] + w);
} else {
if(res[0])
ans = min(ans, mstw - res[0] + w);
}
}
}
signed main() {
n = read(), m = read();
d.init();
for(int i = 1; i <= m; ++i) {
int u = read(), v = read(), w = read();
ins(u, v, w);
}
krus();
dfs1(1, 0);
dfs2(1, 1);
tree.build(1, n, 1);
MST_2();
return printf("%lld\n", ans), 0;
}