#include <bits/stdc++.h>
using namespace std;
#define int long long
#define _3bkarm cin.tie(NULL); cout.tie(NULL); ios::sync_with_stdio(false);
struct dsu {
int number_of_components;
vector<int> parent, size;
void build(int n) {
number_of_components = n - 1;
size.assign(n, 1);
parent.assign(n, 0);
for (int i = 0; i < n; ++i) {
parent[i] = i;
}
}
int root(int u) {
while (u != parent[u]) {
u = parent[u] = parent[parent[u]];
} return u;
}
int is_same_set(int u, int v) {
return root(u) == root(v);
}
void merge(int u, int v) {
int u_root = root(u);
int v_root = root(v);
if (u_root == v_root) {
return;
}
if (size[u_root] < size[v_root]) {
swap(u_root, v_root);
}
--number_of_components;
size[u_root] += size[v_root];
parent[v_root] = u_root;
}
};
void get_shit_done() {
int n, m;
cin >> n >> m;
set<int> adj[11][10];
for (int i = 1; i <= n; ++i) {
for (int j = 1; j <= 10; ++j) {
adj[j][i % j].insert(i);
}
}
dsu ds;
ds.build(n + 1);
for (int i = 0, a, d, k; i < m; ++i) {
cin >> a >> d >> k;
int x = d;
int y = a % d;
int lim = a + k * d;
vector<int> del;
adj[x][y].erase(a);
auto it = adj[x][y].lower_bound(a);
int lst = a + d;
while ( it != adj[x][y].end() and *it <= lim ) {
ds.merge(a, lst);
ds.merge(a, *it);
del.push_back(*it);
lst = *it + d;
++it;
}
if (lst <= lim) {
ds.merge(a, lst);
}
for (int id : del) {
adj[x][y].erase(id);
}
}
cout << ds.number_of_components << '\n';
}
signed main() {
_3bkarm
int ts = 1;
cin >> ts;
while (ts--) {
get_shit_done();
}
return 0;
}
I2luY2x1ZGUgPGJpdHMvc3RkYysrLmg+Cgp1c2luZyBuYW1lc3BhY2Ugc3RkOwoKI2RlZmluZSBpbnQgbG9uZyBsb25nCiNkZWZpbmUgXzNia2FybSBjaW4udGllKE5VTEwpOyBjb3V0LnRpZShOVUxMKTsgaW9zOjpzeW5jX3dpdGhfc3RkaW8oZmFsc2UpOwoKCnN0cnVjdCBkc3UgewogICAgaW50IG51bWJlcl9vZl9jb21wb25lbnRzOwogICAgdmVjdG9yPGludD4gcGFyZW50LCBzaXplOwoKICAgIHZvaWQgYnVpbGQoaW50IG4pIHsKICAgICAgICBudW1iZXJfb2ZfY29tcG9uZW50cyA9IG4gLSAxOwogICAgICAgIHNpemUuYXNzaWduKG4sIDEpOwogICAgICAgIHBhcmVudC5hc3NpZ24obiwgMCk7CiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBuOyArK2kpIHsKICAgICAgICAgICAgcGFyZW50W2ldID0gaTsKICAgICAgICB9CiAgICB9CgogICAgaW50IHJvb3QoaW50IHUpIHsKICAgICAgICB3aGlsZSAodSAhPSBwYXJlbnRbdV0pIHsKICAgICAgICAgICAgdSA9IHBhcmVudFt1XSA9IHBhcmVudFtwYXJlbnRbdV1dOwogICAgICAgIH0gcmV0dXJuIHU7CiAgICB9CgogICAgaW50IGlzX3NhbWVfc2V0KGludCB1LCBpbnQgdikgewogICAgICAgIHJldHVybiByb290KHUpID09IHJvb3Qodik7CiAgICB9CgogICAgdm9pZCBtZXJnZShpbnQgdSwgaW50IHYpIHsKICAgICAgICBpbnQgdV9yb290ID0gcm9vdCh1KTsKICAgICAgICBpbnQgdl9yb290ID0gcm9vdCh2KTsKCiAgICAgICAgaWYgKHVfcm9vdCA9PSB2X3Jvb3QpIHsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KCiAgICAgICAgaWYgKHNpemVbdV9yb290XSA8IHNpemVbdl9yb290XSkgewogICAgICAgICAgICBzd2FwKHVfcm9vdCwgdl9yb290KTsKICAgICAgICB9CgogICAgICAgIC0tbnVtYmVyX29mX2NvbXBvbmVudHM7CiAgICAgICAgc2l6ZVt1X3Jvb3RdICs9IHNpemVbdl9yb290XTsKICAgICAgICBwYXJlbnRbdl9yb290XSA9IHVfcm9vdDsKICAgIH0KfTsKCnZvaWQgZ2V0X3NoaXRfZG9uZSgpIHsKICAgIGludCBuLCBtOwogICAgY2luID4+IG4gPj4gbTsKCiAgICBzZXQ8aW50PiBhZGpbMTFdWzEwXTsKICAgIGZvciAoaW50IGkgPSAxOyBpIDw9IG47ICsraSkgewogICAgICAgIGZvciAoaW50IGogPSAxOyBqIDw9IDEwOyArK2opIHsKICAgICAgICAgICAgYWRqW2pdW2kgJSBqXS5pbnNlcnQoaSk7CiAgICAgICAgfQogICAgfQoKICAgIGRzdSBkczsKICAgIGRzLmJ1aWxkKG4gKyAxKTsKICAgIGZvciAoaW50IGkgPSAwLCBhLCBkLCBrOyBpIDwgbTsgKytpKSB7CiAgICAgICAgY2luID4+IGEgPj4gZCA+PiBrOwogICAgICAgIGludCB4ID0gZDsKICAgICAgICBpbnQgeSA9IGEgJSBkOwogICAgICAgIGludCBsaW0gPSBhICsgayAqIGQ7CgogICAgICAgIHZlY3RvcjxpbnQ+IGRlbDsKICAgICAgICBhZGpbeF1beV0uZXJhc2UoYSk7CiAgICAgICAgYXV0byBpdCA9IGFkalt4XVt5XS5sb3dlcl9ib3VuZChhKTsKCiAgICAgICAgaW50IGxzdCA9IGEgKyBkOwogICAgICAgIHdoaWxlICggaXQgIT0gYWRqW3hdW3ldLmVuZCgpIGFuZCAqaXQgPD0gbGltICkgewogICAgICAgICAgICBkcy5tZXJnZShhLCBsc3QpOwogICAgICAgICAgICBkcy5tZXJnZShhLCAqaXQpOwogICAgICAgICAgICBkZWwucHVzaF9iYWNrKCppdCk7CiAgICAgICAgICAgIGxzdCA9ICppdCArIGQ7CiAgICAgICAgICAgICsraXQ7CiAgICAgICAgfQogICAgICAgIGlmIChsc3QgPD0gbGltKSB7CiAgICAgICAgICAgIGRzLm1lcmdlKGEsIGxzdCk7CiAgICAgICAgfQoKICAgICAgICBmb3IgKGludCBpZCA6IGRlbCkgewogICAgICAgICAgICBhZGpbeF1beV0uZXJhc2UoaWQpOwogICAgICAgIH0KICAgIH0KCiAgICBjb3V0IDw8IGRzLm51bWJlcl9vZl9jb21wb25lbnRzIDw8ICdcbic7Cn0KCnNpZ25lZCBtYWluKCkgewogICAgXzNia2FybQoKICAgIGludCB0cyA9IDE7CiAgICBjaW4gPj4gdHM7CiAgICB3aGlsZSAodHMtLSkgewogICAgICAgIGdldF9zaGl0X2RvbmUoKTsKICAgIH0KCiAgICByZXR1cm4gMDsKfQ==