#include using namespace std; const int nmax=1e5+42; int n,m; struct info { int u,v,c; }; info inp[nmax]; int parent[nmax]; int root(int node) { if(node==parent[node])return node; parent[node]=root(parent[node]); return parent[node]; } vector< pair > adj[nmax]; int up[20][nmax],costs_up[20][nmax]; int depth[nmax]; void dfs(int node,int par) { up[0][node]=par; for(int i=1;i<20;i++) { up[i][node]=up[i-1][up[i-1][node]]; costs_up[i][node]=max(costs_up[i-1][node],costs_up[i-1][up[i-1][node]]); } for(auto w:adj[node]) if(w.first!=par) { costs_up[0][w.first]=w.second; depth[w.first]=depth[node]+1; dfs(w.first,node); } } int query(int u,int v) { if(depth[u]>depth[v])swap(u,v); int ret=0; for(int i=19;i>=0;i--) if(depth[v]-(1<=depth[u]) { ret=max(ret,costs_up[i][v]); v=up[i][v]; } if(u==v)return ret; for(int i=19;i>=0;i--) if(up[i][u]!=up[i][v]) { ret=max(ret,costs_up[i][u]); u=up[i][u]; ret=max(ret,costs_up[i][v]); v=up[i][v]; } ret=max(ret,costs_up[0][u]); ret=max(ret,costs_up[0][v]); return ret; } bool cmp(info a,info b) { return a.c>b.c; } int main() { freopen("cycle.in","r",stdin); freopen("cycle.out","w",stdout); scanf("%i%i",&n,&m); for(int i=1;i<=m;i++) { scanf("%i%i%i",&inp[i].u,&inp[i].v,&inp[i].c); } for(int i=1;i<=n;i++)parent[i]=i; sort(inp+1,inp+m+1,cmp); for(int i=1;i<=m;i++) { int u=inp[i].u; int v=inp[i].v; int c=inp[i].c; if(root(u)==root(v))continue; adj[u].push_back({v,c}); adj[v].push_back({u,c}); parent[root(u)]=root(v); } for(int i=1;i<=n;i++) if(root(i)==i)dfs(i,i); for(int i=1;i<=n;i++)parent[i]=i; int outp=0; for(int i=1;i<=m;i++) { int u=inp[i].u; int v=inp[i].v; int c=inp[i].c; if(root(u)!=root(v)) { parent[root(u)]=root(v); continue; } outp=max(outp,c+query(u,v)); } printf("%i\n",outp); return 0; }