#include <bits/stdc++.h>
#pragma GCC optimize("O3")
#pragma GCC optimize("Ofast")
#pragma GCC optimization("unroll-loops")
using namespace std;
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(nullptr);
  int n, m;
  cin >> n >> m;
  vector<pair<pair<int, int>, int>> g(m);
  for (auto &p : g) cin >> p.first.first >> p.first.second >> p.second;
  for (auto &p : g) p.first.first--, p.first.second--;
  int ans = 0;
  vector<map<int, int>> ma(n);
  for (auto p : g) {
    int u = p.first.first;
    int v = p.first.second;
    int d = p.second;
    int cur = 0;
    if (ma[u].empty())
      cur = 0;
    else {
      auto ti = ma[u].upper_bound(d);
      if (ti == ma[u].begin())
        cur = 0;
      else {
        ti--;
        cur = ti->second;
      }
    }
    cur++;
    ans = max(ans, cur);
    auto tt = ma[v].upper_bound(d + 1);
    if (tt != ma[v].begin()) {
      tt--;
      if (tt->second >= cur) continue;
    }
    ma[v][d + 1] = cur;
    auto it = ma[v].upper_bound(d + 1);
    while (!(it == ma[v].end() || it->second > cur)) it = ma[v].erase(it);
  }
  cout << ans;
  cin >> n;
}
