Components: Start at . Decrement on successful union.
Max size: Start at .
After union, update to max of current and new component size. After each edge, output components maxSize. Time: for edges. This is the best you can do for this problem type. Use union by size (not rank) so you always know each component's exact size from the root's stored value.