All the work done in CONNECTED. Let JOIN just add the given edge to a set of edges. Now, can use depth-first-search to test connectivity when we need to. Basically, if we start at u and can reach v, they are connected. If not, not.
That gives us: for all the calls
to CONNECTED and JOIN. This dominates that
for sorting the edges, giving O(|E|2) running time.
Explanation: for each edge that we consider adding, we do a depth-first search over edges to see if the endpoints are already connected.