#include #include #include #include #include #include #include #include #include #include #include #include #include using namespace std; typedef long long ll; typedef pair P; #define MOD 1000000007 // 10^9 + 7 #define INF 1000000000 // 10^9 #define LLINF 1LL<<60 class UF { private: std::vector parent; std::vector num_member; // 同じグループに属するメンバーの数 // 自身込み public: // コンストラクタ ※注意※ 0~nまでのn+1個を作る UF(int n) { for (int i = 0; i <= n; i++) { parent.push_back(i); // num_member.push_back(1); } } // 木の根を求める int root(int x) { if (parent[x] == x)return x; else return parent[x] = root(parent[x]); } // 同じ集合に属するメンバーの数を求める int numOfmember(int x) { if (parent[x] == x) return num_member[x]; else return num_member[x] = numOfmember(parent[x]); } // xとyの属する集合を合併 void unite(int x, int y) { int rx = root(x); int ry = root(y); if (rx == ry) return; // 元々合併済みの場合 if (num_member[rx] < num_member[ry]) { num_member[ry] = numOfmember(ry) + numOfmember(rx); parent[rx] = ry; } else if(num_member[rx] > num_member[ry]){ num_member[rx] = numOfmember(ry) + numOfmember(rx); parent[ry] = rx; } else { // num_member[rx] == num_member[ry] if (rx < ry) { num_member[rx] = numOfmember(ry) + numOfmember(rx); parent[ry] = rx; } else { num_member[ry] = numOfmember(ry) + numOfmember(rx); parent[rx] = ry; } } } // xとyが同じ集合に属するか否か bool same(int x, int y) { return root(x) == root(y); // rootが同じなら同じ集合に含まれる } }; int main() { cin.tie(0); ios::sync_with_stdio(false); int N, M; cin >> N >> M; UF monkey(N); for (int i = 0; i < M; i++) { int a, b; cin >> a >> b; monkey.unite(a, b); } for (int i = 1; i <= N; i++) { cout << monkey.root(i) << endl; } return 0; }