#include <bits/stdc++.h>
using namespace std;
struct edge {
  int u, v, w;
};
struct node {
  int best1, w1;
  int best2, w2;
};
bool cmp(edge a, edge b) { return a.w < b.w; }
node V[300010];
edge E[300010];
deque<pair<int, int> >::iterator it;
int longest(int u, int w) {
  if (V[u].w1 < w) {
    return V[u].best1;
  } else {
    return V[u].best2;
  }
}
void update(int v, int val, int w) {
  if (V[v].w1 < w) {
    if (V[v].best1 >= val) {
      return;
    }
    V[v].best2 = V[v].best1;
    V[v].w2 = V[v].w1;
    V[v].best1 = val;
    V[v].w1 = w;
  } else if (V[v].w1 == w) {
    V[v].best1 = max(V[v].best1, val);
  }
}
int main() {
  int n, m, i;
  int res = 0;
  scanf("%d%d", &n, &m);
  for (i = 0; i < m; i++) {
    scanf("%d%d%d", &E[i].u, &E[i].v, &E[i].w);
  }
  sort(E, E + m, cmp);
  for (i = 0; i < m; i++) {
    update(E[i].v, longest(E[i].u, E[i].w) + 1, E[i].w);
  }
  for (i = 1; i <= n; i++) {
    res = max(res, V[i].best1);
  }
  printf("%d", res);
}
