In a given 2D binary array A, there are two islands.  (An island is a 4-directionally connected group of 1s not connected to any other 1s.)
Now, we may change 0s to 1s so as to connect the two islands together to form 1 island.
Return the smallest number of 0s that must be flipped.  (It is guaranteed that the answer is at least 1.)
 
Example 1:
Input: A = [[0,1],[1,0]]
Output: 1
Example 2:
Input: A = [[0,1,0],[0,0,0],[0,0,1]]
Output: 2
Example 3:
Input: A = [[1,1,1,1,1],[1,0,0,0,1],[1,0,1,0,1],[1,0,0,0,1],[1,1,1,1,1]]
Output: 1

 
Constraints:

2 <= A.length == A[0].length <= 100
A[i][j] == 0 or A[i][j] == 1

Difficulty: interview

Starter code:

class Solution:
    def shortestBridge(self, A: List[List[int]]) -> int:
        

Solutions:
["class Solution:\n    def shortestBridge(self, A: List[List[int]]) -> int:\n        m, n = len(A), len(A[0])\n        dirs = [(0, 1), (1, 0), (0, -1), (-1, 0)]\n        queue = deque()\n        boundary = set()\n        found = False\n        for i in range(m):\n            for j in range(n):\n                if A[i][j] == 1:\n                    A[i][j] = 2\n                    queue.append((i, j))\n                    while queue:\n                        ci, cj = queue.popleft()\n                        for di, dj in dirs:\n                            ni, nj = ci + di, cj + dj\n                            if 0 <= ni < m and 0 <= nj < n:\n                                if A[ni][nj] == 1:\n                                    A[ni][nj] = 2\n                                    queue.append((ni, nj))\n                                elif A[ni][nj] == 0:\n                                    boundary.add((ci, cj))\n                    found = True\n                    break\n            if found:\n                break\n                \n        queue = deque(boundary)\n        steps = 0\n        while queue:\n            for _ in range(len(queue)):\n                i, j = queue.popleft()\n                for di, dj in dirs:\n                    ni, nj = i + di, j + dj\n                    if 0 <= ni < m and 0 <= nj < n:\n                        if A[ni][nj] == 0:\n                            A[ni][nj] = 2\n                            queue.append((ni, nj))\n                        elif A[ni][nj] == 1:\n                            return steps\n            steps += 1", "from collections import deque\nclass Solution:\n    def shortestBridge(self, A: List[List[int]]) -> int:\n        q = deque()\n        m, n  = len(A), len(A[0])\n\n        def explore_island(r, c):\n            if not 0 <= r < m or not 0 <= c < n or A[r][c] == -1:\n                return\n            if A[r][c] == 1:           \n                A[r][c] = -1    \n                explore_island(r+1, c)\n                explore_island(r-1, c)\n                explore_island(r, c+1)\n                explore_island(r, c-1)\n            elif A[r][c] == 0:\n                q.append((r, c, 1))\n                \n        def findFirst():\n            for i in range(m):\n                for j in range(n):\n                    if A[i][j] == 1:\n                        explore_island(i, j)\n                        return\n        findFirst()\n        \n        while q:\n            cur_x, cur_y, cur_t = q.popleft()\n            for i, j in (cur_x+1, cur_y), (cur_x-1, cur_y), (cur_x, cur_y+1), (cur_x, cur_y-1):\n                if 0<=i<m and 0<=j<n:\n                    if A[i][j] == 0:\n                        A[i][j] = -1\n                        q.append((i, j, cur_t + 1))\n                    elif A[i][j] == 1:                 \n                        return cur_t\n                    \n#         q = collections.deque()\n        # def explore_island(r, c):\n        #     if not 0 <= r < len(A) or not 0 <= c < len(A[r]) or A[r][c] == -1:\n        #         return\n        #     if A[r][c] == 1:           \n        #         A[r][c] = -1    \n        #         explore_island(r+1, c)\n        #         explore_island(r-1, c)\n        #         explore_island(r, c+1)\n        #         explore_island(r, c-1)\n        #     elif A[r][c] == 0:\n        #         q.append((r, c, 1))\n                \n#         def find_first_island():   \n#             for r, row in enumerate(A):\n#                 for c, v in enumerate(row):\n#                     if v == 1:\n#                         explore_island(r, c)\n#                         return\n#         find_first_island()            \n\n        # while q:\n        #     cur_r, cur_c, cur_l = q.popleft()\n        #     for x, y in (cur_r+1, cur_c), (cur_r-1, cur_c), (cur_r, cur_c+1), (cur_r, cur_c-1):\n        #         if 0 <= x < len(A) and 0 <= y < len(A[x]):\n        #             if A[x][y] == 1:\n        #                 return cur_l\n        #             elif A[x][y] == 0:\n        #                 A[x][y] = -1\n        #                 q.append((x, y, cur_l + 1))\n", "class Solution:\n    def shortestBridge(self, A: List[List[int]]) -> int:\n        def dfs(i, j, n, m):\n            A[i][j] = 2\n            queue.append((i, j))\n            directions = [(-1, 0), (1, 0), (0, -1), (0, 1)]\n            for dx, dy in directions:\n                x, y = i + dx, j + dy\n                if 0 <= x < n and 0 <= y < m and A[x][y] == 1:\n                    dfs(x, y, n, m)\n\n        from collections import deque\n        queue = deque()\n        n, m = len(A), len(A[0])\n        for i in range(n):\n            for j in range(m):\n                if A[i][j] == 1:\n                    dfs(i, j, n, m)\n                    break\n            else:\n                continue\n            break\n\n        \n        directions = [(-1, 0), (1, 0), (0, -1), (0, 1)]\n        step = 0\n        while queue:\n            size = len(queue)\n            flag = False\n            for i in range(size):\n                point = queue.popleft()\n                x, y = point[0], point[1]\n                for dx, dy in directions:\n                    _x, _y = x + dx, y + dy\n                    if _x < 0 or _x >= n or _y < 0 or _y >= m or A[_x][_y] == 2:\n                        continue\n                    if A[_x][_y] == 1:\n                        return step\n                    A[_x][_y] = 2\n                    queue.append((_x, _y))\n            step += 1\n\n", "class Solution:\n    def shortestBridge(self, A: List[List[int]]) -> int:\n        def dfs(i, j):\n            A[i][j] = -1\n            bfs.append((i, j))\n            for x, y in ((i - 1, j), (i + 1, j), (i, j - 1), (i, j + 1)):\n                if 0 <= x < n and 0 <= y < n and A[x][y] == 1:\n                    dfs(x, y)\n        def first():\n            for i in range(n):\n                for j in range(n):\n                    if A[i][j]:\n                        return i, j\n        n, step, bfs = len(A), 0, []\n        dfs(*first())\n        while bfs:\n            new = []\n            for i, j in bfs:\n                for x, y in ((i - 1, j), (i + 1, j), (i, j - 1), (i, j + 1)):\n                    if 0 <= x < n and 0 <= y < n:\n                        if A[x][y] == 1:\n                            return step\n                        elif not A[x][y]:\n                            A[x][y] = -1\n                            new.append((x, y))\n            step += 1\n            bfs = new", "from queue import Queue\n\ndef valid(m, i, j):\n    return 0 <= i < len(m) and 0 <= j < len(m[0])\n\ndef findAnIsland(m, e):\n    stack = []\n    for i in range(len(m)):\n        for j in range(len(m[0])):\n            if m[i][j] == 1 and (i, j) not in e:\n                stack.append((i, j))\n                break\n        else:\n            continue\n        break\n    result, edges = set(), set()\n    while stack:\n        ci, cj = stack.pop()\n        result.add((ci, cj))\n        for di, dj in ((0,1), (1,0), (0,-1), (-1,0)):\n            cdi, cdj = ci+di, cj+dj\n            if valid(m, cdi, cdj) and (cdi, cdj) not in e and (cdi, cdj) not in result:\n                if m[cdi][cdj] == 1:\n                    stack.append((cdi, cdj))\n                else:\n                    edges.add((ci, cj))\n    return result, edges\n\nclass Solution:\n    def shortestBridge(self, A: List[List[int]]) -> int:\n        a, aedges = findAnIsland(A, set())\n        b, bedges = findAnIsland(A, a)\n        min_flip = float('inf')\n        q = Queue()\n        for i, j in aedges:\n            q.put((i, j, 0))\n        while not q.empty():\n            ci, cj, dist = q.get()\n            for di, dj in ((0,1), (1,0), (0,-1), (-1,0)):\n                cdi, cdj = ci+di, cj+dj\n                if valid(A, cdi, cdj):\n                    if (cdi, cdj) in bedges:\n                        min_flip = min(min_flip, dist)\n                        return min_flip\n                    elif A[cdi][cdj] == 0 or A[cdi][cdj] > dist + 1:\n                        A[cdi][cdj] = dist + 1\n                        q.put((cdi, cdj, dist + 1))\n        return min_flip\n\n", "WATER = 0\nLAND = 1\nISLAND = 2\nBRIDGE = 3\nDIR = ((-1, 0), (1, 0), (0, -1), (0, 1))\nfrom copy import deepcopy\nclass Solution:\n    def shortestBridge(self, A):\n        x0, y0 = self.findFirstLand(A)\n        q = deque([(x0, y0)])\n        visited = set([(x0, y0)])\n        self.bfs(A, q, visited, LAND)\n        q = deque(visited)\n        return self.bfs(A, q, visited, WATER, LAND) - 1\n        \n    def findFirstLand(self, A):\n        m, n = len(A), len(A[0])\n        for x in range(m):\n            for y in range(n):\n                if A[x][y] == LAND:\n                    return x, y\n    \n    def bfs(self, A, q, visited, target, des=-1):\n        m, n = len(A), len(A[0])\n        step = 0\n        while q:\n            for _ in range(len(q)):\n                x, y = q.popleft()\n                for dx, dy in DIR:\n                    nx, ny = x + dx, y + dy\n                    if 0 <= nx <= m - 1 and 0 <= ny <= n - 1 and (nx, ny) not in visited:\n                        if A[nx][ny] == des:\n                            return step + 1\n                        if A[nx][ny] == target:\n                            q.append((nx, ny))\n                            visited.add((nx, ny))\n            step += 1\n        return step - 1", "class Solution:\n    def shortestBridge(self, A: List[List[int]]) -> int:\n        \\\"\\\"\\\"\\\"\n        1. find the 1st island (DFS)\n        2. increment on the 1st island's boundary until it hit island (BFS)\n        3. return the step\n        \\\"\\\"\\\"\n        def dfs(i, j):\n            A[i][j] = -1  # mark as visited\n            queue.append((i, j))\n            for x, y in ((i-1, j), (i+1, j), (i, j-1), (i, j+1)):\n                if 0 <= x < n and 0 <= y < n and A[x][y] == 1:\n                    dfs(x, y)\n        \n        def first():\n            for i in range(len(A)):\n                for j in range(len(A[0])):\n                    if A[i][j] == 1:\n                        return (i, j)\n        \n        # step 1 find the 1st island\n        queue = deque()\n        n = len(A)\n        dfs(*first())\n        \n        # step 2 BFS from island 1\n        step = 0 # because we start from island 1\n        while queue:\n            size = len(queue)\n            for _ in range(size):\n                i, j = queue.popleft()\n                A[i][j] = -1\n                for x, y in ((i-1, j), (i+1, j), (i, j-1), (i, j+1)):\n                     if 0 <= x < n and 0 <= y < n:\n                        if A[x][y] == 1:\n                            return step\n                        elif A[x][y] == 0: \n                            A[x][y] = -1  # \u00a0\u95dc\u9375 \u624d\u4e0d\u6703\u628a\u91cd\u8907\u7684add to queue, will TLE if not\n                            queue.append((x, y))      \n            step += 1\n        return 0\n   \n        \n        \n                \n        ", "class Solution(object):\n    def shortestBridge(self, A):\n        R, C = len(A), len(A[0])\n\n        def neighbors(r, c):\n            for nr, nc in ((r-1,c),(r,c-1),(r+1,c),(r,c+1)):\n                if 0 <= nr < R and 0 <= nc < C:\n                    yield nr, nc\n\n        def get_components():\n            done = set()\n            components = []\n            for r, row in enumerate(A):\n                for c, val in enumerate(row):\n                    if val and (r, c) not in done:\n                        # Start dfs\n                        stack = [(r, c)]\n                        seen = {(r, c)}\n                        while stack:\n                            node = stack.pop()\n                            for nei in neighbors(*node):\n                                if A[nei[0]][nei[1]] and nei not in seen:\n                                    stack.append(nei)\n                                    seen.add(nei)\n                        done |= seen\n                        components.append(seen)\n            return components\n\n        source, target = get_components()\n        #print source, target\n        queue = collections.deque([(node, 0) for node in source])\n        done = set(source)\n        while queue:\n            node, d = queue.popleft()\n            if node in target: return d-1\n            for nei in neighbors(*node):\n                if nei not in done:\n                    queue.append((nei, d+1))\n                    done.add(nei)", "class Solution(object):\n    def shortestBridge(self, A):\n        R, C = len(A), len(A[0])\n\n        def neighbors(r, c):\n            for nr, nc in ((r-1,c),(r,c-1),(r+1,c),(r,c+1)):\n                if 0 <= nr < R and 0 <= nc < C:\n                    yield nr, nc\n\n        def get_components():\n            done = set()\n            components = []\n            for r, row in enumerate(A):\n                for c, val in enumerate(row):\n                    if val and (r, c) not in done:\n                        # Start dfs\n                        stack = [(r, c)]\n                        seen = {(r, c)}\n                        while stack:\n                            node = stack.pop()\n                            for nei in neighbors(*node):\n                                if A[nei[0]][nei[1]] and nei not in seen:\n                                    stack.append(nei)\n                                    seen.add(nei)\n                        done |= seen\n                        components.append(seen)\n            return components\n\n        source, target = get_components()\n        queue = collections.deque([(node, 0) for node in source])\n        done = set(source)\n        while queue:\n            node, d = queue.popleft()\n            if node in target: return d-1\n            for nei in neighbors(*node):\n                if nei not in done:\n                    queue.append((nei, d+1))\n                    done.add(nei)", "class Solution:\n    def shortestBridge(self, A: List[List[int]]) -> int:\n        if(len(A) == 0):\n            return 0\n        m = len(A)\n        n = len(A[0])\n        queue = []\n        found = False\n        for i in range(m):\n            if(found):\n                break\n            for j in range(n):\n                if(A[i][j] == 1):\n                    self.dfs(i,j,A, queue)\n                    found = True\n                    break\n        directions =[(0,1),(1,0),(0,-1),(-1,0)]\n        while(queue):\n            path, x,y = queue.pop(0)\n            for dx,dy in directions:\n                if(x+dx < 0 or y+dy < 0 or x+dx >= m or y+dy>= n):\n                    continue\n                if(A[x+dx][y+dy] == 1):\n                    return path\n                if(A[x+dx][y+dy] == 0):\n                    A[x+dx][y+dy] = 2\n                    queue.append((path+1,x+dx,y+dy))\n        return -1\n                    \n    def dfs(self,i,j,grid,queue):\n        queue.append((0,i,j))\n        grid[i][j] = 2\n        stack = [(i,j)]\n        directions = [(0,1),(1,0),(0,-1),(-1,0)]\n        while(stack):\n            x,y = stack.pop()\n            for dx,dy in directions:\n                if(x+dx<0 or y+dy<0 or x+dx>=len(grid) or y+dy>=len(grid[0])):\n                    continue\n                if(grid[x+dx][y+dy] == 1):\n                    queue.append((0,x+dx,y+dy))\n                    stack.append((x+dx,y+dy))\n                    grid[x+dx][y+dy] = 2\n            \n                \n", "class Solution:\n    def shortestBridge(self, A: List[List[int]]) -> int:\n        r = len(A)\n        c = len(A[0])\n        path = [(1, 0), (-1, 0), (0, 1), (0, -1)]\n        idx = []        \n        for i in range(r):\n            for j in range(c):\n                if A[i][j] == 1:\n                    idx.append((i, j))\n        queue = collections.deque([idx[0]])\n        seen = {tuple(idx[0])}\n        island = collections.deque([(idx[0][0], idx[0][1], 0)])\n        while queue:\n            x, y = queue.popleft()\n            for i in path:\n                a = x + i[0]\n                b = y + i[1]\n                if 0 <= a < r and 0 <= b < c and A[a][b] == 1 and (a, b) not in seen:\n                    queue.append((a, b))\n                    seen.add((a, b))\n                    island.append((a, b, 0))\n        while island:\n            x, y, z = island.popleft()\n            for i in path:\n                a = x + i[0]\n                b = y + i[1]\n                if 0 <= a < r and 0 <= b < c and (a, b) not in seen:\n                    if A[a][b] == 0:\n                        island.append((a, b, z + 1))\n                        seen.add((a, b))\n                    else:\n                        return z", "class Solution:\n    \n    def find_island(self, i, j):\n        if (i>=0 and i<self.m ) and ( j>=0 and j<self.n ) and ( self.grid[i][j]==1 ):\n            self.island.append([i,j])\n            self.grid[i][j]=-1\n            D=[[1,0],[-1,0],[0,1],[0,-1]]\n            for d in D:\n                self.find_island(i+d[0], j+d[1])\n    \n    def expand_island(self):\n        D=[[1,0],[-1,0],[0,1],[0,-1]]\n        while len(self.island)>0:\n            [i,j]=self.island.pop(0)\n            for d in D:\n                if (i+d[0] in range(self.m)) and (j+d[1] in range(self.n)):\n                    if self.grid[i+d[0]][j+d[1]]==1:\n                        return self.grid[i][j]+1\n                    if self.grid[i+d[0]][j+d[1]]==0:\n                        self.island.append([i+d[0], j+d[1]])\n                        self.grid[i+d[0]][j+d[1]]= self.grid[i][j]-1\n        return self.m+self.n-1\n    \n    def shortestBridge(self, A: List[List[int]]) -> int:\n        from itertools import product\n        self.grid=A\n        self.m, self.n=len(A), len(A[0])\n        self.island=[]\n        for i in range(self.n):\n            for j in range(self.m):\n                if len(self.island)==0 and self.grid[i][j]==1:\n                    self.find_island(i,j)\n                    return abs(self.expand_island())\n", "class Solution:\n    def shortestBridge(self, A: List[List[int]]) -> int:\n        def dirs(V, M, N):\n            res = []            \n            if V[0] > 0:\n                res.append((V[0]-1, V[1]))\n            if V[0] < M-1:\n                res.append((V[0]+1, V[1]))\n            if V[1] > 0:\n                res.append((V[0], V[1]-1))\n            if V[1] < N-1:\n                res.append((V[0], V[1]+1))                \n            return res\n\n        \n        \n        def bfs(grid):\n            q = []\n            for j in I[0]: \n                level[j] = 0 \n                q.append(j)\n                visited.add(j) \n                        \n            while q: \n                v = q.pop(0)                \n                for neighbor in dirs(v, len(grid), len(grid[0])):\n                    if neighbor not in visited:\n                        q.append(neighbor)\n                        visited.add(neighbor)\n                        if neighbor in level: \n                            level[neighbor] = min(level[neighbor],level[v] + 1)\n                        else:\n                            level[neighbor] = level[v] + 1\n\n                        \n            return                         \n\n                        \n        def dfs(grid, i,j, m, n, S): \n            S.add((i,j)) \n            vis.add((i,j)) \n            \n            if (i<(m-1)) and ((i+1,j) not in vis) and (grid[i+1][j] == 1): \n                dfs(grid, i+1, j, m, n, S)\n                \n            if (i>0) and ((i-1,j) not in vis) and (grid[i-1][j] == 1):\n                dfs(grid, i-1, j, m, n, S)\n                                \n            if (j<(n-1)) and ((i,j+1) not in vis) and (grid[i][j+1] == 1):\n                dfs(grid, i, j+1, m, n, S)\n                                \n            if (j>0) and ((i,j-1) not in vis) and (grid[i][j-1] == 1):\n                dfs(grid, i, j-1, m, n, S)                            \n            return \n        \n        M, N = len(A), len(A[0])\n        I = []                \n        vis = set()\n        \n        for i in range(M):\n            for j in range(N): \n                if ((i,j) not in vis) and (A[i][j] == 1): \n                    s = set()\n                    dfs(A,i,j,M,N,s)\n                    I.append(s)\n        \n        # print(len(I[0]), len(I[1]))\n        \n        level = {}\n        visited = set()\n        bfs(A)\n        \n        # d = [level[j] for j in I[1]]\n        \n        # print(level)\n        # print(d) \n        \n        return min([level[j] for j in I[1]])-1", "class Solution:\n    def shortestBridge(self, A: List[List[int]]) -> int:\n        m, n = len(A), len(A[0])\n        r, c = -1, -1\n        \n        for i, row in enumerate(A):\n            for j, val in enumerate(row):\n                if val == 1:\n                    r = i\n                    c = j\n                    break\n        \n        if r == -1 or c == -1:\n            return -1\n        \n        \n        nei = [(0,1),(1,0),(0,-1),(-1,0)]\n        \n        def dfs(A, i, j, q):\n            q.append((i, j, 0))\n            A[i][j] = 2\n            \n            for dx, dy in nei:\n                nx = i + dx\n                ny = j + dy\n                if 0 <= nx < m and 0 <= ny < n and A[nx][ny] == 1:\n                    dfs(A, nx, ny, q)\n                    \n            return\n        \n        q = []\n        dfs(A, r, c, q)\n        \n        while q:\n            cx, cy, dis = q.pop(0)\n            \n            for dx, dy in nei:\n                nx, ny = cx + dx, cy + dy\n                if 0 <= nx < m and 0 <= ny < n:\n                    if A[nx][ny] == 1:\n                        return dis\n                    \n                    if A[nx][ny] == 0:\n                        q.append((nx, ny, dis+1))\n                        A[nx][ny] = 2\n                        \n        return -1\n                \n", "class Solution:\n    \n    def find_island(self, i, j):\n        if (i>=0 and i<self.m ) and ( j>=0 and j<self.n ) and ( self.grid[i][j]==1 ):\n            self.island.append([i,j])\n            self.grid[i][j]=-1\n            for d in [[1,0],[-1,0],[0,1],[0,-1]]:\n                self.find_island(i+d[0], j+d[1])\n    \n    def expand_island(self):\n        while len(self.island)>0:\n            [i,j]=self.island.pop(0)\n            for d in [[1,0],[-1,0],[0,1],[0,-1]]:\n                if (i+d[0] in range(self.m)) and (j+d[1] in range(self.n)):\n                    if self.grid[i+d[0]][j+d[1]]==1:\n                        return self.grid[i][j]+1\n                    if self.grid[i+d[0]][j+d[1]]==0:\n                        self.island.append([i+d[0], j+d[1]])\n                        self.grid[i+d[0]][j+d[1]]= self.grid[i][j]-1\n        return self.m+self.n-1\n    \n    def shortestBridge(self, A: List[List[int]]) -> int:\n        self.grid=A\n        self.m, self.n=len(A), len(A[0])\n        self.island=[]\n        for i in range(self.n):\n            for j in range(self.m):\n                if len(self.island)==0 and self.grid[i][j]==1:\n                    self.find_island(i,j)\n                    return abs(self.expand_island())", "class Solution:\n    def shortestBridge(self, A: List[List[int]]) -> int:\n        # https://leetcode.com/problems/shortest-bridge/discuss/843901/Python-Easy-BFS-Approach-with-Comments!\n        rows = len(A)\n        cols = len(A[0])\n        directions = ((1, 0), (-1, 0), (0, 1), (0, -1))\n        # Function to check if a given location is an edge.\n        def edge_check(ro, co):\n            r = []\n            for y, x in directions:\n                nr = ro + y\n                nc = co + x\n                if nr < rows and nr >= 0 and nc < cols and nc >= 0 and A[nr][nc] == 0:\n                    return True\n            return False\n        # Keep a flag for when we finish surveying the 1st island.\n        edges_1 = []\n        found_1 = False\n        edges_2 = []\n        # Work through our grid until we find an island.\n        for row in range(rows):\n            for col in range(cols):\n                # If we find one we'll start our bfs, marking visited locations with # so we don't revisit.\n                if A[row][col] == 1:\n                    A[row][col] = '#'\n                    q = collections.deque([])\n                    q.append((row, col))\n                    while q:\n                        r, c = q.popleft()\n                        # If we haven't found 1 yet (we must be working through 1 now).\n                        # Append the edge (row, col).\n                        if not found_1 and edge_check(r, c):\n                            edges_1.append((r, c))\n                        # Otherwise we must be on island 2.\n                        else:\n                            if edge_check(r, c):\n                                edges_2.append((r, c))\n                        # Continue working through the adjacent cells.\n                        for y, x in directions:\n                            nr = r + y\n                            nc = c + x\n                            if nr < rows and nr >= 0 and nc < cols and nc >= 0 and A[nr][nc] == 1:\n                                q.append((nr, nc))\n                                A[nr][nc] = '#'\n\n                    found_1 = True\n        # Sort the coordinates\n        c1 = sorted(edges_1, key=lambda x: (x[0], x[1]))\n        c2 = sorted(edges_2, key=lambda x: (x[0], x[1]))\n\n        minn = float('inf')\n        # Find/return the min distance between points.\n        for x1, x2 in c1:\n            for y1, y2 in c2:\n                minn = min(minn, abs(x1-y1)+abs(x2-y2)-1)\n\n        return minn\n", "class Solution:\n    def shortestBridge(self, A: List[List[int]]) -> int:\n        def trace_island(A, start_i, start_j, second, edges):\n            queue = collections.deque()\n            queue.append((start_i, start_j))\n            \n            while queue:\n                i, j = queue.popleft()\n                isedge = False\n                for di, dj in [(1, 0), (0, 1), (-1, 0), (0, -1), (0, 0)]:\n                    if  0 <= di+i < len(A) and 0<= dj+j < len(A[0]) and A[di+i][dj+j] == 1:\n                        if second:\n                            A[di+i][dj+j] = 2\n                        else:\n                            A[di+i][dj+j] = -1\n\n                        if not (di ==0 and dj==0):\n                            queue.append((di+i, dj+j))\n                    else:\n                        isedge = True\n                if isedge and not second:\n                    edges.append((i,j))\n            \n        \n        outedge = []\n        second = False\n        for i in range(len(A)):\n            for j in range(len(A[0])):\n                if A[i][j] == 1:\n                    trace_island(A, i, j, second, outedge)\n                    second = True\n        output = 0\n        while(outedge):\n            temp = []\n            for i, j in outedge:\n                for di, dj in [(1, 0), (0, 1), (-1, 0), (0, -1)]:\n                    if  0 <= di+i < len(A) and 0<= dj+j < len(A[0]) and A[di+i][dj+j] != -1:\n                        if A[di+i][dj+j] == 2:\n                            return output\n                        temp.append((di+i, dj+j))\n                        A[di+i][dj+j] = -1\n            outedge = temp\n            output += 1\n\n    \n                \n                    \n                    \n        \n", "class Solution:\n    def shortestBridge(self, A: List[List[int]]) -> int:\n        # find a 1, add all its neighbors queue and explore from there to look for a 1\n        q = []\n        r = len(A)\n        c = len(A[0])\n        result = float('inf')\n        seen = [[False]*c for _ in range(r)]\n        found = False\n        for i in range(r):\n            if found:\n                break\n            for j in range(c):\n                if A[i][j] == 1:\n                    # add all the 1's which are connected to this (i, j) to the q\n                    q = self.neighbors(i, j, A, seen, r, c)\n                    found = True\n                    break\n                    \n        # explore all points near to these elements in the q and keep the min distance\n        # if I see any 1\n        while q:\n            x, y, dis = q.pop(0)\n            for d1, d2 in ((-1, 0), (0, -1), (1, 0), (0, 1)):\n                n_x, n_y = d1+x, d2+y\n                if 0 <=n_x<r and 0 <=n_y<c and not seen[n_x][n_y]:\n                    if A[n_x][n_y] == 1:\n                        result = min(result, dis)\n                    q.append((n_x, n_y, dis+1))\n                    seen[n_x][n_y] = True\n            \n        return result\n    \n    def neighbors(self, i, j, A, seen, r, c):\n        q = [(i, j)]\n        seen[i][j] = True\n        ls = []\n        while q:\n            x, y = q.pop(0)\n            # distance is zero for all these 1\n            ls.append((x, y, 0))\n            for d1, d2 in ((-1, 0), (0, -1), (1, 0), (0, 1)):\n                n_x, n_y = d1+x, d2+y\n                if 0 <=n_x<r and 0 <=n_y<c and A[n_x][n_y]==1 and not seen[n_x][n_y]:\n                    q.append((n_x, n_y))\n                    seen[n_x][n_y] = True\n        return ls", "class Solution:\n    def shortestBridge(self, A):\n        def dfs(i, j):\n            A[i][j] = -1\n            bfs.append((i, j))\n            for x, y in ((i - 1, j), (i + 1, j), (i, j - 1), (i, j + 1)):\n                if 0 <= x < n and 0 <= y < n and A[x][y] == 1:\n                    dfs(x, y)\n        def first():\n            for i in range(n):\n                for j in range(n):\n                    if A[i][j]:\n                        return i, j\n        n, step, bfs = len(A), 0, []\n        dfs(*first())\n        while bfs:\n            new = []\n            for i, j in bfs:\n                for x, y in ((i - 1, j), (i + 1, j), (i, j - 1), (i, j + 1)):\n                    if 0 <= x < n and 0 <= y < n:\n                        if A[x][y] == 1:\n                            return step\n                        elif not A[x][y]:\n                            A[x][y] = -1\n                            new.append((x, y))\n            step += 1\n            bfs = new", "class Solution:\n    def shortestBridge(self, A: List[List[int]]) -> int:\n        if not len(A) or not len(A[0]):\n            return 0\n        m, n = len(A), len(A[0])\n\n        def neighbors(i, j):\n            for ni, nj in ((i - 1, j), (i + 1, j), (i, j - 1), (i, j + 1)):\n                if 0 <= ni < m and 0 <= nj < n:\n                    yield ni, nj\n\n        def dfs(i, j, seen, island):\n            if (i, j) not in seen:\n                seen.add((i, j))\n                for ni, nj in neighbors(i, j):\n                    if A[ni][nj] == 1:\n                        dfs(ni, nj, seen, island)\n                    else:\n                        island.add((i, j))\n\n        def find_island():\n            seen = set()\n            island = set()\n            for i in range(m):\n                for j in range(n):\n                    if A[i][j] == 1:\n                        dfs(i, j, seen, island)\n                        return seen, island\n        \n        seen, island = find_island()\n        q = collections.deque(list([(x, 0) for x in island]))\n        \n        while q:\n            (i, j), cnt = q.popleft()\n            for ni, nj in neighbors(i, j):\n                if (ni, nj) not in seen:\n                    seen.add((ni, nj))\n                    if A[ni][nj] == 1:\n                        return cnt\n                    q.append(((ni, nj), cnt + 1))\n        \n        return -1\n", "import  queue\n\nclass Solution:\n    def shortestBridge(self, A: List[List[int]]) -> int:\n        \n        def adjacent(i,q):\n            nonlocal A\n            \n            l = []\n\n            if i > 0:\n                l.append([i-1,q])\n            if i < len(A)-1:\n                l.append([i+1,q])\n            if q > 0:\n                l.append([i,q-1])\n            if q < len(A[0])-1:\n                l.append([i,q+1])\n        \n            return l\n        \n        def fill(i,q):\n            nonlocal A\n            \n            A[i][q] = 2\n            \n            qu = queue.Queue()\n            qu.put([i,q])\n            seen = set()\n            \n            while not qu.empty():\n                \n                current = qu.get()\n                seen.add(tuple(current))\n                \n                l = adjacent(current[0],current[1])\n                \n                for a,b in l:\n                    if A[a][b] == 1:\n                        A[a][b] = 2\n                        qu.put([a,b])\n                        \n            return seen\n\n        starts = []\n        broken = False\n        for i in range(len(A)):\n            for q in range(len(A[0])):\n                \n                if A[i][q] == 1:\n                    \n                    starts = fill(i,q)\n                    broken = True\n                    break\n            if broken:\n                break\n            \n        qu = queue.Queue()\n        \n        for el in list(starts):\n            qu.put(list(el)+[0])\n            \n        while not qu.empty():\n            current = qu.get()\n            \n            l = adjacent(current[0],current[1])\n            \n            for i,q in l:\n                if A[i][q] == 1:\n                    return current[2]\n                elif A[i][q] == 0:\n                    A[i][q] = 2\n                    qu.put([i,q,current[2]+1])", "class Solution:\n    def shortestBridge(self, A: List[List[int]]) -> int:\n        R, C = len(A), len(A[0])\n        directions = [(0, 1), (0, -1), (1, 0), (-1, 0)]\n\n        # define DFS search of groups\n        def dfs(row, col, group):\n            A[row][col] = marker\n            group.append((row, col))\n            \n            for dr, dc in directions:\n                new_row, new_col = row + dr, col + dc\n                if (0 <= new_row < R) and (0 <= new_col < C) and (A[new_row][new_col] == 1):\n                    dfs(new_row, new_col, group)\n                    \n            return group\n                    \n\n        # use DFS to find the two groups, mark them differently and store them in groups list\n        groups, marker = [], 2\n        for r in range(R):\n            for c in range(C):\n                if A[r][c] == 1:\n                    groups.append((dfs(r, c, []), marker))\n                    marker += 1       \n        \n        # construct queue from smaller source group & target set\n        groups = sorted(groups, key=lambda x: len(x[0]))\n\n        src_group, src_marker = groups[0]\n        q = deque([(row, col, 0) for row, col in src_group])\n\n        target = set(groups[1][0])\n\n        # perform BFS until found the other group marker, ensures shortest path\n        while q:\n            row, col, curr_distance = q.pop()\n            \n            if (row, col) in target:\n                return curr_distance - 1\n                \n            for dr, dc in directions:\n                new_row, new_col = row + dr, col + dc\n                if 0 <= new_row < R and 0 <= new_col < C and A[new_row][new_col] != src_marker:\n                    q.appendleft((new_row, new_col, curr_distance + 1))\n                    A[new_row][new_col] = src_marker\n        \n        # should never reach here if two groups in A\n        return -1\n", "class Solution:\n    def shortestBridge(self, A: List[List[int]]) -> int:\n        m, n = len(A) if A else 0, len(A[0]) if A else 0\n        p, q = -1, -1\n        \n        def neighbors(r, c):\n            for nr, nc in [(r-1, c), (r+1, c), (r, c-1), (r, c+1)]:\n                if nr in range(m) and nc in range(n):\n                    yield nr, nc\n\n        done = set()\n        components = []\n        \n        for i, j in product(list(range(m)), list(range(n))):\n            if A[i][j] == 1:\n                #use dfs to detect the two island components\n                if (i,j) not in done:\n                    stack = [(i,j)]\n                    seen = {(i,j)}\n                    while stack:\n                        node = stack.pop()\n                        for p, q in neighbors(*node):\n                            if (p,q) not in seen:\n                                if A[p][q] == 1:\n                                    seen.add((p,q))\n                                    stack.append((p,q))\n                    done |= seen\n                    components.append(seen)\n        \n        source, target = components\n        \n        #\n        #BFS lke search from all source cells to any target cell\n        #\n        heap = []        \n        for i, j in source:\n            heappush(heap, (0, (i,j)))\n            \n        done = set(source)\n        while heap:\n            dist, (i, j) = heappop(heap)\n            if (i, j) in target:\n                return dist-1\n            for r, s in neighbors(i,j):\n                if A[r][s] not in source and (r,s) not in done:\n                    done.add((r,s))\n                    heappush(heap, (dist+1, (r,s)))\n                    \n        \n            \n", "class Solution:\n    def shortestBridge(self, A: List[List[int]]) -> int:\n        \n        R, C = len(A), len(A[0])\n        visited =[[0 for i in range(len(A))] for j in range(len(A[0]))]\n        boundary = set()\n        # island1 = set()\n        dX = [0, 0, 1, -1]\n        dY = [1, -1, 0 , 0]\n\n        def dfs( visited, boundary, x, y):\n            # print(x, y)\n            if  0 <= x < C and 0 <= y < R and visited[x][y]==0:\n                if A[x][y] == 1:\n                    visited[x][y] = 1;\n                    # island1.add((x,y))\n                    for dirX, dirY in zip(dX, dY):\n\n                        dfs(visited, boundary, x+dirX, y + dirY)\n                else:\n                    boundary.add((x,y))\n        \\\"\\\"\\\"\n        step 1: use DFS to find the first island\n        need to record island1 and boundary\n        \\\"\\\"\\\"\n        foundflag = 0;\n        for i in range(C):\n            for j in range(R):\n                if A[i][j] == 1:\n                    # print(\\\"found start\\\")\n                    dfs(visited, boundary, i, j)\n                    foundflag = 1;\n                    break;\n            if foundflag == 1:\n                break;\n\n        \\\"\\\"\\\"\n        step 2: use BFS to find the shortest path\n        need to record island1 and boundary\n        \\\"\\\"\\\"\n        queue = [x for x in boundary]\n        bridge_len = 1;\n        \n        while(len(queue) >0):\n            \n            for index in range(len(queue)):\n                \n                curX, curY = queue.pop(0);\n                \n                for dirX, dirY in zip(dX, dY):\n                    \n                    xtmp, ytmp = curX + dirX, curY + dirY;\n                    \n                    if  0 <= xtmp < C and 0 <= ytmp < R and visited[xtmp][ytmp] == 0:\n                        \n                        visited[xtmp][ytmp] = 1;\n                        # if (xtmp,ytmp) not in island1:\n                        if A[xtmp][ytmp] == 1:\n                            return bridge_len;\n                        else:\n                            queue.append((xtmp, ytmp));\n            bridge_len += 1;", "class Solution:\n    def shortestBridge(self, A: List[List[int]]) -> int:\n        def dfs(i, j):\n            A[i][j] =-1\n            bfs.append((i, j))\n            for x, y in ((i - 1, j), (i + 1, j), (i, j - 1), (i, j + 1)):\n                if 0 <= x < n and 0 <= y < n and A[x][y] == 1:\n                    dfs(x, y) \n        def first():\n            for i in range(n):\n                for j in range(n):\n                    if A[i][j]: \n                        return i , j\n        n, step, bfs = len(A), 0, [] \n        dfs (*first())\n        print (A)\n        while bfs :\n            new = []\n            for i, j in bfs:\n                for x, y in ((i - 1, j), (i + 1, j), (i, j - 1) , (i, j + 1)):\n                    if 0 <= x < n and 0 <= y < n: \n                        if A[x][y] == 1:\n                            return step\n                        elif not A[x][y]:\n                            A[x][y] = -1\n                            new.append((x, y))\n            step += 1 \n            bfs = new", "class Solution:\n    def shortestBridge(self, A: List[List[int]]) -> int:\n        moves = [(1, 0), (0, 1), (-1, 0), (0, -1)]\n        m, n = len(A), len(A[0])\n        \n        visited = set()\n        outliners_1, outliners_2 = set(), set()\n        \n        def dfs(curr_i, curr_j, outliners):\n            for delta_i, delta_j in moves:\n                next_i, next_j = curr_i + delta_i, curr_j + delta_j\n                if 0 <= next_i < m and 0 <= next_j < n:\n                    if A[next_i][next_j] == 0:\n                        outliners.add((curr_i, curr_j))\n                    else:\n                        if (next_i, next_j) not in visited:\n                            visited.add((next_i, next_j))\n                            dfs(next_i, next_j, outliners)\n        \n        for i in range(m):\n            for j in range(n):\n                if A[i][j] == 1:\n                    if (i, j) not in visited:\n                        if not outliners_1:\n                            visited.add((i, j))\n                            dfs(i, j, outliners_1)\n                        else:\n                            visited.add((i, j))\n                            dfs(i, j, outliners_2)\n\n        # actually don't need bfs, since we can either pass 1 or 0, so we can just calculate the Manhatton Distance\n        min_dist = float(\\\"inf\\\")\n        for i, j in outliners_1:\n            for k, p in outliners_2:\n                min_dist = min(abs(i - k) + abs(j - p)  - 1, min_dist)\n        \n        return min_dist", "import typing as t\nimport heapq\n\n\nclass Solution:\n    def shortestBridge(self, A: t.List[t.List[int]]) -> int:\n        dist_arr: t.Dict[t.Tuple[int, int], float] = {}\n        heap: t.List[t.Tuple[float, t.Tuple[int, int]]] = []\n\n        row_limit = len(A)\n        col_limit = len(A[0])\n        first_one_found = False\n        for i in range(row_limit):\n            for j in range(col_limit):\n                distance = float(\\\"inf\\\")\n                if A[i][j] == 1 and first_one_found is False:\n                    distance = 0\n                    first_one_found = True\n                    heapq.heappush(heap, (distance, (i, j)))\n                dist_arr[(i, j)] = distance\n\n        min_dist = float(\\\"inf\\\")\n        while heap:\n            current_dist, (i, j) = heapq.heappop(heap)\n            if A[i][j] == 1 and current_dist > 0:\n                min_dist = min(min_dist, current_dist)\n            for x_offset, y_offset in ((-1, 0), (0, 1), (1, 0), (0, -1)):\n                new_i, new_j = i + x_offset, j + y_offset\n                if new_i < 0 or new_i >= row_limit or new_j < 0 or new_j >= col_limit:\n                    continue\n                if A[new_i][new_j] == 1:\n                    new_dist = current_dist\n                else:\n                    new_dist = current_dist + 1\n                if new_dist < dist_arr[(new_i, new_j)]:\n                    dist_arr[(new_i, new_j)] = new_dist\n                    heapq.heappush(heap, (new_dist, (new_i, new_j)))\n            # print(f\\\"{heap=}, {current_dist=}, {i=}, {j=}\\\")\n        return int(min_dist)", "class Solution:\n    def shortestBridge(self, A: List[List[int]]) -> int:\n        def dirs(V, M, N):\n            res = []            \n            if V[0] > 0:\n                res.append((V[0]-1, V[1]))\n            if V[0] < M-1:\n                res.append((V[0]+1, V[1]))\n            if V[1] > 0:\n                res.append((V[0], V[1]-1))\n            if V[1] < N-1:\n                res.append((V[0], V[1]+1))                \n            return res\n\n        \n        \n        def bfs(grid):\n            q = []\n            for j in I[0]: \n                level[j] = 0 \n                q.append(j)\n                visited.add(j) \n                        \n            while q: \n                v = q.pop(0)                \n                for neighbor in dirs(v, len(grid), len(grid[0])):\n                    if neighbor not in visited:\n                        q.append(neighbor)\n                        visited.add(neighbor)\n                        if neighbor in level: \n                            level[neighbor] = min(level[neighbor],level[v] + 1)\n                        else:\n                            level[neighbor] = level[v] + 1\n\n                        \n            return                         \n\n                        \n        def dfs(grid, v, S): \n            S.add(v) \n            vis.add(v) \n            \n            for neighbor in dirs(v,len(grid),len(grid[0])): \n                if neighbor not in vis and grid[neighbor[0]][neighbor[1]] == 1: \n                    dfs(grid, (neighbor[0], neighbor[1]), S)\n                    \n            return \n        \n        M, N = len(A), len(A[0])\n        I = []                \n        vis = set()\n        \n        for i in range(M):\n            for j in range(N): \n                if ((i,j) not in vis) and (A[i][j] == 1): \n                    s = set()\n                    dfs(A,(i,j),s)\n                    I.append(s)\n        \n        # print(len(I[0]), len(I[1]))\n        \n        level = {}\n        visited = set()\n        bfs(A)\n        \n        # print(level)\n        # print(d) \n        \n        return min([level[j] for j in I[1]])-1", "class Solution:\n    def shortestBridge(self, A: List[List[int]]) -> int:\n        def dirs(V, M, N):\n            res = []            \n            if V[0] > 0:\n                res.append((V[0]-1, V[1]))\n            if V[0] < M-1:\n                res.append((V[0]+1, V[1]))\n            if V[1] > 0:\n                res.append((V[0], V[1]-1))\n            if V[1] < N-1:\n                res.append((V[0], V[1]+1))                \n            return res\n\n                \n        def bfs(grid):\n            q = []\n            for j in I[0]: \n                level[j] = 0 \n                q.append(j)\n                visited.add(j) \n                        \n            while q: \n                v = q.pop(0)                \n                for neighbor in dirs(v, len(grid), len(grid[0])):\n                    if neighbor not in visited:\n                        q.append(neighbor)\n                        visited.add(neighbor)\n                        if neighbor in level: \n                            level[neighbor] = min(level[neighbor],level[v] + 1)\n                        else:\n                            level[neighbor] = level[v] + 1                        \n            return                         \n\n\n        \n        def dfs(grid, v, S): \n            S.add(v) \n            visited.add(v) \n            \n            for neighbor in dirs(v,len(grid),len(grid[0])): \n                if neighbor not in visited and grid[neighbor[0]][neighbor[1]] == 1: \n                    dfs(grid, (neighbor[0], neighbor[1]), S)\n                    \n            return \n        \n        M, N = len(A), len(A[0])\n        I = []                \n        visited = set()\n        \n        for i in range(M):\n            for j in range(N): \n                if ((i,j) not in visited) and (A[i][j] == 1): \n                    s = set()\n                    dfs(A,(i,j),s)\n                    I.append(s)\n        \n        # print(len(I[0]), len(I[1]))\n        \n        level = {}\n        visited = set()\n        bfs(A)         \n        \n        return min([level[j] for j in I[1]])-1", "class Solution:\n    \n    def find_island(self, i, j):\n        self.island.append([i,j])\n        self.grid[i][j]=-1\n        D=[[1,0],[-1,0],[0,1],[0,-1]]\n        for d in D:\n            if (i+d[0] in range(self.m)) and (j+d[1] in range(self.n)) and (self.grid[i+d[0]][j+d[1]]==1):\n                self.find_island(i+d[0],j+d[1])\n                \n    def expand_island(self):\n        D=[[1,0],[-1,0],[0,1],[0,-1]]\n        while len(self.island)>0:\n            [i,j]=self.island.pop(0)\n            depth=abs(self.grid[i][j])\n            for d in D:\n                if (i+d[0] in range(self.m)) and (j+d[1] in range(self.n)):\n                    if self.grid[i+d[0]][j+d[1]]==1:\n                        return depth-1\n                    if self.grid[i+d[0]][j+d[1]]==0:\n                        self.island.append([i+d[0], j+d[1]])\n                        self.grid[i+d[0]][j+d[1]]= -1*(depth+1)\n        \n        return self.m+self.n-1\n                \n            \n            \n    \n    def shortestBridge(self, A: List[List[int]]) -> int:\n        self.grid=A\n        self.m=len(A)\n        self.n=len(A[0])\n        self.island=[]\n        for i in range(self.m):\n            for j in range(self.n):\n                if self.grid[i][j]==1 and len(self.island)==0:\n                    self.find_island(i,j)\n        \n        \n        res=self.expand_island()\n        \n        return res\n        \n        \n", "class Solution:\n    def shortestBridge(self, A: List[List[int]]) -> int:\n        # https://leetcode.com/problems/shortest-bridge/discuss/843901/Python-Easy-BFS-Approach-with-Comments!\n        rows = len(A)\n        cols = len(A[0])\n        directions = ((1, 0), (-1, 0), (0, 1), (0, -1))\n        # Function to check if a given location is an edge.\n        def edge_check(ro, co):\n            r = []\n            for y, x in directions:\n                nr = ro + y\n                nc = co + x\n                if nr < rows and nr >= 0 and nc < cols and nc >= 0 and A[nr][nc] == 0:\n                    return True\n            return False\n        # Keep a flag for when we finish surveying the 1st island.\n        edges_1 = set()\n        found_1 = False\n        edges_2 = set()\n        # Work through our grid until we find an island.\n        for row in range(rows):\n            for col in range(cols):\n                # If we find one we'll start our bfs, marking visited locations with # so we don't revisit.\n                if A[row][col] == 1:\n                    A[row][col] = '#'\n                    q = collections.deque([])\n                    q.append((row, col))\n                    while q:\n                        r, c = q.popleft()\n                        # If we haven't found 1 yet (we must be working through 1 now).\n                        # Append the edge (row, col).\n                        if not found_1 and edge_check(r, c):\n                            edges_1.add((r, c))\n                        # Otherwise we must be on island 2.\n                        else:\n                            if edge_check(r, c):\n                                edges_2.add((r, c))\n                        # Continue working through the adjacent cells.\n                        for y, x in directions:\n                            nr = r + y\n                            nc = c + x\n                            if nr < rows and nr >= 0 and nc < cols and nc >= 0 and A[nr][nc] == 1:\n                                q.append((nr, nc))\n                                A[nr][nc] = '#'\n\n                    found_1 = True\n        # Sort the coordinates\n        c1 = sorted(list(edges_1), key=lambda x: (x[0], x[1]))\n        c2 = sorted(list(edges_2), key=lambda x: (x[0], x[1]))\n\n        minn = float('inf')\n        # Find/return the min distance between points.\n        for x1, x2 in c1[:250]:\n            for y1, y2 in c2[:250]:\n                minn = min(minn, abs(x1-y1)+abs(x2-y2)-1)\n\n        return minn", "class Solution:\n    def shortestBridge(self, A: List[List[int]]) -> int:\n        # https://leetcode.com/problems/shortest-bridge/discuss/843901/Python-Easy-BFS-Approach-with-Comments!\n        rows = len(A)\n        cols = len(A[0])\n        directions = ((1, 0), (-1, 0), (0, 1), (0, -1))\n        # Function to check if a given location is an edge.\n        def edge_check(ro, co):\n            r = []\n            for y, x in directions:\n                nr = ro + y\n                nc = co + x\n                if nr < rows and nr >= 0 and nc < cols and nc >= 0 and A[nr][nc] == 0:\n                    return True\n            return False\n        # Keep a flag for when we finish surveying the 1st island.\n        edges_1 = []\n        found_1 = False\n        edges_2 = []\n        # Work through our grid until we find an island.\n        for row in range(rows):\n            for col in range(cols):\n                # If we find one we'll start our bfs, marking visited locations with # so we don't revisit.\n                if A[row][col] == 1:\n                    A[row][col] = '#'\n                    q = collections.deque([])\n                    q.append((row, col))\n                    while q:\n                        r, c = q.popleft()\n                        # If we haven't found 1 yet (we must be working through 1 now).\n                        # Append the edge (row, col).\n                        if not found_1 and edge_check(r, c):\n                            edges_1.append((r, c))\n                        # Otherwise we must be on island 2.\n                        else:\n                            if edge_check(r, c):\n                                edges_2.append((r, c))\n                        # Continue working through the adjacent cells.\n                        for y, x in directions:\n                            nr = r + y\n                            nc = c + x\n                            if nr < rows and nr >= 0 and nc < cols and nc >= 0 and A[nr][nc] == 1:\n                                q.append((nr, nc))\n                                A[nr][nc] = '#'\n\n                    found_1 = True\n        # Sort the coordinates\n        c1 = sorted(edges_1, key=lambda x: (x[0], x[1]))\n        c2 = sorted(edges_2, key=lambda x: (x[0], x[1]))\n\n        minn = float('inf')\n        # Find/return the min distance between points.\n        for x1, x2 in c1:\n            for y1, y2 in c2:\n                minn = min(minn, abs(x1-y1)+abs(x2-y2)-1)\n\n        return minn", "class Solution:\n    def shortestBridge1(self, grid: List[List[int]]) -> int:\n        \\\"\\\"\\\"\n        # loop to find first 1 in one of the 2 islands\n        # dfs from first 1 and mask all 1 to -1 in this island and collect boundry as well\n        # From boundries of first island, bfs until find 1 which must be part of 2nd island\n        \\\"\\\"\\\"\n        \n        def moves(row, col):\n            for rm, cm in (0, 1), (1, 0), (0, -1), (-1, 0):\n                nr, nc = row + rm, col + cm\n                if 0 <= nr < rows and 0 <= nc < cols:\n                    yield nr, nc\n        \n        def get_first() -> Tuple[int, int]:\n            for r in range(rows):\n                for c in range(cols):\n                    if grid[r][c]:\n                        return r, c\n        \n        def update_boundaries_dfs_rec(row, col):\n            grid[row][col] = -1\n            for nr, nc in moves(row, col):\n                if not grid[nr][nc]:\n                    boundary_set.add((row, col))\n                if  grid[nr][nc] == 1:\n                    update_boundaries_dfs_rec(nr, nc)\n        \n        rows, cols = len(grid), len(grid[0])\n        # bfs to find short distance\n        boundary_set = set()\n        update_boundaries_dfs_rec(*get_first())\n        step = 0\n        while boundary_set:\n            next_boundary_set = set()\n            for r, c in boundary_set:\n                for nr, nc in moves(r, c):\n                    if grid[nr][nc] == 1:\n                        return step\n                    if grid[nr][nc]:\n                        continue\n                    grid[nr][nc] == -1\n                    next_boundary_set.add((nr, nc))\n            step += 1\n            boundary_set = next_boundary_set\n            \n    def shortestBridge(self, A):\n        def dfs(i, j):\n            A[i][j] = -1\n            bfs.append((i, j))\n            for x, y in ((i - 1, j), (i + 1, j), (i, j - 1), (i, j + 1)):\n                if 0 <= x < n and 0 <= y < n and A[x][y] == 1:\n                    dfs(x, y)\n                    \n        def first():\n            for i in range(n):\n                for j in range(n):\n                    if A[i][j]:\n                        return i, j\n                    \n        n, step, bfs = len(A), 0, []\n        dfs(*first())\n        while bfs:\n            new = []\n            for i, j in bfs:\n                for x, y in ((i - 1, j), (i + 1, j), (i, j - 1), (i, j + 1)):\n                    if 0 <= x < n and 0 <= y < n:\n                        if A[x][y] == 1:\n                            return step\n                        # if A[x][y] == -1:\n                        #     continue\n                        elif not A[x][y]:\n                            A[x][y] = -1\n                            new.append((x, y))\n            step += 1\n            bfs = new\n                \n                \n                \n                \n                \n            \n        ", "class Solution:\n    def shortestBridge(self, A: List[List[int]]) -> int:\n        def dirs(V, M, N):\n            res = []            \n            if V[0] > 0:\n                res.append((V[0]-1, V[1]))\n            if V[0] < M-1:\n                res.append((V[0]+1, V[1]))\n            if V[1] > 0:\n                res.append((V[0], V[1]-1))\n            if V[1] < N-1:\n                res.append((V[0], V[1]+1))                \n            return res\n\n        \n        \n        def bfs(grid):\n            q = []\n            for j in I[0]: \n                level[j] = 0 \n                q.append(j)\n                visited.add(j) \n                        \n            while q: \n                v = q.pop(0)                \n                for neighbor in dirs(v, len(grid), len(grid[0])):\n                    if neighbor not in visited:\n                        q.append(neighbor)\n                        visited.add(neighbor)\n                        if neighbor in level: \n                            level[neighbor] = min(level[neighbor],level[v] + 1)\n                        else:\n                            level[neighbor] = level[v] + 1\n\n                        \n            return                         \n\n                        \n        def dfs(grid, i,j, m, n, S): \n            S.add((i,j)) \n            vis.add((i,j)) \n            \n            for neighbor in dirs((i,j),m,n): \n                if neighbor not in vis and grid[neighbor[0]][neighbor[1]] == 1: \n                    dfs(grid, neighbor[0], neighbor[1], m, n, S)\n#             if (i<(m-1)) and ((i+1,j) not in vis) and (grid[i+1][j] == 1): \n#                 dfs(grid, i+1, j, m, n, S)\n                \n#             if (i>0) and ((i-1,j) not in vis) and (grid[i-1][j] == 1):\n#                 dfs(grid, i-1, j, m, n, S)\n                                \n#             if (j<(n-1)) and ((i,j+1) not in vis) and (grid[i][j+1] == 1):\n#                 dfs(grid, i, j+1, m, n, S)\n                                \n#             if (j>0) and ((i,j-1) not in vis) and (grid[i][j-1] == 1):\n#                 dfs(grid, i, j-1, m, n, S)                            \n            return \n        \n        M, N = len(A), len(A[0])\n        I = []                \n        vis = set()\n        \n        for i in range(M):\n            for j in range(N): \n                if ((i,j) not in vis) and (A[i][j] == 1): \n                    s = set()\n                    dfs(A,i,j,M,N,s)\n                    I.append(s)\n        \n        # print(len(I[0]), len(I[1]))\n        \n        level = {}\n        visited = set()\n        bfs(A)\n        \n        # print(level)\n        # print(d) \n        \n        return min([level[j] for j in I[1]])-1", "class Solution:\n    def shortestBridge(self, A: List[List[int]]) -> int:\n        \n        R, C = len(A), len(A[0])\n        visited =[[0 for i in range(len(A))] for j in range(len(A[0]))]\n        boundary = set()\n        island1 = set()\n        dX = [0, 0, 1, -1]\n        dY = [1, -1, 0 , 0]\n\n        def dfs( visited, boundary, x, y):\n            # print(x, y)\n            if  0 <= x < C and 0 <= y < R and visited[x][y]==0:\n                if A[x][y] == 1:\n                    visited[x][y] = 1;\n                    island1.add((x,y))\n                    for dirX, dirY in zip(dX, dY):\n\n                        dfs(visited, boundary, x+dirX, y + dirY)\n                else:\n                    boundary.add((x,y))\n        \\\"\\\"\\\"\n        step 1: use DFS to find the first island\n        need to record island1 and boundary\n        \\\"\\\"\\\"\n        foundflag = 0;\n        for i in range(C):\n            for j in range(R):\n                if A[i][j] == 1:\n                    # print(\\\"found start\\\")\n                    dfs(visited, boundary, i, j)\n                    foundflag = 1;\n                    break;\n            if foundflag == 1:\n                break;\n\n        \\\"\\\"\\\"\n        step 2: use BFS to find the shortest path\n        need to record island1 and boundary\n        \\\"\\\"\\\"\n        queue = [x for x in boundary]\n        bridge_len = 1;\n        # visited =[[0 for i in range(len(A))] for j in range(len(A[0]))]\n        \n        while(len(queue) >0):\n            \n            for index in range(len(queue)):\n                \n                curX, curY = queue.pop(0);\n                \n                for dirX, dirY in zip(dX, dY):\n                    \n                    xtmp, ytmp = curX + dirX, curY + dirY;\n                    \n                    if  0 <= xtmp < C and 0 <= ytmp < R and visited[xtmp][ytmp] == 0:\n                        \n                        visited[xtmp][ytmp] = 1;\n                        # if (xtmp,ytmp) not in island1:\n                        if A[xtmp][ytmp] == 1:\n                            return bridge_len;\n                        else:\n                            queue.append((xtmp, ytmp));\n            bridge_len += 1;", "class Solution:\n    def shortestBridge(self, A: List[List[int]]) -> int:\n        def dirs(V, M, N):\n            res = []            \n            if V[0] > 0:\n                res.append((V[0]-1, V[1]))\n            if V[0] < M-1:\n                res.append((V[0]+1, V[1]))\n            if V[1] > 0:\n                res.append((V[0], V[1]-1))\n            if V[1] < N-1:\n                res.append((V[0], V[1]+1))                \n            return res\n\n                \n        def bfs(q):\n            for j in q: \n                level[j] = 0 \n                visited.add(j) \n                        \n            while q: \n                v = q.pop(0)                \n                for neighbor in dirs(v, len(A), len(A[0])):\n                    if neighbor not in visited:\n                        q.append(neighbor)\n                        visited.add(neighbor)\n                        if neighbor in level: \n                            level[neighbor] = min(level[neighbor],level[v] + 1)\n                        else:\n                            level[neighbor] = level[v] + 1                        \n            return                         \n\n\n        \n        def dfs(grid, v, S): \n            S.add(v) \n            visited.add(v) \n            \n            for neighbor in dirs(v,len(grid),len(grid[0])): \n                if neighbor not in visited and grid[neighbor[0]][neighbor[1]] == 1: \n                    dfs(grid, (neighbor[0], neighbor[1]), S)\n                    \n            return \n        \n        I = []                \n        visited = set()\n        \n        for i in range(len(A)):\n            for j in range(len(A[0])):\n                if ((i,j) not in visited) and (A[i][j] == 1): \n                    s = set()\n                    dfs(A,(i,j),s)\n                    I.append(s)\n        \n        # print(len(I[0]), len(I[1]))\n        \n        level = {}\n        visited = set()\n        bfs(list(I[0]))   \n        \n        return min([level[j] for j in I[1]])-1", "class Solution:\n    def shortestBridge(self, A: List[List[int]]) -> int:\n        def dirs(V, M, N):\n            res = []            \n            if V[0] > 0:\n                res.append((V[0]-1, V[1]))\n            if V[0] < M-1:\n                res.append((V[0]+1, V[1]))\n            if V[1] > 0:\n                res.append((V[0], V[1]-1))\n            if V[1] < N-1:\n                res.append((V[0], V[1]+1))                \n            return res\n\n                \n        def bfs(grid):\n            q = []\n            for j in I[0]: \n                level[j] = 0 \n                q.append(j)\n                visited.add(j) \n                        \n            while q: \n                v = q.pop(0)                \n                for neighbor in dirs(v, len(grid), len(grid[0])):\n                    if neighbor not in visited:\n                        q.append(neighbor)\n                        visited.add(neighbor)\n                        if neighbor in level: \n                            level[neighbor] = min(level[neighbor],level[v] + 1)\n                        else:\n                            level[neighbor] = level[v] + 1                        \n            return                         \n\n\n        \n        def dfs(grid, v, S): \n            S.add(v) \n            visited.add(v) \n            \n            for neighbor in dirs(v,len(grid),len(grid[0])): \n                if neighbor not in visited and grid[neighbor[0]][neighbor[1]] == 1: \n                    dfs(grid, (neighbor[0], neighbor[1]), S)\n                    \n            return \n        \n        I = []                \n        visited = set()\n        \n        for i in range(len(A)):\n            for j in range(len(A[0])):\n                if ((i,j) not in visited) and (A[i][j] == 1): \n                    s = set()\n                    dfs(A,(i,j),s)\n                    I.append(s)\n        \n        # print(len(I[0]), len(I[1]))\n        \n        level = {}\n        visited = set()\n        bfs(A)         \n        \n        return min([level[j] for j in I[1]])-1", "class Solution:\n    def shortestBridge(self, A: List[List[int]]) -> int:\n        i1 = []\n        m = len(A)\n        n = len(A[0])\n        vis = [[False for _ in range(n)] for _ in range(m)]\n        def check(x,y):\n            return x>=0 and x<m and y>=0 and y<n\n        dx = [0, -1, 0, 1]\n        dy = [1, 0, -1, 0]\n        def dfs(p_x, p_y, i):\n            vis[p_x][p_y] = True\n            i.append((p_x, p_y))\n            for j in range(4):\n                c_x, c_y = p_x + dx[j], p_y + dy[j]\n                if check(c_x, c_y) and not vis[c_x][c_y]:\n                    if A[c_x][c_y]:\n                        dfs(c_x, c_y, i)\n        \n        conn = 0\n        for i in range(m):\n            for j in range(n):\n                if not vis[i][j] and A[i][j]:\n                    if conn == 0:\n                        dfs(i, j, i1)\n                    elif conn == 1:\n                        break\n                    conn += 1\n            if conn == 1:\n                break\n        q = deque()\n        d = [[float('inf') for _ in range(n)] for _ in range(m)]\n        for v in i1:\n            q.append(v)\n            d[v[0]][v[1]] = 0\n        ans = float('inf')\n        while q:\n            s_x, s_y = q[0][0], q[0][1]\n            q.popleft()\n            for i in range(4):\n                c_x, c_y = s_x + dx[i], s_y + dy[i]\n                if check(c_x, c_y):\n                    if d[c_x][c_y] > (d[s_x][s_y] + 1):\n                        d[c_x][c_y] = d[s_x][s_y] + 1\n                        q.append((c_x, c_y))\n                        if A[c_x][c_y]:\n                            ans = min(ans, d[c_x][c_y] - 1)\n        \n        return ans ", "import queue\n\ndef findIsland(map, color):\n    res = [0, 0]\n    for row, line in enumerate(map):\n        for col, n in enumerate(line):\n            if n == color:\n                return [row, col]\n    return res\n\n\ndef bfs(row, col, map, rows, cols, find_color, color):\n    delta = [[-1, 0], [1, 0], [0, -1], [0, 1]]\n    visited = [[False for col in range(len(map[0]))] for row in range(len(map))]\n    boundry = queue.Queue()\n    q = queue.Queue()\n    q.put((row, col))\n    while not q.empty():\n        r, c = q.get()\n        # print(\\\"(\\\", r, c, \\\")\\\", q.qsize())\n        if map[r][c] == find_color:\n            map[r][c] = color\n        for d in delta:\n            new_row = r + d[0]\n            new_col = c + d[1]\n            if new_row < 0 or new_col < 0 or new_row >= rows or new_col >= cols:\n                continue\n            if map[new_row][new_col] == 0:\n                boundry.put((new_row, new_col, 1))\n            if map[new_row][new_col] != find_color:\n                continue\n            if visited[new_row][new_col]:\n                continue\n            visited[new_row][new_col] = True\n            q.put((new_row, new_col))\n\n    return boundry\n    # for r, c in boundry:\n    #     map[r][c] = 1\n            # print(\\\"(\\\", new_row, new_col, \\\")\\\", end=\\\" - \\\", flush=True)\n        # print()\n\ndef bfs2(q, map, rows, cols, find_color):\n    delta = [[-1, 0], [1, 0], [0, -1], [0, 1]]\n    visited = [[False for col in range(len(map[0]))] for row in range(len(map))]\n    # q.put((row, col))\n    color = 1\n    while not q.empty():\n        r, c, col = q.get()\n        map[r][c] = col\n        for d in delta:\n            new_row = r + d[0]\n            new_col = c + d[1]\n            if new_row < 0 or new_col < 0 or new_row >= rows or new_col >= cols:\n                continue\n            if map[new_row][new_col] == 'Y':\n                return col\n            if visited[new_row][new_col]:\n                continue\n            if map[new_row][new_col] != find_color:\n                continue\n            else:\n                q.put((new_row, new_col, col+1))\n            visited[new_row][new_col] = True\n\nclass Solution:\n    def shortestBridge(self, A: List[List[int]]) -> int:\n        pos = findIsland(A, 1)\n        # print(pos)\n        boundry1 = bfs(pos[0], pos[1], A, len(A), len(A[0]), 1, \\\"X\\\")\n        pos = findIsland(A, 1)\n        # print(pos)\n        boundry2 = bfs(pos[0], pos[1], A, len(A), len(A[0]), 1, \\\"Y\\\")\n        dist = bfs2(boundry1, A, len(A), len(A[0]), 0)\n        # for line in A:\n        #     for char in line:\n        #         print(str(char),' ',  end=\\\"\\\")\n        #     print(flush=True)\n        print(dist)\n        return dist", "class Solution:\n    def shortestBridge(self, A: List[List[int]]) -> int:\n        \n        self.A = A\n        self.R = len(self.A)\n        self.C = len(self.A[0])\n        \n        p = self.findGround()\n        \n        if p == None:\n            return -1\n        \n        self.firstIsland = set()\n        \n        self.embraceIsland( p)\n\n        return self.bfs()\n    \n    def findGround(self):\n        for i in range(0, self.R):\n            for j in range(0, self.C):\n                if self.isGround((i, j)):\n                    return (i, j)\n                \n        return None\n    \n    def isGround(self, p):\n        return self.A[p[0]][p[1]] == 1\n    \n                \n    def inGrid(self, p):\n        \n        if not (0 <= p[0] < self.R):\n            return False\n        \n        if not (0 <= p[1] < self.C):\n            return False\n        \n        return True\n    \n    def getNeis(self, p):\n        neis = []\n        \n        neis.append((p[0] + 1, p[1]))\n        neis.append((p[0] - 1, p[1]))\n        neis.append((p[0], p[1] + 1))\n        neis.append((p[0], p[1] - 1))\n        \n        return neis\n    \n    \n    def embraceIsland(self, p):\n        \n        self.firstIsland.add(p)\n        \n        for nei in self.getNeis(p):\n            if self.inGrid(nei) and self.isGround(nei) and nei not in self.firstIsland:\n                self.embraceIsland(nei)\n    \n    def bfs(self):\n        q = collections.deque()\n        visited = set()\n        \n        for p in self.firstIsland:\n            q.appendleft((p, 0))\n            \n        while q:\n            node, dist = q.pop()\n            \n            if self.isGround(node) and node not in self.firstIsland:\n                return dist - 1\n            \n            if node in visited:\n                continue\n                \n            visited.add(node)\n            \n            for nei in self.getNeis(node):\n                if self.inGrid(nei) and nei not in visited:\n                    q.appendleft((nei, dist + 1))\n        return -1\n    \n", "from queue import Queue\n\ndef valid(m, i, j):\n    return 0 <= i < len(m) and 0 <= j < len(m[0])\n\ndef findAnIsland(m, e):\n    stack = []\n    for i in range(len(m)):\n        for j in range(len(m[0])):\n            if m[i][j] == 1 and (i, j) not in e:\n                stack.append((i, j))\n                break\n        else:\n            continue\n        break\n    result, edges = set(), set()\n    while stack:\n        ci, cj = stack.pop()\n        result.add((ci, cj))\n        for di, dj in ((0,1), (1,0), (0,-1), (-1,0)):\n            cdi, cdj = ci+di, cj+dj\n            if valid(m, cdi, cdj) and (cdi, cdj) not in e and (cdi, cdj) not in result:\n                if m[cdi][cdj] == 1:\n                    stack.append((cdi, cdj))\n                else:\n                    edges.add((ci, cj))\n    return result, edges\n\nclass Solution:\n    def shortestBridge(self, A: List[List[int]]) -> int:\n        a, aedges = findAnIsland(A, set())\n        b, bedges = findAnIsland(A, a)\n        q = Queue()\n        for i, j in aedges:\n            q.put((i, j, 0))\n        while not q.empty():\n            ci, cj, dist = q.get()\n            for di, dj in ((0,1), (1,0), (0,-1), (-1,0)):\n                cdi, cdj = ci+di, cj+dj\n                if valid(A, cdi, cdj):\n                    if (cdi, cdj) in bedges:\n                        return dist\n                    elif A[cdi][cdj] == 0 or A[cdi][cdj] > dist + 1:\n                        A[cdi][cdj] = dist + 1\n                        q.put((cdi, cdj, dist + 1))\n        return -1", "class Solution:\n    \n    # Assigining '2' to one of the islands\n    def paint(self, A, i, j):\n        if i >= len(A) or i < 0 or j < 0 or j >= len(A[0]) or A[i][j] == 0 or A[i][j] == 2:\n            return\n        A[i][j] = 2\n        for nb in [(0,1),(0,-1),(1,0),(-1,0)]:\n            self.paint(A, i + nb[0], j + nb[1])\n\n    # expanding from the perimeter of the island & incrementing color with every next outward move\n    def expand(self, A, i, j, color):\n        if i >= len(A) or i < 0 or j < 0 or j >= len(A[0]):\n            return False\n        if A[i][j] == 0:\n            A[i][j] = color + 1\n        return A[i][j] == 1\n\n    def shortestBridge(self, A: List[List[int]]) -> int:\n        if not A:\n            return 0\n        m, n, flag = len(A), len(A[0]), False\n        \n        # Finding and coloring the first encountered island\n        for i in range(m):\n            if flag:\n                break\n            for j in range(n):\n                if A[i][j] == 1:\n                    self.paint(A, i, j)\n                    flag = True\n                    break\n        \n        # Growing outward and tracking number of steps taken to bump into other island\n        for color in range(2, 2+m+n+1):\n            for i in range(m):\n                for j in range(n):\n                    if A[i][j] == color and ( self.expand(A, i-1, j, color) or self.expand(A, i, j+1, color) or\n                                              self.expand(A, i+1, j, color) or self.expand(A, i, j-1, color)):\n                        return color-2", "class Solution:\n    def shortestBridge(self, A: List[List[int]]) -> int:\n        u = {(i, j): (i, j) for i in range(len(A)) for j in range(len(A[0])) if A[i][j]}\n        def head(p):\n            if u[p] == p:\n                return p\n            h = head(u[p])\n            u[p] = h\n            return h\n\n        def union(p1, p2):\n            u[head(p2)] = head(p1)\n\n        for i, row in enumerate(A):\n            for j, v in enumerate(row):\n                if not v:\n                    continue\n\n                if i and A[i-1][j]:\n                    union((i - 1, j), (i, j))\n                if j and A[i][j-1]:\n                    union((i, j - 1), (i, j))\n\n        grps = {p1: set() for p1, p2 in list(u.items()) if p1 == p2}\n        for p in list(u.keys()):\n            grps[head(p)].add(p)\n\n        grps = list(grps.values())\n\n        s = 0\n        layer, target = grps\n        while layer:\n            new_layer = []\n            for x, y in layer:\n                for dx, dy in [(1, 0), (-1, 0), (0, 1), (0, -1)]:\n                    nx = x + dx\n                    ny = y + dy\n                    if nx < 0 or nx >= len(A) or ny < 0 or ny >= len(A[0]):\n                        continue\n                    if A[nx][ny] == 1 and (nx, ny) in target:\n                        return s\n                    if not A[nx][ny]:\n                        new_layer.append((nx, ny))\n                        A[nx][ny] = -1\n            s += 1\n            layer = new_layer\n\n        return  # invalid, must be able to find s\n\n", "class Solution:\n    def shortestBridge(self, A: List[List[int]]) -> int:\n        r = len(A)\n        c = len(A[0])\n        dirs = [(-1,0),(1,0),(0,-1),(0,1)]\n        dist = [[float('inf') for j in range(c)] for i in range(r)]\n        island1 = set()\n        island2 = set()\n        def dfs(x,y,island):\n            island.add((x,y))\n            for i,j in dirs:\n                if 0<=x+i<r and 0<=y+j<c and A[x+i][y+j] == 1 and (x+i,y+j) not in island:\n                    dfs(x+i,y+j,island)\n                    \n        for i in range(r):\n            for j in range(c):\n                if A[i][j] == 1:\n                    if len(island1) == 0:\n                        dfs(i,j,island1)\n                    elif (i,j) not in island1:\n                        dfs(i,j,island2)\n\n        q = collections.deque(list(island1))\n        d = 1\n        res = float('inf')\n        while q:\n            size = len(q)\n            for i in range(size):\n                (x,y) = q.popleft()\n                for i,j in dirs:\n                    if 0<=x+i<r and 0<=y+j<c:\n                        if A[x+i][y+j] == 0 and d < dist[x+i][y+j]:\n                            q.append((x+i,y+j))\n                            dist[x+i][y+j] = d\n                        if (x+i,y+j) in island2:\n                            res = min(res,d-1)\n            d+=1\n        return res\n        \n                    \n                \n                        \n        \n", "class Solution:\n    def shortestBridge(self, A: List[List[int]]) -> int:\n        gather = []\n        for y in range(len(A)):\n            for x in range(len(A[y])):\n                if A[y][x] == 1:\n                    A[y][x] = 2\n                    gather.append((x, y, 0))\n                    break\n            if gather:\n                break\n\n        dirs = [(1, 0), (-1, 0), (0, 1), (0, -1)]\n        seen = set([gather[0]])\n        while gather:\n            frontier = []\n            for x, y, _ in gather:\n                for dx, dy in dirs:\n                    xx, yy = x + dx, y + dy\n                    if (xx, yy, 0) in seen:\n                        continue\n                    if 0 <= yy < len(A) and 0 <= xx < len(A[yy]) and A[yy][xx] == 1:\n                        A[yy][xx] = 2\n                        seen.add((xx, yy, 0))\n                        frontier.append((xx, yy, 0))\n            gather = frontier\n\n        bfs = list(seen)\n        while bfs:\n            frontier = []\n            for x, y, n in bfs:\n                A[y][x] = 2\n                for dx, dy in dirs:\n                    xx, yy = x + dx, y + dy\n                    if 0 <= yy < len(A) and 0 <= xx < len(A[yy]):\n                        if A[yy][xx] == 1:\n                            return n\n                        elif A[yy][xx] == 0:\n                            A[yy][xx] = 2\n                            frontier.append((xx, yy, n+1))\n            bfs = frontier\n        \n        return -1", "class Solution:\n    def shortestBridge(self, grid: List[List[int]]) -> int:\n        \\\"\\\"\\\"\n        # loop to find first 1 in one of the 2 islands\n        # dfs from first 1 and mask all 1 to -1 in this island and collect boundry as well\n        # From boundries of first island, bfs until find 1 which must be part of 2nd island\n        \\\"\\\"\\\"\n        \n        def moves(row, col):\n            for rm, cm in (0, 1), (1, 0), (0, -1), (-1, 0):\n                nr, nc = row + rm, col + cm\n                if 0 <= nr < rows and 0 <= nc < cols:\n                    yield nr, nc\n        \n        def get_first() -> Tuple[int, int]:\n            for r in range(rows):\n                for c in range(cols):\n                    if grid[r][c]:\n                        return r, c\n        \n        def update_boundaries_dfs_rec(row, col):\n            grid[row][col] = -1\n            for nr, nc in moves(row, col):\n                if not grid[nr][nc]:\n                    boundary_set.add((row, col))\n                if  grid[nr][nc] == 1:\n                    update_boundaries_dfs_rec(nr, nc)\n            \n        def update_boundaries_dfs_itr(row, col):\n            pass\n        \n        rows, cols = len(grid), len(grid[0])\n        \n        # bfs to find short distance\n        boundary_set = set()\n        update_boundaries_dfs_rec(*get_first())\n        \n        step = 0\n        while boundary_set:\n            next_boundary_set = set()\n            for r, c in boundary_set:\n                for nr, nc in moves(r, c):\n                    if grid[nr][nc] == 1:\n                        return step\n                    if grid[nr][nc]:\n                        continue\n                    grid[nr][nc] == -1\n                    next_boundary_set.add((nr, nc))\n            step += 1\n            boundary_set = next_boundary_set\n            \n    def shortestBridge1(self, A):\n        def dfs(i, j):\n            A[i][j] = -1\n            bfs.append((i, j))\n            for x, y in ((i - 1, j), (i + 1, j), (i, j - 1), (i, j + 1)):\n                if 0 <= x < n and 0 <= y < n and A[x][y] == 1:\n                    dfs(x, y)\n                    \n        def first():\n            for i in range(n):\n                for j in range(n):\n                    if A[i][j]:\n                        return i, j\n                    \n        n, step, bfs = len(A), 0, []\n        dfs(*first())\n        while bfs:\n            new = []\n            for i, j in bfs:\n                for x, y in ((i - 1, j), (i + 1, j), (i, j - 1), (i, j + 1)):\n                    if 0 <= x < n and 0 <= y < n:\n                        if A[x][y] == 1:\n                            return step\n                        elif not A[x][y]:\n                            A[x][y] = -1\n                            new.append((x, y))\n            step += 1\n            bfs = new\n                \n                \n                \n                \n                \n            \n        ", "class Solution:\n    def shortestBridge(self, A: List[List[int]]) -> int:\n        \n        \n        N = len(A)\n        def neighbors(r, c):\n            for dr, dc in (r+1, c), (r-1, c), (r, c+1), (r, c-1):\n                if 0 <= dr < N and 0 <= dc < N:\n                    yield dr, dc\n        \n        def get_components():\n            visited = set()\n            island = []\n            for r in range(N):\n                for c in range(N):\n                    if A[r][c] == 1 and (r, c) not in visited:\n                        stack = [(r, c)]\n                        seen = {(r, c)}\n                        while stack:\n                            i, j = stack.pop()\n                            for dr, dc in neighbors(i, j):\n                                if A[dr][dc] == 1 and (dr, dc) not in seen:\n                                    stack.append((dr, dc))\n                                    seen.add((dr, dc))\n                        island.append(seen)\n                        visited |= seen\n            return island\n    \n        island = get_components()\n        queue = collections.deque([(node, 0) for node in island[0]])\n        visited=island[0]\n        print (visited)\n        while queue:\n            node, d = queue.popleft()\n            if node in island[1]:\n                return d-1\n            for r, c in neighbors(*node):\n                if (r, c) not in visited:\n                    queue.append(((r,c), d+1))\n                    visited |= set([(r, c)])\n        \n        \\\"\\\"\\\"\n        nrow, ncol = len(A), len(A[0])\n        \n        def is_valid(nr, nc):\n            if 0 <= nr < nrow and 0 <= nc < ncol:\n                return True\n            return False\n        \n        def get_components():\n            visited = set()\n            components = []\n            for r, row in enumerate(A):\n                for c, val in enumerate(row):\n                    if val and (r, c) not in visited:\n                        stack = [(r, c)]\n                        seen = {(r, c)}\n                        while stack:\n                            r1, c1 = stack.pop()\n                            for nei in ((r1-1, c1), (r1+1, c1), (r1, c1-1), (r1, c1+1)):\n                                if is_valid(nei[0], nei[1]) and A[nei[0]][nei[1]] and nei not in seen:\n                                    stack.append(nei)\n                                    seen.add(nei)\n                        visited = visited.union(seen) # visited |= seen\n                        components.append(seen)\n            return components\n        \n        components = get_components()\n        print (components)\n        \\\"\\\"\\\"\n\n            \n        \n                    ", "import queue\ndef isOk(x,y,m,n):\n    return x >= 0 and y >= 0 and x < m and y < n\nclass Solution:\n    def shortestBridge(self, A: List[List[int]]) -> int:\n        m = len(A)\n        n = len(A[0])\n        visited = [[False for _ in range(n)] for _ in range(m)]\n        \n        def dfs(start):\n            island = []\n            x,y = start\n            visited[x][y] = True\n            stack = [start]\n            while stack:\n                x,y = stack.pop()\n                island.append((x,y))\n                xRows = [0,0,-1,1]\n                yCols = [-1,1,0,0]\n                for i in range(4):\n                    new_x = x + xRows[i]\n                    new_y = y + yCols[i]\n                    \n                    if isOk(new_x, new_y, m, n) and not visited[new_x][new_y] and A[new_x][new_y] == 1:\n                        stack.append((new_x, new_y))\n                        visited[new_x][new_y] = True\n            return island \n        islands = []\n        for i in range(m):\n            for j in range(n):\n                if not visited[i][j] and A[i][j] == 1: \n                    island = dfs((i, j))\n                    islands.append(island)\n        source_island, target_island = islands\n        print(source_island)\n        print(target_island)\n        \n        target_island = set(target_island)\n        \n        visited = [[False for _ in range(n)] for _ in range(m)]\n        \n        def bfs(source_island, target_island, visited):\n            q = queue.Queue()\n            for start in source_island:\n                x,y  = start\n                q.put((x,y,0))\n            while q.qsize() > 0 :\n                u =  q.get()\n                x, y, w = u\n                xRows = [-1,1,0, 0]\n                yCols = [0,0,-1,1]\n                for i in range(4):\n                    new_x = x + xRows[i]\n                    new_y = y + yCols[i]\n                    if isOk(new_x, new_y, m, n) and not visited[new_x][new_y]:         \n                        if (new_x, new_y) in target_island:\n                            return w\n                        visited[new_x][new_y] = True\n                        q.put((new_x, new_y, w + 1))\n        return bfs(source_island, target_island, visited )\n                \n", "class Solution:\n    def shortestBridge(self, A: List[List[int]]) -> int:\n        options = [[-1, 0], [1, 0], [0, 1], [0, -1]]\n        flip_req = float('inf')\n        isl_one_coords = set()\n        \n        \n        def get_all(i, j):\n            nonlocal flip_req, isl_one_coords, options\n            for opt in options:\n                new_coord = (i + opt[0], j + opt[1])\n                if 0 <= new_coord[0] < len(A) and 0 <= new_coord[1] < len(A[0]):\n                    if A[new_coord[0]][new_coord[1]] and not new_coord in isl_one_coords:\n                        isl_one_coords.add(new_coord)\n                        get_all(new_coord[0], new_coord[1])\n            \n        \n        def bfs():\n            nonlocal flip_req, isl_one_coords, options\n            dist = 0\n            level = set([x for x in isl_one_coords])\n            next_level = set()\n            while level:\n                for coords in level:\n                    for opt in options:\n                        new_coord = (coords[0] + opt[0], coords[1] + opt[1])\n                        if 0 <= new_coord[0] < len(A) and 0 <= new_coord[1] < len(A[0]) and not new_coord in isl_one_coords:\n                            if A[new_coord[0]][new_coord[1]]:\n                                return dist\n                            if not A[new_coord[0]][new_coord[1]]:\n                                isl_one_coords.add(new_coord)\n                                next_level.add(new_coord)\n                dist += 1\n                level, next_level = next_level, set()\n                print((level, next_level, isl_one_coords))\n                \n\n            \n        for i in range(len(A)):\n            for j in range(len(A[0])):\n                if A[i][j]: \n                    isl_one_coords.add((i, j))\n                    get_all(i, j)\n                    return bfs()\n", "class Solution:\n    def shortestBridge(self, A: List[List[int]]) -> int:\n        i1, i2 = [], []\n        m = len(A)\n        n = len(A[0])\n        vis = [[False for _ in range(n)] for _ in range(m)]\n        def check(x,y):\n            return x>=0 and x<m and y>=0 and y<n\n        dx = [0, -1, 0, 1]\n        dy = [1, 0, -1, 0]\n        def dfs(p_x, p_y, i):\n            vis[p_x][p_y] = True\n            i.append((p_x, p_y))\n            for j in range(4):\n                c_x, c_y = p_x + dx[j], p_y + dy[j]\n                if check(c_x, c_y) and not vis[c_x][c_y]:\n                    if A[c_x][c_y]:\n                        dfs(c_x, c_y, i)\n        \n        conn = 0\n        for i in range(m):\n            for j in range(n):\n                if not vis[i][j] and A[i][j]:\n                    if conn == 0:\n                        dfs(i, j, i1)\n                    elif conn == 1:\n                        dfs(i, j, i2)\n                    else:\n                        conn += 1\n                        break\n                    conn += 1\n        \n        q = deque()\n        d = [[float('inf') for _ in range(n)] for _ in range(m)]\n        for v in i1:\n            q.append(v)\n            d[v[0]][v[1]] = 0\n        ans = float('inf')\n        while q:\n            s_x, s_y = q[0][0], q[0][1]\n            q.popleft()\n            for i in range(4):\n                c_x, c_y = s_x + dx[i], s_y + dy[i]\n                if check(c_x, c_y):\n                    if d[c_x][c_y] > (d[s_x][s_y] + 1):\n                        d[c_x][c_y] = d[s_x][s_y] + 1\n                        q.append((c_x, c_y))\n                        if A[c_x][c_y]:\n                            ans = min(ans, d[c_x][c_y] - 1)\n        \n        # for v in i2:\n        #     ans = min(ans, d[v[0]][v[1]])\n        return ans ", "class Solution:\n    def shortestBridge(self, A: List[List[int]]) -> int:\n        \n        self.A = A\n        self.R = len(self.A)\n        self.C = len(self.A[0])\n        \n        p = self.findGround()\n        \n        if p == None:\n            return -1\n        \n        self.firstIsland = set()\n        \n        self.embraceIsland( p)\n\n        return self.bfs()\n    \n    def findGround(self):\n        for i in range(0, self.R):\n            for j in range(0, self.C):\n                if self.isGround((i, j)):\n                    return (i, j)\n                \n        return None\n    \n    def isGround(self, p):\n        return self.A[p[0]][p[1]] == 1\n    \n                \n    def inGrid(self, p):\n        \n        if not (0 <= p[0] < self.R):\n            return False\n        \n        if not (0 <= p[1] < self.C):\n            return False\n        \n        return True\n    \n    def getNeis(self, p):\n        neis = []\n        \n        neis.append((p[0] + 1, p[1]))\n        neis.append((p[0] - 1, p[1]))\n        neis.append((p[0], p[1] + 1))\n        neis.append((p[0], p[1] - 1))\n        \n        return neis\n    \n    \n    def embraceIsland(self, p):\n        \n        if p in self.firstIsland:\n            return\n        \n        self.firstIsland.add(p)\n        \n        for nei in self.getNeis(p):\n            if self.inGrid(nei) and self.isGround(nei) and nei not in self.firstIsland:\n                self.embraceIsland(nei)\n    \n    def bfs(self):\n        q = collections.deque()\n        visited = set()\n        \n        for p in self.firstIsland:\n            q.appendleft((p, 0))\n            \n        while q:\n            node, dist = q.pop()\n            \n            if self.isGround(node) and node not in self.firstIsland:\n                return dist - 1\n            \n            if node in visited:\n                continue\n                \n            visited.add(node)\n            \n            for nei in self.getNeis(node):\n                if self.inGrid(nei) and nei not in visited:\n                    q.appendleft((nei, dist + 1))\n        return -1\n    \n", "class Solution:\n    def shortestBridge(self, A: List[List[int]]) -> int:\n        R, C = len(A), len(A[0])\n        dist = [[float('inf')] * C for _ in range(R)]\n        directs = [(-1, 0), (1, 0), (0, -1), (0, 1)]\n\n        src = None\n        for r in range(R):\n            for c in range(C):\n                if A[r][c] == 1:\n                    dist[r][c] = 0\n                    src = (r, c)\n                if src:\n                    break\n            if src:\n                break\n\n        queue = [(0, r, c)]\n        \n        while queue:\n            d, r, c = heapq.heappop(queue)\n\n            for dr, dc in directs:\n                nr, nc = r+dr, c+dc\n                if not (0 <= nr < R and 0 <= nc < C):\n                    continue\n                enqueue = False\n                if A[nr][nc] == 1 and A[r][c] == 1:\n                    if  d < dist[nr][nc]:\n                        dist[nr][nc] = d\n                        enqueue = True\n                else:\n                    if d + 1 < dist[nr][nc]:\n                        dist[nr][nc] = d + 1\n                        enqueue = True\n                if enqueue:\n                    heapq.heappush(queue, (dist[nr][nc], nr, nc))\n\n        ans = float('inf')\n\n        for r in range(R):\n            for c in range(C):\n                if A[r][c] == 1 and dist[r][c] > 0:\n                    ans = min(ans, dist[r][c]-1)\n\n        return ans", "class Solution:\n    def shortestBridge(self, A: List[List[int]]) -> int:\n        i1, i2 = [], []\n        m = len(A)\n        n = len(A[0])\n        vis = [[False for _ in range(n)] for _ in range(m)]\n        def check(x,y):\n            return x>=0 and x<m and y>=0 and y<n\n        dx = [0, -1, 0, 1]\n        dy = [1, 0, -1, 0]\n        def dfs(p_x, p_y, i):\n            vis[p_x][p_y] = True\n            i.append((p_x, p_y))\n            for j in range(4):\n                c_x, c_y = p_x + dx[j], p_y + dy[j]\n                if check(c_x, c_y) and not vis[c_x][c_y]:\n                    if A[c_x][c_y]:\n                        dfs(c_x, c_y, i)\n        \n        conn = 0\n        for i in range(m):\n            for j in range(n):\n                if not vis[i][j] and A[i][j]:\n                    if conn == 0:\n                        dfs(i, j, i1)\n                    elif conn == 1:\n                        dfs(i, j, i2)\n                    else:\n                        conn += 1\n                        break\n                    conn += 1\n        \n        q = deque()\n        d = [[float('inf') for _ in range(n)] for _ in range(m)]\n        for v in i1:\n            q.append(v)\n            d[v[0]][v[1]] = 0\n        while q:\n            s_x, s_y = q[0][0], q[0][1]\n            q.popleft()\n            for i in range(4):\n                c_x, c_y = s_x + dx[i], s_y + dy[i]\n                if check(c_x, c_y):\n                    if d[c_x][c_y] > (d[s_x][s_y] + 1):\n                        d[c_x][c_y] = d[s_x][s_y] + 1\n                        q.append((c_x, c_y))\n        ans = float('inf')\n        for v in i2:\n            ans = min(ans, d[v[0]][v[1]])\n        return ans - 1", "class Solution:\n    def shortestBridge(self, A: List[List[int]]) -> int:\n        i1, i2 = [], []\n        m = len(A)\n        n = len(A[0])\n        vis = [[False for _ in range(n)] for _ in range(m)]\n        def check(x,y):\n            return x>=0 and x<m and y>=0 and y<n\n        dx = [0, -1, 0, 1]\n        dy = [1, 0, -1, 0]\n        def dfs(p_x, p_y, i):\n            vis[p_x][p_y] = True\n            i.append((p_x, p_y))\n            for j in range(4):\n                c_x, c_y = p_x + dx[j], p_y + dy[j]\n                if check(c_x, c_y) and not vis[c_x][c_y]:\n                    if A[c_x][c_y]:\n                        dfs(c_x, c_y, i)\n        \n        conn = 0\n        for i in range(m):\n            for j in range(n):\n                if not vis[i][j] and A[i][j]:\n                    if conn == 0:\n                        dfs(i, j, i1)\n                    elif conn == 1:\n                        dfs(i, j, i2)\n                    else:\n                        conn += 1\n                        break\n                    conn += 1\n        \n        q = deque()\n        d = [[float('inf') for _ in range(n)] for _ in range(m)]\n        for v in i1:\n            q.append(v)\n            d[v[0]][v[1]] = 0\n        ans = float('inf')\n        while q:\n            s_x, s_y = q[0][0], q[0][1]\n            q.popleft()\n            for i in range(4):\n                c_x, c_y = s_x + dx[i], s_y + dy[i]\n                if check(c_x, c_y):\n                    if d[c_x][c_y] > (d[s_x][s_y] + 1):\n                        d[c_x][c_y] = d[s_x][s_y] + 1\n                        q.append((c_x, c_y))\n                        if vis[c_x][c_y]:\n                            ans = min(ans, d[c_x][c_y] - 1)\n        \n        # for v in i2:\n        #     ans = min(ans, d[v[0]][v[1]])\n        return ans ", "class Solution:\n    def shortestBridge(self, A: List[List[int]]) -> int:\n        queue = []\n        def markIsland2(i, j):\n            if i < 0 or i >= len(A) or j < 0 or j >= len(A): return False\n            if A[i][j] == 2: return False\n            if A[i][j] == 0: return True\n            A[i][j] = 2\n            shore = False\n            for x, y in [(1, 0), (-1, 0), (0, 1), (0, -1)]:\n                shore |= markIsland2(i+x, j+y)\n            if shore: queue.append((i,j))\n            return False\n        \n        flag = False\n        for i in range(len(A)):\n            if flag: break\n            for j in range(len(A)):\n                if A[i][j] == 1:\n                    markIsland2(i, j)\n                    flag = True\n                    break\n\n        def BFS(i,j):\n            # A[i][j] = 2\n            queue.append((i,j))\n            for x, y in [(1, 0), (-1, 0), (0, 1), (0, -1)]:\n                if 0 <= (i+x) < len(A) and  0 <= (j+y) < len(A):\n                    if A[i+x][j+y] == 1: return True\n                    elif A[i+x][j+y] == 0: \n                        A[i+x][j+y] = 2\n                        queue.append((i+x,j+y))\n            else: return False\n                  \n        cnt = 0\n        while queue:\n            size = len(queue)\n            for _ in range(size):\n                i, j = queue.pop(0)\n                if BFS(i, j): return cnt\n            cnt += 1", "class Solution:\n    def shortestBridge(self, A: List[List[int]]) -> int:\n        def dfs(A,i,j):\n            if i < 0 or j < 0 or i > len(A)-1 or j > len(A[0])-1:\n                return\n            if visited[i][j] or A[i][j] == 0: return\n            visited[i][j] = True\n            queue.append((i,j))\n            for k in range(4):\n                rr = i + rowVector[k]\n                cc = j + colVector[k]\n                dfs(A,rr,cc)\n        \n        visited = [[False for i in range(len(A[0]))] for j in range(len(A))]\n        rowVector = [1,-1,0,0]\n        colVector = [0,0,1,-1]\n        queue = []\n        found = False\n        \n        for i in range(len(A)):\n            if found:\n                break;\n            for j in range(len(A[0])):\n                if A[i][j] == 1:\n                    dfs(A,i,j)\n                    found = True\n                    break;\n                    \n        count = 0\n        while queue:\n            subQ= []\n            while queue:\n                temp = queue.pop(0)\n                for k in range(4):\n                    i = temp[0] + rowVector[k]\n                    j = temp[1] + colVector[k]\n                    if i < 0 or j < 0 or i > len(A)-1 or j > len(A[0])-1 or visited[i][j]:\n                        continue;\n                    if A[i][j] == 1:\n                        return count\n                    subQ.append((i,j))\n                    visited[i][j] = True\n            queue = subQ\n            count += 1\n        return -1", "class Solution:\n    def shortestBridge(self, A: List[List[int]]) -> int:\n        \n        rows = len(A)\n        cols = len(A[0])\n        directions = ((1, 0), (-1, 0), (0, 1), (0, -1))\n        \n        def edge_check(ro, co):\n            r = []\n            for y, x in directions:\n                nr = ro + y\n                nc = co + x\n                if nr < rows and nr >= 0 and nc < cols and nc >= 0 and A[nr][nc] == 0:\n                    return True\n        \n        \n        edges_1 = set()\n        found_1 = False\n        edges_2 = set()\n        for row in range(rows):\n            for col in range(cols):\n                if A[row][col] == 1:\n                    A[row][col] = '#'\n                    q = collections.deque([])\n                    q.append((row, col))\n                    while q:\n                        r, c = q.popleft()\n                        if not found_1 and edge_check(r, c):\n                            edges_1.add((r, c))\n                        else:\n                            if edge_check(r, c):\n                                edges_2.add((r, c))\n                        for y, x in directions:\n                            nr = r + y\n                            nc = c + x\n                            if nr < rows and nr >= 0 and nc < cols and nc >= 0 and A[nr][nc] == 1:\n                                q.append((nr, nc))\n                                A[nr][nc] = '#'\n                                \n                    found_1 = True\n                    \n        # print(edges_1, edges_2)\n        \n        c1 = sorted(list(edges_1), key=lambda x: (x[0], x[1]))\n        c2 = sorted(list(edges_2), key=lambda x: (x[0], x[1]))\n        \n        d = 0\n        \n        # q = \n        \n        ds = []\n        \n        for x1, x2 in c1[:400]:\n            for y1, y2 in c2[:400]:\n                ds.append(abs(x1-y1)+abs(x2-y2)-1)\n                \n        return min(ds)", "class Solution:\n    def shortestBridge(self, A: List[List[int]]) -> int:\n        if(len(A) == 0):\n            return 0\n        m = len(A)\n        n = len(A[0])\n        queue = []\n        component = 2\n        for i in range(m):\n            for j in range(n):\n                if(A[i][j] == 1):\n                    self.dfs(i,j,A, queue, component)\n                    print(A)\n                    component += 1\n        directions =[(0,1),(1,0),(0,-1),(-1,0)]\n        while(queue):\n            path, x,y = queue.pop(0)\n            if(A[x][y] == 3):\n                continue\n            for dx,dy in directions:\n                if(x+dx < 0 or y+dy < 0 or x+dx >= m or y+dy>= n):\n                    continue\n                if(A[x+dx][y+dy] == 3):\n                    return path\n                if(A[x+dx][y+dy] == 0):\n                    A[x+dx][y+dy] = 2\n                    queue.append((path+1,x+dx,y+dy))\n                    \n    def dfs(self,i,j,grid,queue, component):\n        queue.append((0,i,j))\n        grid[i][j] = component\n        stack = [(i,j)]\n        directions = [(0,1),(1,0),(0,-1),(-1,0)]\n        while(stack):\n            x,y = stack.pop()\n            for dx,dy in directions:\n                if(x+dx<0 or y+dy<0 or x+dx>=len(grid) or y+dy>=len(grid[0])):\n                    continue\n                if(grid[x+dx][y+dy] == 1):\n                    queue.append((0,x+dx,y+dy))\n                    stack.append((x+dx,y+dy))\n                    grid[x+dx][y+dy] = component\n            \n                \n", "class Solution:\n    def shortestBridge(self, A: List[List[int]]) -> int:\n        num_rows, num_cols = len(A), len(A[0])\n        \n        def components():\n            done = set()\n            components = []\n            \n            for row in range(num_rows):\n                for col in range(num_cols):\n                    if A[row][col] and (row, col) not in done:\n                        stack = [(row, col)]\n                        seen = {(row, col)}\n                        while stack:\n                            curr = stack.pop()\n                            for (a,b) in [(1,0),(-1,0),(0,1),(0,-1)]:\n                                nei = (curr[0]+a, curr[1]+b)\n                                if 0<=nei[0]<num_rows and 0<=nei[1]<num_cols\\\\\n                                and A[nei[0]][nei[1]] and nei not in seen:\n                                    stack.append(nei)\n                                    seen.add(nei)\n                        done |= seen\n                        components.append(seen)\n                        if len(components)==2:\n                            return components\n                        \n        source, target = components()\n        queue = [(node, 0) for node in source]\n        done = set(source)\n        while queue:\n            curr, d = queue.pop(0)\n            print(curr)\n            if curr in target: return d-1\n            for (a,b) in [(1,0),(-1,0),(0,1),(0,-1)]:\n                nei = (curr[0] + a, curr[1] + b)\n                if 0<=nei[0]<num_rows and 0<=nei[1]<num_cols and nei not in done:\n                    queue.append((nei,d+1))\n                    done.add(nei)", "class Solution:\n    def shortestBridge(self, A: List[List[int]]) -> int:\n        \n        \n        R, C = len(A), len(A[0])\n        \n        def getNeighbors(curr_points):\n            neighbors = set()\n            for i,j in curr_points:\n                \n                for row,col in [(i+1, j), (i-1, j), (i, j-1), (i, j+1)]:\n                    \n                    if 0 <= row < R and 0 <= col < C:\n                        neighbors.add((row, col))\n            \n            return neighbors\n        \n        def get_islands():\n            def dfs(pos, visited):\n                i, j = pos\n                \n                if (i >= R or\n                    i < 0 or\n                    j >= C or\n                    j < 0 or \n                    A[i][j] == 0 or\n                    pos in visited):\n                    return\n            \n                visited.add(pos)\n                \n                dfs((i+1, j), visited)\n                dfs((i-1, j), visited)\n                dfs((i, j+1), visited)\n                dfs((i, j-1), visited)\n            \n            \n            island1, island2 = set(), set()\n            \n            for i in range(R):\n                for j in range(C):\n                    \n                    if A[i][j] == 1:\n                        if not island1:\n                            dfs((i,j), island1)\n                        elif not island2 and (i,j) not in island1:\n                            dfs((i,j), island2)\n                    \n            return island1, island2 \n            \n            \n        island1, island2 = get_islands()\n        \n        # BFS starting from island1\n        #queue = collections.deque()\n        min_distance = 0\n        \n        while True:\n            neighbors = getNeighbors(island1)\n            for neighbor in neighbors:\n                if neighbor in island2:\n                    return min_distance\n\n                island1.add(neighbor)\n            min_distance += 1\n#         min_distance = None\n#         for p1 in island1:\n#             for p2 in island2:\n                \n#                 if min_distance is None:\n#                     min_distance = self.dist(p1, p2)\n#                 else:\n#                     min_distance = min(min_distance, self.dist(p1,p2))\n        \n        return min_distance\n            \n    \n    def dist(self, x, y):\n        return abs(x[0] - y[0]) + abs(x[1] - y[1]) -1", "class Solution(object):\n    def shortestBridge(self, A):\n        R, C = len(A), len(A[0])\n\n        def neighbors(r, c):\n            for nr, nc in ((r-1,c),(r,c-1),(r+1,c),(r,c+1)):\n                if 0 <= nr < R and 0 <= nc < C:\n                    yield nr, nc\n\n        def get_components():\n            done = set()\n            components = []\n            for r, row in enumerate(A):\n                for c, val in enumerate(row):\n                    if val and (r, c) not in done:\n                        # Start dfs\n                        stack = [(r, c)]\n                        seen = {(r, c)}\n                        while stack:\n                            node = stack.pop()\n                            for nei in neighbors(*node):\n                                if A[nei[0]][nei[1]] and nei not in seen:\n                                    stack.append(nei)\n                                    seen.add(nei)\n                        done |= seen\n                        components.append(seen)\n            return components\n\n        source, target = get_components()\n        print(source, target)\n        queue = collections.deque([(node, 0) for node in source])\n        done = set(source)\n        while queue:\n            node, d = queue.popleft()\n            if node in target: return d-1\n            for nei in neighbors(*node):\n                if nei not in done:\n                    queue.append((nei, d+1))\n                    done.add(nei)", "class Solution:\n    def shortestBridge(self, A: List[List[int]]) -> int:\n        \n        rows = len(A)\n        cols = len(A[0])\n        directions = ((1, 0), (-1, 0), (0, 1), (0, -1))\n        \n        def edge_check(ro, co):\n            r = []\n            for y, x in directions:\n                nr = ro + y\n                nc = co + x\n                if nr < rows and nr >= 0 and nc < cols and nc >= 0 and A[nr][nc] == 0:\n                    return True\n        \n        edges_1 = set()\n        found_1 = False\n        edges_2 = set()\n        for row in range(rows):\n            for col in range(cols):\n                if A[row][col] == 1:\n                    A[row][col] = '#'\n                    q = collections.deque([])\n                    q.append((row, col))\n                    while q:\n                        r, c = q.popleft()\n                        if not found_1 and edge_check(r, c):\n                            edges_1.add((r, c))\n                        else:\n                            if edge_check(r, c):\n                                edges_2.add((r, c))\n                        for y, x in directions:\n                            nr = r + y\n                            nc = c + x\n                            if nr < rows and nr >= 0 and nc < cols and nc >= 0 and A[nr][nc] == 1:\n                                q.append((nr, nc))\n                                A[nr][nc] = '#'\n                                \n                    found_1 = True\n                    \n        \n        # c1 = sorted(list(edges_1), key=lambda x: (x[0], x[1]))\n        # c2 = sorted(list(edges_2), key=lambda x: (x[0], x[1]))\n        \n        minn = float('inf')\n        \n        for x1, x2 in edges_1:\n            for y1, y2 in edges_2:\n                minn = min(minn, abs(x1-y1)+abs(x2-y2)-1)\n                \n        return minn", "import numpy as np\n\nclass Solution:\n    def shortestBridge(self, A: List[List[int]]) -> int:\n        self.R, self.C = len(A), len(A[0])\n        self.queue = []   # implement queue as list\n        # self.visited = [[0]*self.C]*self.R  # weird construction doesn't work quite right\n        self.visited = []\n        for k in range(self.R): self.visited.append([0]*self.C)\n                    \n        \n        count = 0\n        \n        for rr in range(self.R):\n            for cc in range(self.C):\n                if A[rr][cc]==1:\n                    self.dfs(A,rr,cc)\n                    count = 1\n                if count > 0:  # break out of for-loop to get just first island\n                    break\n            if count > 0:\n                break\n                \n                \n        while self.queue: # bfs\n            node_visit = self.queue.pop(0)  # pop first element from queue\n            q_step= node_visit.step\n            \n            for r_srch, c_srch in self.dirs(A,node_visit.r,node_visit.c):\n                if A[r_srch][c_srch] == 0 and self.visited[r_srch][c_srch] == 0:\n                    self.queue.append(self.node(q_step+1,r_srch,c_srch))\n                    self.visited[r_srch][c_srch] = 1  # forgot this in first submission\n                if A[r_srch][c_srch] == 1:\n                    return q_step                            \n       \n\n    def dirs(self,A,r,c) -> int:\n        dir_list = []\n        for rr,cc in [[r-1,c],[r+1,c],[r,c-1],[r,c+1]]:\n            if rr >= 0 and cc >= 0 and rr < self.R and cc < self.C:\n                dir_list.append([rr,cc])\n        return dir_list\n    \n    def dfs(self,A,r,c):\n        if A[r][c] != 1:\n            return\n        A[r][c] = 2\n        self.queue.append(self.node(0,r,c))  # adding nodes to queue for bfs\n        self.visited[r][c] = 1  # visited by dfs \n\n        for r_srch, c_srch in self.dirs(A,r,c):\n            self.dfs(A,r_srch,c_srch)\n            \n    class node:\n        def __init__(self,step,r,c):\n            self.step = step\n            self.r = r\n            self.c = c\n                \n", "class Solution:\n    def shortestBridge(self, A: List[List[int]]) -> int:\n        # find first island\n        # find all boundary cells for first island\n        m = len(A)\n        n = len(A[0])\n        visited = [[False]*n for _ in range(m)]\n        directions = [(0, 1), (0, -1), (-1, 0), (1, 0)]\n        \n        def findFirstIsland():\n            for r in range(m):\n                for c in range(n):\n                    if A[r][c] == 1:\n                        return (r, c)\n        \n        # starts from all boundary cells for first island\n        queue = deque()\n        \n        def dfs(r, c):\n            if visited[r][c]:\n                return\n            # find all boundary cells\n            # mark first island as visited\n            visited[r][c] = True\n            if isBoundary(r, c):\n                queue.append((r, c, -1))\n            for dr, dc in directions:\n                nr, nc = r+dr, c+dc\n                if not (0 <= nr < m and 0 <= nc < n):\n                    continue\n                if A[nr][nc] == 1 and not visited[nr][nc]:\n                    dfs(nr, nc)\n            \n        def isBoundary(r, c):\n            for dr, dc in directions:\n                nr, nc = r+dr, c+dc\n                if not (0 <= nr < m and 0 <= nc < n):\n                    continue\n                if A[nr][nc] == 0:\n                    return True\n            return False\n            \n        sr, sc = findFirstIsland()\n        dfs(sr, sc)\n    \n        visited2 = [[False]*n for _ in range(m)]\n        # do BFS starting from boundary cells\n        while queue:\n            r, c, d = queue.popleft()\n            visited2[r][c] = True\n            if not visited[r][c] and A[r][c] == 1:\n                return d\n            \n            for dr, dc in directions:\n                nr, nc = r+dr, c+dc\n                if not (0 <= nr < m and 0 <= nc < n):\n                    continue\n                if not visited2[nr][nc]:\n                    visited2[nr][nc] = True\n                    queue.append((nr, nc, d+1))\n                    # if A[nr][nc] == 1:\n                    #     return d+1\n                    \n        return 1\n        \n        \n", "from collections import deque\n\nclass Solution:\n    def shortestBridge(self, A: List[List[int]]) -> int:\n        \n        def get_edges(visited, A, i,j, isle):\n            dirs = [(0,1),(0,-1),(1,0),(-1,0)]\n            queue = deque([(i,j)])\n            visited[i][j] = True\n            edges = set()\n            while(queue):\n                edge = 0\n                ci,cj = queue.popleft()\n                for di,dj in dirs:\n                    x = ci+di\n                    y = cj+dj\n                    if(0<=x<m and 0<=y<n and A[x][y] == 1 and not visited[x][y]):\n                        queue.append((x,y))\n                        visited[x][y] = True\n                    elif(0<=x<m and 0<=y<n and A[x][y] == 0):\n                        edge = 1\n                if(edge):\n                    edges.add((ci,cj))\n            return edges\n        \n        def manattan(a,b,c,d):\n            return abs(a-c)+abs(b-d)-1\n        \n        visited = [[0]*len(A[0]) for i in range(len(A))]\n        m = len(A)\n        n = len(A[0])\n        edge_islands = []\n        counts = 0\n        for ii in range(m):\n            for jj in range(n):\n                if(A[ii][jj] == 1 and not visited[ii][jj]):\n                    counts+=1\n                    edge_islands.append(get_edges(visited,A,ii,jj,counts))\n        \n        \n        isle1 = edge_islands[0]\n        isle2 = edge_islands[1]\n        mins = float('inf')\n        for i1 in isle1:\n            for i2 in isle2:\n                mins = min(mins,manattan(i1[0],i1[1],i2[0],i2[1]))\n        return mins\n", "class Solution:\n    def shortestBridge(self, A: List[List[int]]) -> int:\n        M = len(A)\n        N = len(A[0])\n        q = collections.deque()\n        i0 = None\n        j0 = None\n        for i in range(M):\n            for j in range(N):\n                if A[i][j]==1:\n                    i0, j0 = i, j\n                    break\n            if i0 is not None:\n                break\n                \n        q.append((i0, j0))\n        A[i0][j0] = 2\n        vis = set()\n        dirs_lst = [(-1, 0), (1, 0), (0, 1), (0, -1)]\n        boarder = set()\n        while q:\n            i, j = q.popleft()\n            for di, dj in dirs_lst:\n                ni = i+di\n                nj = j+dj\n                if ni<0 or ni>M-1 or nj<0 or nj>N-1:\n                    boarder.add((i, j))\n                    continue\n                if A[ni][nj]==0:\n                    boarder.add((i, j))\n                    continue\n                if (ni, nj) in vis:\n                    continue\n                A[ni][nj] = 2\n                vis.add((ni, nj))\n                q.append((ni, nj))\n            \n        # print (boarder)\n            \n        vis.clear()\n        for i, j in boarder:\n            q.append((i, j, 0))\n            # vis.add((i, j))\n        res = math.inf\n        while q:\n            i, j, nsteps = q.popleft()\n            for di, dj in dirs_lst:\n                ni = i+di\n                nj = j+dj\n                if ni<0 or ni>M-1 or nj<0 or nj>N-1:\n                    continue\n                if (ni, nj) in vis:\n                    continue\n                if A[ni][nj]==1:\n                    res = min(res, nsteps)\n                    continue\n                vis.add((ni, nj))\n                q.append((ni, nj, nsteps+1))\n        return res\n            \n                \n        \n            \n", "class Solution:\n    def shortestBridge(self, grid: List[List[int]]) -> int:\n        \\\"\\\"\\\"\n        # loop to find first 1 in one of the 2 islands\n        # dfs from first 1 and mask all 1 to -1 in this island and collect boundry as well\n        # From boundries of first island, bfs until find 1 which must be part of 2nd island\n        \\\"\\\"\\\"\n        \n        def moves(row, col):\n            for rm, cm in (0, 1), (1, 0), (0, -1), (-1, 0):\n                nr, nc = row + rm, col + cm\n                if 0 <= nr < rows and 0 <= nc < cols:\n                    yield nr, nc\n        \n        def get_first() -> Tuple[int, int]:\n            for r in range(rows):\n                for c in range(cols):\n                    if grid[r][c]:\n                        return r, c\n        \n        def update_boundaries_dfs_rec(row, col):\n            grid[row][col] = -1\n            for nr, nc in moves(row, col):\n                if not grid[nr][nc]:\n                    boundary_set.add((row, col))\n                if  grid[nr][nc] == 1:\n                    update_boundaries_dfs_rec(nr, nc)\n        \n        rows, cols = len(grid), len(grid[0])\n        # bfs to find short distance\n        boundary_set = set()\n        update_boundaries_dfs_rec(*get_first())\n        step = 0\n        while boundary_set:\n            next_boundary_set = set()\n            for r, c in boundary_set:\n                for nr, nc in moves(r, c):\n                    if grid[nr][nc] == 1:\n                        return step\n                    if grid[nr][nc]:\n                        continue\n                    grid[nr][nc] == -1\n                    next_boundary_set.add((nr, nc))\n            step += 1\n            boundary_set = next_boundary_set\n            \n    def shortestBridge1(self, A):\n        def dfs(i, j):\n            A[i][j] = -1\n            bfs.append((i, j))\n            for x, y in ((i - 1, j), (i + 1, j), (i, j - 1), (i, j + 1)):\n                if 0 <= x < n and 0 <= y < n and A[x][y] == 1:\n                    dfs(x, y)\n                    \n        def first():\n            for i in range(n):\n                for j in range(n):\n                    if A[i][j]:\n                        return i, j\n                    \n        n, step, bfs = len(A), 0, []\n        dfs(*first())\n        while bfs:\n            new = []\n            for i, j in bfs:\n                for x, y in ((i - 1, j), (i + 1, j), (i, j - 1), (i, j + 1)):\n                    if 0 <= x < n and 0 <= y < n:\n                        if A[x][y] == 1:\n                            return step\n                        if A[x][y] == -1:\n                            continue\n                        elif not A[x][y]:\n                            A[x][y] = -1\n                            new.append((x, y))\n            step += 1\n            bfs = new\n                \n                \n                \n                \n                \n            \n        ", "class Solution:\n    def shortestBridge(self, mat: List[List[int]]) -> int:\n        R = len(mat)\n        C = len(mat and mat[0])\n\n        def expand(island, other):\n            new = set()\n            for r, c in island:\n                for nr, nc in (r+1, c), (r, c+1), (r-1, c), (r, c - 1):\n                    if R > nr >= 0 <= nc < C:\n                        if (nr, nc) in other:\n                            return True\n                        if mat[nr][nc] == 0:\n                            mat[nr][nc] = 2\n                            new.add((nr, nc))\n            island.update(new)\n                            \n        def findIsland(r, c, island):\n            island.add((r, c))\n            mat[r][c] = 2\n            for nr, nc in (r+1, c), (r, c+1), (r-1, c), (r, c - 1):\n                if R > nr >= 0 <= nc < C and mat[nr][nc] == 1 and (nr, nc) not in island:\n                    findIsland(nr, nc, island)\n\n        islands = []\n        for r in range(R):\n            for c in range(C):\n                if mat[r][c] == 1:\n                    island = set()\n                    findIsland(r, c, island)\n                    islands.append(island)\n\n        ans = 0\n        while True:\n            if expand(*islands):\n                return ans\n            ans += 1\n            # islands.reverse()\n", "class Solution:\n    def shortestBridge(self, A: List[List[int]]) -> int:\n        R, C = len(A), len(A[0])\n        dist = [[float('inf')] * C for _ in range(R)]\n        directs = [(-1, 0), (1, 0), (0, -1), (0, 1)]\n\n        def findSrc():\n            for r in range(R):\n                for c in range(C):\n                    if A[r][c] == 1:\n                        return r, c\n\n        r, c = findSrc()\n        dist[r][c] = 0\n        queue = [(0, r, c)]\n        \n        def neighbors(r, c):\n            for nr, nc in [(r-1,c), (r+1,c), (r,c-1), (r,c+1)]:\n                if 0 <= nr < R and 0 <= nc < C:\n                    yield nr, nc\n        \n        while queue:\n            d, r, c = heapq.heappop(queue)\n            \n            for nr, nc in neighbors(r, c):\n                enqueue = False\n                if A[nr][nc] == 1 and A[r][c] == 1:\n                    if  d < dist[nr][nc]:\n                        dist[nr][nc] = d\n                        enqueue = True\n                else:\n                    if d + 1 < dist[nr][nc]:\n                        dist[nr][nc] = d + 1\n                        enqueue = True\n                if enqueue:\n                    heapq.heappush(queue, (dist[nr][nc], nr, nc))\n\n        ans = float('inf')\n\n        for r in range(R):\n            for c in range(C):\n                if A[r][c] == 1 and dist[r][c] > 0:\n                    ans = min(ans, dist[r][c]-1)\n\n        return ans", "class Solution:\n    def shortestBridge(self, mat: List[List[int]]) -> int:\n        R = len(mat)\n        C = len(mat and mat[0])\n\n        def expand(island, other):\n            new = set()\n            for r, c in island:\n                for nr, nc in (r+1, c), (r, c+1), (r-1, c), (r, c - 1):\n                    if R > nr >= 0 <= nc < C:\n                        if (nr, nc) in other:\n                            return True\n                        if mat[nr][nc] == 0:\n                            mat[nr][nc] = 2\n                            new.add((nr, nc))\n            island.update(new)\n                            \n        def findIsland(r, c, island):\n            island.add((r, c))\n            mat[r][c] = 2\n            for nr, nc in (r+1, c), (r, c+1), (r-1, c), (r, c - 1):\n                if R > nr >= 0 <= nc < C and mat[nr][nc] == 1 and (nr, nc) not in island:\n                    findIsland(nr, nc, island)\n\n        islands = []\n        for r in range(R):\n            for c in range(C):\n                if mat[r][c] == 1:\n                    island = set()\n                    findIsland(r, c, island)\n                    islands.append(island)\n\n        ans = 0\n        while True:\n            if expand(*islands):\n                return ans\n            ans += 1\n            islands.reverse()", "# 9:27 -> DNF\n# get an island as sets of 1s, bfs, O(|V|), where V is all A[i][j]\n# For one of the islands, run bfs from all its nodes to find the other island\n# return shortest of such bfs'\nfrom math import sqrt\nclass Solution:\n    def shortestBridge(self, A: List[List[int]]) -> int:\n        \n        def get_islands(A):\n            island_one = set()\n            for i in range(len(A)):\n                for j in range(len(A[0])):\n                    if A[i][j] == 1 and (i, j) not in island_one:\n                        if not island_one:\n                            island_one = make_island(A, i, j, set())\n                        else:\n                            return island_one, make_island(A, i, j, set())\n                    \n        \n        def make_island(A, i, j, visited):\n            visited.add((i, j))\n            up = A[i][j + 1] if j < len(A[0]) - 1 else 0\n            down = A[i][j - 1] if j > 0 else 0\n            left = A[i - 1][j] if i > 0 else 0\n            right = A[i + 1][j] if i < len(A) - 1 else 0\n            if up and (i, j + 1) not in visited:\n                make_island(A, i, j + 1, visited)\n            if down and (i, j - 1) not in visited:\n                make_island(A, i, j - 1, visited)\n            if left and (i - 1, j) not in visited:\n                make_island(A, i - 1, j, visited)\n            if right and (i + 1, j) not in visited:\n                make_island(A, i + 1, j, visited)\n            return visited\n        \n        def find_shortest_bridge(A, i, j, start_island, global_dist_map):\n            queue = [(i, j)]\n            dist_map = { (i, j) : 0 }\n            while queue:\n                i, j = queue.pop(0)\n                neighbors = []\n                if (i, j + 1) not in start_island and j < len(A[0]) - 1:\n                    neighbors.append((i, j + 1))\n                if (i, j - 1) not in start_island and j > 0:\n                    neighbors.append((i, j - 1))\n                if (i - 1, j) not in start_island and i > 0:\n                    neighbors.append((i - 1, j))\n                if (i + 1, j) not in start_island and i < len(A) - 1:\n                    neighbors.append((i + 1, j))\n                for neighbor in neighbors:\n                    n_i, n_j = neighbor\n                    if A[n_i][n_j] == 1:\n                        return dist_map[(i, j)] + 1\n                    if neighbor not in global_dist_map or global_dist_map[neighbor] > dist_map[(i, j)] + 1:\n                        queue.append(neighbor)\n                        global_dist_map[neighbor] = dist_map[neighbor] = dist_map[(i, j)] + 1\n            return False\n                \n        def find_shortest_pair(island1, island2):\n            min_distance = len(A)*len(A[0])\n            shortest_coords = None\n            for coords1 in island1:\n                for coords2 in island2:\n                    distance_between = sqrt( (coords2[0] - coords1[0]) ** 2 + (coords2[1] - coords1[1]) ** 2 )\n                    if distance_between < min_distance:\n                        min_distance = distance_between\n                        shortest_coords = coords1, coords2\n            return shortest_coords\n        \n        first_island, second_island = get_islands(A)\n        \n        min_island = first_island if len(first_island) < len(second_island) else second_island\n        \n        shortest_bridge = len(A)*len(A[0])\n        \n        global_dist_map = {}\n        \n        for island in min_island:\n            i, j = island\n            shortest_bridge_here = find_shortest_bridge(A, i, j, min_island, global_dist_map)\n            if shortest_bridge_here:\n                shortest_bridge = min(shortest_bridge, shortest_bridge_here)\n        \n        return shortest_bridge - 1\n        \n#         first_coords, second_coords = find_shortest_pair(first_island, second_island)\n        \n#         i, j = first_coords\n        \n#         return find_shortest_bridge(A, i, j, first_island) - 1\n\n#         shortest_bridge = len(A)*len(A[0])\n        \n#         for island in first_island:\n#             i, j = island\n#             shortest_bridge_here = find_shortest_bridge(A, i, j, first_island)\n#             if shortest_bridge_here:\n#                 shortest_bridge = min(shortest_bridge, shortest_bridge_here)\n        \n#         return shortest_bridge - 1\n", "# 9:27 -> DNF\n# get an island as sets of 1s, bfs, O(|V|), where V is all A[i][j]\n# For one of the islands, run bfs from all its nodes to find the other island\n# return shortest of such bfs'\nclass Solution:\n    def shortestBridge(self, A: List[List[int]]) -> int:\n        \n        def get_islands(A):\n            island_one = set()\n            for i in range(len(A)):\n                for j in range(len(A[0])):\n                    if A[i][j] == 1 and (i, j) not in island_one:\n                        if not island_one:\n                            island_one = make_island(A, i, j, set())\n                        else:\n                            return island_one, make_island(A, i, j, set())\n                    \n        \n        def make_island(A, i, j, visited):\n            visited.add((i, j))\n            up = A[i][j + 1] if j < len(A[0]) - 1 else 0\n            down = A[i][j - 1] if j > 0 else 0\n            left = A[i - 1][j] if i > 0 else 0\n            right = A[i + 1][j] if i < len(A) - 1 else 0\n            if up and (i, j + 1) not in visited:\n                make_island(A, i, j + 1, visited)\n            if down and (i, j - 1) not in visited:\n                make_island(A, i, j - 1, visited)\n            if left and (i - 1, j) not in visited:\n                make_island(A, i - 1, j, visited)\n            if right and (i + 1, j) not in visited:\n                make_island(A, i + 1, j, visited)\n            return visited\n        \n        def find_shortest_bridge(A, i, j, start_island, global_dist_map):\n            queue = [(i, j)]\n            dist_map = { (i, j) : 0 }\n            while queue:\n                i, j = queue.pop(0)\n                neighbors = []\n                if (i, j + 1) not in start_island and j < len(A[0]) - 1:\n                    neighbors.append((i, j + 1))\n                if (i, j - 1) not in start_island and j > 0:\n                    neighbors.append((i, j - 1))\n                if (i - 1, j) not in start_island and i > 0:\n                    neighbors.append((i - 1, j))\n                if (i + 1, j) not in start_island and i < len(A) - 1:\n                    neighbors.append((i + 1, j))\n                for neighbor in neighbors:\n                    n_i, n_j = neighbor\n                    if A[n_i][n_j] == 1:\n                        return dist_map[(i, j)] + 1\n                    if neighbor not in global_dist_map or global_dist_map[neighbor] > dist_map[(i, j)] + 1:\n                        queue.append(neighbor)\n                        global_dist_map[neighbor] = dist_map[neighbor] = dist_map[(i, j)] + 1\n            return False\n        \n        first_island, second_island = get_islands(A)\n        \n        min_island = first_island if len(first_island) < len(second_island) else second_island\n        \n        shortest_bridge = len(A)*len(A[0])\n        \n        global_dist_map = {}\n        \n        for island in min_island:\n            i, j = island\n            shortest_bridge_here = find_shortest_bridge(A, i, j, min_island, global_dist_map)\n            if shortest_bridge_here:\n                shortest_bridge = min(shortest_bridge, shortest_bridge_here)\n        \n        return shortest_bridge - 1\n        \n#         first_coords, second_coords = find_shortest_pair(first_island, second_island)\n        \n#         i, j = first_coords\n        \n#         return find_shortest_bridge(A, i, j, first_island) - 1\n\n#         shortest_bridge = len(A)*len(A[0])\n        \n#         for island in first_island:\n#             i, j = island\n#             shortest_bridge_here = find_shortest_bridge(A, i, j, first_island)\n#             if shortest_bridge_here:\n#                 shortest_bridge = min(shortest_bridge, shortest_bridge_here)\n        \n#         return shortest_bridge - 1\n", "class Solution:\n    def shortestBridge(self, A: List[List[int]]) -> int:\n        self.map = A\n        self.rows = len(self.map)\n        self.cols = len(self.map[0])\n        \n        self.queue = []\n        \n        # Source island index: 2\n        self.src = 2\n        # Destination island index: 3\n        self.dst = 3\n        for island_index in [self.src, self.dst]:\n            add_to_queue = (island_index == self.src)\n            self.exploreIsland(island_index, add_to_queue)\n            \n        self.queue_index = 0\n        return self.bridgeBFS()\n        \n    def exploreIsland(self, index, add):\n        row, col = self.getIslandLocation()\n        self.islandDFS(index, row, col, add)\n    \n    def getIslandLocation(self):\n        for row in range(self.rows):\n            for col in range(self.cols):\n                if self.map[row][col] == 1: return (row, col)\n    \n    def islandDFS(self, index, row, col, add):\n        if self.validCoords(row, col) and self.map[row][col] == 1:\n            self.map[row][col] = index\n            if add: self.queue.append((row, col, 0))\n            for search_row in range(row - 1, row + 2, 2):\n                self.islandDFS(index, search_row, col, add)\n            for search_col in range(col - 1, col + 2, 2):\n                self.islandDFS(index, row, search_col, add)\n                \n    def validCoords(self, row, col):\n        if row < 0 or row >= self.rows:\n            return False\n        if col < 0 or col >= self.cols:\n            return False\n        return True\n    \n    def bridgeBFS(self):\n        while self.queue_index < len(self.queue):\n            row, col, dist = self.queue[self.queue_index]\n            self.queue_index += 1\n            for search_row in range(row - 1, row + 2, 2):\n                if self.processCoord(search_row, col, dist): return dist\n            for search_col in range(col - 1, col + 2, 2):\n                if self.processCoord(row, search_col, dist): return dist\n    \n    def processCoord(self, row, col, dist):\n        if not self.validCoords(row, col): return False\n        if self.map[row][col] == self.dst:\n            return True\n        elif self.map[row][col] != self.src:\n            self.queue.append((row, col, dist + 1))\n            self.map[row][col] = self.src\n        return False\n", "class Solution:\n    def dfs(self, A,i,j,replace):\n        if i < 0 or i >= len(A) or j < 0 or j >= len(A[0]):\n            return\n        if A[i][j] == 0 or A[i][j] == replace:\n            return\n        A[i][j] = replace\n        r = self.dfs(A,i+1,j,replace)\n        d = self.dfs(A,i,j+1,replace)\n        u = self.dfs(A,i-1,j,replace)\n        l = self.dfs(A,i,j-1,replace)\n        return\n    \n    def find(self,A,i,j,old):\n        if i < 0 or i >= len(A) or j < 0 or j >= len(A[0]):\n            return False\n        if A[i][j] == -1:\n            return True\n        if A[i][j] == 0:\n            A[i][j] = old+1\n            return False\n        if A[i][j] == old+1:\n            return False\n        A[i][j] = old+1\n        return self.find(A,i+1,j,old) or self.find(A,i-1,j,old) or self.find(A,i,j+1,old) or self.find(A,i,j-1,old)\n\n        \n    def shortestBridge(self, A: List[List[int]]) -> int:\n        iindex = 0\n        i,j = 0,0\n        replace = -1\n        start = ()\n        while i < len(A):\n            j=0\n            while j < len(A[0]):\n                if A[i][j] == 1:\n                    self.dfs(A,i,j,replace)\n                    iindex+=1\n                    replace=-2\n                    start = (i,j)\n                j+=1\n            i+=1\n        old=1\n        while True:\n            #print(A)\n            if self.find(A,start[0],start[1],old):\n                break\n            old+=1\n        return old-1", "class Solution:\n    \\\"\\\"\\\"\n    [\n        [1,1,1,1,1],\n        [1,1,1,1,1],\n        [0,0,1,1,1],\n        [1,0,0,1,1],\n        [1,1,1,0,1]]\n    \\\"\\\"\\\"\n    def shortestBridge(self, A: List[List[int]]) -> int:\n        def is_valid(r, c):\n            return 0 <= r < len(A) and 0 <= c < len(A[0])\n        \n        def dfs(r, c, island, visited):\n            if A[r][c] == 0:\n                return\n            if (r, c) in visited:\n                return\n            dirs = [\n                [0, 1],\n                [0, - 1],\n                [1, 0],\n                [-1, 0]\n            ]\n            visited.add((r, c))\n            is_border = False\n            for dir in dirs:\n                nr = r + dir[0]\n                nc = c + dir[1]\n                if (nr, nc) in visited:\n                    continue\n                # only record border coordinates\n                if not is_valid(nr, nc):\n                    is_border = True\n                    \n                    continue\n                if A[nr][nc] == 0:\n                    is_border = True\n                    \n                    continue\n                dfs(nr, nc, island, visited)\n            if is_border:\n                island.append((r, c))\n            return\n        \n        islands = []\n        visited = set()\n        \n        for r in range(len(A)):\n            for c in range(len(A[0])):\n                if A[r][c] == 1 and (r, c) not in visited:\n                    island = []\n                    dfs(r, c, island, visited)\n                    islands.append(island)\n        \n        def get_shortest_dist(islands1, islands2):\n            min_dist = len(A)\n            for i in range(len(islands1)):\n                for j in range(len(islands2)):\n                    r_dist = abs(islands1[i][0] - islands2[j][0])\n                    c_dist = abs(islands1[i][1] - islands2[j][1])\n                    min_dist = min(min_dist, r_dist + c_dist)\n            return min_dist - 1\n        \n        return get_shortest_dist(islands[0], islands[1])\n        \n            ", "class Solution:\n    def shortestBridge(self, A: List[List[int]]) -> int:\n        self.map = A\n        self.rows = len(self.map)\n        self.cols = len(self.map[0])\n        \n        self.queue = []\n        \n        # Source island index: 2\n        self.src = 2\n        # Destination island index: 3\n        self.dst = 3\n        for island_index in [self.src, self.dst]:\n            add_to_queue = (island_index == self.src)\n            self.exploreIsland(island_index, add_to_queue)\n            \n        return self.bridgeBFS()\n        \n    def exploreIsland(self, index, add):\n        row, col = self.getIslandLocation()\n        self.islandDFS(index, row, col, add)\n    \n    def getIslandLocation(self):\n        for row in range(self.rows):\n            for col in range(self.cols):\n                if self.map[row][col] == 1: return (row, col)\n    \n    def islandDFS(self, index, row, col, add):\n        if self.validCoords(row, col) and self.map[row][col] == 1:\n            self.map[row][col] = index\n            if add: self.queue.append((row, col, 0))\n            for search_row in range(row - 1, row + 2, 2):\n                self.islandDFS(index, search_row, col, add)\n            for search_col in range(col - 1, col + 2, 2):\n                self.islandDFS(index, row, search_col, add)\n                \n    def validCoords(self, row, col):\n        if row < 0 or row >= self.rows:\n            return False\n        if col < 0 or col >= self.cols:\n            return False\n        return True\n    \n    def bridgeBFS(self):\n        while len(self.queue) > 0:\n            row, col, dist = self.queue.pop(0)\n            for search_row in range(row - 1, row + 2, 2):\n                if self.processCoord(search_row, col, dist): return dist\n            for search_col in range(col - 1, col + 2, 2):\n                if self.processCoord(row, search_col, dist): return dist\n    \n    def processCoord(self, row, col, dist):\n        if not self.validCoords(row, col): return False\n        if self.map[row][col] == self.dst:\n            return True\n        elif self.map[row][col] != self.src:\n            self.queue.append((row, col, dist + 1))\n            self.map[row][col] = self.src\n        return False\n", "import collections\n\nclass Solution:\n    def shortestBridge(self, A: List[List[int]]) -> int:\n        m=len(A)\n        n=len(A[0])\n        \n        def neighbors(r, c):\n            for nr, nc in ((r-1,c),(r,c-1),(r+1,c),(r,c+1)):\n                if 0 <= nr < m and 0 <= nc < n:\n                    yield nr, nc\n                    \n        seen=set()\n        \n        islands={2:set(),3:set()}\n        \n        def color_island(r,c,island_id):\n            seen.add((r,c))\n            if A[r][c] != 1:\n                return\n            \n            A[r][c] = island_id\n            islands[island_id].add((r,c))\n            \n            for x,y in neighbors(r,c):\n                if (x,y) not in seen:\n                    color_island(x,y,island_id)\n        \n        islands_found=0\n        for r in range(m):\n            if islands_found==2:\n                break\n            for c in range(n):\n                if islands_found==2:\n                    break\n                if A[r][c]==1:\n                    islands_found+=1\n                    color_island(r,c,islands_found+1)\n                    \n\n        \n        source = islands[2]\n        target = islands[3]\n\n        queue = collections.deque([(node, 0) for node in source])\n        seen=source\n        while queue:\n            (r,c),d= queue.popleft()\n            if (r,c) in target:\n                return d-1\n            for x,y in neighbors(r,c):\n                if (x,y) not in seen:\n                    queue.append(((x,y),d+1))\n                    seen.add((x,y))", "class Solution:\n    \n    DIRS = [[1, 0], [-1, 0], [0, 1], [0, -1]]\n    \n    def shortestBridge(self, A: List[List[int]]) -> int:\n        if not A:\n            return 0\n        m, n = len(A), len(A[0])\n        queue = collections.deque()\n        found = False\n        for i in range(m):\n            for j in range(n):\n                if A[i][j] == 1:\n                    self.dfs(A, i, j, m, n, queue)\n                    found = True\n                    break\n            if found:\n                break\n        bridge = 0\n        while queue:\n            for _ in range(len(queue)):\n                x, y = queue.popleft()\n                for d in self.DIRS:\n                    next_x, next_y = x + d[0], y + d[1]\n                    if 0 <= next_x < m and 0 <= next_y < n and A[next_x][next_y] == 0:\n                        queue.append((next_x, next_y))\n                        A[next_x][next_y] = 2\n                    if 0 <= next_x < m and 0 <= next_y < n and A[next_x][next_y] == 1:\n                        return bridge\n            bridge += 1\n        return bridge\n             \n    \n    def dfs(self, A, i, j, m, n, queue):\n        if i < 0 or i >= m or j < 0 or j >= n or A[i][j] != 1:\n            return\n        A[i][j] = 2\n        queue.append((i, j))\n        self.dfs(A, i+1, j, m, n, queue)\n        self.dfs(A, i-1, j, m, n, queue)\n        self.dfs(A, i, j+1, m, n, queue)\n        self.dfs(A, i, j-1, m, n, queue)\n        \n        \n        \n", "class Solution:\n    def shortestBridge(self, mat: List[List[int]]) -> int:\n        R = len(mat)\n        C = len(mat and mat[0])\n\n        def expand(island, other):\n            new = set()\n            for r, c in island:\n                for nr, nc in (r+1, c), (r, c+1), (r-1, c), (r, c - 1):\n                    if R > nr >= 0 <= nc < C:\n                        if (nr, nc) in other:\n                            return True\n                        if mat[nr][nc] == 0:\n                            mat[nr][nc] = 2\n                            new.add((nr, nc))\n            island.update(new)\n                            \n        def findIsland(r, c, island):\n            island.add((r, c))\n            mat[r][c] = 2\n            for nr, nc in (r+1, c), (r, c+1), (r-1, c), (r, c - 1):\n                if R > nr >= 0 <= nc < C and mat[nr][nc] == 1:\n                    findIsland(nr, nc, island)\n\n        islands = []\n        for r in range(R):\n            for c in range(C):\n                if mat[r][c] == 1:\n                    island = set()\n                    findIsland(r, c, island)\n                    islands.append(island)\n\n        ans = 0\n        while True:\n            if expand(*islands):\n                return ans\n            ans += 1\n            islands = islands[::-1]", "# https://leetcode.com/problems/shortest-bridge/\nfrom typing import List\nfrom queue import Queue\n\n\nclass Solution:\n    def shortestBridge(self, A: List[List[int]]) -> int:\n        first_island, second_island = set(), set()\n        directions = [(0, 1), (0, -1), (1, 0), (-1, 0)]\n\n        def get_all(x, y, island):\n            if (x, y) in island or A[y][x] == 0:\n                return\n\n            island.add((x, y))\n\n            for dx, dy in directions:\n                if 0 <= x + dx < len(A[0]) and 0 <= y + dy < len(A):\n                    get_all(x + dx, y + dy, island)\n\n        first_in = False\n        for y in range(len(A)):\n            for x in range(len(A[0])):\n                if A[y][x] == 1:\n                    if not first_in:\n                        get_all(x, y, first_island)\n                        first_in = True\n\n                    elif (x, y) not in first_island:\n                        get_all(x, y, second_island)\n                        break\n\n        visited = set()\n        q = Queue()\n        for x, y in first_island:\n            q.put((x, y, 0))\n\n        while not q.empty():\n            x, y, depth = q.get()\n\n            if (x, y) in second_island:\n                return depth - 1\n\n            for dx, dy in directions:\n                X, Y = x + dx, y + dy\n                if 0 <= X < len(A[0]) and 0 <= Y < len(A) and (X, Y) not in visited:\n                    q.put((X, Y, depth + 1))\n                    visited.add((X, Y))\n\n", "from queue import Queue\n\ndef valid(m, i, j):\n    return 0 <= i < len(m) and 0 <= j < len(m[0])\n\ndef findAnIsland(m, e):\n    stack = []\n    for i in range(len(m)):\n        for j in range(len(m[0])):\n            if m[i][j] == 1 and (i, j) not in e:\n                stack.append((i, j))\n                break\n        else:\n            continue\n        break\n    result, edges = set(), set()\n    while stack:\n        ci, cj = stack.pop()\n        result.add((ci, cj))\n        for di, dj in ((0,1), (1,0), (0,-1), (-1,0)):\n            cdi, cdj = ci+di, cj+dj\n            if valid(m, cdi, cdj) and (cdi, cdj) not in e and (cdi, cdj) not in result:\n                if m[cdi][cdj] == 1:\n                    stack.append((cdi, cdj))\n                else:\n                    edges.add((ci, cj))\n    return result, edges\n\nclass Solution:\n    def shortestBridge(self, A: List[List[int]]) -> int:\n        a, aedges = findAnIsland(A, set())\n        b, bedges = findAnIsland(A, a)\n        min_flip, q = float('inf'), Queue()\n        for i, j in aedges:\n            q.put((i, j, 0))\n        while not q.empty():\n            ci, cj, dist = q.get()\n            for di, dj in ((0,1), (1,0), (0,-1), (-1,0)):\n                cdi, cdj = ci+di, cj+dj\n                if valid(A, cdi, cdj):\n                    if (cdi, cdj) in bedges:\n                        min_flip = min(min_flip, dist)\n                    elif A[cdi][cdj] == 0 or A[cdi][cdj] > dist + 1:\n                        A[cdi][cdj] = dist + 1\n                        q.put((cdi, cdj, dist + 1))\n        return min_flip\n\n", "class Solution:\n    def shortestBridge(self, A: List[List[int]]) -> int:\n        if len(A) == 0:\n            return -1\n\n        rows = len(A)\n        columns = len(A[0])\n        seen = dict()\n\n        # identify the components\n        def dfs(row, column):\n            island = set()\n            border = set()\n            to_visit = [(row, column)]\n            while len(to_visit) > 0:\n                r, c = to_visit.pop()\n                if r < 0 or r >= rows or c < 0 or c >= columns or (r, c) in seen or A[r][c] != 1:\n                    continue\n\n                seen[(r, c)] = island\n                island.add((r, c))\n                if (r > 0 and A[r - 1][c] == 0) or \\\\\n                    (r < rows - 1 and A[r + 1][c] == 0) or \\\\\n                    (c > 0 and A[r][c - 1] == 0) or \\\\\n                    (c < columns - 1 and A[r][c + 1] == 0):\n                    border.add((r, c))\n\n                to_visit.append((r - 1, c))\n                to_visit.append((r, c - 1))\n                to_visit.append((r + 1, c))\n                to_visit.append((r, c + 1))\n\n            return island, border\n\n\n        borders = []\n        for row in range(rows):\n            for column in range(columns):\n                if A[row][column] != 1 or (row, column) in seen:\n                    continue\n\n                island, border = dfs(row, column)\n                borders.append(border)\n\n        assert len(borders) == 2\n\n        min_distance = rows + columns\n        for r1, c1 in borders[0]:\n            for r2, c2 in borders[1]:\n                min_distance = min(min_distance, abs(r1 - r2) + abs(c1 - c2) - 1)\n\n        return min_distance", "'''Idea is straightforward.\nWe get root of first island from \\\"first\\\" function\nWe dfs root and add indexes of the island to bfs (all indexes of island 1)\nWe bfs and expand the first island in other words\nFinally return step number when facing other island\nNote: This can also be done with referenced array if you don't want to modify A.'''\nclass Solution:\n    def shortestBridge(self, A):\n        def dfs(i, j):\n            if (i,j) not in seen:\n                seen.append((i,j))\n                A[i][j] = -1\n                bfs.append((i, j))\n                for x, y in ((i - 1, j), (i + 1, j), (i, j - 1), (i, j + 1)):\n                    if 0 <= x < n and 0 <= y < n and A[x][y] == 1:\n                        dfs(x, y)\n                    \n        def first():\n            for i in range(n):\n                for j in range(n):\n                    if A[i][j]:\n                        return i, j\n                    \n        n, step, bfs = len(A), 0, []\n        seen = []\n        i,j  = first()\n        dfs(i,j)\n        \n        \n        while bfs:\n            new = []\n            for i, j in bfs:\n                for x, y in ((i - 1, j), (i + 1, j), (i, j - 1), (i, j + 1)):\n                    if 0 <= x < n and 0 <= y < n:\n                        if A[x][y] == 1:\n                            return step\n                        elif not A[x][y]:\n                            A[x][y] = -1\n                            new.append((x, y))\n            step += 1\n            bfs = new", "class Solution:\n    def shortestBridge(self, A: List[List[int]]) -> int:\n        # there are only two islands, make sure you read the questions right\n        # need to find the two island first\n        if not A: return 0\n        m = len(A)\n        n = len(A[0])\n        # count how many 1's and count how many ones in the island? \n        def getnei(i, j): \n            xy = []\n            if i > 0: \n                xy.append((i-1, j))\n            if j > 0:\n                xy.append((i, j-1))\n            if i < m-1: \n                xy.append((i+1, j))\n            if j < m-1: \n                xy.append((i, j+1))\n            return xy\n            \n        def dfs1(i, j): \n            # mark the first group as 2\n            if A[i][j] != 1: \n                return \n            A[i][j] = -1\n            for x, y in getnei(i, j): \n                dfs1(x, y)\n                \n        def bfs(i, j, dist_map, thresh): \n            seen = set()\n            q = collections.deque()\n            q.append((i, j, 0))\n            done = False\n            while q and not done: \n                (ii, jj, depth) = q.popleft()\n                if depth > thresh: \n                    done = True\n                    break\n                    \n                for x, y in getnei(ii, jj): \n                    if (x, y) in dist_map and dist_map[(x, y)]  < depth: \n                        # don't bother\n                        continue\n                        \n                    if A[x][y] == -1: \n                        # must be the shortest distance\n                        thresh = min(depth, thresh) # you have to make \n                        done = True\n                        break\n                    elif A[x][y] == 0: \n                        # only care about 0\n                        if (x, y) in seen: \n                            continue\n                        seen.add((x, y))\n                        q.append((x, y, depth+1))\n                        \n            return thresh\n\n        # already knew there are only two islands\n        ans = math.inf\n        is_second = False\n        dist_map = {}\n        for i in range(m): \n            for j in range(n): \n                if A[i][j] == 1: \n                    if not is_second: \n                        # mark the first group -1\n                        dfs1(i, j)\n                        is_second = True\n                    else:\n                        ans = min(ans, bfs(i, j, dist_map, ans))\n\n        return ans\n        \n        \n", "class Solution:\n    def shortestBridge(self, A: List[List[int]]) -> int:\n        directions = [(0, 1), (1, 0), (0, -1), (-1, 0)]\n        islands, index = [set(), set()], -1\n        visited = set()\n        def traverse(current):\n            nonlocal A, islands, index, visited, directions\n            islands[index].add(current)\n            \n            for d in directions:\n                new_i, new_j = current[0] + d[0], current[1] + d[1]\n                if (0 <= new_i < len(A) and\n                    0 <= new_j < len(A[0]) and\n                    (new_i, new_j) not in visited and\n                    A[new_i][new_j] == 1):\n                    visited.add((new_i, new_j))\n                    traverse((new_i, new_j))\n        \n        for i in range(len(A)):\n            for j in range(len(A[0])):\n                if (i, j) not in visited and A[i][j] == 1:\n                    index += 1\n                    traverse((i, j))\n        \n        one, two = islands\n        result = sys.maxsize\n        for index in one:\n            visited = set()\n            queue = collections.deque([(index, 0)])\n            while queue:\n                current = queue.popleft()\n                if current[1] >= result:\n                    break\n                for d in directions:\n                    new_i, new_j = current[0][0] + d[0], current[0][1] + d[1]\n                    if (0 <= new_i < len(A) and\n                        0 <= new_j < len(A[0]) and\n                        (new_i, new_j) not in one and\n                        (new_i, new_j) not in visited):\n                        if (new_i, new_j) in two:\n                            result = min(result, current[1])\n                            break\n                        visited.add((new_i, new_j))\n                        queue.append(((new_i, new_j), current[1] + 1))\n        return result\n                \n", "from typing import List\n\n\nclass Solution:\n    def shortestBridge(self, A: List[List[int]]) -> int:\n        if not A or not A[0]:\n            return 0\n        # closest distance between two 1s from different groups\n        h, w = len(A), len(A[0])\n\n        def _get_island():\n            \\\"\\\"\\\"Return border of current island\\\"\\\"\\\"\n            island = set()\n            border = set()\n            idx_i = 0\n            idx_j = 0\n            for i in range(h):\n                for j in range(w):\n                    if A[i][j] == 1:\n                        # find an 1\n                        idx_i, idx_j = i, j\n                        break\n            # BFS\n            island.add((idx_i, idx_j))\n            queue = [(idx_i, idx_j)]\n            while queue:\n                i, j = queue.pop()\n                # only keep border\n                # if at vertical border\n                if i > 0 and A[i - 1][j] == 1 and j > 0 and A[i][j - 1] == 1 \\\\\n                        and i < h - 1 and A[i + 1][j] == 1 and j < w - 1 and A[i][j + 1] == 1:\n                    # not at border\n                    pass\n                else:\n                    border.add((i, j))\n                nxts = set()\n                if i > 0:\n                    nxts.add((i - 1, j))\n                if j > 0:\n                    nxts.add((i, j - 1))\n                if i < h - 1:\n                    nxts.add((i + 1, j))\n                if j < w - 1:\n                    nxts.add((i, j + 1))\n                for nxt in nxts:\n                    if A[nxt[0]][nxt[1]] == 1 and nxt not in island:\n                        island.add(nxt)\n                        queue.append(nxt)\n\n            # change current island to 0\n            for i, j in island:\n                A[i][j] = 0\n            return border\n\n        island_1 = _get_island()\n        island_2 = _get_island()\n        res = h + w\n        for i1 in island_1:\n            for i2 in island_2:\n                res = min(res, abs(i1[0] - i2[0]) + abs(i1[1] - i2[1]) - 1)\n        return res\n\n", "class Solution:\n    def shortestBridge(self, A: List[List[int]]) -> int:\n        rows = len(A)\n        cols = len(A[0])\n\n        def getNeighbors(i, j):\n              for x, y in ((i - 1, j), (i + 1, j), (i, j - 1), (i, j + 1)):\n                    if x >= 0 and x < rows and y >= 0 and y < cols:\n                          yield x, y\n\n        def findComponents():\n            visited = set()\n            connectedNodes = [[] for i in range(2)]\n\n            def findConnnectedComponent(i, j):\n                visited.add((i, j))\n                connectedNodes[connectedCompNumber].append((i, j))\n                for x, y in getNeighbors(i, j):\n                      if (x, y) not in visited and A[x][y]:\n                            findConnnectedComponent(x, y)\n\n            connectedCompNumber = -1\n            for i in range(rows):\n                for j in range(cols):\n                      if (i, j) not in visited and A[i][j] == 1:\n                            connectedCompNumber += 1\n                            findConnnectedComponent(i, j)\n            return connectedNodes\n\n        def findDistance() -> int:\n            shortedDist = 1\n            source, target = findComponents()\n\n            queue = collections.deque()\n            for s in source:\n                queue.appendleft((s, 0))\n            done = set()\n            for s in source:\n                done.add(s)\n            while queue:\n                node, dist = queue.pop()\n                if node in target:\n                      return dist - 1\n                for n in getNeighbors(*node):\n                      if n not in done:\n                            queue.appendleft((n, dist + 1))\n                            done.add(n)\n\n        return findDistance()", "import collections\nclass Solution:\n    def shortestBridge(self, A: List[List[int]]) -> int:\n        found = False\n        res=[]\n        for i in range(len(A)):\n            for j in range(len(A[0])):\n                if A[i][j]==1:\n                    self.dfs(A,i,j,res)\n                    found = True\n                    break\n            if found:\n                break\n        cnt =0       \n        while res:\n            tmp=[]\n            for x,y in res:\n                for dx,dy in ((1,0),(-1,0),(0,1),(0,-1)):\n                    if 0<=x+dx<len(A) and 0<=y+dy<len(A[0]) and A[x+dx][y+dy]!=2:\n                        if A[x+dx][y+dy]==0:\n                            A[x+dx][y+dy]=2\n                        if A[x+dx][y+dy]==1:\n                            return cnt\n                        tmp.append([x+dx,y+dy])\n            cnt+=1\n            res = tmp\n        return -1\n        \n        \n        \n        \n        \n    def dfs(self,A,i,j,res):\n        if 0<=i<len(A) and 0<=j<len(A[0]) and A[i][j]==1:\n            A[i][j]=2\n            res.append([i,j])\n            self.dfs(A,i+1,j,res)\n            self.dfs(A,i-1,j,res)\n            self.dfs(A,i,j-1,res)\n            self.dfs(A,i,j+1,res)", "class Solution(object):\n    def shortestBridge(self, A):\n        R, C = len(A), len(A[0])\n\n        def neighbors(r, c):\n            for nr, nc in ((r-1,c),(r,c-1),(r+1,c),(r,c+1)):\n                if 0 <= nr < R and 0 <= nc < C:\n                    yield nr, nc\n\n        def get_components():\n            components = []\n            for r, row in enumerate(A):\n                for c, val in enumerate(row):\n                    if val == 1:\n                        A[r][c] = 2\n                        stack = [(r, c)]\n                        #seen = {(r, c)}\n                        seen = [(r, c)]\n                        while stack:\n                            node = stack.pop()\n                            for x, y in neighbors(*node):\n                                if A[x][y] == 1:\n                                    A[x][y] = 2\n                                    stack.append((x, y))\n                                    #seen.add((x, y))\n                                    seen.append((x, y))\n                        components.append(seen)\n            return components\n\n        source, target = get_components()\n        queue = collections.deque([(node, 0) for node in source])\n        done = set(source)\n        while queue:\n            node, d = queue.popleft()\n            if node in target: return d-1\n            for nei in neighbors(*node):\n                if nei not in done:\n                    queue.append((nei, d+1))\n                    done.add(nei)", "from queue import Queue\n\ndef valid(m, i, j):\n    return 0 <= i < len(m) and 0 <= j < len(m[0])\n\ndef findAnIsland(m, e):\n    stack = []\n    for i in range(len(m)):\n        for j in range(len(m[0])):\n            if m[i][j] == 1 and (i, j) not in e:\n                stack.append((i, j))\n                break\n        else:\n            continue\n        break\n    result, edges = set(), set()\n    while stack:\n        ci, cj = stack.pop()\n        result.add((ci, cj))\n        for di, dj in ((0,1), (1,0), (0,-1), (-1,0)):\n            cdi, cdj = ci+di, cj+dj\n            if valid(m, cdi, cdj) and (cdi, cdj) not in e and (cdi, cdj) not in result:\n                if m[cdi][cdj] == 1:\n                    stack.append((cdi, cdj))\n                else:\n                    edges.add((ci, cj))\n    return result, edges\n\nclass Solution:\n    def shortestBridge(self, A: List[List[int]]) -> int:\n        a, aedges = findAnIsland(A, set())\n        b, bedges = findAnIsland(A, a)\n        min_flip = float('inf')\n        q = Queue()\n        for i, j in aedges:\n            q.put((i, j, 0))\n        while not q.empty():\n            ci, cj, dist = q.get()\n            for di, dj in ((0,1), (1,0), (0,-1), (-1,0)):\n                cdi, cdj = ci+di, cj+dj\n                if valid(A, cdi, cdj):\n                    if (cdi, cdj) in bedges:\n                        min_flip = min(min_flip, dist)\n                    elif A[cdi][cdj] == 0 or A[cdi][cdj] > dist + 1:\n                        A[cdi][cdj] = dist + 1\n                        q.put((cdi, cdj, dist + 1))\n        return min_flip\n", "class Solution:\n    def __init__(self):\n        self.components = []\n        self.comp = []\n        self.seen = set()\n    def isValid(self, r, c, A):\n        if r < 0 or c < 0 or r >= len(A) or c >= len(A):\n            return False\n        return True\n        \n    def dfs(self, r, c, A):\n        if not self.isValid(r, c, A) or (r,c) in self.seen or A[r][c] != 1:\n            return \n        self.comp.append((r,c))\n        self.seen.add((r,c))\n        self.dfs(r + 1, c, A)\n        self.dfs(r - 1, c, A)\n        self.dfs(r, c + 1, A)\n        self.dfs(r, c - 1, A)\n\n    def shortestBridge(self, A: List[List[int]]) -> int:\n        \n        for i in range(len(A)):\n            for j in range(len(A[0])):\n                if (i, j) not in self.seen and A[i][j] == 1:\n                    self.comp = []\n                    self.dfs(i, j,  A)\n                    self.components.append(self.comp)\n        \n        source, target = self.components\n        visited = set(source)\n        queue = collections.deque([(node,0) for node in source])\n        \n        while queue:\n            node, d = queue.popleft()\n            if node in target:\n                return d - 1\n            else:\n                for dr, dc in [(1, 0), (-1, 0), (0, 1), (0, -1)]:\n                    nr = node[0] + dr\n                    nc = node[1] + dc\n                    if (nr,nc) not in visited and self.isValid(nr, nc, A):\n                        queue.append(((nr, nc), d + 1))\n                        visited.add((nr, nc))\n        return -1\n", "class Solution:    \n    def __init__(self):\n        self.islandA = []\n        self.islandB = []\n        self.maxRow = 0\n        self.maxColumn = 0\n        self.maps = []\n        self.directions = [[1,0], [-1,0], [0,1], [0,-1]]\n    \n    def shortestBridge(self, A: List[List[int]]) -> int:\n        self.maps = A\n        self.maxRow = len(A) - 1\n        self.maxColumn = len(A[0]) - 1\n        \n        for row in range(len(A)):\n            for column in range(len(A[row])):\n                value = A[row][column]\n                \n                if value == 1:\n                    if len(self.islandA) == 0:\n                        self.islandA = self.floodFill(A, self.islandA, row, column)\n        \n        stack = self.islandA\n        print(stack)\n        steps = 0\n        \n        while stack:\n            temp = []\n\n            for st in stack:\n                for direction in self.directions:\n                    nextColumn = st[0] + direction[0]\n                    nextRow = st[1] + direction[1]\n                    \n                    if nextColumn < 0 or nextColumn > self.maxColumn or nextRow < 0 or nextRow > self.maxRow or A[nextColumn][nextRow] == 2:\n                        continue\n                    \n                    if A[nextColumn][nextRow] == 1:\n                        return steps\n                    \n                    A[nextColumn][nextRow] = 2\n                    temp.append([nextColumn, nextRow])\n            steps += 1\n            stack = temp\n                \n        return 1\n                \n    def floodFill(self, A, island, row, column):\n        if [row,column] not in island:\n            island.append([row,column])\n            A[row][column] = 2\n            \n        for direction in self.directions:\n            nextColumn = column - direction[0]\n            nextRow = row - direction[1]\n            \n            if nextColumn < 0 or nextColumn > self.maxColumn or nextRow < 0 or nextRow > self.maxRow:\n                continue\n                \n            if self.maps[nextRow][nextColumn] == 1 and [nextRow, nextColumn] not in island:\n                island = self.floodFill(A, island, nextRow, nextColumn)\n        \n        return island\n", "class Solution:\n    def shortestBridge(self, A: List[List[int]]) -> int:\n        m = len(A)\n        n = len(A[0])\n\n        found = False\n        for i in range(m):\n            for j in range(n):\n                if A[i][j] == 1:\n                    found = True\n                    break\n            if found: break\n        src = []\n        q = []\n        src.append((i,j))\n        q.append((i,j))\n        visited = [[False for _ in range(n)] for _ in range(m)]\n        visited[i][j] = True\n\n        while q:\n            curi, curj = q.pop(0)\n            for nbori, nborj in [(curi + 1, curj), (curi - 1, curj), (curi, curj+1), (curi, curj-1)]:\n                if 0 <= nbori < m and 0 <= nborj < n:\n                    if not visited[nbori][nborj] and A[nbori][nborj] == 1:\n                        q.append((nbori, nborj))\n                        visited[nbori][nborj] = True\n                        src.append((nbori,nborj))\n\n        found = False\n        for i in range(m):\n            for j in range(n):\n                if A[i][j] == 1 and not visited[i][j]:\n                    found = True\n                    break\n            if found: break\n        dest = []\n        dest.append((i,j))\n        q = []\n        q.append((i,j))\n        visited[i][j] = True\n        while q:\n            curi, curj = q.pop(0)\n            for nbori, nborj in [(curi + 1, curj), (curi - 1, curj), (curi, curj+1), (curi, curj-1)]:\n                if 0 <= nbori < m and 0 <= nborj < n:\n                    if not visited[nbori][nborj] and A[nbori][nborj] == 1:\n                        q.append((nbori, nborj))\n                        visited[nbori][nborj] = True\n                        dest.append((nbori,nborj))\n        \n        source, target = src, dest\n        print(source, target)\n        queue = collections.deque([(node, 0) for node in source])\n        done = set(source)\n        while queue:\n            node, d = queue.popleft()\n            curi, curj = node\n            if node in target: return d-1\n            for nei in[(curi + 1, curj), (curi - 1, curj), (curi, curj+1), (curi, curj-1)]:\n                if nei not in done:\n                    queue.append((nei, d+1))\n                    done.add(nei)", "class Solution:\n    \n    \n    \n    def shortestBridge(self, A: List[List[int]]) -> int:\n        \n        minn = len(A)*2\n        visited = [[False for _ in range(len(A))] for _ in range(len(A))]\n        label = 1\n        found = False\n        \n        islands = {1: [], 2: []}\n        \n        def dfs(i, j):\n            nonlocal A, visited, label, found\n                        \n            if i < 0 or j < 0 or i + 1 > len(A) or j + 1 > len(A) or visited[i][j]:\n                return\n            \n            visited[i][j] = True\n            \n            if A[i][j] == 0:\n                return\n            \n            islands[label].append((i, j))\n            \n            dfs(i, j+1)\n            dfs(i, j-1)\n            dfs(i+1, j)\n            dfs(i-1, j)\n\n            found = True\n        \n        for i in range(len(A)):\n            for j in range(len(A)):\n                if not visited[i][j]:\n                    dfs(i, j)\n                    if found:\n                        label = 2\n                        \n        R, C = len(A), len(A[0])\n\n        def neighbors(r, c):\n            for nr, nc in ((r-1,c),(r,c-1),(r+1,c),(r,c+1)):\n                if 0 <= nr < R and 0 <= nc < C:\n                    yield nr, nc\n        \n        source, target = islands[1], islands[2]\n        print((source, target))\n        queue = collections.deque([(node, 0) for node in source])\n        done = set(source)\n        while queue:\n            node, d = queue.popleft()\n            if node in target: return d-1\n            for nei in neighbors(*node):\n                if nei not in done:\n                    queue.append((nei, d+1))\n                    done.add(nei)\n", "class Solution:\n    def shortestBridge(self, A: List[List[int]]) -> int:\n        m = len(A)\n        n = len(A[0])\n        visited = collections.deque()\n        flag = False\n        for i in range(m):\n            for j in range(n):\n                if A[i][j] == 1:\n                    A[i][j] = 2\n                    visited = self.search(A,i,j,visited)\n                    flag = True\n                    break\n            if flag == True:\n                break\n         \n        steps = 0\n        vis = collections.deque(visited)\n        \n        while visited:\n            size = len(visited)\n            for i in range(size):\n                row,col = visited.popleft()\n                dirs = [(0,1),(0,-1),(1,0),(-1,0)]\n                for d in dirs:\n                    newrow = row+d[0]\n                    newcol = col+d[1]\n                    if 0<=newrow<len(A) and 0<=newcol<len(A[0]) and A[newrow][newcol] == 1:\n                        return steps\n                    elif 0<=newrow<len(A) and 0<=newcol<len(A[0]) and A[newrow][newcol] == 0 and (newrow,newcol) not in vis:\n                        A[newrow][newcol] = 2\n                        visited.append((newrow,newcol))\n                        vis.append((newrow,newcol))\n            steps += 1\n        return -1\n            \n                \n                \n    def search(self,A,i,j,visited):\n        q = collections.deque()\n        q.append((i,j))\n        visited.append((i,j))\n        \n        while q:\n            size = len(q)\n            for i in range(size):\n                r,c = q.popleft()\n                dirs = [(0,1),(0,-1),(1,0),(-1,0)]\n                for d in dirs:\n                    newr = r+d[0]\n                    newc = c+d[1]\n                    if 0<=newr<len(A) and 0<=newc<len(A[0]) and A[newr][newc] == 1 and (newr,newc) not in visited:\n                        A[newr][newc] = 2\n                        q.append((newr,newc))\n                        visited.append((newr,newc))\n        return visited\n", "class Solution:\n    def shortestBridge(self, A: List[List[int]]) -> int:\n        \n        N = len(A)\n        M = len(A[0])\n        \n        #Get border of island\n        def dfs(A, i, j, res, isnum):\n            if not ( 0 <= i < N and 0 <= j < M): return\n            if A[i][j] == 1:\n                A[i][j] = isnum\n                if i == 0 or i == N-1 or j == 0 or j == M -1:\n                    res.append((i,j))\n                elif (i != 0 and A[i-1][j] == 0) or (i != N-1 and A[i+1][j] == 0) or (j != 0 and A[i][j-1] == 0) or (j != M-1 and A[i][j+1] == 0):\n                    res.append((i,j))\n                for m,n in ((-1,0),(1,0),(0,-1),(0,1)):\n                    dfs(A,i+m,j+n, res, isnum)\n            \n        def getislands(A):\n            res = []\n            isnum = 2\n            for i, row in enumerate(A):\n                for j, x in enumerate(row):\n                    if A[i][j] == 1:\n                        border = []\n                        dfs(A, i, j, border, isnum)\n                        res.append(border)\n                        isnum += 1\n                        print (\\\"A:\\\", A)\n            return res\n        \n        islands = getislands(A)\n        print (islands)\n        is1, is2 = islands[0], islands[1]\n        minflip = float(\\\"inf\\\")\n        print (\\\"is1:\\\", is1, \\\"is2:\\\", is2)\n        for island1 in is1:\n            for island2 in is2:\n                minflip = min(sum([abs(x-y) for x,y in zip(island1, island2)]), minflip)\n        return minflip-1\n        ", "class Solution:\n    def shortestBridge(self, A: List[List[int]]) -> int:\n        found_y, found_x = None, None\n        for y in range(len(A)):\n            found_one = False\n            for x in range(len(A[0])):\n                if A[y][x] == 1:\n                    found_y, found_x = y, x\n                    A = self.invertOnes(y, x, A)\n                    found_one = True\n                    break\n            if found_one:\n                break\n                    \n        #print(A)\n        \n        return self.BFS(found_y, found_x, A)\n    \n    \n    def invertOnes(self, y, x, A):\n        neighbors = [(1, 0), (0, 1), (-1, 0), (0, -1)]\n        \n        stack = []\n        stack.append((y, x))\n        A[y][x] = -1\n        \n        while stack:\n            curr_y, curr_x = stack.pop(0)\n            \n            for neighbor in neighbors:\n                new_y, new_x = curr_y + neighbor[0], curr_x + neighbor[1]\n                if new_y >= 0 and new_y < len(A) and new_x >= 0 and new_x < len(A[0]) and A[new_y][new_x] == 1:\n                    A[new_y][new_x] = -1\n                    stack.append((new_y, new_x))\n                    \n        return A\n    \n    def BFS(self, y, x, A):\n        visited = {}\n        neighbors = [(1, 0), (0, 1), (-1, 0), (0, -1)]\n        \n        stack = []\n        stack.append((y, x, 0))\n        visited[(y, x)] = 0\n        min_dist = float('inf')\n        \n        while stack:\n            curr_y, curr_x, curr_dist = stack.pop(0)\n            #print(curr_y, curr_x, curr_dist)\n            if A[curr_y][curr_x] == 1:\n                min_dist = min(min_dist, curr_dist -1)\n            \n            for neighbor in neighbors:\n                new_y, new_x = curr_y + neighbor[0], curr_x + neighbor[1]\n                if new_y >= 0 and new_y < len(A) and new_x >= 0 and new_x < len(A[0]):\n                    if A[new_y][new_x] == -1:\n                        new_dist = 0\n                    else:\n                        new_dist = curr_dist + 1\n                    \n                    if (new_y, new_x) not in visited:\n                        stack.append((new_y, new_x, new_dist))\n                        visited[(new_y), (new_x)] = new_dist\n                    else:\n                        if visited[(new_y), (new_x)] > new_dist:\n                            visited[(new_y), (new_x)] = new_dist\n                            stack.append((new_y, new_x, new_dist))\n                            \n                        \n                    \n        return min_dist\n            \n            \n            \n            \n        \n        \n        \n", "from collections import deque\nclass Solution:\n    def shortestBridge(self, A: List[List[int]]) -> int:\n        #[1,1,1,1,1]\n        #[1,0,0,0,1]\n        #[1,0,1,0,1]\n        #[1,0,0,0,1],\n        #[1,1,1,1,1]]\n        \n        def color(x,y):\n            dfs = [(x,y)]\n            while dfs:\n                a,b = dfs.pop()\n                A[a][b] = 2\n                for mx, my in [(0,1),(0,-1),(1,0),(-1,0)]:\n                    if 0 <= a + mx < len(A) and 0 <= b + my < len(A[0]):\n                        if A[a+mx][b+my] == 1:\n                            dfs.append((a+mx, b+my))\n        def firstOne():\n            for i in range(len(A)):\n                for j in range(len(A[0])):\n                    if A[i][j]:\n                        color(i,j)\n                        return (i,j)\n        \n        point = firstOne()\n        self.best = 1000\n        def findClosest(point):\n            visited = {}\n            bfs = deque([(point,0)])\n            while bfs:\n                curr, dist = bfs.popleft()\n                #print(curr, dist)\n                if curr in visited:\n                    if visited[curr] <= dist: continue\n                visited[curr] = dist\n                for x,y in [(0,1),(0,-1),(1,0),(-1,0)]:\n                    cx = curr[0] + x\n                    cy = curr[1] + y    \n                    if 0 <= cx < len(A) and 0 <= cy < len(A[0]):\n                        if A[cx][cy] == 2:\n                            bfs.append(((cx,cy), 0))\n                        elif A[cx][cy] == 1:\n                            #print(\\\"HERE!\\\")\n                            self.best = min(self.best, dist)\n                        else:\n                            bfs.append(((cx,cy), dist+1))\n        findClosest(point)\n        return self.best", "class Solution:\n    def shortestBridge(self, A: List[List[int]]) -> int:\n        q=collections.deque()\n        \n        def find_first_island():\n            for i in range(len(A)):\n                for j in range(len(A[0])):\n                    if A[i][j]==1:\n                        explore_island(i,j)\n                        return\n        def explore_island(r,c):\n            if not 0<=r<len(A) or not 0<=c<len(A[r]) or A[r][c]==-1:\n                return\n            if A[r][c]==1:\n                A[r][c]=-1\n                explore_island(r+1,c)\n                explore_island(r-1,c)\n                explore_island(r,c+1)\n                explore_island(r,c-1)\n            elif A[r][c]==0:\n                q.append((r,c,1))\n        find_first_island()\n        \n        while q:\n            cur_r,cur_c,cur_l=q.popleft()\n            for x,y in (cur_r+1,cur_c),(cur_r-1,cur_c),(cur_r,cur_c+1),(cur_r,cur_c-1):\n                if 0<=x<len(A) and 0<=y<len(A[0]):\n                    if A[x][y]==1:\n                        return cur_l\n                    elif A[x][y]==0:\n                        A[x][y]=-1\n                        q.append((x,y,cur_l+1))\n", "from typing import List\nfrom collections import deque as queue\nfrom functools import lru_cache\n\n\nclass Solution:\n    def shortestBridge(self, A: List[List[int]]) -> int:\n        n = len(A)\n\n        @lru_cache\n        def neighbours(i, j):\n            return [\n                neighbour for neighbour\n                in [\n                    (i - 1, j) if i > 0 else None,\n                    (i + 1, j) if i < n - 1 else None,\n                    (i, j - 1) if j > 0 else None,\n                    (i, j + 1) if j < n - 1 else None\n                ]\n                if neighbour is not None\n            ]\n\n        # find the first piece of land\n        for i in range(n):\n            for j in range(n):\n                if A[i][j] == 1:\n                    first = (i, j)\n        # mark all pieces on the same land as \\\"2\\\",\n        # so we can easily diferentiate them from the other island\n        q = queue([first])\n        # visited also contains all the pieces of land on the second island\n        visited = set()\n        visited.add(first)\n        while q:\n            i, j = q.popleft()\n            A[i][j] = 2\n            for ni, nj in neighbours(i, j):\n                if (ni, nj) not in visited and A[ni][nj] == 1:\n                    visited.add((ni, nj))\n                    q.append((ni, nj))\n\n        min_distance = float('inf')\n        for li, lj in visited:\n            q = queue([(li, lj, 0)])\n            water_visited = set()\n            while q:\n                i, j, d = q.popleft()\n                for ni, nj in neighbours(i, j):\n                    if A[ni][nj] == 0 and (ni, nj) not in water_visited and d + 1 < min_distance:\n                        water_visited.add((ni, nj))\n                        q.append((ni, nj, d + 1))\n                    elif A[ni][nj] == 1 and d < min_distance:\n                        min_distance = d\n                        if min_distance == 1:\n                            return 1\n\n        return min_distance\n", "import queue\n\ndef isOK(x, y, m, n):\n    return x >=0 and y >=0 and x < m and y < n\n\nclass Solution:\n    def shortestBridge(self, A: List[List[int]]) -> int:\n        m = len(A)\n        n = len(A[0])\n        visited = [[False for _ in range(n)] for _ in range(m)]\n        \n        def dfs(start):\n            island = []\n            x, y = start\n            visited[x][y] = True\n            stack = [start]\n            while stack:\n                x, y = stack.pop()\n                island.append((x, y))\n                xRows = [0,0,-1,1]\n                yCols = [-1, 1, 0,0]\n                for i in range(4):\n                    new_x = x + xRows[i]\n                    new_y = y + yCols[i]\n                    \n                    if isOK(new_x, new_y, m, n) and not visited[new_x][new_y] and A[new_x][new_y]== 1:\n                        stack.append((new_x, new_y))\n                        visited[new_x][new_y] = True\n                        \n            return island\n        \n        islands = []\n        for i in range(m):\n            for j in range(n):\n                if not visited[i][j] and A[i][j] == 1:\n                    island = dfs((i, j))\n                    islands.append(island)\n                    \n                    \n        source_island, target_island = islands\n        \n        print(source_island)\n        print(target_island)\n        \n        visited = [[False for _ in range(n)] for _ in range(m)]\n        \n        def bfs(source_island, target_island, visited):\n            q = queue.Queue()\n            for start in source_island:\n                x,y = start\n                q.put((x, y, 0))\n                \n            while q.qsize() > 0:\n                u = q.get()\n                x, y, w = u\n                xRows = [-1, 1, 0, 0]\n                yCols = [0, 0, -1, 1]\n                for i in range(4):\n                    new_x = x + xRows[i]\n                    new_y = y + yCols[i]\n                    if isOK(new_x, new_y, m, n) and not visited[new_x][new_y]:\n                        if (new_x, new_y) in target_island:\n                            return w\n                        \n                        visited[new_x][new_y] = True\n                        q.put((new_x, new_y, w + 1))\n        # Time Complexity O(V + E)\n        return bfs(source_island, target_island, visited)\n                        \n                    \n        \n                    \n        \n        \n       \n            \n            \n            \n            \n            \n            \n            \n            \n            \n            \n            \n            \n", "import queue\n\ndef isOK(x, y, m, n):\n    return x >= 0 and y >= 0 and x < m and y < n\n\ndef isOnEdge(A, x, y, m, n):\n    xRows = [0, 0, -1, 1]\n    yCols = [-1, 1, 0, 0]\n    for i in range(4):\n        new_x = x + xRows[i]\n        new_y = y + yCols[i]\n        if isOK(new_x, new_y, m, n) and A[new_x][new_y] == 0:\n            return True\n        \n    return False\n\nimport queue\nclass Solution:\n    def shortestBridge(self, A: List[List[int]]) -> int:\n        m = len(A)\n        n = len(A[0])\n        \n        visited = [[False for _ in range(n)] for _ in range(m)]\n        \n        \n        def dfs(start, island): \n            x, y = start\n            island.append(start)\n            visited[x][y] = True\n            xRows = [0, 0, -1, 1]\n            yCols = [-1, 1, 0, 0]\n            for i in range(4):\n                new_x = x + xRows[i]\n                new_y = y + yCols[i]\n                if isOK(new_x, new_y, m, n) and not visited[new_x][new_y] and A[new_x][new_y] == 1:\n                    dfs((new_x, new_y), island)\n                    \n        islands = []\n        for i in range(m):\n            for j in range(n):\n                if not visited[i][j] and A[i][j] == 1:\n                    island = []\n                    dfs((i, j), island)\n                    islands.append(island)\n                    \n        island1 = islands[0]\n        island2 = islands[1]\n        \n        visited = [[False for _ in range(n)] for _ in range(m)]\n        def bfs(source_island, target_island, visited): \n            q = queue.Queue()\n            \n            for start in source_island:\n                x, y = start\n                q.put((x, y, 0))\n            cnt = 0\n            \n            while q.qsize() > 0:\n                start = q.get()\n                x, y, w = start\n                xRows = [0, 0, -1, 1]\n                yCols = [-1, 1, 0, 0]\n                for i in range(4):\n                    new_x = x + xRows[i]\n                    new_y = y + yCols[i]\n                    if isOK(new_x, new_y, m, n) and not visited[new_x][new_y]:\n                        if (new_x, new_y) in target_island:\n                            return w + 1\n                        \n                        visited[new_x][new_y] = True\n                        q.put((new_x, new_y, w + 1))\n                                \n                        \n        return bfs(island1, island2, visited) - 1\n        \n        \n       \n            \n            \n            \n            \n            \n            \n            \n            \n            \n            \n            \n            \n", "import queue\n\ndef isOK(x, y, m, n):\n    return x >=0 and y >=0 and x < m and y < n\n\nclass Solution:\n    def shortestBridge(self, A: List[List[int]]) -> int:\n        m = len(A)\n        n = len(A[0])\n        visited = [[False for _ in range(n)] for _ in range(m)]\n        \n        def dfs(start):\n            island = []\n            x, y = start\n            visited[x][y] = True\n            stack = [start]\n            while stack:\n                x, y = stack.pop()\n                island.append((x, y))\n                xRows = [0,0,-1,1]\n                yCols = [-1, 1, 0,0]\n                for i in range(4):\n                    new_x = x + xRows[i]\n                    new_y = y + yCols[i]\n                    \n                    if isOK(new_x, new_y, m, n) and not visited[new_x][new_y] and A[new_x][new_y]== 1:\n                        stack.append((new_x, new_y))\n                        visited[new_x][new_y] = True\n                        \n            return island\n        \n        islands = []\n        for i in range(m):\n            for j in range(n):\n                if not visited[i][j] and A[i][j] == 1:\n                    island = dfs((i, j))\n                    islands.append(island)\n                    \n                    \n        source_island, target_island = islands\n        \n        print(source_island)\n        print(target_island)\n        \n        visited = [[False for _ in range(n)] for _ in range(m)]\n        \n        def bfs(source_island, target_island, visited):\n            q = queue.Queue()\n            for start in source_island:\n                x,y = start\n                q.put((x, y, 0))\n                \n            while q.qsize() > 0:\n                u = q.get()\n                x, y, w = u\n                xRows = [-1, 1, 0, 0]\n                yCols = [0, 0, -1, 1]\n                for i in range(4):\n                    new_x = x + xRows[i]\n                    new_y = y + yCols[i]\n                    if isOK(new_x, new_y, m, n) and not visited[new_x][new_y]:\n                        if (new_x, new_y) in target_island:\n                            return w\n                        \n                        visited[new_x][new_y] = True\n                        q.put((new_x, new_y, w + 1))\n                        \n                        \n        return bfs(source_island, target_island, visited)\n                    \n        \n                    \n        \n        \n       \n            \n            \n            \n            \n            \n            \n            \n            \n            \n            \n            \n            \n", "import queue\n\n\ndef isOK(x, y, m, n):\n    return x >= 0 and y >= 0 and x < m and y < n\n\nclass Solution:\n    def shortestBridge(self, A: List[List[int]]) -> int:\n        m = len(A)\n        n = len(A[0])\n        \n        visited = [[False for _ in range(n)] for _ in range(m)]\n        \n        \n        def dfs(start):\n            island = []\n            x, y = start\n            stack = [start]\n            visited[x][y] = True\n            while len(stack) > 0:\n                x, y = stack.pop()\n                island.append((x, y))\n                xRows = [0, 0, -1, 1]\n                yCols = [-1, 1, 0, 0]\n                for i in range(4):\n                    new_x = x + xRows[i]\n                    new_y = y + yCols[i]\n                    if isOK(new_x, new_y, m, n) and not visited[new_x][new_y] and A[new_x][new_y] == 1:\n                        visited[new_x][new_y] = True\n                        stack.append((new_x, new_y))\n                        \n            return island\n                    \n        islands = []\n        for i in range(m):\n            for j in range(n):\n                if not visited[i][j] and A[i][j] == 1:\n                    island = dfs((i, j))\n                    islands.append(island)\n                    \n        island1 = islands[0]\n        island2 = islands[1]\n        \n        visited = [[False for _ in range(n)] for _ in range(m)]\n        def bfs(source_island, target_island, visited): \n            q = queue.Queue()\n            \n            for start in source_island:\n                x, y = start\n                q.put((x, y, 0))\n            cnt = 0\n            \n            while q.qsize() > 0:\n                start = q.get()\n                x, y, w = start\n                xRows = [0, 0, -1, 1]\n                yCols = [-1, 1, 0, 0]\n                for i in range(4):\n                    new_x = x + xRows[i]\n                    new_y = y + yCols[i]\n                    if isOK(new_x, new_y, m, n) and not visited[new_x][new_y]:\n                        if (new_x, new_y) in target_island:\n                            return w + 1\n                        \n                        visited[new_x][new_y] = True\n                        q.put((new_x, new_y, w + 1))\n                                \n                        \n        return bfs(island1, island2, visited) - 1\n        \n        \n       \n            \n            \n            \n            \n            \n            \n            \n            \n            \n            \n            \n            \n", "class Solution:\n    def shortestBridge(self, A: List[List[int]]) -> int:\n        \n        count=0\n        borders = collections.defaultdict(list)\n        seen = set()\n        x,y = [1,-1,0,0], [0,0,1,-1]\n        m,n = len(A), len(A[0])\n        for i in range(m):\n            for j in range(n):\n                if A[i][j] == 1 and (i,j) not in seen:\n                    frontier = [(i,j)]\n                    island = {(i,j)}\n                    while frontier:\n                        cur = frontier.pop()\n                        bord = False\n                        for k in range(len(x)):\n                            r,c = cur[0]+x[k], cur[1]+y[k]\n                            if 0<=r<m and 0<=c<n:\n                                if A[r][c]==1 and (r,c) not in island:\n                                    frontier.append((r,c))\n                                    island.add((r,c))\n                                elif A[r][c]==0: borders[count+1].append(cur)\n                    \n                    count+=1\n                    seen.update(island)\n                if count==2: break\n            if count==2: break\n        \n        \n        ans = float('inf')\n        borders\n        \n        for i,j in borders[1]:\n            for x,y in borders[2]:\n                ans = min(ans, abs(i-x)+abs(j-y)-1)\n      \n        return ans", "import queue\n\ndef isOK(x, y, m, n):\n    return x >= 0 and y >= 0 and x < m and y < n\n\n\nimport queue\nclass Solution:\n    def shortestBridge(self, A: List[List[int]]) -> int:\n        m = len(A)\n        n = len(A[0])\n        \n        visited = [[False for _ in range(n)] for _ in range(m)]\n        \n        \n        def dfs(start, island): \n            x, y = start\n            island.append(start)\n            visited[x][y] = True\n            xRows = [0, 0, -1, 1]\n            yCols = [-1, 1, 0, 0]\n            for i in range(4):\n                new_x = x + xRows[i]\n                new_y = y + yCols[i]\n                if isOK(new_x, new_y, m, n) and not visited[new_x][new_y] and A[new_x][new_y] == 1:\n                    dfs((new_x, new_y), island)\n                    \n        islands = []\n        for i in range(m):\n            for j in range(n):\n                if not visited[i][j] and A[i][j] == 1:\n                    island = []\n                    dfs((i, j), island)\n                    islands.append(island)\n                    \n        island1 = islands[0]\n        island2 = islands[1]\n        \n        visited = [[False for _ in range(n)] for _ in range(m)]\n        def bfs(source_island, target_island, visited): \n            q = queue.Queue()\n            \n            for start in source_island:\n                x, y = start\n                q.put((x, y, 0))\n            cnt = 0\n            \n            while q.qsize() > 0:\n                start = q.get()\n                x, y, w = start\n                xRows = [0, 0, -1, 1]\n                yCols = [-1, 1, 0, 0]\n                for i in range(4):\n                    new_x = x + xRows[i]\n                    new_y = y + yCols[i]\n                    if isOK(new_x, new_y, m, n) and not visited[new_x][new_y]:\n                        if (new_x, new_y) in target_island:\n                            return w + 1\n                        \n                        visited[new_x][new_y] = True\n                        q.put((new_x, new_y, w + 1))\n                                \n                        \n        return bfs(island1, island2, visited) - 1\n        \n        \n       \n            \n            \n            \n            \n            \n            \n            \n            \n            \n            \n            \n            \n", "def color(A, i, j, length):\n    A[i][j] = 2\n    if i > 0:\n        if A[i-1][j] == 1:\n            color(A, i-1, j, length)\n    if j > 0:\n        if A[i][j-1] == 1:\n            color(A, i, j-1, length)\n    if i < length - 1:\n        if A[i+1][j] == 1:\n            color(A, i+1, j, length)\n    if j < length -  1:\n        if A[i][j+1] == 1:\n            color(A, i, j+1, length)\n            \ndef expand(A, level, length):\n    for i in range(length):\n        for j in range(length):\n            if A[i][j] == level:\n                if i > 0:\n                    if A[i-1][j] == 1:\n                        return level\n                    elif A[i-1][j] == 0:\n                        A[i-1][j] = level + 1\n                if j > 0:\n                    if A[i][j-1] == 1:\n                        return level\n                    elif A[i][j-1] == 0:\n                        A[i][j-1] = level + 1\n                if i < length - 1:\n                    if A[i+1][j] == 1:\n                        return level\n                    elif A[i+1][j] == 0:\n                        A[i+1][j] = level + 1\n                if j < length - 1:\n                    if A[i][j+1] == 1:\n                        return level\n                    elif A[i][j+1] == 0:\n                        A[i][j+1] = level + 1\n    return 0\nclass Solution:\n    def shortestBridge(self, A):\n        length = len(A)\n        found = 0\n        for i in range(length): \n            for j in range(length):\n                if A[i][j]:\n                    found = 1\n                    color(A, i, j, length)\n                if found == 1:\n                    break\n            if found == 1:\n                break\n                \n        level = 2\n        found = 0\n        while found == 0:\n            found = expand(A, level, length)\n            level += 1\n        return found - 2", "class Solution:\n    def shortestBridge(self, A: List[List[int]]) -> int:\n        \n        islands = []\n        borders = collections.defaultdict(list)\n        seen = set()\n        x,y = [1,-1,0,0], [0,0,1,-1]\n        m,n = len(A), len(A[0])\n        for i in range(m):\n            for j in range(n):\n                if A[i][j] == 1 and (i,j) not in seen:\n                    frontier = [(i,j)]\n                    island = {(i,j)}\n                    while frontier:\n                        cur = frontier.pop()\n                        bord = False\n                        for k in range(len(x)):\n                            r,c = cur[0]+x[k], cur[1]+y[k]\n                            if 0<=r<m and 0<=c<n:\n                                if A[r][c]==1 and (r,c) not in island:\n                                    frontier.append((r,c))\n                                    island.add((r,c))\n                                elif A[r][c]==0:\n                                    borders[len(islands)+1].append(cur)\n                    \n                    islands.append(island)\n                    seen.update(island)\n                if len(islands)==2: break\n            if len(islands)==2: break\n        \n        \n        ans = float('inf')\n        \n        for i,j in borders[1]:\n            for x,y in borders[2]:\n                ans = min(ans, abs(i-x)+abs(j-y)-1)\n      \n        return ans", "class Solution:\n    def shortestBridge(self, A: List[List[int]]) -> int:\n        self.bfs = []\n        flag = 1\n        step = 0\n        for i in range(len(A)):\n            if flag:\n                for j in range(len(A[0])):\n                    if A[i][j] == 1:\n                        self.dfs(A,i,j)\n                        flag = 0 \n                        break\n        \n        while self.bfs:\n            size = len(self.bfs)\n            \n            while size:\n                i,j = self.bfs.pop(0)\n                for x, y in ((i - 1, j), (i + 1, j), (i, j - 1), (i, j + 1)):\n                    if 0 <= x < len(A) and 0 <= y < len(A[0]):\n                        if A[x][y] == 1:\n                            return step\n                        elif A[x][y] == 0:\n                            A[x][y] = -1\n                            self.bfs.append([x,y])\n                size -= 1\n            step += 1\n                \n        return step\n                    \n    def dfs(self,A,i,j):\n        if i >= len(A) or j >= len(A[0]) or i < 0 or j < 0 or A[i][j] != 1:\n            return \n        \n        A[i][j] = -1\n        self.bfs.append([i,j])\n        \n        self.dfs(A,i+1,j)\n        self.dfs(A,i-1,j)\n        self.dfs(A,i,j+1)\n        self.dfs(A,i,j-1)\n        \n", "class Solution:\n    def shortestBridge(self, A: List[List[int]]) -> int:\n        \n        row_shifts = [-1, 0, 1, 0]\n        col_shifts = [0, 1, 0, -1]\n            \n        def bfs_mark_first(row, col, mark):\n            nonlocal A, row_shifts, col_shifts\n            queue = [(row, col)]\n            edges = []\n            while len(queue) > 0:\n                curr_row, curr_col = queue.pop(0)\n                if A[curr_row][curr_col] == mark:\n                    continue\n                A[curr_row][curr_col] = mark\n                add_to_edges = False\n                for row_shift, col_shift in zip(row_shifts, col_shifts):\n                    new_row = curr_row + row_shift\n                    new_col = curr_col + col_shift\n                    if 0 <= new_row < len(A) and 0 <= new_col < len(A[0]):\n                        if A[new_row][new_col] == 1:\n                            queue.append((new_row, new_col))\n                        else:\n                            add_to_edges = True\n                if add_to_edges:\n                    edges.append((curr_row, curr_col))\n            return edges\n        \n        terminate = False\n        for row in range(len(A)):\n            for col in range(len(A[0])):\n                if A[row][col] == 1:\n                    edges = bfs_mark_first(row, col, -1)\n                    terminate = True\n                    break\n            if terminate:\n                break\n                    \n        queue = edges\n        # print(edges)\n        while len(queue) > 0:\n            curr_row, curr_col = queue.pop(0)\n            for row_shift, col_shift in zip(row_shifts, col_shifts):\n                new_row = curr_row + row_shift\n                new_col = curr_col + col_shift\n                if 0 <= new_row < len(A) and 0 <= new_col < len(A[0]):\n                    if A[new_row][new_col] == 0:\n                        A[new_row][new_col] = A[curr_row][curr_col] - 1\n                        queue.append((new_row, new_col))\n                    if A[new_row][new_col] == 1:\n                        return abs(A[curr_row][curr_col]) - 1\n        \n        return -1", "class Solution:\n    def shortestBridge(self, A: List[List[int]]) -> int:\n        \n        R = len(A)\n        C = len(A[0])\n        \n        chk = [[0] * C for _ in range(R)]\n        q = collections.deque()\n        move = [[1, 0], [-1, 0], [0, 1], [0, -1]]\n        flag = False\n        \n        #find the first land\n        for i in range(R):\n            if flag: break\n            for j in range(C):\n                if A[i][j] == 1:\n                    self.dfs(i, j, A, chk, q)\n                    flag = True\n                    break\n        \n        res = 0\n        \n        while q:\n            size = len(q)\n            for _ in range(size):\n                i, j = q.popleft()\n            \n                for m in move:\n                    x, y = i + m[0], j + m[1]\n                    if 0 <= x < R and 0 <= y < C:\n                        chk[x][y] = 1\n                        if A[x][y] == 1:\n                            return res\n                        elif A[x][y] == 0:\n                            A[x][y] = 2\n                            q.append((x, y))\n                        else:\n                            continue\n            res += 1\n            \n        return res\n        \n    def dfs(self, i, j, A, chk, q):\n        # print(i, j)\n        if chk[i][j] == 1:\n            return\n        \n        chk[i][j] = 1\n        \n        R = len(A)\n        C = len(A[0])\n        move = [[1, 0], [0, 1], [-1, 0], [0, -1]]\n        \n        if A[i][j] == 1:\n            q.append((i, j))\n            A[i][j] = 2\n            for m in move:\n                x = i + m[0]\n                y = j + m[1]\n                \n                if 0 <= x < R and 0 <= y < C:\n                    self.dfs(x, y, A, chk, q)\n", "def color(A, i, j):\n    A[i][j] = 2\n    if i > 0:\n        if A[i-1][j] == 1:\n            color(A, i-1, j)\n    if j > 0:\n        if A[i][j-1] == 1:\n            color(A, i, j-1)\n    if i < len(A) - 1:\n        if A[i+1][j] == 1:\n            color(A, i+1, j)\n    if j < len(A) -  1:\n        if A[i][j+1] == 1:\n            color(A, i, j+1)\n            \ndef expand(A, level):\n    for i in range(len(A)):\n        for j in range(len(A)):\n            if A[i][j] == level:\n                if i > 0:\n                    if A[i-1][j] == 1:\n                        return level\n                    elif A[i-1][j] == 0:\n                        A[i-1][j] = level + 1\n                if j > 0:\n                    if A[i][j-1] == 1:\n                        return level\n                    elif A[i][j-1] == 0:\n                        A[i][j-1] = level + 1\n                if i < len(A) - 1:\n                    if A[i+1][j] == 1:\n                        return level\n                    elif A[i+1][j] == 0:\n                        A[i+1][j] = level + 1\n                if j < len(A) - 1:\n                    if A[i][j+1] == 1:\n                        return level\n                    elif A[i][j+1] == 0:\n                        A[i][j+1] = level + 1\n    return 0\nclass Solution:\n    def shortestBridge(self, A):\n        length = len(A)\n        found = 0\n        for i in range(len(A)): \n            for j in range(len(A)):\n                if A[i][j]:\n                    found = 1\n                    color(A, i, j)\n                if found == 1:\n                    break\n            if found == 1:\n                break\n                \n        level = 2\n        found = 0\n        while found == 0:\n            found = expand(A, level)\n            level += 1\n        return found - 2", "class Solution:\n    def dfs(self, A, i, j):\n        if 0 > i or i >= self.m or 0 > j or j >= self.n or A[i][j] == 0 or A[i][j] == 2:\n            return\n\n        A[i][j] = 2\n        self.que.append([i, j])\n        for i0, j0 in self.offset:\n            ii, jj = i + i0, j + j0\n            self.dfs(A, ii, jj)\n\n    def shortestBridge(self, A: List[List[int]]) -> int:\n    #def shortestBridge(self, A) -> int:\n        self.offset = [[-1, 0], [1, 0], [0, -1], [0, 1]]\n        self.m, self.n = len(A), len(A[0])\n        self.que = []\n        ok = 0\n        for i in range(self.m):\n            for j in range(self.n):\n                if A[i][j]:\n                    self.dfs(A, i, j)\n                    ok = 1\n                    break\n            if ok:\n                break\n        rt = 0\n        while len(self.que) > 0:\n            qlen = len(self.que)\n            for k in range(qlen):\n                i,j=self.que.pop(0)\n                for i0, j0 in self.offset:\n                    ii, jj = i + i0, j + j0\n                    if 0 <= ii<self.m and 0<=jj<self.n:\n                        if A[ii][jj] == 0:\n                            A[ii][jj]=3\n                            self.que.append([ii, jj])\n                        elif A[ii][jj] == 1:\n                            return rt#break\n            rt +=1\n        return rt\n\n\n", "class Solution:\n    def shortestBridge(self, A: List[List[int]]) -> int:\n        # Find the first element of the first island\n        x, y = self.get_first(A)\n        \n        # Do DFS to find all elements in the first island\n        q = collections.deque()\n        self.dfs(A, x, y, q)\n\n        # Expand the first island, layer by layer until touch the 2nd island\n        step = 0\n        while q:\n            new_q = collections.deque()\n            size = len(q)\n            for i in range(size):\n                x, y = q.popleft()\n                for d in [[-1, 0], [1, 0], [0, -1], [0, 1]]:\n                    nx, ny = x + d[0], y + d[1]\n                    if 0 <= nx < len(A) and 0 <= ny < len(A[0]):\n                        if A[nx][ny] == 1:\n                            return step\n                        elif A[nx][ny] == 0:\n                            new_q.append([nx, ny])\n                            A[nx][ny] = -1\n            step += 1\n            q = new_q\n                \n        return -1\n        \n    def get_first(self, A):\n        for i in range(len(A)):\n            for j in range(len(A[0])):\n                if A[i][j] == 1:\n                    return i, j\n                \n    def dfs(self, A, x, y, q):\n        A[x][y] = -1\n        q.append([x, y])\n        for d in [[-1, 0], [1, 0], [0, -1], [0, 1]]:\n            nx, ny = x + d[0], y + d[1]\n            if 0 <= nx < len(A) and 0 <= ny < len(A[0]) and A[nx][ny] == 1:\n                self.dfs(A, nx, ny, q)\n        \n", "class Solution:\n    def shortestBridge(self, A: List[List[int]]) -> int:\n        originBridge = []\n        def markBridge (cord):\n            x = cord[1]\n            y = cord[0]\n            A[y][x] = 2\n            originBridge.append(cord)\n            \n            if x < len(A[y])-1:\n                if A[y][x+1] == 1:\n                    markBridge((y,x+1))\n            if x > 0:\n                if A[y][x-1] == 1:\n                    markBridge((y,x-1))\n            if y < len(A)-1:\n                if A[y+1][x] == 1:\n                    markBridge((y+1,x))\n            if y > 0:\n                if A[y-1][x] == 1:\n                    markBridge((y-1,x))\n        for y in range(len(A)):\n            for x in range(len(A[y])):\n                if A[y][x] == 1:\n                    markBridge((y,x))\n                    break\n            if len(originBridge) > 0:\n                break\n        moves = 0\n        bridgeList = set(originBridge)\n        while len(originBridge) > 0:\n            newMoves = []\n            for b in originBridge:\n                y = b[0]\n                x = b[1]\n                if x > 0:\n                    if (y,x-1) not in bridgeList:\n                        if A[y][x-1] == 1:\n                            return moves\n                        else:\n                            bridgeList.add((y,x-1))\n                            newMoves.append((y,x-1))\n                if x < len(A[y])-1:\n                    if (y,x+1) not in bridgeList:\n                        if A[y][x+1] == 1:\n                            return moves\n                        else:\n                            bridgeList.add((y,x+1))\n                            newMoves.append((y,x+1))\n                if y > 0:\n                    if (y-1,x) not in bridgeList:\n                        if A[y-1][x] == 1:\n                            return moves\n                        else:\n                            bridgeList.add((y-1,x))\n                            newMoves.append((y-1,x))\n                if y < len(A)-1:\n                    if (y+1,x) not in bridgeList:\n                        if A[y+1][x] == 1:\n                            return moves\n                        else:\n                            bridgeList.add((y+1,x))\n                            newMoves.append((y+1,x))\n            originBridge = newMoves\n            moves += 1\n        return moves\n                        \n        \n            \n                \n", "from collections import deque\ndirections = [[0, 1], [0, -1], [1, 0], [-1, 0]]\n# \u5148dfs\uff0c \u518dbfs\u3002 \nclass Solution:\n    def shortestBridge(self, A: List[List[int]]) -> int:\n        n = len(A)\n        m = len(A[0])\n        visited = [[False] * m for _ in range(n)]\n        q = deque([])\n        found = False\n        for i in range(n):\n            if found:\n                break\n            for j in range(m):\n                if A[i][j] == 1:\n                    self.dfs(i, j, A, q, visited)\n                    found = True\n                    #\u8fd9\u91cc\u8981break\u3002 \u5982\u679c\u4e0dbreak\u4f1a\u7ee7\u7eed\u5f80\u4e0b\u627e\uff0c\u90a3\u4e48\u4e24\u4e2a\u5c9b\u5c31\u8fde\u6210\u4e00\u4e2a\u4e86\u3002 \n                    break\n        \n        step = 0\n        while q:\n            for _ in range(len(q)):\n                x, y = q.popleft()\n                for dx, dy in directions:\n                    nx, ny = x + dx, y+dy\n                    if not self.isValid(nx, ny, A) or visited[nx][ny]:\n                        continue\n                    \n                    if A[nx][ny] == 1:\n                        return step\n                    q.append((nx, ny))\n                    visited[nx][ny] = True\n                \n            step += 1\n        return -1\n        \n    def dfs(self,i, j, A, q, visited):\n        if not self.isValid(i, j, A) or visited[i][j] or A[i][j] == 0:\n            return\n        visited[i][j] = True\n        q.append((i, j))\n        for dx, dy in directions:\n            nx, ny = i+dx, j+dy\n            # if not self.isValid(nx, ny, A) or visited[nx][ny]:\n            #     continue\n            self.dfs(nx, ny, A, q, visited)\n        \n    def isValid(self, i, j, A):\n        return i >= 0 and i < len(A) and j >= 0 and j < len(A[0])", "from collections import deque\ndirections = [[0, 1], [0, -1], [1, 0], [-1, 0]]\n# \u5148dfs\uff0c \u518dbfs\u3002 \nclass Solution:\n    def shortestBridge(self, A: List[List[int]]) -> int:\n        n = len(A)\n        m = len(A[0])\n        visited = [[False] * m for _ in range(n)]\n        q = deque([])\n        found = False\n        for i in range(n):\n            if found:\n                break\n            for j in range(m):\n                if A[i][j] == 1:\n                    self.dfs(i, j, A, q, visited)\n                    found = True\n                    #\u8fd9\u91cc\u8981break\u3002 \u5982\u679c\u4e0dbreak\u4f1a\u7ee7\u7eed\u5f80\u4e0b\u627e\uff0c\u90a3\u4e48\u4e24\u4e2a\u5c9b\u5c31\u8fde\u6210\u4e00\u4e2a\u4e86\u3002 \n                    break\n        \n        step = 0\n        while q:\n            size = len(q)\n            while size > 0:\n                x, y = q.popleft()\n                for dx, dy in directions:\n                    nx, ny = x + dx, y+dy\n                    if not self.isValid(nx, ny, A) or visited[nx][ny]:\n                        continue\n                    \n                    if A[nx][ny] == 1:\n                        return step\n                    q.append((nx, ny))\n                    visited[nx][ny] = True\n                size -= 1\n            step += 1\n        return -1\n        \n    def dfs(self,i, j, A, q, visited):\n        if not self.isValid(i, j, A) or visited[i][j] or A[i][j] == 0:\n            return\n        visited[i][j] = True\n        q.append((i, j))\n        for dx, dy in directions:\n            nx, ny = i+dx, j+dy\n            # if not self.isValid(nx, ny, A) or visited[nx][ny]:\n            #     continue\n            self.dfs(nx, ny, A, q, visited)\n        \n    def isValid(self, i, j, A):\n        return i >= 0 and i < len(A) and j >= 0 and j < len(A[0])", "\\\"\\\"\\\"\n\u53ea\u67092\u4e2a\u5c9b\n\u5148dfs - find 1st island's boundary nodes\uff0c label 1st island with 2\n\u518dbfs - expand 1st island's boundary, and mark unvisited 0 as prevstep+1, until finding 1\ntimeO(m*n) spaceO(m*n)\n\\\"\\\"\\\"\nclass Solution:\n    def shortestBridge(self, A: List[List[int]]) -> int:\n        self.A = A\n        boundaries = self.dfs()\n        \n        # bfs expand 1st island boundaries\n        q = collections.deque([(i,j,self.A[i][j]) for i,j in boundaries]) # coordinate and step(+2)\n        while q:\n            i,j,step = q.popleft()\n            for x,y in ((i - 1, j), (i + 1, j), (i, j - 1), (i, j + 1)):\n                if 0<=x<len(self.A) and 0<=y<len(self.A[0]):\n                    if self.A[x][y]==1: \n                        return step-2\n                    elif self.A[x][y]==0:\n                        self.A[x][y]=step+1\n                        q.append((x,y,step+1))  \n        return -1\n    \n    def getFist1(self): # find 1st island's starting 1\n        for i in range(len(self.A)):\n            for j in range(len(self.A[0])):\n                if self.A[i][j] == 1:\n                    return (i,j)\n        return (-1,-1)\n    \n    def dfs(self): # find 1st island's boundaries; label visited to 2\n        boundaries = set()\n        stack = [self.getFist1()]\n        while stack:\n            i,j = stack.pop()\n            self.A[i][j] = 2 # mark visited as 2\n            for x,y in ((i - 1, j), (i + 1, j), (i, j - 1), (i, j + 1)):\n                if 0<=x<len(self.A) and 0<=y<len(self.A[0]):\n                    if self.A[x][y]==0: # i,j is boundary\n                        boundaries.add((i,j))\n                    elif self.A[x][y]==1: # i,j is in 1st island\n                        stack.append((x,y))\n        return boundaries", "def color(A, i, j):\n    if A[i][j] in (0,2):\n        return\n    A[i][j] = 2\n    if i > 0:\n        if A[i-1][j] == 1:\n            color(A, i-1, j)\n    if j > 0:\n        if A[i][j-1] == 1:\n            color(A, i, j-1)\n    if i < len(A) - 1:\n        if A[i+1][j] == 1:\n            color(A, i+1, j)\n    if j < len(A) - 1:\n        if A[i][j+1] == 1:\n            color(A, i, j+1)\n            \ndef expand(A):\n    for l in range(2, len(A)**2):\n        for i in range(len(A)):\n            for j in range(len(A)):\n                if A[i][j] == l:\n                    if i > 0:\n                        if A[i-1][j] == 0:\n                            A[i-1][j] = l + 1\n                        if A[i-1][j] == 1:\n                            return l - 2\n                    if j > 0:\n                        if A[i][j-1] == 0:\n                            A[i][j-1] = l + 1\n                        if A[i][j-1] == 1:\n                            return l -2\n                    if i < len(A) - 1:\n                        if A[i+1][j] == 0:\n                            A[i+1][j] = l + 1\n                        if A[i+1][j] == 1:\n                            return l - 2\n                    if j < len(A) -1:\n                        if A[i][j+1] == 0:\n                            A[i][j+1] = l + 1\n                        if A[i][j+1] == 1:\n                            return l -2\n                        \nclass Solution:\n    def shortestBridge(self, A):\n        length = len(A)\n        found = 0\n        for i in range(length):\n            for j in range(length):\n                if A[i][j]:\n                    color(A, i, j)\n                    found = 1\n                    break\n            if found == 1:\n                break\n            \n        expansion = expand(A)\n\n        return expansion", "from collections import deque\nDirections = [[-1, 0], [1, 0], [0, -1], [0, 1]]\nclass Solution:\n    def shortestBridge(self, A: List[List[int]]) -> int:\n        queue = deque()\n        found = False\n        for i in range(len(A)):\n            if found:\n                break\n            for j in range(len(A[0])):\n                \n                if A[i][j] == 1:\n                    \n                    visited = set()\n                    \n                    self.dfs(i, j, queue, A, visited)\n                    found = True\n                    break\n        print(queue)\n        \n        step = 0\n        while queue:\n            for _ in range(len(queue)):\n                cur_x, cur_y = queue.popleft()\n                for dx, dy in Directions:\n                    nx, ny = cur_x+dx, cur_y + dy\n                    if not self.isValid(nx, ny, A) or (nx, ny) in visited:\n                        continue\n                    if A[nx][ny] == 1:\n                        return step\n                    queue.append((nx, ny))\n                    visited.add((nx, ny))\n            step += 1\n        return -1\n        \n                \n                \n        \n    \n    def dfs(self, i, j, queue, A, visited):\n        if A[i][j] == 0:\n            return\n        queue.append((i, j))\n        visited.add((i, j))\n        for dx, dy in Directions:\n            nx, ny = i + dx, j + dy\n            if not self.isValid(nx, ny, A) or (nx, ny) in visited:\n                continue\n            self.dfs(nx, ny, queue, A, visited)\n    \n    \n    def isValid(self, x, y, A):\n        return x >= 0 and x < len(A) and y >= 0 and y < len(A[0])\n    \n        \n", "class Solution(object):\n    def shortestBridge(self, A):\n        R, C = len(A), len(A[0])\n\n        def neighbors(r, c):\n            for nr, nc in ((r-1,c),(r,c-1),(r+1,c),(r,c+1)):\n                if 0 <= nr < R and 0 <= nc < C:\n                    yield nr, nc\n\n        def get_components():\n            done = set()\n            components = []\n            for r, row in enumerate(A):\n                for c, val in enumerate(row):\n                    if val and (r, c) not in done:\n                        # Start dfs\n                        stack = [(r, c)]\n                        seen = {(r, c)}\n                        while stack:\n                            node = stack.pop()\n                            for nei in neighbors(*node):\n                                if A[nei[0]][nei[1]] and nei not in seen:\n                                    stack.append(nei)\n                                    seen.add(nei)\n                        done |= seen\n                        components.append(seen)\n            return components\n\n        source, target = get_components()\n\n        queue = collections.deque([(node, 0) for node in source])\n        done = set(source)\n        while queue:\n            node, d = queue.popleft()\n            if node in target: return d-1\n            for nei in neighbors(*node):\n                if nei not in done:\n                    queue.append((nei, d+1))\n                    done.add(nei)", "from random import randint\nfrom collections import deque, Counter, defaultdict\nfrom heapq import heappush, heappop, heapify\nfrom scipy.special import comb, perm\nfrom bisect import bisect, bisect_left, bisect_right\nclass Solution:\n    def shortestBridge(self, A):\n        que, row, col, visited = deque(), len(A), len(A[0]), set()\n        def dfs(i, j):\n            if i < 0 or i > row - 1 or j < 0 or j > col - 1 or (i, j) in visited:\n                return\n            visited.add((i, j))\n            if A[i][j] == 0:\n                que.append((i, j))\n                return\n            for ni, nj in [[i + 1, j], [i - 1, j], [i, j + 1], [i, j - 1]]:\n                dfs(ni, nj)\n\n        found = False\n        for i in range(row):\n            for j in range(col):\n                if A[i][j] == 1:\n                    dfs(i, j)\n                    found = True\n                    break\n            if found:\n                break\n\n        cnt = 0\n        while que:\n            n = len(que)\n            for _ in range(n):\n                i, j = que.popleft()\n                if A[i][j] == 1:\n                    return cnt\n                for ni, nj in [[i + 1, j], [i - 1, j], [i, j + 1], [i, j - 1]]:\n                    if 0 <= ni < row and 0 <= nj < col and (ni, nj) not in visited:\n                        que.append((ni, nj))\n                        visited.add((ni, nj))\n            cnt += 1\n", "\\\"\\\"\\\"\n    1. Problem Summary / Clarifications / TDD:\n\n\\\"\\\"\\\"\n\nclass Solution:\n    def __init__(self):\n        self.moves = [(0,-1),(-1,0),(0,+1),(+1,0)]\n        \n    def shortestBridge(self, A: List[List[int]]) -> int:\n                \n        # Find the source islands\n        r, c = 0, 0\n        while r < len(A) and not A[r][c]:\n            while c < len(A[0]) and not A[r][c]:\n                c += 1\n            c = 0 if c == len(A[0]) else c\n            r = r if A[r][c] else r + 1\n            \n        source = set()\n        self.explore_island_dfs(A, r, c, source)\n        \n        # 2. Find min distance between island 1 and 2: BFS\n        visited = source\n        curr_level = list(source)\n        \n        distance = 0\n        while curr_level:\n            \n            next_level = []\n            for (r, c) in curr_level:\n                \n                for mr, mc in self.moves:\n                    ar, ac = r + mr, c + mc\n                    \n                    if not self.valid_position(A, ar, ac):\n                        continue \n\n                    elif A[ar][ac] and (ar, ac) not in source:\n                        return distance\n                    \n                    elif (ar, ac) not in visited and A[ar][ac] == 0:\n                        next_level.append((ar, ac))\n                        visited.add((ar, ac))\n            \n            distance += 1\n            curr_level = next_level\n                    \n        return -1\n        \n    def explore_island_dfs(self, A: List[List[int]], r, c, visited):\n                \n        visited.add((r, c))\n        for mr, mc in self.moves:\n            ar, ac = r + mr, c + mc\n            if self.valid_position(A, ar, ac) and (ar, ac) not in visited and A[ar][ac]:\n                self.explore_island_dfs(A, ar, ac, visited)\n    \n    def valid_position(self, A, r, c):\n        \n        if r in (-1, len(A)) or c in (-1, len(A[0])):\n            return False\n        \n        else:\n            return True\n        \n        \n                    \n                \n        ", "from collections import deque\nDirections = [[-1, 0], [1, 0], [0, -1], [0, 1]]\nclass Solution:\n    def shortestBridge(self, A: List[List[int]]) -> int:\n        queue = deque()\n        found = False\n        for i in range(len(A)):\n            if found:\n                break\n            for j in range(len(A[0])):\n                \n                if A[i][j] == 1:\n                    \n                    visited = set()\n                    \n                    self.dfs(i, j, queue, A, visited)\n                    found = True\n                    break\n        print(queue)\n        \n        step = 0\n        while queue:\n            for _ in range(len(queue)):\n                cur_x, cur_y = queue.popleft()\n                for dx, dy in Directions:\n                    nx, ny = cur_x+dx, cur_y + dy\n                    if not self.isValid(nx, ny, A) or (nx, ny) in visited:\n                        continue\n                    if A[nx][ny] == 1:\n                        return step\n                    queue.append((nx, ny))\n                    visited.add((nx, ny))\n            step += 1\n        return -1\n        \n                \n                \n        \n    \n    def dfs(self, i, j, queue, A, visited):\n        if not self.isValid(i, j, A) or (i, j) in visited or A[i][j] == 0:\n            return\n        queue.append((i, j))\n        visited.add((i, j))\n        for dx, dy in Directions:\n            nx, ny = i + dx, j + dy\n            \n            self.dfs(nx, ny, queue, A, visited)\n    \n    \n    def isValid(self, x, y, A):\n        return x >= 0 and x < len(A) and y >= 0 and y < len(A[0])\n    \n        \n", "class Solution:\n    def shortestBridge(self, A: List[List[int]]) -> int:\n        # make a function that will map out one for the islands\n        # make a second function that will calculate the paths to the next island\n        # make a third function that will traverse the second island and pick the min path\n        \n        # map out one of the islands\n#         self.mapIsland(A)\n#         print(A)\n#         # explore the 0s\n#         for i in range(0, len(A)):\n#             for j in range(0, len(A[i])):\n#                 if A[i][j] == 'a':\n#                     self.calcPath(i, j, A)\n#         print(A)\n#     def mapIsland(self, a):\n#         #find the first 1 and convert that island\n#         for i in range(0, len(a)):\n#             for j in range(0, len(a[i])):\n#                 if a[i][j] == 1:\n#                     return self.explore(i, j, a)\n                \n#     def explore(self, row, col, a):\n#         #convert current node to 'a'\n#         a[row][col] = 'a'\n#         #explore up\n#         if row > 0:\n#             if a[row-1][col] == 1:\n#                 self.explore(row-1, col, a)\n#         #explore left\n#         if col > 0:\n#             if a[row][col-1] == 1:\n#                 self.explore(row, col-1, a)\n#         #explore right\n#         if col < len(a[row])-1:\n#             if a[row][col+1] == 1:\n#                 self.explore(row, col +1, a)\n#         #explore down\n#         if row < len(a)-1:\n#             if a[row+1][col] == 1:\n#                 self.explore(row +1, col, a)\n    \n#     def calcPath(self, row, col, a):\n#         #take the current a and check if there are any 0s to inverement\n#         # if we are at a non 0 look at the neighbors and if they are 0, increment otherwise leave as is?\n#         new = 0\n#         if a[row][col] == 'a':\n#             new = 2\n#         else:\n#             new = a[row][col]+1\n#         #explore up\n#         if row > 0:\n#             if a[row-1][col] != 1 and a[row-1][col] != 'a' and (a[row][col] == 'a' or a[row][col] > a[row-1][col]):\n#                 print(a[row-1][col])\n#                 print(new)\n#                 a[row-1][col] = min(new, a[row-1][col]) if a[row-1][col] != 0 else new\n#                 print(a[row-1][col])\n#                 print(a)\n#                 self.calcPath(row-1, col, a)\n#         #explore left\n#         if col > 0:\n#             if a[row][col-1] != 1 and a[row][col-1] != 'a' and (a[row][col] == 'a' or a[row][col] > a[row][col-1]):\n#                 print(a[row][col-1])\n#                 print(new)\n#                 a[row][col-1] = min(new, a[row][col-1]) if a[row][col-1] != 0 else new\n#                 print(a[row][col-1])\n#                 print(a)\n                \n#                 self.calcPath(row, col-1, a)\n#         #explore right\n#         if col < len(a[row])-1:\n#             if a[row][col+1] != 1 and a[row][col+1] != 'a' and (a[row][col] == 'a' or a[row][col] > a[row][col+1]):\n#                 print(a[row][col+1])\n#                 print(new)\n#                 a[row][col+1] = min(new, a[row][col+1]) if a[row][col+1] != 0 else new\n#                 print(a[row][col+1])\n#                 print(a)\n#                 self.calcPath(row, col +1, a)\n#         #explore down\n#         if row < len(a)-1:\n#             if a[row+1][col] != 1 and a[row+1][col] != 'a' and (a[row][col] == 'a' or a[row][col] > a[row+1][col]):\n#                 print(a[row+1][col])\n#                 print(new)\n#                 a[row+1][col] = min(new, a[row+1][col]) if a[row+1][col] != 0 else new\n#                 print(a[row+1][col])\n#                 print(a)\n#                 self.calcPath(row +1, col, a)\n                \n\n        R, C = len(A), len(A[0])\n\n        def neighbors(r, c):\n            for nr, nc in ((r-1,c),(r,c-1),(r+1,c),(r,c+1)):\n                if 0 <= nr < R and 0 <= nc < C:\n                    yield nr, nc\n\n        def get_components():\n            done = set()\n            components = []\n            for r, row in enumerate(A):\n                for c, val in enumerate(row):\n                    if val and (r, c) not in done:\n                        # Start dfs\n                        stack = [(r, c)]\n                        seen = {(r, c)}\n                        while stack:\n                            node = stack.pop()\n                            for nei in neighbors(*node):\n                                if A[nei[0]][nei[1]] and nei not in seen:\n                                    stack.append(nei)\n                                    seen.add(nei)\n                        done |= seen\n                        components.append(seen)\n            return components\n\n        source, target = get_components()\n        # print source, target\n        queue = collections.deque([(node, 0) for node in source])\n        done = set(source)\n        while queue:\n            node, d = queue.popleft()\n            if node in target: return d-1\n            for nei in neighbors(*node):\n                if nei not in done:\n                    queue.append((nei, d+1))\n                    done.add(nei)\n", "class Solution:\n    def shortestBridge(self, A: List[List[int]]) -> int:\n        rows, cols = len(A), len(A[0])\n        starting_points = set()\n        \n        def traverse_island(r, c):\n            A[r][c] = -1\n            \n            for ar, ac in [(r + 1, c), (r, c + 1), (r - 1, c), (r, c - 1)]:\n                if 0 <= ar < rows and 0 <= ac < cols:\n                    if A[ar][ac] == 0:\n                        starting_points.add((ar, ac, 0))\n                    elif A[ar][ac] == 1:\n                        traverse_island(ar, ac)\n                        \n        for r in range(rows):\n            for c in range(cols):\n                if A[r][c] == 1:\n                    traverse_island(r, c)\n                    break\n            else:\n                continue\n                \n            break\n        \n        q = deque(starting_points)\n        \n        while q:\n            r, c, dist = q.popleft()\n            \n            for ar, ac in [(r + 1, c), (r, c + 1), (r - 1, c), (r, c - 1)]:\n                if 0 <= ar < rows and 0 <= ac < cols and A[ar][ac] != -1:\n                    if A[ar][ac] == 1: \n                        return dist + 1\n                    \n                    A[ar][ac] = -1\n                    q.append((ar, ac, dist + 1))\n            \n        return 0", "class Solution:\n    def shortestBridge(self, A: List[List[int]]) -> int:\n        R, C = len(A), len(A[0])\n        \n        def neighbors(r, c):\n            for cr, cc in [(r+1,c),(r,c-1), (r-1,c), (r,c+1)]:\n                if 0 <=cr<R and 0<=cc<C:\n                    yield cr, cc\n        \n        def get_connections():\n            connections = []\n            done = set()\n            for r, row in enumerate(A):\n                for c, val in enumerate(row):\n                    if val and (r,c) not in done:\n                        print(\\\"r : \\\", r, \\\"c : \\\", c)\n                        #Start DFS\n                        stack = [(r,c)]\n                        seen = {(r,c)}\n                        while stack:\n                            node = stack.pop()\n                            for nei in neighbors(*node):\n                                if A[nei[0]][nei[1]] and nei not in seen:\n                                    stack.append(nei)\n                                    seen.add(nei)                           \n                        done |= seen                 \n                        connections.append(seen)\n                                             \n            return connections\n                                             \n            \n        source, target = get_connections()\n        done = set(source)                      \n        queue = collections.deque([(node,0) for node in source])\n        while queue:\n            #BFS\n            node, d = queue.popleft()\n            if node in target:\n                return d-1\n            for nei in neighbors(*node):\n                if nei not in done:\n                    queue.append((nei, d+1))\n                    done.add(nei)\n                    \n                                             \n                                             ", "'''\n\n\n\n'''\n# need a queue for bfs\nfrom collections import deque\n\nclass Solution:\n    def shortestBridge(self, A: List[List[int]]) -> int:\n        \n        \n        # figure rows and cols\n        rows = len (A)\n        cols = len (A[0]) if rows else 0\n        \n        if not rows or not cols:\n            return -1\n        \n        self.queue = deque ()\n        self.visited = set()\n        \n        # perform a dfs to flip all 1's, flood fill\n        def floodFill (A, row, col, rows, cols):\n            \n            if not (0 <= row < rows and 0 <= col < cols):\n                return\n            \n            if not A[row][col] or (row, col) in self.visited:\n                return\n            \n            A[row][col] = 2\n            \n            self.queue.append ((row, col, 0))\n            self.visited.add ((row, col))\n            \n            floodFill (A, row + 1, col, rows, cols)\n            floodFill (A, row - 1, col, rows, cols)\n            floodFill (A, row, col + 1, rows, cols)\n            floodFill (A, row, col - 1, rows, cols)\n               \n        # flood fill\n        flood_fill = False\n             \n        # iterate over rows and cols\n        for row in range (rows):\n            for col in range (cols):\n                if A[row][col] == 1:\n                    flood_fill = True\n                    floodFill (A, row, col, rows, cols)                \n                    break\n            if flood_fill:\n                break\n                    \n        # possible directions for move\n        directions = [(0, 1), (1, 0), (-1, 0), (0, -1)]\n        \n        \n        # use a visited set        \n        \n        #print (self.queue)\n        # iterate until queue cease to persists\n        while len (self.queue):\n            \n            # pop the first node\n            top_r, top_c, dist = self.queue.popleft()\n            \n            for d_r, d_c in directions:\n                n_r = top_r + d_r\n                n_c = top_c + d_c\n                \n                if 0 <= n_r < rows and 0 <= n_c < cols and (n_r, n_c) not in self.visited:\n                    if A[n_r][n_c] == 0:\n                        self.queue.append ((n_r, n_c, dist + 1))\n                        self.visited.add((n_r, n_c))\n                    elif A[n_r][n_c] == 1:\n                        return dist\n                    \n                    \n        return -1 \n    \n            \n                    \n\n        \n        \n                    \n                    \n", "class Solution(object):\n    def shortestBridge(self, A):\n        R, C = len(A), len(A[0])\n\n        def neighbors(r, c):\n            for nr, nc in ((r-1,c),(r,c-1),(r+1,c),(r,c+1)):\n                if 0 <= nr < R and 0 <= nc < C:\n                    yield nr, nc\n\n        def get_components():\n            done = set()\n            components = []\n            for r, row in enumerate(A):\n                for c, val in enumerate(row):\n                    if val and (r, c) not in done:\n                        # Start dfs\n                        stack = [(r, c)]\n                        seen = {(r, c)}\n                        while stack:\n                            node = stack.pop()\n                            for nei in neighbors(*node):\n                                if A[nei[0]][nei[1]] and nei not in seen:\n                                    stack.append(nei)\n                                    seen.add(nei)\n                        done |= seen\n                        components.append(seen)\n            return components\n\n        source, target = get_components()\n        # print source, target\n        queue = collections.deque([(node, 0) for node in source])\n        done = set(source)\n        while queue:\n            node, d = queue.popleft()\n            if node in target: return d-1\n            for nei in neighbors(*node):\n                if nei not in done:\n                    queue.append((nei, d+1))\n                    done.add(nei)", "class Solution:\n    def shortestBridge(self, A: List[List[int]]) -> int:\n        R, C = len(A), len(A[0])\n        \n        def neighbors(r,c):\n            for nr, nc in ((r-1,c),(r,c-1),(r+1,c),(r,c+1)):\n                if 0 <= nr < R and 0 <= nc < C:\n                    yield nr,nc\n        \n        def get_components():\n            done = set()\n            components = []\n            for r, row in enumerate(A):\n                for c, val in enumerate(row):\n                    if val and (r,c) not in done:\n                        # Start DFS\n                        stack = [(r,c)]\n                        seen = {(r,c)}\n                        while stack:\n                            node = stack.pop()\n                            for dr, dc in neighbors(*node):\n                                if A[dr][dc] and (dr,dc) not in seen:\n                                    stack.append((dr,dc))\n                                    seen.add((dr,dc))\n                        done |= seen\n                        components.append(seen)\n            return components\n        \n        source, target = get_components()\n        print((source, target))\n        queue = collections.deque([(node, 0) for node in source])\n        done = set(source)\n        while queue:\n            node, d = queue.popleft()\n            if node in target:\n                return d-1\n            for nei in neighbors(*node):\n                if nei not in done:\n                    queue.append((nei, d+1))\n                    done.add(nei)\n", "class Solution:\n    def shortestBridge(self, A: List[List[int]]) -> int:\n        def first():\n            for i in range(len(A)):\n                for j in range(len(A[0])):\n                    if A[i][j] == 1:\n                        return i, j\n        def first_island(i, j):\n            stack = [(i, j)]\n            island = []\n            dirs = [(1, 0), (0, 1), (-1, 0), (0, -1)]\n            while stack:\n                x, y = stack.pop()\n                A[x][y] = 2\n                island.append((x, y, 0))\n                for dx, dy in dirs:\n                    tx, ty = x + dx, y + dy\n                    if len(A) > tx >= 0 and len(A[0]) > ty >= 0 and A[tx][ty] == 1:\n                        stack.append((tx, ty))\n            return island\n        \n        def bfs(queue):\n            queue = collections.deque(queue)\n            dirs = [(1, 0), (0, 1), (-1, 0), (0, -1)]\n            while queue:\n                length = len(queue)\n                for _ in range(length):\n                    x, y, level = queue.popleft()\n                    for dx, dy in dirs:\n                        tx, ty = x + dx, y + dy\n                        if len(A) > tx >= 0 and len(A[0]) > ty >= 0:\n                            if A[tx][ty] == 1:\n                                return level\n                            elif not A[tx][ty]:\n                                A[tx][ty] = -1\n                                queue.append((tx, ty, level+1))\n                                \n        return bfs(first_island(*first()))\n", "\\\"\\\"\\\"\n    1. Problem Summary / Clarifications / TDD:\n\n\\\"\\\"\\\"\n\nclass Solution:\n    def __init__(self):\n        self.moves = [(0,-1),(-1,0),(0,+1),(+1,0)]\n        \n    def shortestBridge(self, A: List[List[int]]) -> int:\n        \n        islands = []\n        \n        # Find the 2 islands\n        visited = set()\n        for r in range(len(A)):\n            for c in range(len(A[0])):\n                if A[r][c] and (r, c) not in visited:\n                    island = set()\n                    self.explore_island_dfs(A, r, c, visited, island)\n                    \n                    islands.append(island)\n                \n        # 2. Find min distance between island 1 and 2\n        visited = islands[0]\n        curr_level = list(visited)\n        \n        distance = 0\n        while curr_level:\n            \n            next_level = []\n            for (r, c) in curr_level:\n                \n                for mr, mc in self.moves:\n                    ar, ac = r + mr, c + mc\n                    \n                    if not self.valid_position(A, ar, ac):\n                        continue \n\n                    if (ar, ac) in islands[1]:\n                        return distance\n\n                    elif (ar, ac) not in visited and A[ar][ac] == 0:\n                        next_level.append((ar, ac))\n                        visited.add((ar, ac))\n            \n            distance += 1\n            curr_level = next_level\n                    \n        return len(A) * len(A[0])\n    \n    def explore_island_dfs(self, A: List[List[int]], r, c, visited, island):\n        \n        if r < 0 or r == len(A) or c < 0 or c == len(A[0]) or (r, c) in visited or not A[r][c]:\n            return\n        \n        visited.add((r,c))\n        island.add((r,c))\n        \n        self.explore_island_dfs(A, r - 1, c, visited, island)\n        self.explore_island_dfs(A, r, c - 1, visited, island)\n        self.explore_island_dfs(A, r + 1, c, visited, island)\n        self.explore_island_dfs(A, r, c + 1, visited, island)\n    \n    def valid_position(self, A, r, c):\n        \n        if r < 0 or r == len(A) or c < 0 or c == len(A[0]):\n            return False\n        \n        else:\n            return True\n        \n        \n                    \n                \n        ", "class Solution:\n    def shortestBridge(self, A: List[List[int]]) -> int:\n        islands = [set(), set()]\n        stack = []\n        index = -1\n        \n        # build islands\n        for i in range(len(A)):\n            for j in range(len(A[0])):\n                if A[i][j] == 0 or (i, j) in islands[0] or (i, j) in islands[1]: continue\n                \n                index += 1\n                stack.append((i, j))\n                islands[index].add((i, j))\n                \n                while stack:\n                    r, c = stack.pop()\n                    \n                    for dr, dc in [(0, 1), (0, -1), (1, 0), (-1, 0)]:\n                        nr, nc = r + dr, c + dc\n                        if 0 <= nr < len(A) and 0 <= nc < len(A[0]) \\\\\n                        and A[nr][nc] == 1 and (nr, nc) not in islands[index]:\n                            stack.append((nr, nc))\n                            islands[index].add((nr, nc))\n        \n        import collections\n        queue = collections.deque()\n        visited = set()\n        \n        for r, c in islands[0]: queue.appendleft((r, c, 0))\n            \n        while queue:\n            r, c, dist = queue.pop()\n            \n            for dr, dc in [(0, 1), (0, -1), (1, 0), (-1, 0)]:\n                nr, nc = r + dr, c + dc\n                if (nr, nc) in islands[1]: return dist\n                \n                if 0 <= nr < len(A) and 0 <= nc < len(A[0]) \\\\\n                and A[nr][nc] == 0 and (nr, nc) not in visited:\n                    queue.appendleft((nr, nc, dist+1))\n                    visited.add((nr, nc))\n        ", "import heapq\nimport sys\nsys.setrecursionlimit(10**8)\n\nclass First:\n    val = True\n\nclass Solution:\n    def shortestBridge(self, A: List[List[int]]) -> int:\n        h, w = len(A), len(A[0])\n        direction = [(-1, 0), (0, 1), (1, 0), (0, -1)]\n        First.val = True\n        \n        visited = [[0 for i in range(w)] for i in range(h)]\n        \n        def dfs(y, x, color):\n            visited[y][x] = 1\n            A[y][x] = color\n            for dy, dx in direction:\n                ny, nx = y + dy, x + dx\n                if ny < 0 or ny >= h or nx < 0 or nx >= w:\n                    continue\n                if visited[ny][nx] or A[ny][nx] == 0:\n                    continue\n                dfs(ny, nx, color)\n        \n        for i in range(h):\n            for j in range(w):\n                if visited[i][j]:\n                    continue\n                if A[i][j]:\n                    if First.val:\n                        First.val = False\n                        dfs(i, j, 1)\n                    else:\n                        dfs(i, j, 2)\n                        break        \n        \n        def bfs(i, j, start):\n            q = [[0, i, j]]\n            answer = 0\n            while q:\n                step, y, x = heapq.heappop(q)\n                if A[y][x] and A[y][x] != start:\n                    return step\n                for dy, dx in direction:\n                    ny, nx = y + dy, x + dx\n                    if ny < 0 or ny >= h or nx < 0 or nx >= w:\n                        continue\n                    if visited[ny][nx] == 2:\n                        continue\n                    visited[ny][nx] = 2\n                    if A[ny][nx]:\n                        heapq.heappush(q, [step, ny, nx])\n                    else:\n                        heapq.heappush(q, [step+1, ny, nx])\n                        \n        result = 0\n        for i in range(h):\n            for j in range(w):\n                if visited[i][j] == 2:\n                    continue\n                if A[i][j]:\n                    start = A[i][j]\n                    result = bfs(i, j, start)\n                    break\n            if result:\n                break\n        \n        return result", "class Solution:\n    def shortestBridge(self, A: List[List[int]]) -> int:\n        islands = [set(), set()]\n        stack = []\n        index = -1\n        \n        # build islands\n        for i in range(len(A)):\n            for j in range(len(A[0])):\n                if A[i][j] == 0 or (i, j) in islands[0] or (i, j) in islands[1]: continue\n                \n                index += 1\n                stack.append((i, j))\n                islands[index].add((i, j))\n                \n                while stack:\n                    r, c = stack.pop()\n                    \n                    for dr, dc in [(0, 1), (0, -1), (1, 0), (-1, 0)]:\n                        nr, nc = r + dr, c + dc\n                        if 0 <= nr < len(A) and 0 <= nc < len(A[0]) \\\\\n                        and A[nr][nc] == 1 and (nr, nc) not in islands[index]:\n                            stack.append((nr, nc))\n                            islands[index].add((nr, nc))\n        \n        import collections\n        queue = collections.deque()\n        visited = set()\n        \n        for r, c in islands[0]:\n            queue.appendleft((r, c, 0))\n        while queue:\n            r, c, dist = queue.pop()\n            \n            for dr, dc in [(0, 1), (0, -1), (1, 0), (-1, 0)]:\n                nr, nc = r + dr, c + dc\n                if (nr, nc) in islands[1]: return dist\n                \n                if 0 <= nr < len(A) and 0 <= nc < len(A[0]) \\\\\n                and A[nr][nc] == 0 and (nr, nc) not in visited:\n                    queue.appendleft((nr, nc, dist+1))\n                    visited.add((nr, nc))\n        ", "class Solution:\n    def shortestBridge(self, A: List[List[int]]) -> int:\n        '''\n        [1 1 1 1 1]\n        [1 0 0 0 1]\n        [1 0 1 0 1]\n        [1 0 0 0 1]\n        [1 1 1 1 1]\n        \n        [0 2 0]\n        [0 0 0]\n        [0 0 1]\n        \n        Find one island - convert all of it to 2. then put them all in queue. Find all non-2's that are 1 away as next frontier.\n        Check if you ever reach 1\n        '''\n        def isvalid(row,col):\n            return 0 <= row < len(A) and 0 <= col < len(A[0])\n        \n        def dfs(row,col):\n            if not isvalid(row,col) or A[row][col] != 1:\n                return\n            A[row][col] = 2\n            for i,j in [(1,0),(0,1),(-1,0),(0,-1)]:\n                new_row = row+i\n                new_col = col+j\n                dfs(new_row,new_col)\n            return\n                    \n        # Find one island and use dfs to make them all #\n        found = False\n        for row in range(len(A)):\n            for col in range(len(A[0])):\n                if A[row][col] ==1:\n                    dfs(row,col)\n                    found = True\n                    break\n            if found:\n                break\n        \n        # Do BFS starting from 2's \n        twos = []\n        for row in range(len(A)):\n            for col in range(len(A[0])):\n                if A[row][col] ==2:\n                    twos.append((row,col))\n        steps = 0\n        while twos:\n            next_ = []\n            steps += 1\n            for point in twos:\n                row, col = point\n                for i,j in [(1,0),(0,1),(-1,0),(0,-1)]:\n                    new_row = row+i\n                    new_col = col+j\n                    if isvalid(new_row,new_col) and A[new_row][new_col] == 0:\n                        A[new_row][new_col] = -1\n                        next_.append((new_row,new_col))\n                    elif isvalid(new_row,new_col) and A[new_row][new_col] == 1:\n                        return steps-1\n            twos = next_\n        return -1\n                    \n                \n        \n                    \n", "class Solution:\n    def shortestBridge(self, A: List[List[int]]) -> int:\n        \n        q = collections.deque()\n        \n        def ExploreIslands(x, y):\n            if not 0<=x<len(A) or not 0<=y<len(A[0]) or A[x][y]==-1:\n                return\n            if A[x][y]==1:\n                A[x][y]=-1\n                ExploreIslands(x, y+1)\n                ExploreIslands(x, y-1)\n                ExploreIslands(x+1, y)\n                ExploreIslands(x-1, y)\n            else:\n                q.appendleft((x, y, 1))\n                \n        def FindFirstIsland():\n            for i, row in enumerate(A):\n                for j, val in enumerate(row):\n                    if val==1:\n                        ExploreIslands(i, j)\n                        return\n        \n        FindFirstIsland()\n        while True:\n            x, y, distance = q.popleft()\n            for new_x, new_y in [(x+1, y), (x-1, y), (x, y+1), (x, y-1)]:\n                if 0<=new_x<len(A) and 0<=new_y<len(A[0]):\n                    if A[new_x][new_y]==1:\n                        return distance\n                    elif A[new_x][new_y]==0:\n                        A[new_x][new_y] = -1\n                        q.append((new_x, new_y, distance+1))", "import collections\nclass Solution:\n    def shortestBridge(self, A: List[List[int]]) -> int:\n        visited = set()\n        \n        def do_dfs(A,i,j,visited,seen):\n            visited.add((i,j))\n            seen.add((i,j))\n            for x,y in [[i+1,j],[i-1,j],[i,j-1],[i,j+1]]:\n                if 0<= x < len(A) and 0<= y<len(A[0]) and A[x][y] and (x,y) not in visited:\n                    do_dfs(A,x,y,visited,seen)\n            # return seen\n        \n        comp = []\n        for i in range(len(A)):\n            for j in range(len(A[0])):\n                if A[i][j] == 1 and (i,j) not in visited:\n                    seen = set()\n                    do_dfs(A, i,j, visited,seen)\n                    # print(a)\n                    comp.append(seen)\n                \n        s,t = comp[0],comp[1]\n        # print(comp,len(comp))\n        queue = collections.deque([(node,0) for node in s])\n        done = s\n        while queue:\n            \n            node, d = queue.popleft()\n            if node in t:return d-1\n            # print('here',node)\n            for n in[(node[0]+1,node[1]),(node[0]-1,node[1]),(node[0],node[1]+1),(node[0],node[1]-1)]:\n                # print(n,A[n[0]][n[1]] , n not in done)\n                if 0<= n[0] < len(A) and 0<= n[1]<len(A[0]) and n not in done:\n                    # print('here')\n                    queue.append((n,d+1))\n                    done.add(n)\n\n        \n", "class Solution:\n    def shortestBridge(self, A: List[List[int]]) -> int:\n        \n        m = len(A)\n        n = len(A[0])\n        found = 0\n        queue = []\n        \n        def dfs(a, b):\n            queue.append((a, b))\n            A[a][b] = -1\n            for x, y in (a+1, b), (a-1, b), (a, b+1), (a, b-1):\n                if 0<=x< m and 0<=y<n and A[x][y] == 1:\n                    dfs(x, y)\n        \n        \n        for i in range(m):\n            if found: \n                break\n            for j in range(n):\n                if A[i][j] == 1:\n                    found = 1\n                    dfs(i, j)\n                    break\n        step = 0\n        while queue:\n            new_queue = []\n            for x, y in queue:\n                for _x, _y in (x+1, y), (x-1, y), (x, y+1), (x, y-1):\n                    if 0<=_x< m and 0<=_y<n:\n                        if A[_x][_y] == 1:\n                            return step\n                        elif not A[_x][_y]:\n                            A[_x][_y] = -1\n                            new_queue.append((_x, _y))\n            step += 1\n            queue = new_queue\n        return -1\n                    \n                        \n                \n            \n            \n        \n", "class Solution:\n    def shortestBridge(self, A: List[List[int]]) -> int:     \n        def neighbors(u, v):\n            for du, dv in [(-1, 0), (1, 0), (0, -1), (0, 1)]:\n                nu, nv = u + du, v + dv\n                if 0<=nu<m and 0<=nv<n:\n                    yield (nu, nv)\n        def components():\n            def dfs(u, v, acc):\n                acc.add((u, v))\n                visited.add((u, v))\n                \n                for nu,nv in neighbors(u, v):\n                    if (nu,nv) not in visited and A[nu][nv] == 1:\n                        dfs(nu,nv,acc)\n            res = []\n            visited = set()\n            for u in range(m):\n                for v in range(n):\n                    if A[u][v] == 1 and (u,v) not in visited:\n                        res.append(set())\n                        dfs(u,v, res[-1])\n            return res\n        def bfs(ps, pt):\n            q = deque()\n            visited = set()\n            for p in ps:\n                q.append(p)\n                visited.add(p)\n            distance = 0\n            while q:\n                qsize = len(q)\n                for i in range(qsize):\n                    (u, v) = q.popleft()\n                    for nu, nv in neighbors(u, v):\n                        if (nu,nv) in pt:\n                            return distance\n                        if (nu, nv) not in visited:\n                            q.append((nu, nv))\n                            visited.add((nu, nv))\n                distance += 1\n            return 0\n                    \n                \n        \n        m = len(A)\n        n = len(A[0])\n        \n        source, target = components()\n\n        \n        return bfs(source, target)\n", "class Solution:\n    def shortestBridge(self, A: List[List[int]]) -> int:\n        R,C= len(A), len(A[0])\n        done = set()\n        \n        def dfs(x,y,seen,R,C):\n            if A[x][y] == 0: return\n            \n            seen.add((x,y))\n            for nr, nc in ((x-1,y),(x,y-1),(x+1,y),(x,y+1)):\n                if 0 <= nr < R and 0 <= nc < C and A[nr][nc] == 1 and (nr,nc) not in seen and (nr,nc) not in done:\n                    dfs(nr,nc,seen,R,C)\n            \n        \n        islands = []\n        for r, row in enumerate(A):\n            for c, col in enumerate(row):\n                if col and (r,c) not in done:\n                    seen = set()\n                    dfs(r,c,seen,R,C)\n                    islands.append(seen)\n                    done |= seen\n        \n        \n        first, second = islands\n        q = list(first)\n        count = 0\n        seen = set()\n        while q:\n            temp = []\n            for x,y in q:\n                for nx,ny in ((x-1,y),(x,y-1),(x+1,y),(x,y+1)):\n                    if 0 <= nx < R and 0 <= ny < C and (nx,ny) not in first and (nx,ny) not in seen:\n                        if (nx,ny) in second: return count\n                        temp.append((nx,ny))\n                        seen.add((nx,ny))\n            count += 1\n            q = temp[:]\n        return 0", "class Solution:\n    def shortestBridge(self, A: List[List[int]]) -> int:\n# ref:\n# https://leetcode.com/problems/shortest-bridge/discuss/189293/C%2B%2B-BFS-Island-Expansion-%2B-UF-Bonus\n        R,C=len(A),len(A[0])\n        def inside(i,j):\n            return 0<=i<R and 0<=j<C\n        def dfs_paint_2(i,j):\n            A[i][j]=2\n            for (ii,jj) in [(i+1,j),(i-1,j),(i,j+1),(i,j-1)]:\n                if inside(ii,jj) and A[ii][jj]==1:\n                    dfs_paint_2(ii,jj)\n        def neighbor_is_1(i,j):\n            for (ii,jj) in [(i+1,j),(i-1,j),(i,j+1),(i,j-1)]:\n                if inside(ii,jj) and A[ii][jj]==1:\n                    return True\n            return False\n        def paint_neighbor(i,j,color):\n            for (ii,jj) in [(i+1,j),(i-1,j),(i,j+1),(i,j-1)]:\n                if inside(ii,jj) and A[ii][jj]==0:\n                    A[ii][jj]=color\n        \n        for i,row in enumerate(A):\n            for j,ele in enumerate(row):\n                if ele==1:\n                    dfs_paint_2(i,j)\n                    break\n            else:\n                continue\n            break\n            \n        \n        # now the island I have touched is in color-2\n        # the other one, untouched, is in color-1\n        for color in range(2,max(R,C)+2):\n            for i,row in enumerate(A):\n                for j,ele in enumerate(row):\n                    if ele==color:\n                        if neighbor_is_1(i,j):\n                            return color-2\n                        paint_neighbor(i,j,color+1)\n", "class Solution:\n    def shortestBridge(self, A: List[List[int]]) -> int:\n# ref:\n# https://leetcode.com/problems/shortest-bridge/discuss/189293/C%2B%2B-BFS-Island-Expansion-%2B-UF-Bonus\n        R,C=len(A),len(A[0])\n        def inside(i,j):\n            return 0<=i<R and 0<=j<C\n        def dfs_paint_2(i,j):\n            A[i][j]=2\n            for (ii,jj) in [(i+1,j),(i-1,j),(i,j+1),(i,j-1)]:\n                if inside(ii,jj) and A[ii][jj]==1:\n                    dfs_paint_2(ii,jj)\n        def neighbor_is_1(i,j):\n            for (ii,jj) in [(i+1,j),(i-1,j),(i,j+1),(i,j-1)]:\n                if inside(ii,jj) and A[ii][jj]==1:\n                    return True\n            return False\n        def paint_neighbor(i,j,color):\n            for (ii,jj) in [(i+1,j),(i-1,j),(i,j+1),(i,j-1)]:\n                if inside(ii,jj) and A[ii][jj]==0:\n                    A[ii][jj]=color\n        \n        def paint_2():\n            for i,row in enumerate(A):\n                for j,ele in enumerate(row):\n                    if ele==1:\n                        dfs_paint_2(i,j)\n                        return\n        paint_2()\n\n        \n        # now the island I have touched is in color-2\n        # the other one, untouched, is in color-1\n        for color in range(2,max(R,C)+2):\n            for i,row in enumerate(A):\n                for j,ele in enumerate(row):\n                    if ele==color:\n                        if neighbor_is_1(i,j):\n                            return color-2\n                        paint_neighbor(i,j,color+1)\n", "\\\"\\\"\\\"\n    1. Problem Summary / Clarifications / TDD:\n\n\\\"\\\"\\\"\n\nclass Solution:\n    def __init__(self):\n        self.moves = [(0,-1),(-1,0),(0,+1),(+1,0)]\n        \n    def shortestBridge(self, A: List[List[int]]) -> int:\n        \n        islands = []\n        \n        # Find the 2 islands\n        visited = set()\n        for r in range(len(A)):\n            for c in range(len(A[0])):\n                if A[r][c] and (r, c) not in visited:\n                    island = set()\n                    self.explore_island_dfs(A, r, c, visited, island)\n                    \n                    islands.append(island)\n                \n        # 2. Find min distance between island 1 and 2: BFS\n        visited = islands[0]\n        curr_level = list(visited)\n        \n        distance = 0\n        while curr_level:\n            \n            next_level = []\n            for (r, c) in curr_level:\n                \n                for mr, mc in self.moves:\n                    ar, ac = r + mr, c + mc\n                    \n                    if not self.valid_position(A, ar, ac):\n                        continue \n\n                    elif (ar, ac) in islands[1]:\n                        return distance\n                    \n                    elif (ar, ac) not in visited and A[ar][ac] == 0:\n                        next_level.append((ar, ac))\n                        visited.add((ar, ac))\n            \n            distance += 1\n            curr_level = next_level\n                    \n        return len(A) * len(A[0])\n    \n    def explore_island_dfs(self, A: List[List[int]], r, c, visited, island):\n                \n        visited.add((r,c))\n        island.add((r,c))\n        \n        for mr, mc in self.moves:\n            ar, ac = r + mr, c + mc\n            \n            if self.valid_position(A, ar, ac) and (ar, ac) not in visited and A[ar][ac]:\n                self.explore_island_dfs(A, ar, ac, visited, island)\n    \n    def valid_position(self, A, r, c):\n        \n        if r < 0 or r == len(A) or c < 0 or c == len(A[0]):\n            return False\n        \n        else:\n            return True\n        \n        \n                    \n                \n        ", "class Solution:\n    def shortestBridge(self, A: List[List[int]]) -> int:\n# ref:\n# https://leetcode.com/problems/shortest-bridge/discuss/189293/C%2B%2B-BFS-Island-Expansion-%2B-UF-Bonus\n        R,C=len(A),len(A[0])\n        def inside(i,j):\n            return 0<=i<R and 0<=j<C\n        def dfs_paint_2(i,j):\n            A[i][j]=2\n            for (ii,jj) in [(i+1,j),(i-1,j),(i,j+1),(i,j-1)]:\n                if inside(ii,jj) and A[ii][jj]==1:\n                    dfs_paint_2(ii,jj)\n        def neighbor_is_1(i,j):\n            for (ii,jj) in [(i+1,j),(i-1,j),(i,j+1),(i,j-1)]:\n                if inside(ii,jj) and A[ii][jj]==1:\n                    return True\n            return False\n        def paint_neighbor(i,j,color):\n            for (ii,jj) in [(i+1,j),(i-1,j),(i,j+1),(i,j-1)]:\n                if inside(ii,jj) and A[ii][jj]==0:\n                    A[ii][jj]=color\n        \n        for i,row in enumerate(A):\n            for j,ele in enumerate(row):\n                if ele==1:\n                    dfs_paint_2(i,j)\n                    break\n            else:\n                continue\n            break\n            \n        \n        # now the island I have touched is in color-2\n        # the other one, untouched, is in color-1\n        print(A)\n        for color in range(2,max(R,C)+2):\n            for i,row in enumerate(A):\n                for j,ele in enumerate(row):\n                    if ele==color:\n                        if neighbor_is_1(i,j):\n                            return color-2\n                        paint_neighbor(i,j,color+1)\n", "class Solution:\n    def shortestBridge(self, A: List[List[int]]) -> int:\n        q = collections.deque()\n        def explore_island(r, c):\n            if not 0 <= r < len(A) or not 0 <= c < len(A[r]) or A[r][c] == -1:\n                return\n            if A[r][c] == 1:           \n                A[r][c] = -1    \n                explore_island(r+1, c)\n                explore_island(r-1, c)\n                explore_island(r, c+1)\n                explore_island(r, c-1)\n            elif A[r][c] == 0:\n                q.append((r, c, 1))\n                \n        def find_first_island():   \n            for r, row in enumerate(A):\n                for c, v in enumerate(row):\n                    if v == 1:\n                        explore_island(r, c)\n                        return\n        find_first_island()            \n\n        while q:\n            cur_r, cur_c, cur_l = q.popleft()\n            for x, y in (cur_r+1, cur_c), (cur_r-1, cur_c), (cur_r, cur_c+1), (cur_r, cur_c-1):\n                if 0 <= x < len(A) and 0 <= y < len(A[x]):\n                    if A[x][y] == 1:\n                        return cur_l\n                    elif A[x][y] == 0:\n                        A[x][y] = -1\n                        q.append((x, y, cur_l + 1))", "class Solution:\n    def shortestBridge(self, A: List[List[int]]) -> int:     \n        def neighbors(u, v):\n            for du, dv in [(-1, 0), (1, 0), (0, -1), (0, 1)]:\n                nu, nv = u + du, v + dv\n                if 0<=nu<m and 0<=nv<n:\n                    yield (nu, nv)\n        def components():\n            def dfs(u, v, acc):\n                acc.add((u, v))\n                visited.add((u, v))\n                \n                for nu,nv in neighbors(u, v):\n                    if (nu,nv) not in visited and A[nu][nv] == 1:\n                        dfs(nu,nv,acc)\n            res = []\n            visited = set()\n            for u in range(m):\n                for v in range(n):\n                    if A[u][v] == 1 and (u,v) not in visited:\n                        res.append(set())\n                        dfs(u,v, res[-1])\n            return res\n        def bfs(ps, pt):\n            q = deque()\n            visited = set()\n            for p in ps:\n                q.append(p)\n                visited.add(p)\n            distance = 0\n            while q:\n                qsize = len(q)\n                for i in range(qsize):\n                    (u, v) = q.popleft()\n                    for nu, nv in neighbors(u, v):\n                        if (nu,nv) in pt:\n                            return distance\n                        if (nu, nv) not in visited:\n                            q.append((nu, nv))\n                            visited.add((nu, nv))\n                distance += 1\n            return 0\n                    \n                \n        \n        m = len(A)\n        n = len(A[0])\n        \n        source, target = components()\n        print(source)\n        print(target)\n        \n        return bfs(source, target)\n", "class Solution:\n    def shortestBridge(self, A: List[List[int]]) -> int:\n        q = collections.deque()\n        def explore_island(r, c):\n            if not 0 <= r < len(A) or not 0 <= c < len(A[r]) or A[r][c] == -1:\n                return\n            if A[r][c] == 1:           \n                A[r][c] = -1    \n                explore_island(r+1, c)\n                explore_island(r-1, c)\n                explore_island(r, c+1)\n                explore_island(r, c-1)\n            elif A[r][c] == 0:\n                q.append((r, c, 1))\n                \n        def find_first_island():   \n            for r, row in enumerate(A):\n                for c, v in enumerate(row):\n                    if v == 1:\n                        explore_island(r, c)\n                        return\n        find_first_island()            \n\n        while q:\n            cur_r, cur_c, cur_l = q.popleft()\n            for x, y in (cur_r+1, cur_c), (cur_r-1, cur_c), (cur_r, cur_c+1), (cur_r, cur_c-1):\n                if 0 <= x < len(A) and 0 <= y < len(A[x]):\n                    if A[x][y] == 1:\n                        return cur_l\n                    elif A[x][y] == 0:\n                        A[x][y] = -1\n                        q.append((x, y, cur_l + 1))\n                    continue", "class Solution:\n    def shortestBridge(self, A: List[List[int]]) -> int:\n        m = len(A)\n        n = len(A[0])\n        def get_poss(i, j, val=1):\n            poss = [(i + 1, j), (i - 1, j), (i, j + 1), (i, j - 1)]\n            poss = [(x, y) for x, y in poss if x >= 0 and x < m and y >= 0 and y < n\n                    and A[x][y] == val]\n            return poss\n        \n        def expand(i, j):\n            A[i][j] = '#'\n            poss = get_poss(i, j)\n            for x, y in poss:\n                expand(x, y)\n            \n        found_first = False\n        boundaries = []\n        for i in range(m):\n            for j in range(n):\n                if A[i][j] == 1:\n                    if not found_first:\n                        found_first = True\n                        expand(i, j)\n                    else:\n                        #if get_poss(i, j, 0):\n                        boundaries.append((i, j))\n        \n        def bfs(boundaries):\n            recorder = set(boundaries)\n            depth = 0\n            roots = boundaries        \n            while roots:\n                next_level = []\n                for x, y in roots:\n                    poss1 = get_poss(x, y, '#')\n                    if poss1:\n                        return depth\n                    poss = get_poss(x, y, 0)\n                    for pos in poss:\n                        if pos not in recorder:\n                            recorder.add(pos)\n                            next_level.append(pos)\n                depth += 1\n                roots = next_level\n        return bfs(boundaries)\n", "class Solution:\n    def shortestBridge(self, A: List[List[int]]) -> int:\n        \n        island_one = set()\n\n        def dfs(r,c):\n            if (r,c) in island_one:\n                return \n            island_one.add((r,c))\n\n            for r1, c1 in {(r+1,c), (r, c+1), (r-1,c), (r,c-1)}: \n                        if 0 <= r1 < len(A) and 0 <= c1 < len(A[0]) and (r1,c1) not in island_one and A[r1][c1] == 1:\n                            dfs(r1, c1)\n\n        f = False\n        for i in range(len(A)):\n            for j in range(len(A[0])):\n                if A[i][j] == 1:\n                    dfs(i,j)\n                    f = True\n                    break\n            if f: break\n\n\n        def bfs():\n            q = collections.deque([(r,c,0) for r,c in list(island_one)])\n            seen = set()\n            while q:\n                r,c,level = q.popleft()\n\n                if A[r][c] == 1 and (r,c) not in island_one:\n                    return level-1\n\n                for r1, c1 in {(r+1,c), (r, c+1), (r-1,c), (r,c-1)}: \n                        if 0 <= r1 < len(A) and 0 <= c1 < len(A[0]) and A[r1][c1] not in island_one and (r1,c1) not in seen:\n                            q.append((r1,c1,level+1))\n                            seen.add((r1,c1))\n        return bfs()\n                        \n                        \n            \n            \n    \n    \n    \n        \n", "\nclass Solution(object):\n    def shortestBridge(self, A):\n        R, C = len(A), len(A[0])\n\n        def neighbors(r, c):\n            for nr, nc in ((r-1,c),(r,c-1),(r+1,c),(r,c+1)):\n                if 0 <= nr < R and 0 <= nc < C:\n                    yield nr, nc\n\n        def get_components():\n            done = set()\n            components = []\n            for r, row in enumerate(A):\n                for c, val in enumerate(row):\n                    if val and (r, c) not in done:\n                        # Start dfs\n                        stack = [(r, c)]\n                        seen = {(r, c)}\n                        while stack:\n                            node = stack.pop()\n                            for nei in neighbors(*node):\n                                if A[nei[0]][nei[1]] and nei not in seen:\n                                    stack.append(nei)\n                                    seen.add(nei)\n                        done |= seen\n                        components.append(seen)\n            return components\n\n        source, target = get_components()\n        queue = collections.deque([(node, 0) for node in source])\n        done = set(source)\n        while queue:\n            node, d = queue.popleft()\n            if node in target: return d-1\n            for nei in neighbors(*node):\n                if nei not in done:\n                    queue.append((nei, d+1))\n                    done.add(nei)", "import heapq\nclass Solution:\n    directions = [(1, 0), (0, 1), (-1, 0), (0, -1)]\n    def shortestBridge(self, mat: List[List[int]]) -> int:\n        row = None\n        col = None\n        found = False\n        for i in range(len(mat)):\n            if found:\n                break\n            for j in range(len(mat[i])):\n                if mat[i][j]:\n                    row = i\n                    col = j\n                    Solution.paint_one_island(mat, row, col, mat[row][col] + 1)\n                    found = True\n                    break\n        target_dest = 1\n        return Solution.minimum_expand(mat, row, col, target_dest)\n    \n    @staticmethod\n    def mark_next(mat, row, col, val, target_dest):\n        for i in range(len(Solution.directions)):\n            new_row = row + Solution.directions[i][0]\n            new_col = col + Solution.directions[i][1]\n            if new_row < 0 or new_row >= len(mat) or new_col < 0 or new_col >= len(mat[0]):\n                continue\n            if mat[new_row][new_col] == target_dest:\n                return True\n            if not mat[new_row][new_col]:\n                mat[new_row][new_col] = val + 1\n        return False\n    \n    @staticmethod\n    def minimum_expand(mat, row, col, target_dest):\n        st_val = mat[row][col]\n        for val in range(st_val, len(mat)*len(mat[0])):\n            for row in range(len(mat)):\n                for col in range(len(mat[row])):\n                    is_reached = False\n                    if mat[row][col] == val:\n                        is_reached = Solution.mark_next(mat, row, col, val, target_dest)\n                    if is_reached:\n                        return val - st_val\n        return -1\n            \n    \n    @staticmethod\n    def paint_one_island(mat, row, col, val):\n        if row < 0 or row >= len(mat) or col < 0 or col >= len(mat[0]):\n            return\n        if mat[row][col] == val or not mat[row][col]:\n            return\n        mat[row][col] = val\n        for i in range(len(Solution.directions)):\n            Solution.paint_one_island(mat, row + Solution.directions[i][0], col + Solution.directions[i][1], val)", "class Solution:\n    def shortestBridge(self, A: List[List[int]]) -> int:\n        M, N = len(A), len(A[0])\n        \n        def dfs(i, j):\n            A[i][j] = 2\n            for x, y in [(i - 1, j), (i + 1, j), (i, j - 1), (i, j + 1)]:\n                if 0 <= x < M and 0 <= y < N and A[x][y] == 1:\n                    dfs(x, y)\n            return\n        \n        flag = 0\n        for i in range(M):\n            for j in range(N):\n                if A[i][j] == 1:\n                    flag = 1\n                    break\n            if flag: break\n        dfs(i, j)\n        # print(A)\n        q = collections.deque([(0, i, j) for i in range(M) for j in range(N) if A[i][j] == 1])\n        seen = set([(i, j) for i in range(M) for j in range(N) if A[i][j] == 1])\n        while q:\n            step, i, j = q.popleft()\n            if A[i][j] == 2:\n                return step - 1\n            for x, y in [(i - 1, j), (i + 1, j), (i, j - 1), (i, j + 1)]:\n                if 0 <= x < M and 0 <= y < N and (x, y) not in seen and A[x][y] in [0, 2]:\n                    seen.add((x, y))\n                    q.append((step + 1, x, y))", "class Solution:\n    def shortestBridge(self, A: List[List[int]]) -> int:\n        m, n = len(A), len(A[0])\n        # mark first island as -1, find and start at second island, bfs until first island is reached while adding steps along\n        # find first island\n        self.first = []\n        def dfs(i, j, m, n):\n            if 0 <= i < m and 0 <= j < n and A[i][j] == 1:               \n                A[i][j] = 2\n                self.first.append((i,j))\n                for r, c in [(i+1, j), (i-1, j), (i, j+1), (i, j-1)]:\n                    dfs(r, c, m, n)\n        \n        for i in range(m):\n            for j in range(n):\n                if A[i][j] == 1:\n                    dfs(i, j, m, n)\n                    break\n            if A[i][j] == 2:\n                break\n        res = m * n\n        while self.first:\n            i, j = self.first.pop(0)\n            for r, c in [(i+1, j), (i-1, j), (i, j+1), (i, j-1)]:\n                if 0 <= r < m and 0 <= c < n:\n                    if A[r][c] == 0:\n                        A[r][c] = A[i][j] + 1\n                        self.first.append((r,c))\n                    if A[r][c] == 1:\n                        res = min(res, A[i][j] - 2)\n                        A[i][j] == -1\n                        break\n            if A[i][j] == -1:\n                break\n        return res", "class Solution:\n    def shortestBridge(self, A: List[List[int]]) -> int:\n        n = len(A)\n        zeros = set()\n        def dfs(i, j):\n            A[i][j] = 2\n            for di, dj in [[0, -1], [0, 1], [-1, 0], [1, 0]]:\n                ii, jj = i + di, j + dj\n                if 0 <= ii < n and 0 <= jj < n:\n                    if A[ii][jj] == 1:\n                        dfs(ii, jj)\n                    elif A[ii][jj] == 0:\n                        zeros.add((ii, jj))\n        for i in range(n):\n            for j in range(n):\n                if A[i][j] == 1:\n                    dfs(i, j)\n                    break\n            else:\n                continue\n            break\n        \n        result = 2 * n\n        # print(zeros)\n        q = collections.deque(zeros)\n        visited = {(i, j)}\n        steps = 1\n        while q:\n            for _ in range(len(q)):\n                i, j = q.popleft()\n                for di, dj in [[0, -1], [0, 1], [-1, 0], [1, 0]]:\n                    ii, jj = i + di, j + dj\n                    if 0 <= ii < n and 0 <= jj < n:\n                        if A[ii][jj] == 0 and (ii, jj) not in visited:\n                            visited.add((ii, jj))\n                            q.append((ii, jj))\n                        if A[ii][jj] == 1:\n                            result = min(result, steps)\n            steps += 1\n        return result            \n", "class Solution:\n    \n    def transform_island(self, A, i, j, queue, visited):\n        if i < 0 or i >= len(A) or j < 0 or j >= len(A[i]) or (i, j) in visited:\n            return\n        \n        if A[i][j] == 0:\n            return\n        \n        A[i][j] = float('inf')\n        queue.append((0, i, j))\n        visited.add((i, j))\n        self.transform_island(A, i+1, j, queue, visited)\n        self.transform_island(A, i, j+1, queue, visited)\n        self.transform_island(A, i-1, j, queue, visited)\n        self.transform_island(A, i, j-1, queue, visited)\n    \n    def shortestBridge(self, A: List[List[int]]) -> int:\n        queue = collections.deque([])\n        visited = set()\n        # find the first 1, and search all its neighbors to turn it into -1\n        for i in range(len(A)):\n            should_break = False\n            for j in range(len(A[i])):\n                if A[i][j] == 1:\n                    self.transform_island(A, i, j, queue, set())\n                    should_break = True\n                    break\n            if should_break:\n                break\n        \n        # print(A, queue)\n        # BFS approach\n        while len(queue) > 0:\n            prev_val, i, j = queue.popleft()\n            next_val = prev_val - 1 # records the amount of steps\n            print(('q', i, j, next_val))\n            if A[i][j] == 1: # reached the other island\n                return -prev_val-1\n            \n             # push boundary of the island\n            if i > 0 and A[i-1][j] >= 0 and (i-1, j) not in visited:\n                visited.add((i-1, j))\n                queue.append((next_val, i-1, j))\n            if i < len(A)-1 and A[i+1][j] >= 0 and (i+1, j) not in visited:\n                visited.add((i+1, j))\n                queue.append((next_val, i+1, j))\n            if j > 0 and A[i][j-1] >= 0 and (i, j-1) not in visited:\n                visited.add((i, j-1))\n                queue.append((next_val, i, j-1))\n            if j < len(A[0])-1 and A[i][j+1] >= 0 and (i, j+1) not in visited:\n                visited.add((i, j+1))\n                queue.append((next_val, i, j+1))\n", "class Solution:\n    def shortestBridge(self, A: List[List[int]]) -> int:\n        #allow change A\n        m = len(A)\n        n = len(A[0])\n        q = collections.deque([])\n        for i in range(m):\n            for j in range(n):\n                if A[i][j] == 1:\n                    q.append((i, j))\n                    newq = collections.deque([(i, j)])\n                    break\n            else:\n                continue\n            break\n        # print(q, newq)        \n        while q:\n            x, y = q.popleft()\n            A[x][y] = 2\n            for dx, dy in [(1, 0), (-1, 0), (0, 1), (0, -1)]:\n                nx, ny = x + dx, y + dy\n                if 0 <= nx < m and 0 <= ny < n and A[nx][ny] == 1:\n                    A[nx][ny] = 2\n                    newq.append((nx, ny))\n                    q.append((nx, ny))\n                    \n        # print(q, newq)\n        # print(A)\n        steps = 0\n        while newq:\n            newsize = len(newq)\n            for _ in range(newsize):\n                x, y = newq.popleft()\n                for dx, dy in [(1, 0), (-1, 0), (0, 1), (0, -1)]:\n                    nx, ny = x + dx, y + dy\n                    if nx < 0 or nx >= m or ny < 0 or ny >= m or A[nx][ny] == 2:\n                        continue\n                    if A[nx][ny] == 1:\n                        return steps\n                    elif A[nx][ny] == 0:\n                        A[nx][ny] = 2\n                        newq.append((nx, ny))\n            steps += 1\n                        \n        return -1\n", "from collections import deque\nclass Solution:\n  def findNeighbors(self, root, A):\n    i, j = root\n    neighbors = []\n    if i > 0:\n      neighbors.append((i-1, j))\n    if j > 0:\n      neighbors.append((i, j-1))\n    if i < len(A)-1:\n      neighbors.append((i+1, j))\n    if j < len(A[0])-1:\n      neighbors.append((i, j+1))\n    return neighbors\n  def findIsland(self, root, A):\n    # find all edges\n    queue = [root]\n    visited = set()\n    while queue:\n      pick = queue.pop()\n      if pick in visited:\n        continue\n      visited.add(pick)\n      \n      neighbors = self.findNeighbors(pick, A)\n      for neighbor in neighbors:\n        if A[neighbor[0]][neighbor[1]] == 1:\n          queue.append(neighbor)\n    return visited\n  \n  def shortestBridge(self, A: List[List[int]]) -> int:\n    # find an island\n    # starting with all its edge nodes and do bfs until reaching another island\n    # find one node on one island\n    root = None\n    for i in range(len(A)):\n      for j in range(len(A[0])):\n        if A[i][j] == 1:\n          root = (i, j)\n    \n    queue = deque(self.findIsland(root, A))\n    level = 0\n    visited = self.findIsland(root, A)\n    while queue:\n      print((level, queue, visited))\n      for _ in range(len(queue)):\n        pick = queue.popleft()\n        for neighbor in self.findNeighbors(pick, A):\n          if neighbor in visited:\n            continue\n          visited.add(neighbor)\n          if A[neighbor[0]][neighbor[1]] == 1:\n            print(neighbor)\n            return level\n          queue.append(neighbor)\n      level += 1\n    \n    return level\n  \n# [1,1,1,1,1]\n# [1,0,0,0,1]\n# [1,0,1,0,1]\n# [1,0,0,0,1]\n# [1,1,1,1,1]\n", "from itertools import product\n\nclass Solution(object):\n    def getNeighbors(self, lst, x, y):\n        # print(f'getting neighbors for {x}, {y}')\n        numRows = len(lst)\n        numCols = len(lst[0])\n        \n        for r, c in [(x+1, y), (x-1, y), (x, y+1), (x, y-1)]:\n            if 0 <= r < numRows and 0 <= c < numCols:\n                yield r, c\n    \n    \n    \n    def dfs(self, r, c, A, seen, component):\n        if A[r][c] and (r, c) not in seen:\n            seen.add((r, c))\n            component.add((r, c))\n\n            for nei in self.getNeighbors(A, r, c):\n                if A[nei[0]][nei[1]] and (nei[0], nei[1]) not in seen:\n                    self.dfs(nei[0], nei[1], A, seen, component)\n\n    def shortestBridge(self, A):\n        \\\"\\\"\\\"\n        :type A: List[List[int]]\n        :rtype: int\n        \\\"\\\"\\\"\n        R = len(A)\n        C = len(A[0])\n        components = []\n        seen = set()\n        \n        for rIdx, row in enumerate(A):\n            for cIdx, val in enumerate(row):\n                if val and (rIdx, cIdx) not in seen:\n                    component = set()\n                    self.dfs(rIdx, cIdx, A, seen, component)\n                    components.append(component)\n        \n        # print(components)\n        source, target = components[0], components[1]\n        print(f'source {source}, target {target}')\n        \n        queue = collections.deque([(node, 0) for node in source])\n        \n        visited = set(source)\n        \n        while queue:\n            node, dist = queue.popleft()\n            # print(f'node - {node}, distance - {dist}')\n            \n            visited.add(node)\n            \n            for x, y in self.getNeighbors(A, *node):\n                # print(f'processing neighbor {x}, {y}')\n                if (x, y) in target:\n                    return dist\n                if (x, y) not in visited:\n                    # print(f'adding node {(x,y)} to the queue')\n                    queue.append(((x, y), dist+1))\n                    visited.add((x, y))", "class Solution:\n    def shortestBridge(self, grid: List[List[int]]) -> int:\n        if not grid: return 0\n        nrow = len(grid)\n        ncol = len(grid[0])\n        \n        q = deque()\n        \n        def explore_island(grid, i, j):\n            if i < 0 or i >= nrow or j < 0 or j >= ncol or grid[i][j] != 1:\n                return\n            grid[i][j] = 2\n            q.append((i, j, 0))\n            for ni, nj in [(i-1, j), (i+1, j), (i, j-1), (i, j+1)]:\n                explore_island(grid, ni, nj)\n        \n        def get_coordinates(grid):\n            for i in range(nrow):\n                for j in range(ncol):\n                    if grid[i][j] == 1:\n                        explore_island(grid, i, j)\n                        return\n            return\n        get_coordinates(grid)\n        \n        while q:\n            i, j, dist = q.popleft()\n            for ni, nj in [(i-1, j), (i+1, j), (i, j-1), (i, j+1)]:\n                if ni >= 0 and ni < nrow and nj >= 0 and nj < ncol and grid[ni][nj] != 2:\n                    if grid[ni][nj] == 1:\n                        return dist\n                    elif grid[ni][nj] == 0:\n                        grid[ni][nj] = 2\n                        q.append((ni, nj, dist+1))", "class Solution:\n    def shortestBridge(self, A: List[List[int]]) -> int:\n        n = len(A)\n        zeros = set()\n        def dfs(i, j):\n            A[i][j] = 2\n            for di, dj in [[0, -1], [0, 1], [-1, 0], [1, 0]]:\n                ii, jj = i + di, j + dj\n                if 0 <= ii < n and 0 <= jj < n:\n                    if A[ii][jj] == 1:\n                        dfs(ii, jj)\n                    elif A[ii][jj] == 0:\n                        zeros.add((ii, jj))\n        for i in range(n):\n            for j in range(n):\n                if A[i][j] == 1:\n                    dfs(i, j)\n                    break\n            else:\n                continue\n            break\n        \n        result = 2 * n\n        # print(zeros)\n        q = collections.deque(zeros)\n        zeros = set()\n        steps = 1\n        while q:\n            for _ in range(len(q)):\n                i, j = q.popleft()\n                for di, dj in [[0, -1], [0, 1], [-1, 0], [1, 0]]:\n                    ii, jj = i + di, j + dj\n                    if 0 <= ii < n and 0 <= jj < n:\n                        if A[ii][jj] == 0 and (ii, jj) not in zeros:\n                            zeros.add((ii, jj))\n                            q.append((ii, jj))\n                        if A[ii][jj] == 1:\n                            result = min(result, steps)\n            steps += 1\n        return result            \n", "class Solution:\n    def __init__(self):\n        self.map = None\n        self.w, self.h = 0, 0\n        \n    def get_neighbors(self, r, c):\n        nei = []\n        for rc in [(r - 1, c), (r + 1, c), (r, c - 1), (r, c + 1)]:\n            if 0 <= rc[0] < self.h and 0 <= rc[1] < self.w:\n                nei.append(rc)\n        return nei\n    \n    def find_island(self):\n        done = set()\n        islands = []\n        for r in range(len(self.map)):\n            for c in range(len(self.map[0])):\n                if self.map[r][c] and (r, c) not in done:\n                    stack = [(r, c)]\n                    seen = {(r, c)}\n                    while stack:\n                        cell = stack.pop(0)\n                        neighbors = self.get_neighbors(cell[0], cell[1])\n                        for nei in neighbors:\n                            if self.map[nei[0]][nei[1]] and nei not in seen:\n                                stack.append(nei)\n                                seen.add(nei)\n                    islands.append(seen)\n                    done |= seen\n        return islands\n                     \n    def shortestBridge(self, A: List[List[int]]) -> int:\n        self.map = A\n        self.w, self.h = len(A), len(A[0])\n        source, target = self.find_island()\n        queue = [(node, 0) for node in source]\n        while queue:\n            node, d = queue.pop(0)\n            if node in target: return d - 1\n            neighbors = self.get_neighbors(node[0], node[1])\n            for nei in neighbors:\n                if nei not in source:\n                    queue.append((nei, d + 1))\n                    source.add(nei)\n            \n        \n        \n", "class Solution:\n    def shortestBridge(self, A: List[List[int]]) -> int:\n        \n        self.A = A\n        self.R = len(self.A)\n        self.C = len(self.A[0])\n        \n        p = self.findGround()\n        #print(p)\n        \n        if p == None:\n            return -1\n        \n        self.firstIsland = set()\n        \n        self.embraceIsland( p)\n        #print(self.firstIsland)\n\n        return self.bfs()\n    \n    def findGround(self):\n        for i in range(0, self.R):\n            for j in range(0, self.C):\n                if self.isGround((i, j)):\n                    return (i, j)\n                \n        return None\n    \n    def isGround(self, p):\n        return self.A[p[0]][p[1]] == 1\n    \n                \n    def inGrid(self, p):\n        \n        if not (0 <= p[0] < self.R):\n            return False\n        \n        if not (0 <= p[1] < self.C):\n            return False\n        \n        return True\n    \n    def getNeis(self, p):\n        neis = []\n        \n        neis.append((p[0] + 1, p[1]))\n        neis.append((p[0] - 1, p[1]))\n        neis.append((p[0], p[1] + 1))\n        neis.append((p[0], p[1] - 1))\n        \n        return neis\n    \n    def getNeisAround(self, p):\n        \n        neis = []\n        \n        neis.append((p[0] + 1   , p[1]))\n        neis.append((p[0] - 1   , p[1]))\n        neis.append((p[0]       , p[1] + 1))\n        neis.append((p[0]       , p[1] - 1))\n        neis.append((p[0] + 1   , p[1] + 1))\n        neis.append((p[0] + 1   , p[1] - 1))\n        neis.append((p[0] - 1   , p[1], - 1))\n        neis.append((p[0] - 1  , p[1] + 1))\n        \n        return neis\n    \n    \n    def embraceIsland(self, p):\n        \n        self.firstIsland.add(p)\n        \n        for nei in self.getNeis(p):\n            if self.inGrid(nei) and self.isGround(nei) and nei not in self.firstIsland:\n                self.embraceIsland(nei)\n    \n    def isWaterAround(self, p):\n        for nei in self.getNeisAround(p):\n            \n            if not self.inGrid(nei):\n                return True\n            \n            if not self.isGround(nei):\n                return True\n            \n        return False\n    \n    def bfs(self):\n        q = collections.deque()\n        visited = set()\n        \n        for p in self.firstIsland:\n            q.appendleft((p, 0))\n            \n        while q:\n            node, dist = q.pop()\n            \n            if self.isGround(node) and node not in self.firstIsland:\n                return dist - 1\n            \n            if node in visited:\n                continue\n                \n            visited.add(node)\n            \n            for nei in self.getNeis(node):\n                if self.inGrid(nei) and nei not in visited:\n                    q.appendleft((nei, dist + 1))\n                    \n        return -1\n    \n", "class Solution:\n    def shortestBridge(self, A: List[List[int]]) -> int:\n        \n        self.A = A\n        self.R = len(self.A)\n        self.C = len(self.A[0])\n        \n        p = self.findGround()\n        \n        if p == None:\n            return -1\n        \n        self.firstIsland = set()\n        \n        self.embraceIsland( p)\n\n        return self.bfs()\n    \n    def findGround(self):\n        for i in range(0, self.R):\n            for j in range(0, self.C):\n                if self.isGround((i, j)):\n                    return (i, j)\n                \n        return None\n    \n    def isGround(self, p):\n        return self.A[p[0]][p[1]] == 1\n    \n                \n    def inGrid(self, p):\n        \n        if not (0 <= p[0] < self.R):\n            return False\n        \n        if not (0 <= p[1] < self.C):\n            return False\n        \n        return True\n    \n    def getNeis(self, p):\n        neis = []\n        \n        neis.append((p[0] + 1, p[1]))\n        neis.append((p[0] - 1, p[1]))\n        neis.append((p[0], p[1] + 1))\n        neis.append((p[0], p[1] - 1))\n        \n        return neis\n    \n    def getNeisAround(self, p):\n        \n        neis = []\n        \n        neis.append((p[0] + 1   , p[1]))\n        neis.append((p[0] - 1   , p[1]))\n        neis.append((p[0]       , p[1] + 1))\n        neis.append((p[0]       , p[1] - 1))\n        neis.append((p[0] + 1   , p[1] + 1))\n        neis.append((p[0] + 1   , p[1] - 1))\n        neis.append((p[0] - 1   , p[1], - 1))\n        neis.append((p[0] - 1  , p[1] + 1))\n        \n        return neis\n    \n    \n    def embraceIsland(self, p):\n        \n        self.firstIsland.add(p)\n        \n        for nei in self.getNeis(p):\n            if self.inGrid(nei) and self.isGround(nei) and nei not in self.firstIsland:\n            #if self.inGrid(nei) and self.isGround(nei) and self.isWaterAround(nei) and nei not in self.firstIsland:\n                self.embraceIsland(nei)\n    \n    def isWaterAround(self, p):\n        for nei in self.getNeisAround(p):\n            if not self.inGrid(nei):\n                return True\n            \n            if not self.isGround(nei):\n                return True\n            \n        return False\n    \n    def bfs(self):\n        q = collections.deque()\n        visited = set()\n        \n        for p in self.firstIsland:\n            q.appendleft((p, 0))\n            \n        while q:\n            node, dist = q.pop()\n            \n            if self.isGround(node) and node not in self.firstIsland:\n                return dist - 1\n            \n            if node in visited:\n                continue\n                \n            visited.add(node)\n            \n            for nei in self.getNeis(node):\n                if self.inGrid(nei) and nei not in visited:\n                    q.appendleft((nei, dist + 1))\n                    \n        return -1\n    \n", "class Solution:\n    def shortestBridge(self, A: List[List[int]]) -> int:\n        # mark first island as 2 with dfs, bfs until second island is reached while adding increment for each level\n        m, n = len(A), len(A[0])\n        # find first island\n        self.first = []\n        def dfs(i, j, m, n):\n            if 0 <= i < m and 0 <= j < n and A[i][j] == 1:               \n                A[i][j] = 2\n                self.first.append((i,j))\n                for r, c in [(i+1, j), (i-1, j), (i, j+1), (i, j-1)]:\n                    dfs(r, c, m, n)\n        \n        for i in range(m):\n            for j in range(n):\n                if A[i][j] == 1:\n                    dfs(i, j, m, n)\n                    break\n            if A[i][j] == 2:\n                break\n        res = m * n\n        while self.first:\n            i, j = self.first.pop(0)\n            for r, c in [(i+1, j), (i-1, j), (i, j+1), (i, j-1)]:\n                if 0 <= r < m and 0 <= c < n:\n                    if A[r][c] == 0:\n                        A[r][c] = A[i][j] + 1\n                        self.first.append((r,c))\n                    if A[r][c] == 1:\n                        res = min(res, A[i][j] - 2)\n                        A[i][j] == -1\n                        break\n            if A[i][j] == -1:\n                break\n        return res", "class Solution:\n    def shortestBridge(self, A: List[List[int]]) -> int:\n        row_len = len(A)\n        col_len = len(A[0])\n        \n        def neighbour(r, c):\n            for i , j in [[r + 1, c], [r - 1, c], [r, c + 1], [r, c - 1]]:\n                if 0 <= i < row_len and 0 <= j < col_len:\n                    yield i, j\n        \n        def helper(A, r, c, queue):\n            if not (0 <= r < row_len and 0 <= c <col_len) or A[r][c] == 0 or A[r][c] == 2:\n                return\n            A[r][c] = 2\n            queue.append((r, c))\n            for i, j in neighbour(r, c):\n                helper(A, i, j, queue)\n                    \n                    \n        start_r = -1\n        start_c = -1\n        for r in range(row_len):\n            for c in range(col_len):\n                if A[r][c] == 1:\n                    start_r = r\n                    start_c = c\n                    break\n            \n        queue = deque()\n        helper(A, start_r, start_c, queue)\n        step = 0\n        while queue:\n            size = len(queue)\n            for i in range(size):\n                r, c = queue.popleft()\n                for i, j in neighbour(r, c):\n                    if A[i][j] == 1:\n                        return step\n                    if A[i][j] == 0:\n                        A[i][j] = 2\n                        queue.append((i, j))\n            step += 1\n", "class Solution:\n    def shortestBridge(self, A: List[List[int]]) -> int:\n        N, M = len(A), len(A[0])\n        def labelIsland(i, j):\n            stack = [(i,j)]\n            visited = {(i,j)}\n            while stack:\n                x, y = stack.pop()\n                A[x][y] = 2\n                for nx, ny in [(x-1,y), (x+1,y), (x,y-1), (x,y+1)]:\n                    if 0 <= nx < N and 0 <= ny < M and (nx,ny) not in visited:\n                        if A[nx][ny] == 1:\n                            visited.add((nx,ny))\n                            stack.append((nx, ny))\n            return visited\n        \n        def bfs(source) -> int:\n            queue = collections.deque([(0, x[0], x[1]) for x in source])\n            visited = source\n            ans = math.inf\n            while queue:\n                dist, x, y = queue.popleft()\n                for nx, ny in [(x-1,y), (x+1,y), (x,y-1), (x,y+1)]:\n                    if 0 <= nx < N and 0 <= ny < M and (nx,ny) not in visited:\n                        if A[nx][ny] == 1:\n                            return dist\n                        else:\n                            visited.add((nx,ny))\n                            queue.append((dist+1, nx, ny))\n            return ans\n                            \n        ans = math.inf\n        for i in range(N):\n            for j in range(M):\n                if A[i][j] == 1:\n                    source = labelIsland(i,j)\n                    return bfs(source)", "'''Idea is straightforward.\nWe get root of first island from \\\"first\\\" function\nWe dfs root and add indexes of the island to bfs (all indexes of island 1)\nWe bfs and expand the first island in other words\nFinally return step number when facing other island\nNote: This can also be done with referenced array if you don't want to modify A.'''\nclass Solution:\n    def shortestBridge(self, A: List[List[int]]) -> int:\n        n = len(A)\n        # get one point from any island\n        def getFirst():\n            for i, row in enumerate(A):\n                for j, point in enumerate(row):\n                    if point == 1:\n                        return (i,j)\n        islandA = []\n        boundaries = set()\n        # DFS first to find the boundary of first island\n        stack = [getFirst()]\n        while len(stack) > 0:\n            i, j = stack.pop()\n            # label it\n            A[i][j] = -1\n            islandA.append((i, j))\n            isBound = False\n            for x, y in ((i - 1, j), (i + 1, j), (i, j - 1), (i, j + 1)):\n                if 0 <= x < n and 0 <= y < n:\n                    if A[x][y] == 0:\n                        boundaries.add((i,j))\n                    elif A[x][y] == 1:\n                        stack.append((x,y))\n                    \n        \n        # all the points on island A is stored in islandA now\n        # BFS to expend it\n        step = 0\n        while boundaries:\n            new = []\n            for i, j in boundaries:\n                for x, y in ((i - 1, j), (i + 1, j), (i, j - 1), (i, j + 1)):\n                    if 0 <= x < n and 0 <= y < n:\n                        if A[x][y] == 1:\n                            return step\n                        elif not A[x][y]:\n                            A[x][y] = -1\n                            new.append((x, y))\n            step += 1\n            boundaries = new", "class Solution:\n    def mark_island(self, A, row, column, marker, border_coordinates):\n        if (0 <= row < len(A) and 0 <= column < len(A[0]) and A[row][column] != marker):\n            if (A[row][column] == 0):\n                return True\n            else:\n                A[row][column] = marker\n                rets = [self.mark_island(A, row + 1, column, marker, border_coordinates),\n                       self.mark_island(A, row - 1, column, marker, border_coordinates),\n                       self.mark_island(A, row, column + 1, marker, border_coordinates),\n                       self.mark_island(A, row, column - 1, marker, border_coordinates)]\n                \n                \n                if (True in rets):\n                    border_coordinates.append((row, column, ))\n                \n        return False\n                \n                \n                \n    def shortestBridge(self, A: List[List[int]]) -> int:\n        border_coordinates = [[], []]\n        marker = 2\n        smallest_distance = len(A) * len(A[0])\n        \n        \n        for row in range(len(A)):\n            for column in range(len(A[0])):\n                if (A[row][column] == 1):\n                    self.mark_island(A, row, column, marker, border_coordinates[marker - 2])\n                    marker += 1\n                    \n        \n        for coordinates1 in border_coordinates[0]:\n            for coordinates2 in border_coordinates[1]:\n                distance = abs(coordinates1[0] - coordinates2[0]) + abs(coordinates1[1] - coordinates2[1]) - 1\n                \n                \n                if (distance < smallest_distance):\n                    smallest_distance = distance\n            \n        return smallest_distance", "class Solution:\n    \n    def find_island(self, i, j):\n        if (i in range(self.m)) and (j in range(self.n)) and (self.grid[i][j]==1):\n            self.island.append([i,j])\n            self.grid[i][j]=-1\n            D=[[1,0],[-1,0],[0,1],[0,-1]]\n            for d in D:\n                self.find_island(i+d[0],j+d[1])\n                \n    def expand_island(self):\n        D=[[1,0],[-1,0],[0,1],[0,-1]]\n        while len(self.island)>0:\n            [i,j]=self.island.pop(0)\n            depth=abs(self.grid[i][j])\n            for d in D:\n                if (i+d[0] in range(self.m)) and (j+d[1] in range(self.n)):\n                    if self.grid[i+d[0]][j+d[1]]==1:\n                        return self.grid[i][j]+1\n                    if self.grid[i+d[0]][j+d[1]]==0:\n                        self.island.append([i+d[0], j+d[1]])\n                        self.grid[i+d[0]][j+d[1]]= -1*(depth+1)\n        \n        return self.m+self.n-1\n    \n    def shortestBridge(self, A: List[List[int]]) -> int:\n        from itertools import product\n        self.grid=A\n        self.m, self.n=len(A), len(A[0])\n        self.island=[]\n        for i, j in product(range(self.n), range(self.m)):\n            if len(self.island)==0:\n                self.find_island(i,j)\n            else:\n                break\n        \n        return abs(self.expand_island())", "class Solution:\n    def shortestBridge(self, A: List[List[int]]) -> int:\n        \n       \n        m = len(A)\n        n = len(A[0])\n        \n        def get_neighbors(i, j):\n            dirs = [\n                (-1, 0),\n                (1, 0),\n                (0, -1),\n                (0, 1),\n                \n            ]\n            \n            ans = []\n            \n            for dx, dy in dirs:\n                new_i = i + dx\n                new_j = j + dy\n                \n                if 0 <= new_i < m and 0 <= new_j < n:\n                    ans.append((new_i, new_j))\n                    \n            return ans\n        \n        def dfs_visit(i, j, visited):\n            \n            \n            if A[i][j] != 1:\n                return\n            \n            if (i, j) in visited:\n                return\n            \n            visited.add((i, j))\n            \n            for neighbor in get_neighbors(i, j):\n                dfs_visit(neighbor[0], neighbor[1], visited)\n                \n            return\n        \n        source_nodes = set()\n        break_flag = False\n        \n        \n        for i in range(m):\n            \n            if break_flag:\n                break\n            for j in range(n):\n                # print(i, j)\n                \n                if A[i][j] == 1:\n                    dfs_visit(i, j, source_nodes)\n                    break_flag = True\n                    break \n                \n        \n        q = []\n        for i, j in source_nodes:\n            q.append(((i, j), 0))\n            \n        visited = set()\n        \n        # print(q)\n            \n        while len(q):\n            curr_node, curr_dist = q.pop(0)\n            \n            for neighbor in get_neighbors(curr_node[0], curr_node[1]):\n                if neighbor in source_nodes:\n                    continue\n                    \n                if neighbor in visited:\n                    continue\n                    \n                if A[neighbor[0]][neighbor[1]] == 1:\n                    return curr_dist\n                \n                visited.add(neighbor)\n                q.append((neighbor, curr_dist + 1))\n        \n        return", "class Solution:\n    def shortestBridge(self, A: List[List[int]]) -> int:\n        \\\"\\\"\\\"\n        [[1,1,1,1,1],\n         [1,0,0,0,1],\n         [1,0,1,0,1],\n         [1,0,0,0,1],\n         [1,1,1,1,1]]\n        \n        \\\"\\\"\\\"\n        if not A: return 0\n        rows, cols = len(A), len(A[0])\n        grids = A\n        source = set()\n        target = set()\n        \n        for i in range(rows):\n            for j in range(cols):\n                if A[i][j] == 1  and not source:\n                    source = self.search_island(grids, i, j ,source)\n                elif A[i][j] == 1 and (i,j) not in source:\n                    target = self.search_island(grids, i, j, target)\n                \n        \n        queue = collections.deque([(i, j, 0) for (i, j) in source])\n        \n        visited = set()\n        #print(source)\n        #print(target)\n        \n        while queue:\n            (row, col, step) = queue.popleft()\n            \n            for (dr, dc) in [(1, 0), (0, 1), (-1, 0), (0, -1)]:\n                r = row + dr\n                c = col + dc\n                if (r, c) in target:\n                    return step\n            \n                if 0 <= r < len(grids) and 0 <= c < len(grids[0]) and grids[r][c] == 0\\\\\n           and (r, c) not in visited:\n                    visited.add((r, c))\n                    queue.append((r, c, step + 1))\n                \n    def search_island(self, grids, row, col, visited):\n        visited.add((row, col))\n        \n        for (dr, dc) in [(1, 0), (0, 1), (-1, 0), (0, -1)]:\n            r = row + dr\n            c = col + dc\n            if self.is_valid(grids, r, c, visited):\n                visited.add((r, c))\n                self.search_island(grids, r, c, visited)\n        \n        return visited\n\n    def is_valid(self, grids, row, col, visited):\n        if 0 <= row < len(grids) and 0 <= col < len(grids[0]) and grids[row][col] == 1\\\\\n           and (row, col) not in visited:\n            return True\n        return False", "class Solution:\n    def shortestBridge(self, A: List[List[int]]) -> int:\n        def trace_island(A, start_i, start_j, second, edges):\n            queue = collections.deque()\n            queue.append((start_i, start_j))\n            \n            while queue:\n                i, j = queue.popleft()\n                isedge = False\n                for di, dj in [(1, 0), (0, 1), (-1, 0), (0, -1), (0, 0)]:\n                    if  0 <= di+i < len(A) and 0<= dj+j < len(A[0]) and A[di+i][dj+j] == 1:\n                        if second:\n                            A[di+i][dj+j] = 2\n                        else:\n                            A[di+i][dj+j] = -1\n\n                        if not (di ==0 and dj==0):\n                            queue.append((di+i, dj+j))\n                    else:\n                        isedge = True\n                if isedge and not second:\n                    edges.append((i,j))\n            \n        \n        outedge = []\n        second = False\n        for i in range(len(A)):\n            for j in range(len(A[0])):\n                if A[i][j] == 1:\n                    trace_island(A, i, j, second, outedge)\n                    print(A)\n                    second = True\n        output = 0\n        while(outedge):\n            temp = []\n            for i, j in outedge:\n                for di, dj in [(1, 0), (0, 1), (-1, 0), (0, -1)]:\n                    if  0 <= di+i < len(A) and 0<= dj+j < len(A[0]) and A[di+i][dj+j] != -1:\n                        if A[di+i][dj+j] == 2:\n                            return output\n                        temp.append((di+i, dj+j))\n                        A[di+i][dj+j] = -1\n            outedge = temp\n            output += 1\n\n    \n                \n                    \n                    \n        \n", "class Solution:\n    def shortestBridge(self, A: List[List[int]]) -> int:\n        def findIslandA(i, j):\n          A[i][j] = -1\n          islandA.append((i, j))\n          for x, y in ((i - 1, j), (i + 1, j), (i, j - 1), (i, j+1)):\n            if 0 <= x < n and 0 <= y < n and A[x][y] == 1:\n              findIslandA(x, y)\n              \n        def first():\n          for i in range(n):\n            for j in range(n):\n              if A[i][j]:\n                return i, j\n              \n        n, step, islandA = len(A), 0, []\n        findIslandA(*first())\n        while islandA:\n          boundaries = []\n          for i, j in islandA:\n            for x, y in ((i - 1, j), (i + 1, j), (i, j - 1), (i, j+1)):\n              if 0 <= x < n and 0 <= y < n:\n                if A[x][y] == 1:\n                  return step\n                elif A[x][y] == 0:\n                  A[x][y] = -1\n                  boundaries.append((x, y))\n          step += 1\n          islandA = boundaries", "class Solution:\n    def shortestBridge(self, grid: List[List[int]]) -> int:\n        def dfs(curr_i, curr_j, outliners):\n            visited.add((curr_i, curr_j))\n            for delta_i, delta_j in [(1, 0), (0, 1), (0, -1), (-1, 0)]:\n                next_i, next_j = curr_i + delta_i, curr_j + delta_j\n                if 0 <= next_i < m and 0 <= next_j < n:\n                    if grid[next_i][next_j] == 0:\n                        outliners.add((next_i, next_j))\n                    elif grid[next_i][next_j] == 1:\n                        if (next_i, next_j) not in visited:\n                            dfs(next_i, next_j, outliners)\n                                       \n\n        m, n = len(grid), len(grid[0])\n        visited = set()\n        outliners_1, outliners_2 = set(), set()\n        for i in range(m):\n            for j in range(n):\n                if grid[i][j] == 1 and (i, j) not in visited:\n                    if len(outliners_1) == 0:\n                        dfs(i, j, outliners_1)\n                    else:\n                        dfs(i, j, outliners_2)\n        \n        min_dist = m + n\n        for (i, j) in outliners_1:\n            for (p, q) in outliners_2:\n                min_dist = min(min_dist, abs(i - p) + abs(j - q) + 1)\n        return min_dist", "class Solution:\n    \n    def find_island(self, i, j):\n        if (i in range(self.m)) and (j in range(self.n)) and (self.grid[i][j]==1):\n            self.island.append([i,j])\n            self.grid[i][j]=-1\n            D=[[1,0],[-1,0],[0,1],[0,-1]]\n            for d in D:\n                self.find_island(i+d[0],j+d[1])\n                \n    def expand_island(self):\n        D=[[1,0],[-1,0],[0,1],[0,-1]]\n        while len(self.island)>0:\n            [i,j]=self.island.pop(0)\n            depth=abs(self.grid[i][j])\n            for d in D:\n                if (i+d[0] in range(self.m)) and (j+d[1] in range(self.n)):\n                    if self.grid[i+d[0]][j+d[1]]==1:\n                        return depth-1\n                    if self.grid[i+d[0]][j+d[1]]==0:\n                        self.island.append([i+d[0], j+d[1]])\n                        self.grid[i+d[0]][j+d[1]]= -1*(depth+1)\n        \n        return self.m+self.n-1\n\n    \n    def shortestBridge(self, A: List[List[int]]) -> int:\n        from itertools import product\n        self.grid=A\n        self.m, self.n=len(A), len(A[0])\n        self.island=[]\n        for i, j in product(range(self.n), range(self.m)):\n            if len(self.island)==0:\n                self.find_island(i,j)\n            else:\n                break\n        \n        res=self.expand_island()\n        return res", "class Solution:\n    def shortestBridge(self, A: List[List[int]]) -> int:\n        \n        \n        N = len(A)\n        def neighbors(r, c):\n            for dr, dc in (r+1, c), (r-1, c), (r, c+1), (r, c-1):\n                if 0 <= dr < N and 0 <= dc < N:\n                    yield dr, dc\n        \n        def get_components():\n            visited = set()\n            island = []\n            for r in range(N):\n                for c in range(N):\n                    if A[r][c] == 1 and (r, c) not in visited:\n                        stack = [(r, c)]\n                        seen = {(r, c)}\n                        while stack:\n                            i, j = stack.pop()\n                            for dr, dc in neighbors(i, j):\n                                if A[dr][dc] == 1 and (dr, dc) not in seen:\n                                    stack.append((dr, dc))\n                                    seen.add((dr, dc))\n                        island.append(seen)\n                        visited |= seen\n            return island\n    \n        island = get_components()\n        queue = collections.deque([(node, 0) for node in island[0]])\n        visited=island[0]\n        while queue:\n            node, d = queue.popleft()\n            if node in island[1]:\n                return d-1\n            for r, c in neighbors(*node):\n                if (r, c) not in visited:\n                    queue.append(((r,c), d+1))\n                    visited |= set([(r, c)])\n        \n        \\\"\\\"\\\"\n        nrow, ncol = len(A), len(A[0])\n        \n        def is_valid(nr, nc):\n            if 0 <= nr < nrow and 0 <= nc < ncol:\n                return True\n            return False\n        \n        def get_components():\n            visited = set()\n            components = []\n            for r, row in enumerate(A):\n                for c, val in enumerate(row):\n                    if val and (r, c) not in visited:\n                        stack = [(r, c)]\n                        seen = {(r, c)}\n                        while stack:\n                            r1, c1 = stack.pop()\n                            for nei in ((r1-1, c1), (r1+1, c1), (r1, c1-1), (r1, c1+1)):\n                                if is_valid(nei[0], nei[1]) and A[nei[0]][nei[1]] and nei not in seen:\n                                    stack.append(nei)\n                                    seen.add(nei)\n                        visited = visited.union(seen) # visited |= seen\n                        components.append(seen)\n            return components\n        \n        components = get_components()\n        print (components)\n        \\\"\\\"\\\"\n\n            \n        \n                    ", "class Solution:\n    def shortestBridge(self, A):\n        \n        \n        # This function is used to find the first index equal to one\n        # Will be the first island's root node\n        def first():\n            for i in range(n):\n                for j in range(n):\n                    if A[i][j]:\n                        return i, j\n        \n        # Depth first search (recursive)\n        def dfs(i, j):\n            # Mark all seen elements with -1 so we don't look at them again\n            A[i][j] = -1\n            # Append element to bfs list\n            bfs.append((i, j))\n            # Look at all points around (i,j)\n            for x, y in ((i - 1, j), (i + 1, j), (i, j - 1), (i, j + 1)):\n                # If point is feasable and its part of the island, apply dfs again\n                if 0 <= x < n and 0 <= y < n and A[x][y] == 1:\n                    dfs(x, y)\n\n        n, step, bfs = len(A), 0, []\n        # Populate bfs list (first island)\n        dfs(*first())\n        # Idea is to look at all points contiguous to the first island, and store them in\n        # new list, while marking them as seen (-1)\n        # Now you cycle through this new list, and see if you touch the second island (any\n        # point = 1) If not, need another step and repeat\n        while bfs:\n            new = []\n            # Cycle through all the points\n            for i, j in bfs:\n                for x, y in ((i - 1, j), (i + 1, j), (i, j - 1), (i, j + 1)):\n                    if 0 <= x < n and 0 <= y < n:\n                        if A[x][y] == 1:\n                            return step\n                        elif not A[x][y]:\n                            A[x][y] = -1\n                            new.append((x, y))\n            step += 1\n            bfs = new\n        \n", "class Solution:\n    def shortestBridge(self, A: List[List[int]]) -> int:\n        \n        def dfs(i, j, A, visited):\n            m = len(A)\n            n = len(A[0])\n            if 0<=i<m and 0<=j<n and A[i][j] == 1 and (i, j) not in visited:\n                visited.add((i,j))\n                dfs(i+1, j, A, visited)\n                dfs(i-1, j, A, visited)\n                dfs(i, j+1, A, visited)\n                dfs(i, j-1, A, visited)\n\n        m = len(A)\n        n = len(A[0])\n        find = False\n        visited = set()\n        for i in range(m):\n            for j in range(n):\n                if A[i][j] == 1:\n                    find = True\n                    dfs(i, j, A, visited)\n                    break\n            if find:\n                break\n        \n        # print(visited)\n        \n        visited_zero = set()\n        queue = []\n        for i, j in visited:\n            for _i, _j in [[0,1],[1,0],[-1,0],[0,-1]]:\n                if 0<=i+_i<m and 0<=j+_j<n and (i+_i, j+_j) not in visited:\n                    assert A[i+_i][j+_j] == 0\n                    visited_zero.add((i+_i, j+_j))\n                    queue.append((i+_i, j+_j, 1))\n        \n        # print(queue)\n        \n        res = 0\n        find = False\n        while not find:\n            i, j, dist = queue.pop(0)\n            for _i, _j in [[0,1],[1,0],[-1,0],[0,-1]]:\n                if 0<=i+_i<m and 0<=j+_j<n and (i+_i, j+_j) not in visited_zero and (i+_i, j+_j) not in visited:\n                    if A[i+_i][j+_j] == 0:\n                        visited_zero.add((i+_i, j+_j))\n                        queue.append((i+_i, j+_j, dist+1))\n                    else:\n                        find = True\n                        res = dist\n        return res", "class Solution:\n    DIRS = ((1, 0), (-1, 0), (0, 1), (0, -1))\n\n    def shortestBridge(self, A: List[List[int]]) -> int:\n        m, n = len(A), len(A[0])\n        \n        # Mark island1 and island2\n        visited = set()\n        islands = []\n        for i in range(m):\n            for j in range(n):\n                if A[i][j] != 1 or (i, j) in visited:\n                    continue\n                    \n                seen = {(i, j)}\n                self.__class__.dfs(A, i, j, seen)\n\n                visited |= seen    # union\n                islands.append(copy.deepcopy(seen))\n                    \n        print(islands)\n        source, target = islands\n        \n        # Flood fill\n        queue = list(source)\n        visited = source\n        step = 0\n        while queue:\n            for _ in range(len(queue)):\n                i, j = queue.pop(0)\n                print(i, j)\n                if (i, j) in target:\n                    return step - 1\n                \n                for delta in self.__class__.DIRS:\n                    x, y = i + delta[0], j + delta[1]\n                    if x < 0 or x >= m or \\\\\n                            y < 0 or y >= n:\n                        continue\n                    if (x, y) in visited:\n                        continue\n                        \n                    visited.add((x, y))\n                    queue.append((x, y))\n            step += 1\n                    \n        return -1\n    \n    @classmethod\n    def dfs(cls, A, i, j, visited):\n        m, n = len(A), len(A[0])\n        \n        for delta in cls.DIRS:\n            x, y = i + delta[0], j + delta[1]\n            if x < 0 or x >= m or \\\\\n                    y < 0 or y >= n:\n                continue\n                \n            if A[x][y] != 1 or (x, y) in visited:\n                continue\n            \n            visited.add((x, y))\n            cls.dfs(A, x, y, visited)\n\n        ", "class Solution:\n    \n    def find_island(self, i, j):\n        if (i in range(self.m)) and (j in range(self.n)) and (self.grid[i][j]==1):\n            self.island.append([i,j])\n            self.grid[i][j]=-1\n            D=[[1,0],[-1,0],[0,1],[0,-1]]\n            for d in D:\n                self.find_island(i+d[0], j+d[1])\n    \n    def expand_island(self):\n        D=[[1,0],[-1,0],[0,1],[0,-1]]\n        while len(self.island)>0:\n            [i,j]=self.island.pop(0)\n            for d in D:\n                if (i+d[0] in range(self.m)) and (j+d[1] in range(self.n)):\n                    if self.grid[i+d[0]][j+d[1]]==1:\n                        return self.grid[i][j]+1\n                    if self.grid[i+d[0]][j+d[1]]==0:\n                        self.island.append([i+d[0], j+d[1]])\n                        self.grid[i+d[0]][j+d[1]]= self.grid[i][j]-1\n        return self.m+self.n-1\n    \n    def shortestBridge(self, A: List[List[int]]) -> int:\n        from itertools import product\n        self.grid=A\n        self.m, self.n=len(A), len(A[0])\n        self.island=[]\n        for i, j in product(range(self.n), range(self.m)):\n            if len(self.island)==0:\n                self.find_island(i,j)\n            else:\n                break    \n        return abs(self.expand_island())", "class Solution:\n    def shortestBridge(self, A: List[List[int]]) -> int:\n        q = []\n        r = len(A)\n        c = len(A[0])\n        result = float('inf')\n        seen = [[False]*c for _ in range(r)]\n        found = False\n        for i in range(r):\n            if found:\n                break\n            for j in range(c):\n                if A[i][j] == 1:\n                    # add all the 1's which are connected to this (i, j) to the q\n                    q = self.neighbors(i, j, A, seen, r, c)\n                    found = True\n                    break\n                    \n        # explore all points near to these elements in the q and keep the min distance\n        # if I see any 1\n        while q:\n            x, y, dis = q.pop(0)\n            for d1, d2 in ((-1, 0), (0, -1), (1, 0), (0, 1)):\n                n_x, n_y = d1+x, d2+y\n                if 0 <=n_x<r and 0 <=n_y<c and not seen[n_x][n_y]:\n                    if A[n_x][n_y] == 1:\n                        result = min(result, dis)\n                    q.append((n_x, n_y, dis+1))\n                    seen[n_x][n_y] = True\n            \n        return result\n    \n    def neighbors(self, i, j, A, seen, r, c):\n        q = [(i, j)]\n        seen[i][j] = True\n        ls = []\n        while q:\n            x, y = q.pop(0)\n            # distance is zero for all these 1\n            ls.append((x, y, 0))\n            for d1, d2 in ((-1, 0), (0, -1), (1, 0), (0, 1)):\n                n_x, n_y = d1+x, d2+y\n                if 0 <=n_x<r and 0 <=n_y<c and A[n_x][n_y]==1 and not seen[n_x][n_y]:\n                    q.append((n_x, n_y))\n                    seen[n_x][n_y] = True\n        return ls", "class Solution:\n    def shortestBridge(self, A: List[List[int]]) -> int:\n        '''\n        1111\n        1001\n        0000\n        1000\n        1110\n        '''\n        \n\n        i1, i2 = self.find_islands(A)\n        \n        for (x, y, n) in self.enlarge(i1):\n            if (x, y) in i2: return n\n        \n    \n    def find_islands(self, A: List[List[int]]) -> List[Set[Tuple[int, int]]]:\n        visited = set()\n        islands = []\n        for x, ys in enumerate(A):\n            for y, c in enumerate(ys):\n                if (x, y) not in visited and c == 1:\n                    to_visit = [(x,y)]\n                    island = set()\n                    while to_visit:\n                        cx, cy = to_visit.pop(0)\n                        if (cx, cy) in visited: continue\n                        visited.add((cx, cy))\n                        island.add((cx, cy))\n                        for (ax, ay) in self.adjacent((cx, cy)):\n                            if ax >= 0 and ay >= 0 and ax < len(A) and ay < len(A[ax]) and A[ax][ay] == 1:\n                                to_visit.append((ax, ay))\n                    islands.append(island)\n        return islands\n                    \n    \n    def enlarge(self, island: Set[Tuple[int, int]]) -> Generator[Tuple[int, int, int], None, None]:\n        visited = set()\n        to_visit = []\n        for x, y in island:\n            visited.add((x, y))\n            for ax, ay in self.adjacent((x, y)):\n                visited.add((x, y))\n                if (ax, ay) not in island:\n                    to_visit.append((ax, ay, 0))\n        while to_visit:\n            x, y, n = to_visit.pop(0)\n            if (x, y) in visited: continue\n            visited.add((x, y))\n            for ax, ay in self.adjacent((x, y)):\n                if (ax, ay) in visited: continue\n                to_visit.append((ax, ay, n + 1))\n            yield x, y, n\n        \n    \n    def adjacent(self, cell: Tuple[int, int]) -> List[Tuple[int, int]]:\n        return [(cell[0]+x, cell[1]+y) for x, y in [(-1, 0), (1, 0), (0, -1), (0, 1)]]", "class Solution:\n    def shortestBridge(self, A: List[List[int]]) -> int:\n        R, C = len(A), len(A[0])\n\n        def neighbors(r, c):\n            for nr, nc in ((r-1,c),(r,c-1),(r+1,c),(r,c+1)):\n                if 0 <= nr < R and 0 <= nc < C:\n                    yield nr, nc\n\n        def get_components():\n            done = set()\n            components = []\n            for r, row in enumerate(A):\n                for c, val in enumerate(row):\n                    if val and (r, c) not in done:\n                        # Start dfs\n                        stack = [(r, c)]\n                        seen = {(r, c)}\n                        while stack:\n                            node = stack.pop()\n                            for nei in neighbors(*node):\n                                if A[nei[0]][nei[1]] and nei not in seen:\n                                    stack.append(nei)\n                                    seen.add(nei)\n                        done.update(seen)\n                        components.append(seen)\n            return components\n\n        source, target = get_components()\n        print(source, target)\n        queue = collections.deque([(node, 0) for node in source])\n        done = set(source)\n        while queue:\n            node, d = queue.popleft()\n            if node in target: return d-1\n            for nei in neighbors(*node):\n                if nei not in done:\n                    queue.append((nei, d+1))\n                    done.add(nei)"]