straightforward solution w/ detailed comments
Code\n\nclass Solution:\n    def containVirus(self, isInfected: List[List[int]]) -> int:\n        if all(cell == 0 for row in isInfected for cell in row): retur
# Code\n```\nclass Solution:\n    def containVirus(self, isInfected: List[List[int]]) -> int:\n        if all(cell == 0 for row in isInfected for cell in row): return 0\n\n        m, n = len(isInfected), len(isInfected[0])\n\n        # neighbors of a cell are those that are 4-directionally adjacent w/o going out of bounds\n        def get_cell_neighbors(y, x):\n            return set((i, j) for (i, j) in ((y - 1, x), (y + 1, x), (y, x - 1), (y, x + 1),)\n                    if 0 <= i < m and 0 <= j < n)\n        \n        quarantined_cells = set()   # set tracking positions of all cells that have been quarantined\n        \n        # compute list of 2-tuples containing info on disjoint infected regions; each 2-tuple holds\n        # the positions of a continuous infected region & positions on its uninfected boundary cells\n        def get_infected_regions():\n            regions, visited = [], set()\n\n            # stack holding all infected cells; used to perform DFS to find disjoint infected regions\n            inf_stk = [(i, j) for i, row in enumerate(isInfected) for j, cell in enumerate(row)\n                       if isInfected[i][j] and (i, j) not in quarantined_cells]\n            while inf_stk:\n                pos = inf_stk.pop()\n                if pos in visited: continue\n\n                # remove neighbors that have already been quarantined to get non-infected neighbors\n                unknown_nbrs = get_cell_neighbors(*pos).difference(quarantined_cells)\n\n                # if the current infected cell is part of the running not-known-to-be-infected boundary\n                # of the infected region currently being searched for, add it to the infected region,\n                # and add its own non-infected neighbors to the running not-known-to-be-infected boundary\n                if regions and pos in regions[-1][1]:\n                    regions[-1][0].add(pos)\n                    regions[-1][1].update(unknown_nbrs)\n                \n                # otherwise, the current infected cell must be a part of a new disjoint infection region\n                else:\n                    regions.append(({pos}, unknown_nbrs))\n\n                # push reachable neighbors that are also infected onto the infection-stack for DFS\n                for i, j in unknown_nbrs:\n                    if isInfected[i][j] == 1: inf_stk.append((i, j))\n                    \n                visited.add(pos)\n            \n            # remove the infected cells themselves from their boundaries to get set of uninfected cells\n            for inf_reg, inf_bound in regions: inf_bound.difference_update(inf_reg)\n            \n            # sort the list of 2-tups in descending order by size of each region\'s uninfected-neighbors\n            return sorted(regions, key=lambda reg_tup: len(reg_tup[1]), reverse=True)\n\n        # the perimeter required to wall-in each infected region is equal to the sum \n        # of the count of infected cells that border each uninfected neighboring cell\n        def calc_wall_perimeter(inf_reg, inf_bound):\n            return sum(len(get_cell_neighbors(i, j).intersection(inf_reg)) for (i, j) in inf_bound)\n\n        res = 0\n        while True:\n            # we call `get_infected_regions` at each iteration to avoid having to manually\n            # merge previously disjoint regions that have since become continuously infected;\n            # this reduces runtime efficiency, but makes the implementation simpler\n            (inf_reg_top, inf_bound_top), *remaining_infections = get_infected_regions()\n\n            # add perimeter of walls needed to quarantine the most-infected region to result\n            res += calc_wall_perimeter(inf_reg_top, inf_bound_top)\n\n            # add all cells of the current iteration\'s most infectious region to the quarantined set\n            for cell in inf_reg_top: quarantined_cells.add(cell)\n\n            # exit when either all infected regions are quarantined, or all cells are infected            \n            if not remaining_infections: break\n            \n            # infect all non-infected boundary cells of the remainining unquarantined regions\n            for _, inf_bound in remaining_infections:\n                for i, j in inf_bound: isInfected[i][j] = 1\n            \n        return res\n```\n\n# Complexity\n- Time complexity: $$O(k*mn)$$, where $k$ is the number of disjoint infected regions\n<!-- Add your time complexity here, e.g. $$O(n)$$ -->\n\n- Space complexity: $$O(mn)$$\n<!-- Add your space complexity here, e.g. $$O(n)$$ -->
['Depth-First Search', 'Graph', 'Matrix', 'Python3']