#include <iostream>
#include <cstring>
#include <queue>
#include <algorithm>

using namespace std;

struct Grid {
	int x;
	int y;
};

int n, m;
bool ans = false;
int direction[4][2] = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};
char c[1005][1005];
int vis[1005][1005];

//记录一下c++的一些语法
//1.关于填充arr,可以使用fill(arr, arr + n, val) / fill_n(arr, count, val)使用迭代器(地址)填充,支持vector和arr填充,但是本质依旧是遍历,和for时间一样
//对于int / long long如果填充为0的话可以使用memset(arr, val, sizeof(arr)),对于char可以填充为任意char,因为memset本质是按字节填充连续内存,对于char只占一个字节所以可以填充为任意值,且memset填充比for要快
//sizeof()获取对象字节数, memset需要incldue<cstring>

//2.对于int *a1 = new int[m];分配的是连续的int空间,而int **a = new int*[n];只是初始化了n个连续指针变量,a[i] = a1之后a的行内内存连续,行间不连续,不能使用memset,所以需要静态数组int a[1005][1005]是一块连续内存

int main() {
	cin >> n >> m;
	cin.ignore();
	int s_x, s_y, e_x, e_y;
	for(int i = 0; i < n; i++) {
		for(int j = 0;  j < m; j++) {
			cin >> c[i][j];
			if (c[i][j] == 'S') {
				s_x = i;
				s_y = j;
			}
			if (c[i][j] == 'E') {
				e_x = i;
				e_y = j;
			}
		}
	}
	//计算S联通块的范围 
	queue<Grid> q;				 
	Grid st;
	st.x = s_x;
	st.y = s_y;
	q.push(st);
	vis[st.x][st.y] = 1;
	int min_x = 1005, min_y = 1005, max_x = -1, max_y = -1;
	while (!q.empty()) {
		Grid g = q.front();
		q.pop();
		if (c[g.x][g.y] == 'E') ans = true;
		min_x = min(min_x, g.x);
		min_y = min(min_y, g.y);
		max_x = max(max_x, g.x);
		max_y = max(max_y, g.y);
		for (int k = 0; k < 4; k++) {
			int x = g.x + direction[k][0];
			int y = g.y + direction[k][1];
			if (x > -1 && x < n && y > -1 && y < m && !vis[x][y] && c[x][y] != '#') {
				vis[x][y] = 1;
				Grid new_grid;
				new_grid.x = x;
				new_grid.y = y;
				q.push(new_grid); 
			} 
		}
	}
	if (!ans) {
		min_x = max(min_x - 1, 0);
		min_y = max(min_y - 1, 0);
		max_x = min(max_x + 1, n - 1);
		max_y = min(max_y + 1, m - 1);
		memset(vis, 0, sizeof(vis));				 
//		Grid st;
		st.x = e_x;
		st.y = e_y;
		q.push(st);
		vis[st.x][st.y] = 1;
		while (!q.empty()) {
			Grid g = q.front();
			q.pop();
			if ((g.x <= max_x && g.x >= min_x) || (g.y <= max_y && g.y >= min_y)) {
				ans = true;
				break;
			}
			for (int k = 0; k < 4; k++) {
				int x = g.x + direction[k][0];
				int y = g.y + direction[k][1];
				if (x > -1 && x < n && y > -1 && y < m && !vis[x][y] && c[x][y] != '#') {
					vis[x][y] = 1;
					Grid new_grid;
					new_grid.x = x;
					new_grid.y = y;
					q.push(new_grid); 
				} 
			}
		}
	}		
	cout << (ans ? "YES" : "NO") << endl;
}