#include <bits/stdc++.h>
using namespace std;
int tree[100005 * 20], lchild[100005 * 20], rchild[100005 * 20], root[100005],
    tot;
int query(int l, int r, int L, int R, int root) {
  if (l <= L && R <= r) return tree[root];
  int mid = L + R >> 1;
  if (r <= mid)
    return query(l, r, L, mid, lchild[root]);
  else if (l > mid)
    return query(l, r, mid + 1, R, rchild[root]);
  else
    return max(query(l, mid, L, mid, lchild[root]),
               query(mid + 1, r, mid + 1, R, rchild[root]));
}
void update(int x, int L, int R, int root, int k) {
  if (L == R) {
    tree[root] = max(tree[root], k);
    return;
  }
  int mid = L + R >> 1;
  if (x <= mid)
    update(x, L, mid, lchild[root] ? lchild[root] : lchild[root] = ++tot, k);
  else
    update(x, mid + 1, R, rchild[root] ? rchild[root] : rchild[root] = ++tot,
           k);
  tree[root] = max(tree[lchild[root]], tree[rchild[root]]);
}
int main() {
  int n, m, sum = 0;
  scanf("%d%d", &n, &m);
  for (int i = 0; i < m; i++) {
    int u, v, w, ans = 0;
    scanf("%d%d%d", &u, &v, &w);
    if (w >= 1) ans = query(0, w - 1, 0, 100000, root[u]);
    update(w, 0, 100000, root[v] ? root[v] : root[v] = ++tot, ans + 1);
    sum = max(sum, ans + 1);
  }
  printf("%d\n", sum);
}
