§ intuition for correctness of rank:

Assume that we had to re-point pointers of all our children to the new root when we decide to make another node the root. That is, we would have:

void mkroot(int newroot, int prevroot) {   for (int child : children[prevroot] {        parent[child] = newroot;   }   parent[prevroot] = newroot];   children[prevroot] = {}; // this has no children anymore}