#include <bits/stdc++.h>
bool debug = 0;
const long long MOD = 1000000007;
const double PI = acos(-1.0);
const double eps = 1e-9;
using namespace std;
map<int, int> seti[100100];
void add(int node, int w, int val) {
  if (debug) printf("Add [%d] -> %d/%d\n", node, w, val);
  auto it = seti[node].lower_bound(w);
  if (it == seti[node].begin() or (--it)->second < val) {
    seti[node][w] = max(seti[node][w], val);
  }
  it = seti[node].lower_bound(w + 1);
  while (it != seti[node].end() and it->second <= val) {
    it = seti[node].erase(it);
  }
}
int get(int node, int w) {
  auto it = seti[node].lower_bound(w);
  it--;
  if (debug) printf("get %d %d -> %d/%d\n", node, w, it->first, it->second);
  return it->second + 1;
}
int main() {
  int n, m;
  scanf("%d %d", &n, &m);
  for (int i = 1; i <= n; i++) seti[i][-999] = 0;
  int a, b, c;
  for (int i = 0; i < m; i++) {
    scanf("%d %d %d", &a, &b, &c);
    add(b, c, get(a, c));
  }
  if (debug) {
    for (int i = 1; i <= n; i++) {
      printf("%d:\n", i);
      for (pair<int, int> j : seti[i]) {
        printf("w[%d] = %d\n", j.first, j.second);
      }
      printf("\n");
    }
  }
  int res = 0;
  for (int i = 1; i <= n; i++) {
    auto it = seti[i].rbegin();
    res = max(res, it->second);
  }
  cout << res << endl;
  return 0;
}
