#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;
}