#include <bits/stdc++.h>
using namespace std;
namespace FastIO
{
struct instream
{
int base = 10;
friend instream &operator>>(instream &in, int &num)
{
int flag = 1;
int ans = 0;
char ch = getchar();
while (ch < '0' || ch > '9')
{
if (ch == '-')
{
flag = -flag;
}
ch = getchar();
}
while (ch >= '0' && ch <= '9')
{
ans = ans * in.base + (ch - '0');
ch = getchar();
}
num = ans * flag;
return in;
}
};
struct outstream
{
template<typename _CharT, typename _Traits = char_traits<_CharT>>
struct typ {
typedef basic_ostream<_CharT, _Traits>& (* end) (basic_ostream<_CharT, _Traits>&);
};
int base = 10;
friend outstream &operator<<(outstream &out, int num)
{
if (num < 0)
{
putchar('-');
num = -num;
}
if (num >= 10)
{
out << num / 10;
}
putchar(num % 10 + '0');
return out;
}
friend outstream &operator<<(outstream &out, const char * s) {
printf("%s", s);
return out;
}
friend outstream &operator<<(outstream &out, string s) {
cout << s;
return out;
}
friend outstream &operator<<(outstream &out, typ<char>::end e) {
puts("");
return out;
}
};
instream fin;
outstream fout;
}
using namespace FastIO;
const int maxn = 1e5 + 1;
const int maxm = 6e5 + 1;
const int maxd = 30;
struct edge {
int from, to, weight, next;
};
struct tree {
int n, cnt;
int head[maxn];
edge e[maxm];
int fa[maxn][maxd];
int dep[maxn];
int mn[maxn][maxd], sc[maxn][maxd];
void get_dep(int u, int depth, int fat) {
dep[u] = depth;
for (int i = head[u]; i; i = e[i].next) {
if (e[i].to != fat) {
get_dep(e[i].to, depth + 1, u);
}
}
}
void get_fa(int cur, int fat) {
fa[cur][0] = fat;
for (int i = 1; i <= log2(dep[cur]) + 1; i++) {
fa[cur][i] = fa[fa[cur][i - 1]][i - 1];
}
for (int i = head[cur]; i; i = e[i].next) {
if (e[i].to != fat) {
get_fa(e[i].to, cur);
}
}
}
void get_mn_sc(int u, int fat) {
for (int i = 1; i <= log2(dep[u]) + 1; i++) {
int mnond = mn[u][i - 1];
int mnonu = mn[fa[u][i - 1]][i - 1];
int scond = sc[u][i - 1];
int sconu = sc[fa[u][i - 1]][i - 1];
if (mnond > mnonu) {
mn[u][i] = mnond;
sc[u][i] = max(mnonu, scond);
} else if (mnond < mnonu) {
mn[u][i] = mnonu;
sc[u][i] = max(mnond, sconu);
} else {
mn[u][i] = mnonu;
sc[u][i] = max(scond, sconu);
}
}
for (int i = head[u]; i; i = e[i].next) {
if (e[i].to != fat) {
mn[e[i].to][0] = e[i].weight;
get_mn_sc(e[i].to, u);
}
}
}
int lca(int u, int v) {
if (dep[u] < dep[v]) swap(u, v);
while (dep[u] > dep[v]) {
u = fa[u][(int) log2(dep[u] - dep[v])];
}
if (u == v) return u;
for (int i = log2(dep[u]); i >= 0; i--) {
if (fa[u][i] != fa[v][i]) {
u = fa[u][i];
v = fa[v][i];
}
}
return fa[u][0];
}
void add_edge(int u, int v, int w) {
e[++cnt] = (edge) {u, v, w, head[u]};
head[u] = cnt;
}
void init() {
get_dep(1, 0, 0);
get_fa(1, 0);
get_mn_sc(1, 0);
}
void output() {
fout << n << endl;
for (int i = 1; i <= n; i++) {
fout << dep[i] << " ";
}
fout << endl;
for (int i = 1; i <= n; i++) {
for (int j = 0; j <= log2(dep[i]); j++) {
fout << mn[i][j] << ' ';
}
fout << endl;
}
fout << endl;
for (int i = 1; i <= n; i++) {
for (int j = 0; j <= log2(dep[i]); j++) {
fout << sc[i][j] << ' ';
}
fout << endl;
}
}
int get_mn(int u, int v) {
int lca_u_v = lca(u, v);
if (lca_u_v == u) {
int lg2v = (int) (log2(dep[v] - dep[lca_u_v]));
int mnv = max(mn[v][lg2v], mn[lca_u_v - lg2v][lg2v]);
return mnv;
}
if (lca_u_v == v) {
int lg2u = (int) (log2(dep[u] - dep[lca_u_v]));
int mnu = max(mn[u][lg2u], mn[lca_u_v - lg2u][lg2u]);
return mnu;
}
int lg2u = (int) (log2(dep[u] - dep[lca_u_v]));
int lg2v = (int) (log2(dep[v] - dep[lca_u_v]));
int mu = max(mn[u][lg2u], mn[lca_u_v - lg2u][lg2u]);
int mv = max(mn[v][lg2v], mn[lca_u_v - lg2v][lg2v]);
return max(mu, mv);
}
int get_sc(int u, int v) {
int lca_u_v = lca(u, v);
if (lca_u_v == u) {
int lg2v = (int) (log2(dep[v] - dep[lca_u_v]));
int scv = max(sc[v][lg2v], sc[lca_u_v - lg2v][lg2v]);
return scv;
}
if (lca_u_v == v) {
int lg2u = (int) (log2(dep[u] - dep[lca_u_v]));
int scu = max(sc[u][lg2u], sc[lca_u_v - lg2u][lg2u]);
return scu;
}
int lg2u = (int) (log2(dep[u] - dep[lca_u_v]));
int lg2v = (int) (log2(dep[v] - dep[lca_u_v]));
int mnu = max(mn[u][lg2u], mn[lca_u_v - lg2u][lg2u]);
int mnv = max(mn[v][lg2v], mn[lca_u_v - lg2v][lg2v]);
int scu = max(sc[u][lg2u], sc[lca_u_v - lg2u][lg2u]);
int scv = max(sc[v][lg2v], sc[lca_u_v - lg2v][lg2v]);
if (mnu > mnv) {
return max(mnv, scu);
} else if (mnu < mnv) {
return max(mnu, scv);
} else {
return max(scu, scv);
}
}
};
struct dsu {
int fa[maxn];
void init(int n) {
for (int i = 1; i <= n; i++) {
fa[i] = i;
}
}
int find(int x) {
if (fa[x] == x) {
return x;
}
return fa[x] = find(fa[x]);
}
};
tree tr;
struct graph {
int n, m, cnt;
int head[maxn];
edge e[maxm];
edge ee[maxm];
bool intree[maxm];
dsu d;
void add_edge(int u, int v, int w) {
e[++cnt] = (edge) {u, v, w, head[u]};
ee[cnt] = (edge) {u, v, w, head[v]};
head[u] = cnt;
}
void init() {
fin >> n >> m;
for (int i = 1; i <= m; i++) {
int u, v, w;
fin >> u >> v >> w;
add_edge(u, v, w);
add_edge(v, u, w);
}
}
int kruskal() {
sort(ee + 1, ee + cnt + 1, [](edge a, edge b) {
return a.weight < b.weight;
});
int ans = 0;
d = dsu();
d.init(n);
tr.n = n;
for (int i = 1; i <= cnt; i++) {
int u = d.find(ee[i].from);
int v = d.find(ee[i].to);
if (u != v) {
ans += ee[i].weight;
d.fa[u] = v;
intree[i] = true;
tr.add_edge(ee[i].from, ee[i].to, ee[i].weight);
}
}
return ans;
}
int second_min_generate_tree() {
int mn = 2e9;
for (int i = 1; i <= cnt; i++) {
if (intree[i]) continue;
int u = ee[i].from;
int v = ee[i].to;
int w = ee[i].weight;
int mnuv = tr.get_mn(u, v);
int scuv = tr.get_sc(u, v);
if (w == mnuv) mn = min(mn, w - scuv);
else mn = min(mn, w - mnuv);
}
return mn;
}
};
graph g;
int main() {
g.init();
int rans = g.kruskal();
tr.init();
int mn = g.second_min_generate_tree();
fout << rans + mn << endl;
return 0;
}