fn dist(a b : tuple3(int, int, int)) : int [ return (a.v1 - b.v1) * (a.v1 - b.v1) + (a.v2 - b.v2) * (a.v2 - b.v2) + (a.v3 - b.v3) * (a.v3 - b.v3); ] fn main [ var lines := list_break_to_lines(read_lazy(h[0])); var n_b := len(lines); var n_conn := select(n_b > 20, 10, 1000); var coords := empty(tuple3(int, int, int)); for l in lines do [ var c := map(list_break(l, ','), ston); coords +<= mktuple3(c[0], c[1], c[2]); ] var dists := empty(tuple3(int, int, int)); for i := 0 to n_b do [ for j := i + 1 to n_b do [ var d := dist(coords[i], coords[j]); dists +<= mktuple3(d, i, j); ] ] dists := list_sort(dists); var connections := fill(empty(int), n_b); for i := 0 to n_conn do [ var a := dists[i].v2; var b := dists[i].v3; connections[a] +<= b; connections[b] +<= a; ] var used := fill(false, n_b); var sizes := empty(int); again: for i := 0 to n_b do [ if not used[i] then [ var size := 0; var worklist := 0 bts i; while worklist <> 0 do [ var j := bsr worklist; worklist btr= j; if used[j] then continue; used[j] := true; size += 1; for c in connections[j] do worklist bts= c; ] sizes +<= size; goto again; ] ] sizes := list_sort(sizes); sizes := list_reverse(sizes); var result := sizes[0] * sizes[1] * sizes[2]; write(h[1], ntos(result) + nl); ]