+ where rowCounts = parMap rpar countSetBits $ binHashes key
+
+
+part2 :: String -> Int
+part2 key = length $ cellEdges cells
+ where cells = presentCells $ binHashes key
+
+binHashes :: String -> [String]
+binHashes key = parMap rpar binHash $ rowSpecs key
+
+
+binHash :: String -> String
+binHash = binify . knotHash
+
+numKey :: (Int, Int) -> Int
+numKey (r, c) = 128 * r + c
+
+
+presentCells :: [String] -> CellSet
+presentCells bhs = S.fromList [(r, c) | r <- [0..127], c <- [0..127], (bhs!!r)!!c == '1']
+
+adjacentCells :: CellSet -> (Int, Int) -> [(Int, Int)]
+adjacentCells cells (r, c) = filter (\k -> S.member k cells) possibles
+ where possibles = [(r, c - 1), (r, c + 1), (r - 1, c), (r + 1, c)]
+
+
+cellEdges :: CellSet -> [G.SCC (Int, Int)]
+cellEdges cells = G.stronglyConnComp [(k, numKey k, map numKey $ adjacentCells cells k) | k <- S.elems cells]