// bfs 主要在怎么扩展下一个数,即:
// 1. 定义状态 : 因为 立着、横躺,竖躺需要判断的坐标不一样,所有定义为这三个状态
// 2. 定义状态转移:即 trans, 当前状态的所有下一个状态的可能值
// 3. 状态合法性判断: 判断新状态是否合法
import java.util.*;
public class Main{
class Status{
// 0 立着
// 1 横躺
// 2 竖躺
int x,y,s;
public Status(int x, int y, int s) {this.x = x; this.y = y; this.s = s;}
}
void run(){
while(jin.hasNext()){
int N = jin.nextInt();
int M = jin.nextInt();
if (N == 0 && M == 0) break;
for (int i = 0 ; i < N ; i++) maze[i] = jin.next().toCharArray();
for (int i = 0 ; i < 3 ; i++) {
for (int j = 0 ; j < maxN ; j++){ // 这里初始化错误找了好久(;´༎ຶД༎ຶ`)
for (int k = 0 ; k < maxN ; k++){ //
distance[i][j][k] = -1;
}
}
}
int answer = solve(N, M);
if (answer == -1) System.out.println("Impossible");
else System.out.println(answer);
}
}
int solve(int N ,int M){
Status start = new Status(-1,-1,0);
Status end = new Status(-1,-1,0);
for (int i = 0 ; i < N ; i++){
for (int j = 0 ; j < M ; j++){
if (maze[i][j] == 'X' && start.x == -1){
if(maze[i+1][j] == 'X') start.s = 2;
else if (maze[i][j+1] == 'X') start.s = 1;
start.x = i;
start.y = j;
} else if (maze[i][j] == 'O') {
end.x = i;
end.y = j;
}
}
}
return bfs( N , M, start, end);
}
int bfs(int N ,int M, Status start, Status end){
queue.clear();
queue.offer(start);
distance[start.s][start.x][start.y] = 0;
while(!queue.isEmpty()){
var s = queue.poll();
for(int i = 0 ; i < 4 ; i++){
// int[] t = trans[s.s][i] // 这么写会MLE
Status next = new Status(s.x+trans[s.s][i][1], s.y+trans[s.s][i][2], trans[s.s][i][0]);
if (!check(next, N, M)) continue;
distance[next.s][next.x][next.y] = distance[s.s][s.x][s.y] + 1;
queue.offer(next);
}
}
return distance[end.s][end.x][end.y];
}
boolean check(Status s, int N, int M){
if(s.x <0 || s.x >= N || s.y < 0 || s.y >= M || maze[s.x][s.y] == '#') return false;
if(s.s == 0 && maze[s.x][s.y] == 'E') return false;
if(distance[s.s][s.x][s.y] != -1) return false;
// if(s.s == 1 && (s.x+1 >= N || maze[s.x+1][s.y] == '#')) return false; // 横躺应该判断y
// if(s.s == 2 && (s.y+1 >= M || maze[s.x][s.y+1] == '#')) return false;
if(s.s == 1 && (s.y+1 >= M || maze[s.x][s.y+1] == '#')) return false;
if(s.s == 2 && (s.x+1 >= N || maze[s.x+1][s.y] == '#')) return false;
return true;
}
private int maxN = 502;
private int statusNumber = 3;
private char[][] maze = new char[maxN][maxN];
private int[][][] distance = new int[statusNumber][maxN][maxN];
Queue<Status> queue = new LinkedList<>();
private int[][][] trans = {
{{2, -2, 0}, {2, 1, 0}, {1, 0, -2}, {1, 0, 1}},
{{1, -1, 0}, {1 ,1, 0}, {0, 0, -1}, {0, 0, 2}},
{{0, -1, 0}, {0, 2 ,0}, {2, 0, -1}, {2, 0, 1}}
};
private Scanner jin = new Scanner(System.in);
public static void main(String[] args) throws Exception {new Main().run();}
}