#include <bits/stdc++.h>
using namespace std;
struct edge {
  int u, v, c;
} edges[300000 + 10];
struct nod {
  int cost, val;
};
vector<nod> adj[300000 + 10];
bool compare(edge x, edge y) {
  if (x.c == y.c) {
    if (x.u == y.u) return x.v < y.v;
    return x.u < y.u;
  }
  return x.c < y.c;
}
int Flower(int tar, int u) {
  int l = 0;
  int h = adj[u].size() - 1;
  int ans = -1;
  while (l <= h) {
    int mid = (l + h) / 2;
    if (adj[u][mid].cost < tar) {
      ans = mid;
      l = mid + 1;
    } else {
      h = mid - 1;
    }
  }
  if (ans == -1)
    return 0;
  else
    return adj[u][ans].val;
}
int main() {
  int n, m, i, j;
  cin >> n >> m;
  for (i = 1; i <= m; i++) {
    scanf("%d %d %d", &edges[i].u, &edges[i].v, &edges[i].c);
  }
  sort(edges + 1, edges + m + 1, compare);
  int ans = 0;
  for (i = 1; i <= m; i++) {
    int u = edges[i].u;
    int v = edges[i].v;
    int c = edges[i].c;
    int cand = Flower(c, u);
    cand++;
    ans = max(ans, cand);
    nod temp;
    temp.cost = c;
    temp.val = cand;
    int sz = adj[v].size();
    if (sz != 0) temp.val = max(temp.val, adj[v][sz - 1].val);
    adj[v].push_back(temp);
  }
  cout << ans << endl;
  return 0;
}
