#include <bits/stdc++.h>
using namespace std;
using ll = long long;

struct h {
	size_t operator()(vector<pair<int, int>> v) const {
		hash<int> hasher;
		size_t result = 0;
		for (auto [x, y]: v) {
			result ^= (hasher(x) << 16) ^ hasher(y);
		}
		return result;
	}
};

vector<vector<int>> used;
int timer = 1;
vector<string> field;
int n, m;
int dfs(int x, int y, vector<pair<int, int>> &v) {
	if (x < 0 || n <= x || y < 0 || m <= y || field[x][y] == '#') return 0;
	int ans = 1;
	used[x][y] = timer;
	for (int i = 0; i < 4; i++) {
		auto [nx, ny] = v[i];
		if ((nx - x) * (nx - x) + (ny - y) * (ny - y) == 1) {
			if (0 <= nx && nx < n && 0 <= ny && ny < m && used[nx][ny] != timer && field[nx][ny] != '#') ans += dfs(nx, ny, v);
		}
	}
	return ans;
}
template <typename T>
void make_sort(vector<T> &v) {
	sort(v.begin(), v.end());
}

int main() {
	ios_base::sync_with_stdio(false);
	cin.tie(nullptr);
	cin >> n >> m;
	field.resize(n);
	for (string &s: field) {
		cin >> s;
	}
	used.resize(n, vector<int>(m, 0));
	unordered_map<vector<pair<int, int>>, int, h> distances;
	queue<vector<pair<int, int>>> q;
	vector<pair<int, int>> start = {{0, 0}, {1, 0}, {0, 1}, {1, 1}};
	make_sort(start);
	q.push(start);
	distances[start] = 1;
	while (!q.empty()) {
		vector<pair<int, int>> slime = q.front();
		q.pop();
		for (int i = 0; i < 4; i++) {
			for (int dx = -1; dx <= 1; dx++) {
				for (int dy = -1; dy <= 1; dy++) {
					vector<pair<int, int>> new_slime = slime;
					new_slime[i].first += dx;
					new_slime[i].second += dy;
					make_sort(new_slime);
					if (dfs(new_slime[0].first, new_slime[0].second, new_slime) == 4) {
						if (distances[new_slime] == 0) {
							distances[new_slime] = distances[slime] + 1;
							q.push(new_slime);
						}
					}
					timer++;
				}
			}
		}
	}
	vector<pair<int, int>> finish = {{n-1, m-1}, {n-2, m-1}, {n-1, m-2}, {n-2, m-2}};
	make_sort(finish);
	cout << distances[finish] - 1;
}