walk / traverse a disjoint set that has union rank and path compression
None of the hacks in the question are necessary, since it's definitely possible to merge two singly linked circular lists without maintaining any additional tail pointers.
Suppose you have heads x and y of two separate circular lists. We first save xn = x.next. Then, set x.next = y.next. Then, set y.next = xn. After these, it's easy to see that the two circular lists have been merged.