#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
int n, m, root[N], cnt;
int ans, u, v, w, num;
struct node {
  int l, r, mx;
  node() : l(0), r(0), mx(0) {}
} e[N * 20];
void upd(int &p, int l, int r, int x, int v) {
  if (!p) p = ++cnt;
  if (l == r) {
    e[p].mx = max(e[p].mx, v);
    return;
  }
  int mid = (l + r) / 2;
  if (x <= mid)
    upd(e[p].l, l, mid, x, v);
  else
    upd(e[p].r, mid + 1, r, x, v);
  e[p].mx = max(e[e[p].l].mx, e[e[p].r].mx);
}
int ask(int p, int l, int r, int ql, int qr) {
  if (ql > qr) return 0;
  if (ql <= l && r <= qr) return e[p].mx;
  int mid = (l + r) / 2, ans = 0;
  if (ql <= mid) ans = max(ans, ask(e[p].l, l, mid, ql, qr));
  if (qr > mid) ans = max(ans, ask(e[p].r, mid + 1, r, ql, qr));
  return ans;
}
int main() {
  scanf("%d%d", &n, &m);
  for (int i = 1; i <= m; ++i) {
    scanf("%d%d%d", &u, &v, &w);
    num = ask(root[u], 0, 1e5, 0, w - 1);
    upd(root[v], 0, 1e5, w, num + 1);
    ans = max(ans, num + 1);
  }
  printf("%d\n", ans);
  return 0;
}
