#include<iostream> #include<sstream> #include<string> #include<vector> #include<list> #include<set> #include<map> #include<stack> #include<queue> #include<algorithm> #pragma warning(disable:4996) using std::cin; using std::cout; using std::endl; using std::stringstream; using std::string; using std::vector; using std::list; using std::pair; using std::set; using std::multiset; using std::map; using std::multimap; using std::stack; using std::queue; class DisjoinSet { private: vector<int>represent, rank; public: DisjoinSet(const int &n):represent(n),rank(n) { for (int i = 0; i < n; i++) { represent[i] = i; } } int find(int i) { return represent[i] = represent[i] == i ? i : find(represent[i]); } void merge(const int &x, const int &y) { auto a = find(x);auto b = find(y); if (rank[a] < rank[b]) { represent[a] = b; } else { represent[b] = a; if (rank[b] == rank[a]) { rank[a]++; } } } int max() { map<int, int>union_amount; for (size_t i = 0; i < represent.size(); i++) { union_amount[find(i)]++; } int maximum = 0; for (auto iter = union_amount.begin(); iter != union_amount.end(); iter++) { maximum = std::max(maximum, iter->second); } return maximum; } }; int main() { //freopen("input.txt", "r", stdin); //freopen("output.txt", "w", stdout); int T; cin >> T; while (T--) { int n, m; cin >> n >> m; DisjoinSet union_set(n); while (m--) { int first, second; cin >> first >> second; if (first > second) { std::swap(first, second); } union_set.merge(first-1, second-1); } cout << union_set.max() << endl; } return 0; }