#include <bits/stdc++.h>
using namespace std;
struct BIT {
  vector<pair<int, int> > f;
  void init() {
    f.push_back(make_pair(-1e9, 0));
    f.push_back(make_pair(0, 0));
    f.push_back(make_pair(1e9, 0));
    sort(f.begin(), f.end());
  }
  void update(int i, int val, bool fake = 0) {
    if (fake) {
      f.push_back(make_pair(i, 0));
      return;
    }
    i = lower_bound(f.begin(), f.end(), make_pair(i, 0)) - f.begin();
    for (; i < f.size(); i += i & -i) f[i].second = max(f[i].second, val);
  }
  int get(int i, bool fake = 0) {
    if (fake) {
      f.push_back(make_pair(i, 0));
      return 0;
    }
    i = lower_bound(f.begin(), f.end(), make_pair(i, 0)) - f.begin();
    int ret = 0;
    for (; i; i -= i & -i) ret = max(ret, f[i].second);
    return ret;
  }
} f[100005];
struct data {
  int u, v, c;
  data(int _u, int _v, int _c) : u(_u), v(_v), c(_c){};
};
int n, m;
vector<data> e;
signed main() {
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  cout.tie(0);
  cin >> n >> m;
  for (int i = 1; i <= m; i++) {
    int u, v, c;
    cin >> u >> v >> c;
    e.push_back(data(u, v, c));
  }
  for (auto &it : e) {
    f[it.u].get(it.c - 1, 1);
    f[it.v].update(it.c, 0, 1);
  }
  for (int i = 1; i <= n; i++) f[i].init();
  int ans = 0;
  for (auto &it : e) {
    int rec = f[it.u].get(it.c - 1);
    ans = max(ans, rec + 1);
    f[it.v].update(it.c, rec + 1);
  }
  cout << ans << '\n';
}
