#include <iostream>
#include <math.h>
#include <vector>
#include <string>
#include <algorithm>
#include <queue>
#include <stack>
#include <map>
#include <cstring>
#include <iomanip>
#include <set>
#include <bitset>
#include <unordered_map>
#include <cstdlib>
using namespace std;
using ll = long long;
using pii = pair<int,int>;
using piii = tuple<int,int,int>;
using piiii = tuple<int,int,int,int>;
#define f first
#define s second
#define endl '\n'
#define all(x) begin(x),end(x)
#define m_p make_pair
int const N = 1010;
int const INF = 1e9+10;
int dp[N][N][9];
int tb[N][N];
vector<pii> tele[11];
pii dir[9] = {{0,0},{0,1},{1,1},{1,0},{1,-1},{0,-1},{-1,-1},{-1,0},{-1,1}};
int main(){
ios_base::sync_with_stdio(0);cin.tie(0);
int n;cin >> n;
int m;cin >> m;
pii st;
pii ed;
for(int i{};i < n;i++){
for(int j{};j < m;j++){
char c;cin >> c;
if(c == 'S') st = {i,j};
else if(c == 'E') ed = {i,j};
else if(c == '#') tb[i][j] = -1;
else if(c >= '0' && c <= '9'){
tb[i][j] = c-'0';
tele[c-'0'].emplace_back(i,j);
}
}
}
deque<piiii> dq;
dq.push_back({st.f,st.s,0,1});
dp[st.f][st.s][0] = 1;
while(!dq.empty()){
auto [i,j,cur,w] = dq.front();dq.pop_front();
if(tb[i][j] == -1) continue;
else if(tb[i][j] > 0){
pii pos;
if(tele[tb[i][j]][0] != m_p(i,j)) pos = {tele[tb[i][j]][0].f,tele[tb[i][j]][0].s};
else pos = {tele[tb[i][j]][1].f,tele[tb[i][j]][1].s};
if(dp[pos.f][pos.s][0]) continue;
dq.push_front({pos.f,pos.s,0,w});
}
dp[i][j][cur] = w;
for(int c{1};c < 9;c++){
auto [x,y] = dir[cur];
if(i+x < 0 || i+x >= n || j+y < 0 || j+y >= m) continue;
if(tb[i+x][j+y] == -1) continue;
if(dp[i+x][j+y][c]) continue;
if(c == cur) dq.emplace_front(i+x,j+y,c,w);
else dq.emplace_back(i+x,j+y,c,w+1);
}
}
int ans = INF;
for(int i{};i < 9;i++){
if(dp[ed.f][ed.s][i] != 0) ans = min(ans,dp[ed.f][ed.s][i]);
}
if(ans == INF) cout << -1;
else cout << ans-1;
}