#include using namespace std; struct UnionFind { std::vector data; UnionFind() = default; explicit UnionFind(std::size_t sz) : data(sz, -1) {} bool unite(int x, int y) { x = find(x), y = find(y); if (x == y) return false; if (data[x] > data[y]) std::swap(x, y); data[x] += data[y]; data[y] = x; return true; } int find(int k) { if (data[k] < 0) return (k); return data[k] = find(data[k]); } int size(int k) { return -data[find(k)]; } bool same(int x, int y) { return find(x) == find(y); } std::vector> groups() { int n = (int)data.size(); std::vector> ret(n); for (int i = 0; i < n; i++) { ret[find(i)].emplace_back(i); } ret.erase( std::remove_if(ret.begin(), ret.end(), [&](const std::vector& v) { return v.empty(); }), ret.end()); return ret; } }; // これ好き int main() { int n, m; cin >> n >> m; using Query = tuple; vector events; for (int i = 0; i < m; ++i) { int u, v, l; cin >> u >> v >> l; --u; --v; events.push_back({l, 0, u, v}); } int q; cin >> q; for (int qi = 0; qi < q; ++qi) { int p, t; cin >> p >> t; --t; events.push_back({p, 1, t, qi}); } sort(events.begin(), events.end()); UnionFind uf(n); vector ans(q); for (auto [w, x, y, z] : events) { if (x == 0) { uf.unite(y, z); } if (x == 1) { ans[z] = uf.size(y); } } for (int a : ans) cout << a << endl; }