//#include <iostream>
#include <fstream>
#include <vector>
#include <set>
#include <map>
#include <cstring>
#include <string>
#include <cmath>
#include <cassert>
#include <ctime>
#include <algorithm>
#include <sstream>
#include <list>
#include <queue>
#include <deque>
#include <stack>
#include <cstdlib>
#include <cstdio>
#include <iterator>
#include <functional>
#include <bitset>
#define mp make_pair
#define pb push_back

#ifdef LOCAL
#define eprintf(...) fprintf(stderr,__VA_ARGS__)
#else
#define eprintf(...)
#endif

#define TIMESTAMP(x) eprintf("["#x"] Time : %.3lf s.\n", clock()*1.0/CLOCKS_PER_SEC)
#define TIMESTAMPf(x,...) eprintf("[" x "] Time : %.3lf s.\n", __VA_ARGS__, clock()*1.0/CLOCKS_PER_SEC)

#if ( _WIN32 || __WIN32__ )
    #define LLD "%I64d"
#else
    #define LLD "%lld"
#endif

using namespace std;

#define TASKNAME "park"

#ifdef LOCAL
static struct __timestamper {
    ~__timestamper(){
        TIMESTAMP(end);
    }
} __TIMESTAMPER;
#endif

typedef long long ll;
typedef long double ld;

const int MAXN = 510;

char s[MAXN][MAXN];
int d[MAXN][MAXN];
int h,w;

const int dx[4] = {0, 1, 0, -1};
const int dy[4] = {1, 0, -1, 0};

void bfs(int x, int y){
    memset(d, 0x3f, sizeof(d));
    queue<int> qx, qy;
    qx.push(x);
    qy.push(y);
    d[x][y] = 0;
    while (!qx.empty()){
        int x = qx.front(); qx.pop();
        int y = qy.front(); qy.pop();                   
        for (int i = 0; i < 4; i++){
            int nx = x + dx[i];
            int ny = y + dy[i];                                                           
            if (nx < 0 || nx >= h) continue;                                              
            if (ny < 0 || ny >= w) continue;                                              
            if (s[nx][ny] == '#') continue;                 
            if (d[nx][ny] > d[x][y] + 1){
                d[nx][ny] = d[x][y] + 1;
                qx.push(nx);
                qy.push(ny);
            }
        }
    }
}

int dst[MAXN][MAXN][2];
int dcnt[MAXN][MAXN][2];
const int MOD = 1000000009;


int main(){
  freopen(TASKNAME".in","r",stdin);
  freopen(TASKNAME".out","w",stdout);
  
  scanf("%d %d",&h,&w);

  for (int i = 0; i < h; i++)
      for (int j = 0; j < w; j++)
          scanf(" %c", &s[i][j]);

  int sx, sy;
  sx = sy = -1;

  for (int i = 0; i < h; i++)
       for (int j = 0; j < w; j++)
           if (s[i][j] == 'X'){
               bfs(i, j);
           } else if (s[i][j] == 'E'){
               sx = i;
               sy = j;
           }

  assert(sx != -1);

           
  if (d[sx][sy] > w*h){
    eprintf("No way!\n");
  	printf("0\n");
  	return 0;
  } 

  memset(dst, 0x3f, sizeof(dst));

  queue<int> qx, qy, qt;
  qx.push(sx);
  qy.push(sy);
  qt.push(0);

  dst[sx][sy][0] = 0;
  dcnt[sx][sy][0] = 1;


  while (!qx.empty()){
  	int x = qx.front(); qx.pop();
  	int y = qy.front(); qy.pop();
  	int t = qt.front(); qt.pop();
//  	eprintf("%d %d %d %c\n", x, y, t, s[x][y]);
  	if (s[x][y] == 'X' && t == 1){
  		printf("%d\n", dcnt[x][y][t]);
  		return 0;
  	}
    for (int i = 0; i < 4; i++){
        int nx = x + dx[i];
        int ny = y + dy[i];
        int nt = t;
//        eprintf("(%d, %d, %d) -> (%d, %d, %d)\n", x, y, t, nx, ny, nt);
        if (nx < 0 || nx >= h) continue;                               
        if (ny < 0 || ny >= w) continue;
        if (s[nx][ny] == '#') continue;
        if (d[nx][ny] != d[x][y] - 1) {
        	nt++;
        	assert(d[nx][ny] == d[x][y] + 1);
        }                                                              
        if (nt == 2) continue;                                         
        if (dst[nx][ny][nt] > dst[x][y][t] + 1){
            dst[nx][ny][nt] = dst[x][y][t] + 1;
            dcnt[nx][ny][nt] = dcnt[x][y][t];
            qx.push(nx);
            qy.push(ny);
            qt.push(nt);
        } else if (dst[nx][ny][nt] == dst[x][y][t] + 1){
            dcnt[nx][ny][nt] += dcnt[x][y][t];
            if (dcnt[nx][ny][nt] >= MOD)
                dcnt[nx][ny][nt] -= MOD;
        }
    }
  }
  assert(false);

  return 0;
}