function hook_edges(E,n) = let parent = {rand(i) == 1 : i in dist(2,n)}; e1,e2 = unzip(E); in {E; ci in parent->e1; cj in parent-> e2 | not(ci) and cj} $ function compress_graph(P,E) = let % update edges to point to new parent % e1,e2 = unzip(e); e = {(i,j): i in p->e1; j in p->e2}; % remove self edges and flip edges up % e = {if i > j then (j,i) else (i,j) : (i,j) in e | i /= j}; % identify roots, relabel roots, and relabel edges % roots = {p == i : p in p ; i in [0:#p]}; labels = enumerate(roots); e1,e2 = unzip(e); e = {(li,lj): li in labels->e1; lj in labels->e2} in (e,pack_index(roots)) $ function rm_connected_components(E,n) = if #E == 0 then [0:n] else let P = [0:n]<-hook_edges(E,n); (E,I) = compress_graph(P,E); R = rm_connected_components(E,#I); Ins = P <- zip(I, I->R); in Ins->Ins $ edges = [(1, 5), (5, 6), (1, 6), (6, 10), (4, 5), (13, 4), (2, 13), (2, 11), (9, 2), (12, 9), (8, 9), (3, 7)]; rm_connected_components(edges,14);