#include <bits/stdc++.h>
using namespace std;
const int INF = 1e9;
const int N = 200 * 1000;
int n;
vector<pair<int, int> > a[2];
struct segtree {
  int n;
  vector<int> t, ps;
  segtree(int n) : n(n) {
    t.resize(4 * n, -INF);
    ps.resize(4 * n, 0);
  }
  void push(int v, int l, int r) {
    if (l + 1 != r) {
      ps[v * 2 + 1] += ps[v];
      ps[v * 2 + 2] += ps[v];
    }
    t[v] += ps[v];
    ps[v] = 0;
  }
  void upd(int v, int l, int r, int pos, int val) {
    push(v, l, r);
    if (l + 1 == r) {
      t[v] = val;
      return;
    }
    int m = (l + r) >> 1;
    if (pos < m)
      upd(v * 2 + 1, l, m, pos, val);
    else
      upd(v * 2 + 2, m, r, pos, val);
    t[v] = max(t[v * 2 + 1], t[v * 2 + 2]);
  }
  void add(int v, int l, int r, int L, int R, int val) {
    push(v, l, r);
    if (L >= R) return;
    if (l == L && r == R) {
      ps[v] += val;
      push(v, l, r);
      return;
    }
    int m = (l + r) >> 1;
    add(v * 2 + 1, l, m, L, min(m, R), val);
    add(v * 2 + 2, m, r, max(m, L), R, val);
    t[v] = max(t[v * 2 + 1], t[v * 2 + 2]);
  }
  int get(int v, int l, int r, int L, int R) {
    push(v, l, r);
    if (L >= R) return -INF;
    if (l == L && r == R) return t[v];
    int m = (l + r) >> 1;
    int r1 = get(v * 2 + 1, l, m, L, min(m, R));
    int r2 = get(v * 2 + 2, m, r, max(m, L), R);
    t[v] = max(t[v * 2 + 1], t[v * 2 + 2]);
    return max(r1, r2);
  }
  void upd(int pos, int val) { return upd(0, 0, n, pos, val); }
  void add(int l, int r, int val) { return add(0, 0, n, l, r, val); }
  int get(int l, int r) { return get(0, 0, n, l, r); }
};
int main() {
  if (fopen("input.in", "r")) {
    freopen("input.in", "r", stdin);
    freopen("output.out", "w", stdout);
  }
  scanf("%d", &n);
  for (int i = 0; i < int(n); ++i) {
    int l, r, t;
    scanf("%d%d%d", &l, &r, &t);
    a[t - 1].push_back(make_pair(r, l));
  }
  for (int i = 0; i < int(2); ++i)
    sort((a[i]).begin(), (a[i]).end(),
         [](pair<int, int> a, pair<int, int> b) { return a.first < b.first; });
  segtree t1(int((a[0]).size()) + 1), t2(int((a[1]).size()) + 1);
  t1.upd(0, 0);
  t2.upd(0, 0);
  int ans = 0;
  for (int i = 0, j = 0; i + j < n;) {
    if (i < int((a[0]).size()) &&
        (j == int((a[1]).size()) || a[0][i].first <= a[1][j].first)) {
      int pos = upper_bound((a[1]).begin(), (a[1]).end(),
                            make_pair(a[0][i].second, -INF)) -
                a[1].begin() + 1;
      int cur = t2.get(0, pos) + 1;
      ans = max(ans, cur);
      t1.upd(i + 1, cur);
      t2.add(0, pos, 1);
      ++i;
    } else {
      int pos = upper_bound((a[0]).begin(), (a[0]).end(),
                            make_pair(a[1][j].second, -INF)) -
                a[0].begin() + 1;
      int cur = t1.get(0, pos) + 1;
      ans = max(ans, cur);
      t2.upd(j + 1, cur);
      t1.add(0, pos, 1);
      ++j;
    }
  }
  printf("%d\n", ans);
}
