#include <bits/stdc++.h>
using namespace std;
const int inf = 1e9 + 7;
const int mod = 1e9 + 7;
const int maxn = 1e5 + 7;
int n, m, k;
struct edge {
  int id, a, b, w, ans;
  void in(int i) {
    id = i;
    scanf("%d%d%d", &a, &b, &w);
    this->ans = 1;
  }
  void out() { printf("%d: a=%d,b=%d,w=%d,ans=%d\n", id, a, b, w, ans); }
} e[maxn], e1[maxn], e2[maxn], et[maxn];
bool cmp1(const edge &e1, const edge &e2) { return e1.id < e2.id; }
bool cmp2(const edge &e1, const edge &e2) { return e1.w < e2.w; }
void divide(int ql, int qr, int mid, int &c1, int &c2) {
  assert(c1 == 0 && c2 == 0);
  for (int i = ql; i <= qr; i++) {
    if (e[i].w <= mid)
      e1[c1++] = e[i];
    else
      e2[c2++] = e[i];
  }
  for (int i = 0; i < c1; i++) e[ql + i] = e1[i];
  for (int i = 0; i < c2; i++) e[ql + c1 + i] = e2[i];
}
int ans[maxn];
void cdq(int ql, int qr, int l, int r) {
  if (ql >= qr || l >= r) return;
  int mid = (l + r) >> 1;
  int c1 = 0, c2 = 0;
  divide(ql, qr, mid, c1, c2);
  cdq(ql + c1, qr, mid + 1, r);
  merge(e + ql, e + ql + c1, e + ql + c1, e + qr + 1, et + ql, cmp1);
  for (int i = ql; i <= qr; i++) e[i] = et[i];
  c1 = c2 = 0;
  for (int i = qr; i >= ql; i--)
    if (e[i].w <= mid)
      ((e[i].ans) =
           ((e[i].ans) > (ans[e[i].b] + 1) ? (e[i].ans) : (ans[e[i].b] + 1)));
    else
      ((ans[e[i].a]) =
           ((ans[e[i].a]) > (e[i].ans) ? (ans[e[i].a]) : (e[i].ans)));
  for (int i = qr; i >= ql; i--)
    if (e[i].w > mid) ans[e[i].a] = 0;
  divide(ql, qr, mid, c1, c2);
  cdq(ql, ql + c1 - 1, l, mid);
  merge(e + ql, e + ql + c1, e + ql + c1, e + qr + 1, et + ql, cmp1);
  for (int i = ql; i <= qr; i++) e[i] = et[i];
}
int main() {
  scanf("%d%d", &n, &m);
  for (int i = 1; i <= m; i++) e[i].in(i);
  cdq(1, m, 0, 1e5);
  int out = 0;
  for (int i = 1; i <= m; i++)
    ((out) = ((out) > (e[i].ans) ? (out) : (e[i].ans)));
  cout << out << endl;
  return 0;
}
