with recursive raw as ( select split(content, e'\n') as content from read_text('data/04.in') ), lines as ( select string_split(unnest(content), '') as line, generate_subscripts(content, 1) as row from raw ), grid as ( select unnest(line) as ch, generate_subscripts(line, 1) as col, row from lines ), rolls as ( select row, col from grid where ch = '@' ), accessible as ( select pos.row, pos.col from rolls pos, rolls adj where adj.row between pos.row - 1 and pos.row + 1 and adj.col between pos.col - 1 and pos.col + 1 group by pos.row, pos.col having count(*) < 5 ), remove (row, col, present, level) as ( select row, col, true from rolls union all select pos.row, pos.col, pos.present and 4 < ( select count(*) from remove adj where adj.present and adj.row between pos.row - 1 and pos.row + 1 and adj.col between pos.col - 1 and pos.col + 1 ) from remove pos where exists ( select pos.row, pos.col, count(*) as c from remove pos, remove adj where pos.present and adj.present and adj.row between pos.row - 1 and pos.row + 1 and adj.col between pos.col - 1 and pos.col + 1 group by pos.row, pos.col having c < 5 ) ), removed as ( select row, col from remove group by row, col having bool_or(not present) ), part2 as ( select (select count(*) from removed) as solution ) select (select count(*) from accessible) as p1, (select count(*) from removed) as p2;