#include <iostream>
#include <cstring>
#include <algorithm>
#include <queue>
#include <vector>
#define x first
#define y second
using namespace std;
typedef pair<int, int> PII;
const int N = 1e6+10;
int h[N], e[N], ne[N], w[N], idx; //稠密图用邻接表
int dist[N];
bool st[N];
int n, m;
void add(int a, int b, int c) //背
{
w[idx] = c, e[idx] = b, ne[idx] = h[a], h[a] = idx ++;
}
int dijkstra()
{
memset(dist, 0x3f, sizeof dist); //初始化距离
dist[1] = 0; //初始化起点距离
priority_queue<PII, vector<PII>, greater<PII> > heap; //定义一个小根堆
heap.push({0, 1}); //起点入堆
while ( heap.size() ) //当堆不空的时候
{
PII t = heap.top(); //取堆顶
heap.pop(); //弹出
int ver = t.second; //取出边
if ( st[ver] ) continue; //如果当前点已经更新过,跳过此次
st[ver] = true; //标记点的状态
for ( int i = h[ver]; i != -1; i = ne[i] ) //遍历当前点能到达的点
{
int j = e[i]; //取出能到达的点
if ( dist[j] > dist[ver] + w[i] ) //判断距离是否用跟新
{
dist[j] = dist[ver] + w[i];
heap.push({dist[j], j}); //更新距离后入堆
}
}
}
if ( dist[n] == 0x3f3f3f3f ) return -1;
return dist[n];
}
int main()
{
cin.tie(0);
ios::sync_with_stdio(false);
memset(h, -1, sizeof h);
cin >> n >> m;
while ( m -- )
{
int a, b, w;
cin >> a >> b >> w;
add(a, b, w);
}
int t = dijkstra();
if ( t == -1 ) puts("-1");
else cout << t << endl;
return 0;
}