#include <bits/stdc++.h>
using namespace std;
const int N = 3e5 + 5;
const int M = 1e6 + 5;
vector < pair <int, int> > v[N];
int ans = 2e9;
int n, m;
struct Edge { int x, y, z; } E[M];
bool cmp(Edge a, Edge b) { return a.z > b.z; }
// namespace Disjoint-Set
int fa[N];
int query(int x) { return x == fa[x] ? fa[x] : fa[x] = query(fa[x]); }
void merge(int x, int y) { fa[query(x)] = query(y); }
int dis[2][N][2];
void dfs(int x, int fa, int p)
{
for (auto cur : v[x])
{
int y = cur.first, z = cur.second;
if (y == fa) continue;
dis[p][y][0] = max(dis[p][x][0], z);
if (dis[p][x][0] >= z) dis[p][y][1] = max(z, dis[p][x][1]);
else dis[p][y][1] = max(dis[p][x][0], dis[p][x][1]);
dfs(y, x, p);
}
}
bool check(int x, int y, int z)
{
if (max(dis[0][x][0], dis[1][y][0]) < z) return 0;
if (dis[0][x][0] >= dis[1][y][0]) retsurn max(dis[0][x][1], dis[1][y][0]) <= z;
else return max(dis[0][x][0], dis[1][y][1]) <= z;
}
int main()
{
scanf("%d%d", &n, &m);
for (int i = 1; i <= m; i++)
{
scanf("%d%d%d", &E[i].x, &E[i].y, &E[i].z);
if (min(E[i].x, E[i].y) == 1 && max(E[i].x, E[i].y) == n) ans = min(ans, E[i].z);
}
sort(E + 1, E + m + 1, cmp);
for (int i = 1; i <= n; i++) fa[i] = i;
for (int i = 1; i <= m; i++)
{
int x = E[i].x, y = E[i].y, z = E[i].z;
if (query(x) == query(y)) continue;
v[x].push_back(make_pair(y, z)); v[y].push_back(make_pair(x, z));
merge(x, y);
}
dfs(1, 0, 0); dfs(n, 0, 1);
for (int i = 1; i <= m; i++)
{
int x = E[i].x, y = E[i].y, z = E[i].z;
if (check(x, y, z)) ans = min(ans, max(dis[0][x][0], dis[1][y][0]) + z);
if (check(y, x, z)) ans = min(ans, max(dis[0][y][0], dis[1][x][0]) + z);
}
printf("%d\n", ans);
return 0;
}