#include <bits/stdc++.h>
using namespace std;
const long long INF = 0x3f3f3f3f3f3f3f3f, N = 2e5 + 10;
long long n, m;
struct node
{
long long y;
long long z;
} ll;
vector<node> G[N];
long long sh[N], dfs1shen1, dfs1shen2 = -INF;
void dfs(long long s, long long fa, long long zz, bool blogg)
{
if (!blogg)
sh[s] = sh[fa] + zz;
if (sh[s] >= dfs1shen2)
{
dfs1shen1 = s;
dfs1shen2 = sh[s];
}
for (auto v : G[s])
{
if (v.y == fa)
continue;
dfs(v.y, s, v.z, 0);
}
}
long long zj1, zj2;
bool vis1[N];
int d1[N];
struct VNode
{
int p;
int d;
bool operator<(const VNode &b) const
{
return d > b.d;
}
};
void dijkstra1(int s)
{
priority_queue<VNode> q;
for (int i = 1; i <= n; i++)
{
d1[i] = INF;
}
d1[s] = 0;
q.push({s, 0});
while (!q.empty())
{
int u = q.top().p;
q.pop();
if (vis1[u])
{
continue;
}
vis1[u] = 1;
for (auto e : G[u])
{
int v = e.y;
int w = e.z;
if (vis1[v] == 0 && d1[v] > d1[u] + w)
{
d1[v] = d1[u] + w;
q.push({v, d1[v]});
}
}
}
}
bool vis2[N];
int d2[N];
void dijkstra2(int s)
{
priority_queue<VNode> q;
for (int i = 1; i <= n; i++)
{
d2[i] = INF;
}
d2[s] = 0;
q.push({s, 0});
while (!q.empty())
{
int u = q.top().p;
q.pop();
if (vis2[u])
{
continue;
}
vis2[u] = 1;
for (auto e : G[u])
{
int v = e.y;
int w = e.z;
if (vis2[v] == 0 && d2[v] > d2[u] + w)
{
d2[v] = d2[u] + w;
q.push({v, d2[v]});
}
}
}
}
signed main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin >> n >> m;
for (long long i = 1; i <= m; i++)
{
long long x, y, z;
cin >> x >> y >> z;
ll.y = y;
ll.z = z;
G[x].push_back(ll);
ll.y = x;
G[y].push_back(ll);
}
sh[1] = 1;
dfs(1, -1, 1145, 1);
zj1 = dfs1shen1;
memset(sh, 0, sizeof(sh));
dfs1shen1 = 0, dfs1shen2 = -INF;
dfs(zj1, 0, 1145, 1);
zj2 = dfs1shen1;
dijkstra1(zj1);
dijkstra2(zj2);
long long ans = -INF;
for (long long i = 1; i <= n; i++)
{
if (i == zj1 || i == zj2)
continue;
ans = max(ans, d1[i] + d2[i] + dfs1shen2);
}
cout << ans;
return 0;
}