#include <bits/stdc++.h>
using namespace std;

#ifdef LOCAL
#define DEBUG(...) debug(#__VA_ARGS__, __VA_ARGS__)
#else
#define DEBUG(...) 6
#endif

template<typename T, typename S> ostream& operator << (ostream &os, const pair<T, S> &p) {return os << "(" << p.first << ", " << p.second << ")";}
template<typename C, typename T = decay<decltype(*begin(declval<C>()))>, typename enable_if<!is_same<C, string>::value>::type* = nullptr>
ostream& operator << (ostream &os, const C &c) {bool f = true; os << "["; for (const auto &x : c) {if (!f) os << ", "; f = false; os << x;} return os << "]";}
template<typename T> void debug(string s, T x) {cerr << "\033[1;35m" << s << "\033[0;32m = \033[33m" << x << "\033[0m\n";}
template<typename T, typename... Args> void debug(string s, T x, Args... args) {for (int i=0, b=0; i<(int)s.size(); i++) if (s[i] == '(' || s[i] == '{') b++; else
if (s[i] == ')' || s[i] == '}') b--; else if (s[i] == ',' && b == 0) {cerr << "\033[1;35m" << s.substr(0, i) << "\033[0;32m = \033[33m" << x << "\033[31m | "; debug(s.substr(s.find_first_not_of(' ', i + 1)), args...); break;}}

template<typename T>
struct BIT {
    int n, lg;
    vector<T> bit;

    BIT(int _n) : n(_n), lg(__lg(n)), bit(n + 1) {}

    BIT(const vector<T> &a) : n((int) a.size()), lg(__lg(n)), bit(n + 1) {
        for (int i=1; i<=n; i++) {
            bit[i] += a[i-1];
            if (i + (i & -i) <= n)
                bit[i+(i&-i)] += bit[i];
        }
    }

    T query(int i) {
        T ret = 0;
        for (i++; i>0; i-=i&-i)
            ret += bit[i];
        return ret;
    }

    T query(int l, int r) {
        return l > r ? 0 : query(r) - query(l - 1);
    }

    void update(int i, T val) {
        for (i++; i<=n; i+=i&-i)
            bit[i] += val;
    }

    int kth(T k) {
        int ret = 0;
        for (int i=lg; i>=0; i--) {
            ret += 1 << i;
            if (ret <= n && bit[ret] < k)
                k -= bit[ret];
            else
                ret -= 1 << i;
        }
        return ret;
    }
};

const int MAXC = 200;

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);

    int t;
    cin >> t;
    while (t--) {
        int n;
        cin >> n;
        vector<array<int, 4>> pts;
        vector<int> compress;
        for (int i=0; i<n; i++) {
            int l, r, c;
            cin >> l >> r >> c;
            pts.push_back({l, -r, i, c});
            pts.push_back({r, -l, i + n, c});
            compress.push_back(l);
            compress.push_back(r);
        }

        sort(compress.begin(), compress.end());
        compress.erase(unique(compress.begin(), compress.end()), compress.end());
        int o = (int) compress.size();

        sort(pts.begin(), pts.end());
        vector<vector<int>> dp(o + 1, vector<int>(MAXC + 1, -1e9));
        BIT<int> bit(o);
        dp[o][0] = 0;
        int mx = -1;
        for (auto [x, y, i, c] : pts) {
            x = int(lower_bound(compress.begin(), compress.end(), x) - compress.begin());
            y = int(lower_bound(compress.begin(), compress.end(), -y) - compress.begin());
            vector<vector<int>> ndp(o + 1, vector<int>(MAXC + 1, -1e9));
            vector<int> lazy(o + 1, -1e9);
            for (int j=0; j<=o; j++) {
                int above = bit.query(y, j - 1), nxt = bit.kth(bit.query(y) + 1);
                for (int k=0; k<=MAXC; k++)
                    if (dp[j][k] >= 0) {
                        if (i < n) {
                            // regular point
                            if (y >= j) {
                                assert(k != 0);
                                // set to color k
                                if (c == 0 || c == k)
                                    ndp[j][k] = max(ndp[j][k], dp[j][k]);
                                // set to different color
                                if (c == 0) {
                                    if (nxt == o) {
                                        if (y == mx)
                                            ndp[o][0] = max(ndp[o][0], dp[j][k]);
                                        else
                                            lazy[y] = max(lazy[y], dp[j][k]);
                                    } else {
                                        ndp[nxt][k] = max(ndp[nxt][k], dp[j][k]);
                                    }
                                } else if (c != k) {
                                    if (nxt == o) {
                                        if (y == mx)
                                            ndp[o][0] = max(ndp[o][0], dp[j][k]);
                                        else
                                            ndp[y][c] = max(ndp[y][c], dp[j][k]);
                                    } else {
                                        ndp[nxt][k] = max(ndp[nxt][k], dp[j][k]);
                                    }
                                }
                            } else {
                                // set to color k
                                if (k != 0 && (c == 0 || c == k)) {
                                    if (above == 0)
                                        ndp[y][k] = max(ndp[y][k], dp[j][k]);
                                    else
                                        ndp[j][k] = max(ndp[j][k], dp[j][k]);
                                }
                                // set to different color
                                if (j == o && y > mx) {
                                    if (c == 0)
                                        lazy[y] = max(lazy[y], dp[j][k]);
                                    else
                                        ndp[y][c] = max(ndp[y][c], dp[j][k]);
                                } else {
                                    ndp[j][k] = max(ndp[j][k], dp[j][k]);
                                }
                            }
                        } else {
                            // query point
                            ndp[j][k] = max(ndp[j][k], dp[j][k] + (above == 0 && x >= j));
                        }
                    }
            }
            for (int j=0; j<=o; j++)
                for (int k=0; k<=MAXC; k++) {
                    if (k > 0)
                        ndp[j][k] = max(ndp[j][k], lazy[j]);
                    dp[j][k] = ndp[j][k];
                }
            if (i < n) {
                bit.update(y, 1);
                mx = max(mx, y);
            }
        }

        int ret = 0;
        for (int j=0; j<=o; j++)
            for (int k=0; k<=MAXC; k++)
                ret = max(ret, dp[j][k]);
        cout << ret << "\n";
    }

    return 0;
}