clean python solution
\nclass Solution(object):\n    def containVirus(self, grid):\n        """\n        :type grid: List[List[int]]\n        :rtype: int\n        """\n        if not
```\nclass Solution(object):\n    def containVirus(self, grid):\n        """\n        :type grid: List[List[int]]\n        :rtype: int\n        """\n        if not grid: return None\n        N,M=len(grid),len(grid[0])\n        \n        def around(r,c,t=None):\n            # all cells 1-step away from (r,c)\n            # optionally, if t!=None, target value must be t\n            for d in (-1,1):\n                for (rr,cc) in ((r+d,c), (r,c+d)):\n                    if 0<=rr<N and 0<=cc<M and (t == None or grid[rr][cc]==t):\n                        yield (rr,cc)\n        \n        def regions():\n            regs=[]\n            seen=set()\n            for r in xrange(N):\n                for c in xrange(M):\n                    if grid[r][c]==1 and (r,c) not in seen:\n                        # this is a new region. do a BFS to find all contiguous ones\n                        reg=set()\n                        front, newfront=[(r,c)], []\n                        while front:\n                            reg.update(front)\n                            while front:\n                                (r,c) = front.pop()\n                                for (rr,cc) in around(r,c,1):\n                                    if (rr, cc) not in reg:\n                                        newfront.append((rr,cc))\n                                        reg.add((rr, cc))\n                            front,newfront=newfront,front\n                        regs.append(reg)\n                        seen.update(reg)\n            return regs\n        \n        def reg_boundary(reg):\n            # cells that would become infected by cells in reg\n            bound=set()\n            for (r,c) in reg:\n                for (rr,cc) in around(r,c,0):\n                    bound.add((rr,cc))\n\n            return bound\n        \n        def reg_walls(reg,bound):\n            # number of walls that would need to be built to contain reg\n            walls=0\n            for (r,c) in bound:\n                for (rr,cc) in around(r,c,1):\n                    if (rr,cc) in reg:\n                        walls+=1    \n            return walls\n        gwalls=0\n        \n        while True:\n            \n            regs=regions()\n            \n            if not regs: break\n            reg = max(regs, key=lambda reg: len(reg_boundary(reg)))\n            walls=reg_walls(reg, reg_boundary(reg))\n            gwalls+=walls\n            \n            # neutralize region\n            for (r,c) in reg:\n                grid[r][c]=2\n\n            # compute next grid iteration after new infections\n            infected=set()\n            for r in xrange(N):\n                for c in xrange(M):\n                    if grid[r][c]==1:\n                        for (rr, cc) in around(r, c, 0):\n                            infected.add((rr, cc))\n\n            for r, c in infected:\n                grid[r][c]=1\n\n            if not infected: break\n\n        return gwalls\n```
[]