#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;
}