#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

// XY
typedef pair<int, int> Point;

#define DUMP false

enum CellType : uint8_t
{
	Free,
	Wall,
	Fire,
	Steve,
};

CellType* cells = nullptr;

int H, W;

vector<Point> FreeCells;
vector<Point> SteveCanReach;
vector<Point> FireCanReach;

bool IsValid(const Point& p)
{
	return p.first >= 0 && p.second >= 0 && p.first < W && p.second < H;
}

CellType GetAt(const Point& p)
{
	if (!IsValid(p))
	{
		return Wall;
	}
	return cells[p.second * W + p.first];
}

void SetAt(const Point& p, const CellType t)
{
	FreeCells.erase(std::remove(FreeCells.begin(), FreeCells.end(), p), FreeCells.end());
	cells[p.second * W + p.first] = t;
}

void DumpCells()
{
#if DUMP
	cout << "-------\n";
	for (int i = 0; i < H; ++i)
	{
		for (int j = 0; j < W; ++j)
		{
			switch (cells[i * W + j])
			{
				case Free: cout << "."; break;
				case Wall: cout << "*"; break;
				case Fire: cout << "X"; break;
				case Steve: cout << "S"; break;
			}
		}
		cout << "\n";
	}
#endif
}

#define SPREAD_FIRE(Pos) if(GetAt(Pos) == Free) { SetAt(Pos, Fire); NewFire.push_back(Pos); }
#define SPREAD_Steve(Pos) if(GetAt(Pos) == Free) { SetAt(Pos, Steve); NewFire.push_back(Pos); }
void SpreadFire()
{
	vector<Point> NewFire;
	NewFire.reserve(FireCanReach.size() * 4);
	for (auto fire_can_reach : FireCanReach)
	{
		int x = fire_can_reach.first;
		int y = fire_can_reach.second;
		Point Up =    {x, y + 1};
		Point Down =  {x, y - 1};
		Point Left =  { x - 1, y };
		Point Right = { x + 1, y };
		SPREAD_FIRE(Up)
		SPREAD_FIRE(Down)
		SPREAD_FIRE(Left)
		SPREAD_FIRE(Right)
	}
	FireCanReach.reserve(FireCanReach.size() * 5);
	FireCanReach.insert(FireCanReach.cend(),NewFire.cbegin(), NewFire.cend());
}

void SpreadSteve()
{
	vector<Point> NewFire;
	NewFire.reserve(SteveCanReach.size() * 4);
	for (auto fire_can_reach : SteveCanReach)
	{
		int x = fire_can_reach.first;
		int y = fire_can_reach.second;
		Point Up =    {x, y + 1};
		Point Down =  {x, y - 1};
		Point Left =  { x - 1, y };
		Point Right = { x + 1, y };
		SPREAD_Steve(Up)
		SPREAD_Steve(Down)
		SPREAD_Steve(Left)
		SPREAD_Steve(Right)
	}
	SteveCanReach.reserve(SteveCanReach.size() * 5);
	SteveCanReach.insert(SteveCanReach.cend(),NewFire.cbegin(), NewFire.cend());
}

int main()
{
	cin >> H;
	cin >> W;
	cells = new CellType[W * H];
	for (int i = 0; i < H; ++i)
	{
		for (int j = 0; j < W; ++j)
		{
			char c;
			cin >> c;
			switch (c)
			{
				case '.': cells[i * W + j] = CellType::Free; FreeCells.emplace_back(j,i); break;
				case '*': cells[i * W + j] = CellType::Wall;  break;
				case 'X': cells[i * W + j] = CellType::Fire;  FireCanReach.emplace_back(j,i); break;
				case 'S': cells[i * W + j] = CellType::Steve;  SteveCanReach.emplace_back(j,i); break;
			}
		}
	}

	DumpCells();
	auto old_empty = FreeCells.size();
	while (!FreeCells.empty())
	{
		SpreadFire();
		DumpCells();
		SpreadSteve();
		DumpCells();
		if (old_empty == FreeCells.size())
		{
			break;
		}
	}
	cout << SteveCanReach.size() << "\n";
}