fn main [ var lines := list_break_to_lines(read_lazy(h[0])); lines := list_flatten(lines); const x := len(lines[0]); const y := len(lines); var a := list_to_array([x, y], list_join(lines, "")); a := array_flatten(a); var sum := 0; for j := 0 to y do [ for i := 0 to x do [ var plant := a[i, j]; if plant = '.' then continue; var area := 1; var set := treeset_from_list([ mktuple2(i, j) ]); var visited := set; var side_set := treeset_init(tuple4(int, int, int, int)); while true do [ var t := treeset_first(set); if t is n then break; set := treeset_clear(set, t.j); for d in [ [0, 1], [0, -1], [1, 0], [-1, 0] ] do [ var xp := t.j.v1 + d[0]; var yp := t.j.v2 + d[1]; if xp >= 0, xp < x, yp >= 0, yp < y, a[xp, yp] = plant then [ if not treeset_test(visited, mktuple2(xp, yp)) then [ area += 1; visited := treeset_set(visited, mktuple2(xp, yp)); set := treeset_set(set, mktuple2(xp, yp)); ] ] else [ side_set := treeset_set(side_set, mktuple4(t.j.v1, t.j.v2, d[0], d[1])); ] ] ] var sides := 0; while true do [ var s := treeset_first(side_set); if s is n then break; side_set := treeset_clear(side_set, s.j); sides += 1; var xd := 1; while true do [ var key := mktuple4(s.j.v1 + xd * s.j.v4, s.j.v2 + xd * s.j.v3, s.j.v3, s.j.v4); if treeset_test(side_set, key) then side_set := treeset_clear(side_set, key); else break; xd += 1; ] xd := -1; while true do [ var key := mktuple4(s.j.v1 + xd * s.j.v4, s.j.v2 + xd * s.j.v3, s.j.v3, s.j.v4); if treeset_test(side_set, key) then side_set := treeset_clear(side_set, key); else break; xd -= 1; ] ] sum += area * sides; while true do [ var t := treeset_first(visited); if t is n then break; visited := treeset_clear(visited, t.j); a[t.j.v1, t.j.v2] := '.'; ] ] ] write(h[1], ntos(sum) + nl); ]