implement a union-find data structure