#include <iostream>
#include <queue>
#include <algorithm>
#include <vector>
#include <algorithm>
#include <set>
#include <cstring>
using namespace std;
int dist_S[1001][1001];
int dist_E[1001][1001];
char mat[1001][1001];
bool visited[1001][1001];

int main() {
    ios_base::sync_with_stdio(false);
    int n,m;
    cin >> n >> m;
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            cin >> mat[i][j];
            dist_S[i][j] = -1;
            dist_E[i][j] = -1;
        }
    }
    memset(visited, false,sizeof visited);
 
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            queue<int> q;
            if(mat[i][j] == 'S'){
                q.push(i);
                q.push(j);
                q.push(0);
                visited[i][j] = true;
                
            
            while(!q.empty()){
                int ci = q.front();
                q.pop();
                int cj =q.front();
                q.pop();
                int dist= q.front();
                q.pop();
                if(mat[ci][cj] == 'E') {
                    cout << dist << endl;
                    return 0;
                }
                if(ci-1>=0 &&  !visited[ci-1][cj]){

                    if(mat[ci-1][cj] == '#'){
                        dist_S[ci - 1][cj] = (dist + 1);
                        
                    }
                    else {
                    visited[ci-1][cj] = true;
                    q.push(ci-1);
                    q.push(cj);
                    q.push(dist +1);
                    }
                }
                if(ci+1<n && !visited[ci+1][cj]){
                    if(mat[ci+1][cj] == '#'){
                        dist_S[ci + 1][cj] = (dist + 1);
                        
                    }
                    else {
                    visited[ci+1][cj] =true;
                    q.push(ci+1);
                    q.push(cj);
                    q.push(dist +1);
                    }
                }
                if(cj+1<m && !visited[ci][cj+1]){

                    if(mat[ci][cj+1] == '#'){
                        dist_S[ci][cj + 1] = (dist + 1);
                        
                    }
                    else {
                    visited[ci][cj+1] =true;
                    q.push(ci);
                    q.push(cj+1);
                    q.push(dist +1);
                    }
                }
                if(cj-1>=0 && !visited[ci][cj-1]){

                    if(mat[ci][cj-1] == '#'){
                        dist_S[ci][cj - 1] = (dist + 1);
                        
                    }
                    else {
                    visited[ci][cj-1] =true;
                    q.push(ci);
                    q.push(cj-1);
                    q.push(dist +1);
                    }
                }
            }
        }
    }
    }
    memset(visited, false, sizeof visited);
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            queue<int> q;
            if(mat[i][j] == 'E'){
                q.push(i);
                q.push(j);
                q.push(0);
                visited[i][j] = true;

            
            while(!q.empty()){
                int ci = q.front();
                q.pop();
                int cj =q.front();
                q.pop();
                int dist= q.front();
                q.pop();
                if(ci-1>=0 &&  !visited[ci-1][cj]){

                    if(mat[ci-1][cj] == '#'){
                        dist_E[ci - 1][cj] =(dist + 1);
                        
                    }
                    else {
                    visited[ci-1][cj] = true;
                    q.push(ci-1);
                    q.push(cj);
                    q.push(dist +1);
                    }
                }
                if(ci+1<n && !visited[ci+1][cj]){

                    if(mat[ci+1][cj] == '#'){
                        dist_E[ci + 1][cj] = (dist + 1);
                        
                    }
                    else {
                    visited[ci+1][cj] =true;
                    q.push(ci+1);
                    q.push(cj);
                    q.push(dist +1);
                    }
                }
                if(cj+1<m && !visited[ci][cj+1]){

                    if(mat[ci][cj+1] == '#'){
                        dist_E[ci][cj + 1] = (dist + 1);
                        
                    }
                    else {
                    visited[ci][cj+1] =true;
                    q.push(ci);
                    q.push(cj+1);
                    q.push(dist +1);
                    }
                }
                if(cj-1>=0 && !visited[ci][cj-1]){

                    if(mat[ci][cj-1] == '#'){
                        dist_E[ci][cj - 1] = (dist + 1);
                        
                    }
                    else {
                    visited[ci][cj-1] =true;
                    q.push(ci);
                    q.push(cj-1);
                    q.push(dist +1);
                }
                }
            }
        }
    }
    }
    int result = -1;
    for(int i =0 ; i < n; i++) {
        for(int j=0 ; j < m; j++) {
            if(mat[i][j] == '#') {
                if(dist_S[i][j] != -1 and dist_E[i][j] != -1) {
                    result = max(result, dist_S[i][j] + dist_E[i][j]);
                }
            }
        }
    }
    cout << result << endl;
    return 0;
}
