#include<bits/stdc++.h>
#define int long long
#define lc(p) (p<<1)
#define rc(p) (p<<1|1)
#define debug puts("-----------")
#define endl puts("")
#define re register
#define in inline
using namespace std;
const int N=1e6+7;
char *p1,p2,buf[N];
#define nc() (p1p2 && (p2=(p1=buf)+fread(buf,1,100000,stdin),p1p2)?EOF:p1++)
in int read(){
int x=0,f=1;
char ch=nc();
while(ch<48||ch>57){
if(ch=='-') f=-1;
ch=nc();
}
while(ch>=48&&ch<=57) x=x10+ch-48,ch=nc();
return xf;
}
struct edge{
int to,w;
};
vector<edge>G[N];
struct node{
int dist,id;
bool operator <(const node &x) const{
return x.dist<dist;
}
};
int degree[N];
vector<int>G2[N];
priority_queue<node>q;
int v[N];
int dis[N],s;
in void dijkstra(){
dis[1]=0;
q.push({0,1});
while(!q.empty()){
node front=q.top();
q.pop();
int id=front.id;
int w=front.dist;
if(v[id]) continue;
v[id]=true;
for(auto to:G[id]){
if(dis[to.to]>dis[id]+to.w){
dis[to.to]=dis[id]+to.w;
if(!degree[to.to]) q.push({dis[to.to],to.to});
}
}
for(auto son:G2[id]){
degree[son]--;
dis[son]=max(dis[son],dis[id]);
if(!degree[son]){
q.push({dis[son],son});
}
}
}
}
signed main(){
int n=read(),m=read();
for(re int i=1;i<=n;i++) dis[i]=1e9;
for(re int i=1;i<=m;i++){
int u=read(),v=read(),w=read();
G[u].push_back({v,w});
}
}