def _available_cell(self) -> Tuple[int, int]:
        """Find next available cell first by row then column.

        First, construct a set containing all cells.
        Then iterate over the spans and remove occupied cells.
        """
        cells = set(itertools.product(range(len(self.rows)), range(len(self.columns))))
        for span in self._spans:
            for cell in span.cells:
                cells.remove(cell)

        if not cells:
            raise NoUnusedCellsError('No available cells')
        return min(cells)
def _available_cell ( self ) -> Tuple [ int , int ] : cells = set ( itertools . product ( range ( len ( self . rows ) ) , range ( len ( self . columns ) ) ) ) for span in self . _spans : for cell in span . cells : cells . remove ( cell ) if not cells : raise NoUnusedCellsError ( 'No available cells' ) return min ( cells )
Find next available cell first by row then column.

        First, construct a set containing all cells.
        Then iterate over the spans and remove occupied cells.