#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cstdlib>
#include <vector>
#include <iostream>
using namespace std;
inline int gi(){
char tmp=getchar();int ans=0;
while(!isdigit(tmp)) tmp=getchar();
while(isdigit(tmp)){
ans = ans * 10 + tmp - '0';
tmp=getchar();
}
return ans;
}
const int N = 1e6;
struct Node{
int u,v;
};
vector<Node> V[N];
int F[3][N];
#define pb push_back
signed main()
{
#ifdef TSUKIAKIOI
freopen("data.in","r",stdin);
#endif
int n,m;
n=gi(),m=gi();
int maxx = 0;
for(int i=1;i<=m;++i){
int u,v,w;
u=gi(),v=gi(),w=gi();
V[w].pb(Node{u,v});
maxx = max(maxx,w);
}
int ans = 0;
int tot = 0;
for(int i=1;i<=maxx+1;++i){
int len = V[i].size();
if(!len) continue;
++tot;
for(int j=0;j<len;++j){
int u = V[i][j].u;int v = V[i][j].v;
F[1][0] = 1;
}
for(int j=0;j<len;++j){
int u = V[i][j].u;int v = V[i][j].v;
F[1][v] = max(F[1][v],F[0][u]+1);
ans = max(ans,F[1][v]);
}
for(int j=0;j<len;++j){
int u = V[i][j].u;int v = V[i][j].v;
F[0][v] = F[1][v];
}
}
printf("%d\n",ans);
return 0;
}