import java.io.*; import java.util.*; import java.math.*; class Main { static int h , w; static String[] field; static int[] dx = {0,0,-1,1}; static int[] dy = {-1,1,0,0}; static boolean[][] isSearched; public static void out (Object o) { System.out.println(o); } public static int[] getBlank () { int start = -1; ArrayList list = new ArrayList(); main:for (int i = 0; i < h; i++) { for (int j = 0; j < w; j++) { if (field[i].charAt(j) == '#' || isSearched[i][j]) continue; isSearched[i][j] = true; start = j << 5 | i; break main; } } list.add(start); Queue queue = new LinkedList(); queue.add(start); while (!queue.isEmpty()) { int q = queue.poll(); int x = q >> 5; int y = q & 15; for (int i = 0; i < dx.length; i++) { int moveX = x + dx[i]; int moveY = y + dy[i]; if (moveX < 0 || moveX >= w || moveY < 0 || moveY >= h) continue; if (field[moveY].charAt(moveX) == '#' || isSearched[moveY][moveX]) continue; list.add(moveX << 5 | moveY); isSearched[moveY][moveX] = true; queue.add(moveX << 5 | moveY); } } int[] ret = new int[list.size()]; for (int i = 0; i < list.size(); i++) ret[i] = list.get(i); return ret; } public static int solve () { int ret = Integer.MAX_VALUE; int[] bl1 = getBlank(); int[] bl2 = getBlank(); //out(bl1.length + "," + bl2.length); for (int i = 0; i < bl1.length; i++) { int x1 = bl1[i] >> 5; int y1 = bl1[i] & 15; //out(x1 + "," + y1); for (int j = 0; j < bl2.length; j++) { int x2 = bl2[j] >> 5; int y2 = bl2[j] & 15; //out("(" + x1 + "," + y1 + ") - (" + x2 + "," + y2 + ")"); ret = Math.min(ret , Math.abs(x1 - x2) + Math.abs(y1 - y2) - 1); } } return ret; } public static void main (String[] args) throws IOException { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); String[] line = br.readLine().split(" "); w = Integer.parseInt(line[0]); h = Integer.parseInt(line[1]); field = new String[h]; isSearched = new boolean[h][w]; for (int i = 0; i < h; i++) { field[i] = br.readLine(); } out(solve()); } }