#include <iostream>
#include <vector>
#include <algorithm>
#include <set>
#include <queue>
#include <map>
using namespace std;
struct seg_tree {
int n;
vector<int> t;
vector<int> push;
vector<int> curpush;
seg_tree(int x) {
n = x;
t.resize(n * 4);
push.resize(n * 4);
curpush.resize(n * 4, -1);
}
void make_push(int i) {
t[i * 2 + 1] += push[i];
t[i * 2 + 2] += push[i];
push[i * 2 + 1] += push[i];
push[i * 2 + 2] += push[i];
push[i] = 0;
}
void sett(int i, int l, int r, int x, int num) {
if (l == x && r == x + 1) {
t[i] = max(t[i], num);
} else {
make_push(i);
int m = (l + r) / 2;
if (x < m) {
sett(i * 2 + 1, l, m, x, num);
} else {
sett(i * 2 + 2, m, r, x, num);
}
t[i] = max(t[i * 2 + 1], t[i * 2 + 2]);
}
}
void add(int i, int l, int r, int ql, int qr, int x) {
if (ql <= l && r <= qr) {
t[i] += x;
push[i] += x;
} else if (ql >= r || qr <= l) {
return;
} else {
make_push(i);
int m = (l + r) / 2;
add(i * 2 + 1, l, m, ql, qr, x);
add(i * 2 + 2, m, r, ql, qr, x);
t[i] = max(t[i * 2 + 1], t[i * 2 + 2]);
}
}
void clearr(int i, int l, int r) {
t[i] = 0;
push[i] = 0;
if (l == r - 1) {
return;
} else {
int m = (l + r) / 2;
if (t[i * 2 + 1] > 0) {
clearr(i * 2 + 1, l, m);
}
if (t[i * 2 + 2] > 0) {
clearr(i * 2 + 2, m, r);
}
}
}
void add(int ql, int qr, int x) {
add(0, 0, n, ql, qr, x);
}
void sett(int x, int num) {
sett(0, 0, n, x, num);
}
int getmax() {
return t[0];
}
};
int main() {
cin.tie(0);
cout.tie(0);
ios::sync_with_stdio(false);
int t;
cin >> t;
seg_tree tree(200001);
while (t--) {
int n;
cin >> n;
vector<vector<int>> albums(n);
vector<vector<int>> localmax(n);
vector<pair<int, int>> best(n);
for (int i = 0; i < n; i++) {
int k;
cin >> k;
best[i].second = i;
for (int j = 0; j < k; j++) {
int p;
cin >> p;
if (p > best[i].first) {
localmax[i].push_back(p);
}
best[i].first = max(best[i].first, p);
albums[i].push_back(p);
}
}
sort(best.begin(), best.end());
int fullans = 0;
for (int l = 0; l < n; l++) {
int i = best[l].second;
for (int j = 0; j < localmax[i].size(); j++) {
tree.add(localmax[i][j], 200001, -1);
}
int ans = tree.getmax() + localmax[i].size();
for (int j = 0; j < localmax[i].size(); j++) {
tree.add(localmax[i][j], 200001, 1);
}
tree.sett(best[l].first, ans);
fullans = max(ans, fullans);
}
tree.clearr(0, 0, 200001);
cout << fullans << '\n';
}
}
706A - Beru-taxi | 686A - Free Ice Cream |
1358D - The Best Vacation | 1620B - Triangles on a Rectangle |
999C - Alphabetic Removals | 1634C - OKEA |
1368C - Even Picture | 1505F - Math |
1473A - Replacing Elements | 959A - Mahmoud and Ehab and the even-odd game |
78B - Easter Eggs | 1455B - Jumps |
1225C - p-binary | 1525D - Armchairs |
1257A - Two Rival Students | 1415A - Prison Break |
1271A - Suits | 259B - Little Elephant and Magic Square |
1389A - LCM Problem | 778A - String Game |
1382A - Common Subsequence | 1512D - Corrupted Array |
667B - Coat of Anticubism | 284B - Cows and Poker Game |
1666D - Deletive Editing | 1433D - Districts Connection |
2B - The least round way | 1324A - Yet Another Tetris Problem |
246B - Increase and Decrease | 22E - Scheme |