#include <iostream>
#include <queue>
#include <vector>
#include <cstring>

using namespace std;

const int MAX = 300;
char grid[MAX][MAX];
bool visited[MAX][MAX];
int dx[] = {-1, 1, 0, 0};
int dy[] = {0, 0, -1, 1};

struct Point {
    int x, y;
};

bool isValid(int x, int y, int n, int m) {
    return x >= 0 && x < n && y >= 0 && y < m && grid[x][y] == '.';
}

int main() {
    int n, m;
    cin >> n >> m;

    queue<Point> q;
    int stevaReach = 0;

    // Inicijalizacija matrice
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < m; ++j) {
            cin >> grid[i][j];
            if (grid[i][j] == 'S') {
                q.push({i, j});
                visited[i][j] = true;
                stevaReach++; // Racunamo pocetnu poziciju Steve
            }
            if (grid[i][j] == 'X') {
                q.push({i, j});
                visited[i][j] = true; // Zapocinjemo sa širenjem vatre
            }
        }
    }

    // BFS širenje vatre i Steve
    while (!q.empty()) {
        int size = q.size();
        for (int i = 0; i < size; ++i) {
            Point p = q.front();
            q.pop();
            for (int d = 0; d < 4; ++d) {
                int nx = p.x + dx[d];
                int ny = p.y + dy[d];
                if (isValid(nx, ny, n, m) && !visited[nx][ny]) {
                    visited[nx][ny] = true;
                    if (grid[p.x][p.y] == 'X') {
                        grid[nx][ny] = 'X';
                    } else if (grid[p.x][p.y] == '.') {
                        grid[nx][ny] = 'S';
                        stevaReach++;
                    }
                    q.push({nx, ny});
                }
            }
        }
    }

    cout << stevaReach << endl;

    return 0;
}