//-------------------------------------------------------------
// Union-Find
//   Balancing + Path-Compression : O(invAckermann)
//
// Verified by
//   - SRM Member Pilot 2 Div1 LV2
//-------------------------------------------------------------

struct UnionFind
{
	vector<int> uf, sz;
	int nc;

	UnionFind(int N): uf(N), sz(N,1), nc(N)
		{ for(int i=0; i<N; ++i) uf[i] = i; }
	int size()
		{ return nc; }
	int Find(int a)
		{ return uf[a]==a ? a : uf[a]=Find(uf[a]); }
	bool Union(int a, int b)
		{
			a = Find(a);
			b = Find(b);
			if( a != b )
			{
				if( sz[a] >= sz[b] ) swap(a, b);
				uf[a] = b;
				sz[b] += sz[a];
				--nc;
			}
			return (a!=b);
		}
};
