/*
离散化思路 和一般的离散化不同 多了个中间加点操作
具体为啥要加点
1-10 1-4 6-10
这三个区间离散化后 5 这个点会丢掉。
加点防止丢点。。。。。。。hhhh
总结  排序 去重 中间加点 再排序
*/
2528 -- Mayor's posters (poj.org)
#include
#include
#include
using namespace std;
const int maxn = 1e6 + 10;
#define ls (u<<1)
#define rs (u<<1|1)
struct node
{
    int l, r;
}e[maxn];
struct sgt
{
    int l, r;
    int co;
}tr[maxn*20];
int a[maxn], la;
int find(int x)
{
    return lower_bound(a + 1, a + 1 + la, x) - a;
}
int t, n, m;
bool vis[maxn];
void build(int u, int l, int r)
{
    tr[u].l=l;tr[u].r=r;tr[u].co=0;
    if (l == r)return;
    int mid = (l + r) / 2;
    build(ls, l, mid);
    build(rs, mid + 1, r);
}
void pushdown(int u)
{
    if (tr[u].co > 0)
    {
        tr[ls].co = tr[rs].co = tr[u].co;
        tr[u].co = 0;
    }
}
void modify(int u, int ql, int qr,int v)
{
    if (ql <= tr[u].l && tr[u].r <= qr)
    {
        tr[u].co = v;
        return;
    }
    pushdown(u);
    int mid = (tr[u].l + tr[u].r) / 2;
    if (ql <= mid)modify(ls, ql, qr, v);
    if (mid < qr)modify(rs, ql, qr, v);
}
void ask(int u, int& ans)
{
    if (tr[u].co != 0 && vis[tr[u].co] == false)ans++, vis[tr[u].co] = true;
    if (tr[u].l == tr[u].r)return;
    pushdown(u);
    int mid = (tr[u].l + tr[u].r) / 2;
    ask(ls, ans); ask(rs, ans);
}
void solve()
{
    la = 0;
    scanf("%d", &n);
    for (int i = 1; i <= n; i++)scanf("%d%d", &e[i].l, &e[i].r), a[++la] = e[i].l, a[++la] = e[i].r;
    sort(a + 1, a + 1 + la);//排序
    la = unique(a + 1, a + 1 + la) - a - 1;//去重
    for (int i = la; i > 1; i--)if (a[i] - a[i - 1] > 1)a[++la] = a[i-1] +1;//中间加点
    sort(a + 1, a + 1 + la);//排序
    build(1, 1, la);
    memset(vis, 0, sizeof vis);
    for (int i = 1; i <= n; i++)
    {
        int l = find(e[i].l), r = find(e[i].r);
        modify(1, l, r, i);
    }
    int ans = 0;
    ask(1, ans);
    printf("%d\n", ans);
}
int main()
{
    scanf("%d", &t);
    while (t--)solve();
    return 0;
}