#include<cstring>
#include<algorithm>
#include<iostream>
#include<cstdio>
#include<queue>
#define de system("pause");
using namespace std;
int r,c;
char s[600][600];
int aim[5];
int ans=1000000;
bool bz[600][600][5];
bool check(int way,int x,int y)
{
if(x<1||x>r||y<1||y>c)return 0;
if(way==1)
{
if(s[x][y]=='#'||s[x][y+1]=='#')return 0;
if(bz[x][y][1])return 0;
}
if(way==2)
{
if(s[x][y]=='#'||s[x+1][y]=='#')return 0;
if(bz[x][y][2])return 0;
}
if(way==3)
{
if(s[x][y]=='#'||s[x][y]=='E')return 0;
if(bz[x][y][3])return 0;
}
return 1;
}
struct node
{
int way,x,y,step;
node(int wa,int xx,int yy,int ste)
{
way=wa;
x=xx;
y=yy;
step=ste;
}
};
queue<node> q;
void so(int x,int y,int way,int step)
{
bz[x][y][way]=1;
q.push(node(way,x,y,step));
if(way==3&&s[x][y]=='O')
{
// cout<<step<<endl;
ans=min(ans,step);
}
}
void bfs()
{
while(!q.empty())
{
node now=q.front();
int x=now.x,y=now.y,way=now.way,step=now.step;
q.pop();
// bz[x][y][way]=0;
if(way==1)
{
if(check(1,x-1,y)) so(x-1,y,1,step+1);
if(check(1,x+1,y)) so(x+1,y,1,step+1);
if(check(3,x,y-1)) so(x,y-1,3,step+1);
if(check(3,x,y+2)) so(x,y+2,3,step+1);
}
if(way==2)
{
if(check(3,x-1,y)) so(x-1,y,3,step+1);
if(check(3,x+2,y)) so(x+2,y,3,step+1);
if(check(2,x,y-1)) so(x,y-1,2,step+1);
if(check(2,x,y+1)) so(x,y+1,2,step+1);
}
if(way==3)
{
if(check(2,x-2,y)) so(x-2,y,2,step+1);
if(check(2,x+1,y)) so(x+1,y,2,step+1);
if(check(1,x,y-2)) so(x,y-2,1,step+1);
if(check(1,x,y+1)) so(x,y+1,1,step+1);
}
}
}
int main()
{
while(1)
{
while(q.size())q.pop();
memset(bz,0,sizeof bz);
scanf("%d%d",&r,&c);
if(r==0&&c==0)break;
int a[10][3];
int cnt=0;
ans=1000000;
for(int i=1;i<=r;++i)
{
scanf("%s",s[i]+1);
for(int j=1;j<=c;j++)
{
if(s[i][j]=='X')
{
++cnt;
a[cnt][1]=i,a[cnt][2]=j;
}
}
}
if(cnt==1) q.push(node(3,a[cnt][1],a[cnt][2],0));
else
{
if(a[1][1]==a[2][1]) q.push(node(1,a[1][1],a[1][2],0));
else q.push(node(2,a[1][1],a[1][2],0));
}
bfs();
if(ans==1000000)puts("Impossible");
else cout<<ans<<endl;
}
return 0;
}