#include <cstdio>
#include <cstring>
#include <vector>
#include <queue>
using namespace std;
#define INF 0x7fffffff/2
const int MaxN = 120;
int visited[MaxN],dis[MaxN];
//求st到ed的最短路,堆优化+邻接表,复杂度O(E*log(V))
typedef struct {
int v,l;
}Edge;
typedef vector<Edge> VE;
VE e[MaxN];
struct Vex{
int v,dis;
friend bool operator<(Vex v1,Vex v2){
return v1.dis > v2.dis;
}
};
priority_queue<Vex> Q;
int dijkstra(VE e[], int n, int st, int ed){
memset(visited,0,sizeof(visited));
for(int i = 0; i <= n; i++){
dis[i] = INF;
}
Vex now,next;
now.dis = dis[now.v = st] = 0;
while(!Q.empty()) Q.pop();
Q.push(now);
while(!Q.empty()){
now = Q.top(); Q.pop();
if(!visited[now.v]){
visited[now.v] = 1;
Edge eg;
for(int i = 0; i < e[now.v].size(); i++){
eg = e[now.v][i];
next.v = eg.v;
if(!visited[eg.v] && eg.l + dis[now.v] < dis[eg.v]){
next.dis = dis[next.v] = eg.l + dis[now.v];
Q.push(next);
}
}
}
}
return dis[ed];
}
int vn,en,map[MaxN][MaxN];
int main(){
Edge eg;
scanf("%d", &vn);
scanf("%d", &en);
int a, b, c;
for(int i = 0; i <= vn; i++){
for(int j = 0;j <= vn; j++){
map[i][j] = INF;
if(i == j) map[i][j] = 0;
}
}
for(int i = 1; i<= en; i++){
scanf("%d%d%d", &a, &b, &c);
map[a][b] = c;
eg.l = c;eg.v=b;
e[a].push_back(eg);
}
for(int i = 1; i <= vn; i++){
for(int j = 0; j <= vn; j++){
printf("[%d][%d] : %3d ", i, j, map[i][j]%1000);
}
printf("\n");
}
//printf("dsfds");
//int len = dijkstra(1,6);
int len = dijkstra(e, 6, 1, 6);
//floyd();
printf("%d\n", len);
return 0;
}
/*
6
9
1 2 6
1 3 3
2 3 2
2 4 5
3 4 3
3 5 4
4 5 2
4 6 3
5 6 5
*/