//Think twice,code once.
#include<bits/stdc++.h>
#define endl '\n'
#define INF 0x3f3f3f3f3f3f3f
#define inf 0x3f3f3f3f
#define ff first
#define ss second
#define pii pair<int,int>
#define int long long
#define mem(i,n) memset(i,n,sizeof i)
#define dg(a) std::cout << #a << " = " << a << endl
typedef long long ll;
typedef unsigned long long ull;
using namespace std;
const int N=3e5+10;
struct node
{
int u;
int val=INF;
int m1=0,m2=0;
operator< (const node&b) const {
if(val!=b.val) return val>b.val;
else m1>b.m1;
}
};
vector<pii>g[N];
node dis[N];
bool vis[N];
void dij()
{
dis[1]={1,0,0,0};
priority_queue<node>q;
q.push(dis[1]);
while(q.size())
{
auto u=q.top().u;
q.pop();
if(vis[u]) continue;
vis[u]=1;
for(auto [v,w]:g[u])
{
node nu=dis[u];
nu.u=v;
if(w>nu.m2) nu.m2=w;
if(nu.m2>nu.m1) swap(nu.m2,nu.m1);
nu.val=nu.m1+nu.m2;
if(nu.val<=dis[v].val)
{
dis[v]=nu;
q.push(dis[v]);
}
}
}
}
void solve()
{
int n,m;
cin >> n >> m;
for(int i=1;i<=m;i++)
{
int u,v,w;
cin >> u >> v >> w;
g[u].push_back({v,w});
g[v].push_back({u,w});
}
dij();
cout << dis[n].val << endl;
}
int32_t main()
{
std::ios_base::sync_with_stdio(false);
std::cin.tie(nullptr);
std::cout.tie(nullptr);
int t = 1;
// std::cin >> t;
while(t--) solve();
return 0;
}