#include <iostream>
#include <algorithm>
#include <queue>
#include <unordered_map>
#include <vector>

using namespace std;

#define MAX 1000
typedef queue<pair<int,pair<int,int>>> searchQueue;

string objs[MAX][MAX];
bool visited[MAX][MAX];
int n,m;

bool canAdd(int in, int im){
  return (in < n && in >= 0 && im < m && im >= 0);
}

bool canVisit(int in, int im, int weight){
  if (!canAdd(in,im) || visited[in][im]) return false;
  string obj = objs[in][im];
  return obj == "." || (obj != "*" && stoi(obj) > weight);
}

void visit(int in, int im, int weight, searchQueue& search){
  if (!canVisit(in,im,weight)) return;
  visited[in][im] = true;
  search.push({weight+1,{in,im}});
}

bool canAddFire(int in, int im, int weight){
  if (!canAdd(in,im)) return false;
  string obj = objs[in][im];
  return obj == ".";
}

void addFire(int in, int im, int weight, vector<pair<int,int>>& fires, vector<pair<int,int>>& loopingFires){
  //cout<<in<<' '<<im<<'\n';
  if (!canAddFire(in,im,weight)) return;
  objs[in][im] = to_string(weight);
  fires.push_back({in,im});
  loopingFires.push_back({in,im});
}

void addFires(vector<pair<int,int>>& loopingFires, int maxWeight, vector<pair<int,int>>& fires){
  vector<pair<int,int>> newLoopingFires;

  for (auto obj: loopingFires){
    addFire(obj.first+1,obj.second,maxWeight,fires,newLoopingFires);
    addFire(obj.first-1,obj.second,maxWeight,fires,newLoopingFires);
    addFire(obj.first,obj.second+1,maxWeight,fires,newLoopingFires);
    addFire(obj.first,obj.second-1,maxWeight,fires,newLoopingFires);
  }

  loopingFires = newLoopingFires;
}

int main(){
  ios_base::sync_with_stdio(false), cin.tie(0); 

  for (int i = 0;i<1000;++i){
    for (int j = 0;j<1000;++j){
      visited[i][j] = false;
    }
  }

  int sn,sm;
  int maxWeight = 0;
  cin>>n>>m;

  vector<pair<int,int>> fires;
 
  for (int i = 0;i<n;++i){
    for (int j = 0;j<m;++j){
      char obj; cin>>obj;

      if (obj == 'S'){
        sn = i;
        sm = j;
        objs[i][j] = ".";
      }else if(obj == 'X'){
        objs[i][j] = "0";
        fires.push_back({i,j});
      }else{
        string toAdd = "";
        toAdd.push_back(obj);
        objs[i][j] = toAdd;
      }
    }
  }

  vector<pair<int,int>> loopingFires = fires;

  searchQueue search;

  addFires(loopingFires,++maxWeight,fires);
  visit(sn,sm,0,search);

  int total = 0;

  while (!search.empty()){
    auto item = search.front();
    int weight = item.first;
    auto nm = item.second;
    int in = nm.first;
    int im = nm.second;

    search.pop();

    total++;

    visit(in+1,im,weight+1,search);
    visit(in-1,im,weight+1,search);
    visit(in,im+1,weight+1,search);
    visit(in,im-1,weight+1,search);

    if (weight + 1 > maxWeight){
      addFires(loopingFires,++maxWeight,fires);
    }
  }

  cout<<total;

  return 0;
}