#include <bits/stdc++.h>
using namespace std;
class seg_max {
 public:
  vector<long long> arr;
  int size, n;
  long long inf;
  seg_max(int m) {
    n = 1;
    while (n < m) n *= 2;
    size = n * 2;
    inf = 0;
    arr.resize(size);
  }
  void update(int i, long long v) {
    i += n;
    arr[i] = v;
    while (i > 1) {
      i /= 2;
      arr[i] = max(arr[2 * i + 1], arr[2 * i]);
    }
  }
  long long range_max(int left, int right) {
    long long res = inf;
    left += n, right += n;
    for (; left <= right; left = (left + 1) / 2, right = (right - 1) / 2) {
      if (left & 1) {
        res = max(res, arr[left]);
      }
      if ((right & 1) == 0) {
        res = max(res, arr[right]);
      }
    }
    return res;
  }
};
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(NULL);
  int n, m;
  cin >> n >> m;
  vector<int> a(m), b(m), w(m);
  vector<vector<int>> sam(n);
  for (int i = 0; i < m; i++) {
    cin >> a[i] >> b[i] >> w[i];
    a[i]--, b[i]--, w[i]++;
    sam[b[i]].push_back(w[i]);
  }
  for (int i = 0; i < n; i++) {
    sam[i].push_back(-1);
    sort(sam[i].begin(), sam[i].end());
    sam[i].erase(unique(sam[i].begin(), sam[i].end()), sam[i].end());
  }
  vector<seg_max> segs;
  for (int i = 0; i < n; i++) {
    segs.push_back(seg_max(sam[i].size()));
  }
  int res = 0;
  for (int i = 0; i < m; i++) {
    int ind = lower_bound(sam[a[i]].begin(), sam[a[i]].end(), w[i]) -
              sam[a[i]].begin();
    ind--;
    int len = segs[a[i]].range_max(0, ind);
    len++;
    res = max(res, len);
    ind = lower_bound(sam[b[i]].begin(), sam[b[i]].end(), w[i]) -
          sam[b[i]].begin();
    segs[b[i]].update(ind, len);
  }
  cout << res << "\n";
  return 0;
}
