record junction [ x y : int; dest : list(int); path_len : list(int); ] fn recurse(junctions : list(junction), visited : int, cj : int) : int [ if cj = len(junctions) - 1 then return 2; visited bts= cj; var j := junctions[cj]; var max_r := -1; for i := 0 to len(j.dest) do [ if visited bt j.dest[i] then continue; var r := recurse(junctions, visited, j.dest[i]); if r >= 0 then [ r += j.path_len[i]; max_r := max(max_r, r); ] ] return max_r; ] fn main [ var lines := list_break_to_lines(read_lazy(h[0])); const x := len(lines[0]); const y := len(lines); var a := list_to_array([x, y], list_join(lines, "")); a := array_flatten(a); a[1, 0] := '#'; a[x - 2, y - 1] := '#'; var junctions := empty(junction); var coords_to_j := array_fill(-1, [x, y]); for i := 1 to x - 1 do [ for j := 1 to y - 1 do [ if a[i, j] = '#' then continue; var n_free := 0; for d in [ [0, -1], [1, 0], [0, 1], [-1, 0] ] do [ var dx, dy := d[0], d[1]; if a[i + dx, j + dy] <> '#' then n_free += 1; ] if n_free <> 2 then [ coords_to_j[i, j] := len(junctions); junctions +<= junction.[ x : i, y : j, dest : empty(int), path_len : empty(int) ]; ] ] ] for k := 0 to len(junctions) do [ var i := junctions[k].x; var j := junctions[k].y; for d in [ [0, -1, 0], [1, 0, 1], [0, 1, 2], [-1, 0, 3] ] do [ var dx, dy := d[0], d[1]; var ii := i + dx; var jj := j + dy; if a[ii, jj] = '#' then continue; var steps := 1; var last_d := d; while coords_to_j[ii, jj] = -1 do [ for dd in [ [0, -1, 0], [1, 0, 1], [0, 1, 2], [-1, 0, 3] ] do [ if dd[2] = (last_d[2] xor 2) then continue; var ddx, ddy := dd[0], dd[1]; if a[ii + ddx, jj + ddy] <> '#' then [ ii += ddx; jj += ddy; last_d := dd; steps += 1; goto next_step; ] ] abort; next_step: ] junctions[k].dest +<= coords_to_j[ii, jj]; junctions[k].path_len +<= steps; ] ] var result := recurse(junctions, 0, 0); write(h[1], ntos(result) + nl); ]