#include <time.h>
#include <math.h>
#include <assert.h>

#include <queue>
#include <vector>
#include <numeric>
#include <iostream>
#include <algorithm>
#include <functional>

template <typename T1, typename T2>
std::istream& operator>>(std::istream& is, std::pair<T1, T2>& v) {
    return is >> v.first >> v.second;
}

template <typename T>
std::istream& operator>>(std::istream& is, std::vector<T>& v) {
    for (T& i: v) is >> i;
    return is;
}

template <typename T1, typename T2>
std::ostream& operator<<(std::ostream& os, const std::pair<T1, T2>& v) {
    return os << v.first << " " << v.second;
}

template <typename T>
std::ostream& operator<<(std::ostream& os, const std::vector<T>& v) {
    int n = (int) v.size();
    for (int i = 0; i < n; ++i) os << v[i] << (i == n - 1 ? "" : " ");
    return os;
}

template <typename T>
void in(T& x) {
    std::cin >> x;
}

template <typename T>
void out(const T H) {
    std::cout << (H);
}

template <typename T1, typename... T2>
void out(const T1 H, const T2... T) {
    std::cout << (H) << " "; out(T...);
}

template <typename T>
void eout(const char *s, const T H) {
    std::cerr << s << "=" << H << "\n";
}

template <typename T1, typename... T2>
void eout(const char *s, const T1 H, const T2... T) {
    while (*s != ',') std::cerr << *s++;
    std::cerr << "=" << H << " | "; eout(++s, T...);
}

#define nl                std::cout << "\n"
#define err(args...)      eout(#args, args)

#define rep(i, n)         for (int i =  0 ; i < (n); ++i)
#define per(i, n)         for (int i = (n) - 1; i > -1; --i)
#define repr(i, l, r)     for (int i = (l); i < (r); ++i)

#define sz(v)             ((int) v.size())
#define all(v)            (v).begin(), (v).end()
#define lla(v)            (v).rbegin(), (v).rend()

#define no                std::cout << "NO\n"
#define yes               std::cout << "YES\n"

const int INF           = 2147483647;
const long long int LNF = 9223372036854775807LL;

using ll  = long long int;
using vi  = std::vector<int>;
using vb  = std::vector<bool>;
using ii  = std::pair<int, int>;
using iii = std::pair< ii, int>;
using vii = std::vector<ii>;

const int N  = 505050;
const int MD = 1000*1000*1000 + 7;

int solve();
int main() {
    std::ios_base::sync_with_stdio(0); std::cin.tie(0);
    //std::cout.tie(0);

    //int t; in(t); repr(tc, 1, t + 1)
    solve();

    return 0;
}

int solve() {
    int n; in(n);
    int m; in(m);
    std::string s[n]; rep(i, n) in(s[i]);

    int ans = 0;
    std::function<void(int, int)> bfs = [&](int i, int j) {
        vii parent[n]; rep(x, n) parent[x].resize(m);
        vb visited[n]; rep(x, n) visited[x].resize(m, false);

        visited[i][j] = true;
        parent[i][j] = {i, j};
        std::queue<ii> q; q.push({i, j});

        while (!q.empty()) {
            auto u = q.front(); q.pop();
            std::tie(i, j) = u;
            for (auto v: vii{{i + 1, j}, {i, j + 1}}) {
                int x, y; std::tie(x, y) = v;
                if (x < n and y < m and s[x][y] == '.' and !visited[x][y]) {
                    q.push({x, y});
                    visited[x][y] = true;
                    parent[x][y] = u;
                }
            }
        }

        if (visited[n - 1][m - 1]) {
            ++ans;
            int x, y; std::tie(x, y) = parent[n - 1][m - 1];
            while (x or y) {
                s[x][y] = '#';
                std::tie(x, y) = parent[x][y];
            }
        }
    }; bfs(0, 0); bfs(0, 0);
    out(ans);
    return 0;
}


#include <math.h>
#include <assert.h>

#include <queue>
#include <vector>
#include <numeric>
#include <iostream>
#include <algorithm>
#include <functional>

template <typename T1, typename T2>
std::istream& operator>>(std::istream& is, std::pair<T1, T2>& v) {
    return is >> v.first >> v.second;
}

template <typename T>
std::istream& operator>>(std::istream& is, std::vector<T>& v) {
    for (T& i: v) is >> i;
    return is;
}

template <typename T1, typename T2>
std::ostream& operator<<(std::ostream& os, const std::pair<T1, T2>& v) {
    return os << v.first << " " << v.second;
}

template <typename T>
std::ostream& operator<<(std::ostream& os, const std::vector<T>& v) {
    int n = (int) v.size();
    for (int i = 0; i < n; ++i) os << v[i] << (i == n - 1 ? "" : " ");
    return os;
}

template <typename T>
void in(T& x) {
    std::cin >> x;
}

template <typename T>
void out(const T H) {
    std::cout << (H);
}

template <typename T1, typename... T2>
void out(const T1 H, const T2... T) {
    std::cout << (H) << " "; out(T...);
}

template <typename T>
void eout(const char *s, const T H) {
    std::cerr << s << "=" << H << "\n";
}

template <typename T1, typename... T2>
void eout(const char *s, const T1 H, const T2... T) {
    while (*s != ',') std::cerr << *s++;
    std::cerr << "=" << H << " | "; eout(++s, T...);
}

#define nl                std::cout << "\n"
#define err(args...)      eout(#args, args)

#define rep(i, n)         for (int i =  0 ; i < (n); ++i)
#define per(i, n)         for (int i = (n) - 1; i > -1; --i)
#define repr(i, l, r)     for (int i = (l); i < (r); ++i)

#define sz(v)             ((int) v.size())
#define all(v)            (v).begin(), (v).end()
#define lla(v)            (v).rbegin(), (v).rend()

#define no                std::cout << "NO\n"
#define yes               std::cout << "YES\n"

const int INF           = 2147483647;
const long long int LNF = 9223372036854775807LL;

using ll  = long long int;
using vi  = std::vector<int>;
using vb  = std::vector<bool>;
using ii  = std::pair<int, int>;
using iii = std::pair< ii, int>;
using vii = std::vector<ii>;

const int N  = 505050;
const int MD = 1000*1000*1000 + 7;

int solve();
int main() {
    std::ios_base::sync_with_stdio(0); std::cin.tie(0);
    //std::cout.tie(0);

    //int t; in(t); repr(tc, 1, t + 1)
    solve();

    return 0;
}

int solve() {
    int n; in(n);
    int m; in(m);
    std::vector < vb > a(n + 2, vb(m + 2, 0));
    rep(i, n) {
        std::string s; in(s);
        rep(j, m) a[i + 1][j + 1] = (s[j] == '.');
    }

    auto bfs = [&](int i, int j) {
        bool visited[n + 2][m + 2] = {{0}};
        ii parent[n + 2][m + 2];

        visited[i][j] = 1;
        std::queue<ii> q; q.push({i, j});

        auto adj = [](ii u) {
            int x = u.first;
            int y = u.second;
            return vii{{x - 1, y}, {x, y - 1}, {x + 1, y}, {x, y + 1}};
        };

        while (!q.empty()) {
            auto u = q.front(); q.pop();
            for (auto v: adj(u)) {
                int x = v.first;
                int y = v.second;
                if (a[x][y] and !visited[x][y]) {
                    q.push(v);
                    visited[x][y] = 1;
                    parent[x][y] = u;
                }
            }
        }

        if (visited[n][m]) {
            int x = parent[n][m].first;
            int y = parent[n][m].second;
            while (x != 1 or y != 1) {
                a[x][y] = 0;
                std::tie(x, y) = parent[x][y];
            }
        }

        return visited[n][m];
    };

    int x = bfs(1, 1) + bfs(1, 1);
    out(x);

    return 0;
}


#include <math.h>
#include <assert.h>

#include <queue>
#include <vector>
#include <numeric>
#include <iostream>
#include <algorithm>
#include <functional>

template <typename T1, typename T2>
std::istream& operator>>(std::istream& is, std::pair<T1, T2>& v) {
    return is >> v.first >> v.second;
}

template <typename T>
std::istream& operator>>(std::istream& is, std::vector<T>& v) {
    for (T& i: v) is >> i;
    return is;
}

template <typename T1, typename T2>
std::ostream& operator<<(std::ostream& os, const std::pair<T1, T2>& v) {
    return os << v.first << " " << v.second;
}

template <typename T>
std::ostream& operator<<(std::ostream& os, const std::vector<T>& v) {
    int n = (int) v.size();
    for (int i = 0; i < n; ++i) os << v[i] << (i == n - 1 ? "" : " ");
    return os;
}

template <typename T>
void in(T& x) {
    std::cin >> x;
}

template <typename T>
void out(const T H) {
    std::cout << (H);
}

template <typename T1, typename... T2>
void out(const T1 H, const T2... T) {
    std::cout << (H) << " "; out(T...);
}

template <typename T>
void eout(const char *s, const T H) {
    std::cerr << s << "=" << H << "\n";
}

template <typename T1, typename... T2>
void eout(const char *s, const T1 H, const T2... T) {
    while (*s != ',') std::cerr << *s++;
    std::cerr << "=" << H << " | "; eout(++s, T...);
}

#define nl                std::cout << "\n"
#define err(args...)      eout(#args, args)

#define rep(i, n)         for (int i =  0 ; i < (n); ++i)
#define per(i, n)         for (int i = (n) - 1; i > -1; --i)
#define repr(i, l, r)     for (int i = (l); i < (r); ++i)

#define sz(v)             ((int) v.size())
#define all(v)            (v).begin(), (v).end()
#define lla(v)            (v).rbegin(), (v).rend()

#define no                std::cout << "NO\n"
#define yes               std::cout << "YES\n"

const int INF           = 2147483647;
const long long int LNF = 9223372036854775807LL;

using ll  = long long int;
using vi  = std::vector<int>;
using vb  = std::vector<bool>;
using ii  = std::pair<int, int>;
using iii = std::pair< ii, int>;
using vii = std::vector<ii>;

const int N  = 505050;
const int MD = 1000*1000*1000 + 7;

int solve();
int main() {
    std::ios_base::sync_with_stdio(0); std::cin.tie(0);
    //std::cout.tie(0);

    //int t; in(t); repr(tc, 1, t + 1)
    solve();

    return 0;
}

int solve() {
    int n; in(n);
    int m; in(m);
    std::vector < vb > a(n + 2, vb(m + 2, 0));
    rep(i, n) {
        std::string s; in(s);
        rep(j, m) a[i + 1][j + 1] = (s[j] == '.');
    }

    std::function<bool(int, int)> bfs = [&](int i, int j) {
        std::vector < vb > visited(n + 2, vb(m + 2, 0));
        std::vector < vii > parent(n + 2, vii(m + 2));

        visited[i][j] = 1;
        std::queue<ii> q; q.push({i, j});

        auto adj = [](ii u) {
            int x = u.first;
            int y = u.second;
            return vii{{x - 1, y}, {x, y - 1}, {x + 1, y}, {x, y + 1}};
        };

        while (!q.empty()) {
            auto u = q.front(); q.pop();
            err(u);
            for (auto v: adj(u)) {
                int x = v.first;
                int y = v.second;
                if (a[x][y] and !visited[x][y]) {
                    err(v);
                    q.push(v);
                    visited[x][y] = 1;
                    parent[x][y] = u;
                }
            }
        }

        if (visited[n][m]) {
            int x = n, y = m;
            do {
                err(x, y);
                a[x][y] = 0;
                std::tie(x, y) = parent[x][y];
            } while (x != 1 or y != 1);
            a[n][m] = 1;
        }

        return !!visited[n][m];
    };

    out(bfs(1, 1) + bfs(1, 1));

    return 0;
}


#include <math.h>
#include <assert.h>

#include <set>
#include <queue>
#include <vector>
#include <numeric>
#include <iostream>
#include <algorithm>
#include <functional>

template <typename T1, typename T2>
std::istream& operator>>(std::istream& is, std::pair<T1, T2>& v) {
    return is >> v.first >> v.second;
}

template <typename T>
std::istream& operator>>(std::istream& is, std::vector<T>& v) {
    for (T& i: v) is >> i;
    return is;
}

template <typename T1, typename T2>
std::ostream& operator<<(std::ostream& os, const std::pair<T1, T2>& v) {
    return os << v.first << " " << v.second;
}

template <typename T>
std::ostream& operator<<(std::ostream& os, const std::vector<T>& v) {
    int n = (int) v.size();
    for (int i = 0; i < n; ++i) os << v[i] << (i == n - 1 ? "" : " ");
    return os;
}

template <typename T>
void in(T& x) {
    std::cin >> x;
}

template <typename T>
void out(const T H) {
    std::cout << (H);
}

template <typename T1, typename... T2>
void out(const T1 H, const T2... T) {
    std::cout << (H) << " "; out(T...);
}

template <typename T>
void eout(const char *s, const T H) {
    std::cerr << s << "=" << H << "\n";
}

template <typename T1, typename... T2>
void eout(const char *s, const T1 H, const T2... T) {
    while (*s != ',') std::cerr << *s++;
    std::cerr << "=" << H << " | "; eout(++s, T...);
}

#define nl                std::cout << "\n"
#define err(args...)      eout(#args, args)

#define rep(i, n)         for (int i =  0 ; i < (n); ++i)
#define per(i, n)         for (int i = (n) - 1; i > -1; --i)
#define repr(i, l, r)     for (int i = (l); i < (r); ++i)

#define sz(v)             ((int) v.size())
#define all(v)            (v).begin(), (v).end()
#define lla(v)            (v).rbegin(), (v).rend()

#define no                std::cout << "NO\n"
#define yes               std::cout << "YES\n"

const int INF           = 2147483647;
const long long int LNF = 9223372036854775807LL;

using ll  = long long int;
using vi  = std::vector<int>;
using vb  = std::vector<bool>;
using ii  = std::pair<int, int>;
using iii = std::pair< ii, int>;
using vii = std::vector<ii>;

const int N  = 505050;
const int MD = 1000*1000*1000 + 7;

int solve();
int main() {
    std::ios_base::sync_with_stdio(0); std::cin.tie(0);
    //std::cout.tie(0);

    //int t; in(t); repr(tc, 1, t + 1)
    solve();

    return 0;
}

int solve() {
    int n; in(n);
    int m; in(m);
    std::string s[n]; rep(i, n) in(s[i]);

    auto adj = [&](ii u) {
        int i, j; std::tie(i, j) = u;
        vii v;
        if (i) v.push_back({i - 1, j});
        if (j) v.push_back({i, j - 1});
        if (i < n - 1) v.push_back({i + 1, j});
        if (j < m - 1) v.push_back({i, j + 1});
        return v;
    };

    auto bfs = [&](int i, int j) {
        ii parent[n][m];
        bool visited[n][m] = {{0}};

        visited[i][j] = 1;
        parent[i][j] = {i, j};

        std::queue<ii> q; q.push({i, j});
        while (!q.empty()) {
            auto u = q.front(); q.pop();
            for (auto v: adj(u)) {
                int x = v.first;
                int y = v.second;
                if (s[x][y] == '.' and !visited[x][y]) {
                    q.push(v);
                    visited[x][y] = 1;
                    parent[x][y] = u;
                }
            }
        }

        if (visited[n - 1][m - 1]) {
            int x = n - 1, y = m - 1;
            while (x or y) {
                s[x][y] = '#';
                std::tie(x, y) = parent[x][y];
            }
            s[n - 1][m - 1] = '.';
        }

        return visited[n - 1][m - 1];
    };

    out(bfs(0, 0) + bfs(0, 0));
    return 0;
}


#include <math.h>
#include <assert.h>

#include <set>
#include <queue>
#include <vector>
#include <numeric>
#include <iostream>
#include <algorithm>
#include <functional>

template <typename T1, typename T2>
std::istream& operator>>(std::istream& is, std::pair<T1, T2>& v) {
    return is >> v.first >> v.second;
}

template <typename T>
std::istream& operator>>(std::istream& is, std::vector<T>& v) {
    for (T& i: v) is >> i;
    return is;
}

template <typename T1, typename T2>
std::ostream& operator<<(std::ostream& os, const std::pair<T1, T2>& v) {
    return os << v.first << " " << v.second;
}

template <typename T>
std::ostream& operator<<(std::ostream& os, const std::vector<T>& v) {
    int n = (int) v.size();
    for (int i = 0; i < n; ++i) os << v[i] << (i == n - 1 ? "" : " ");
    return os;
}

template <typename T>
void in(T& x) {
    std::cin >> x;
}

template <typename T>
void out(const T H) {
    std::cout << (H);
}

template <typename T1, typename... T2>
void out(const T1 H, const T2... T) {
    std::cout << (H) << " "; out(T...);
}

template <typename T>
void eout(const char *s, const T H) {
    std::cerr << s << "=" << H << "\n";
}

template <typename T1, typename... T2>
void eout(const char *s, const T1 H, const T2... T) {
    while (*s != ',') std::cerr << *s++;
    std::cerr << "=" << H << " | "; eout(++s, T...);
}

#define nl                std::cout << "\n"
#define err(args...)      eout(#args, args)

#define rep(i, n)         for (int i =  0 ; i < (n); ++i)
#define per(i, n)         for (int i = (n) - 1; i > -1; --i)
#define repr(i, l, r)     for (int i = (l); i < (r); ++i)

#define sz(v)             ((int) v.size())
#define all(v)            (v).begin(), (v).end()
#define lla(v)            (v).rbegin(), (v).rend()

#define no                std::cout << "NO\n"
#define yes               std::cout << "YES\n"

const int INF           = 2147483647;
const long long int LNF = 9223372036854775807LL;

using ll  = long long int;
using vi  = std::vector<int>;
using vb  = std::vector<bool>;
using ii  = std::pair<int, int>;
using iii = std::pair< ii, int>;
using vii = std::vector<ii>;

const int N  = 505050;
const int MD = 1000*1000*1000 + 7;

int solve();
int main() {
    std::ios_base::sync_with_stdio(0); std::cin.tie(0);
    //std::cout.tie(0);

    //int t; in(t); repr(tc, 1, t + 1)
    solve();

    return 0;
}

int solve() {
    int n; in(n);
    int m; in(m);
    std::string s[n]; rep(i, n) in(s[i]);

    auto adj = [&](ii u) {
        int i, j; std::tie(i, j) = u;
        vii v;
        if (i) v.push_back({i - 1, j});
        if (j) v.push_back({i, j - 1});
        if (i < n - 1) v.push_back({i + 1, j});
        if (j < m - 1) v.push_back({i, j + 1});
        return v;
    };

    auto bfs = [&](int i, int j) {
        ii parent[n][m];
        bool visited[n][m] = {{0}};

        visited[i][j] = 1;
        parent[i][j] = {i, j};

        std::queue<ii> q; q.push({i, j});
        while (!q.empty()) {
            auto u = q.front(); q.pop();
            for (auto v: adj(u)) {
                int x = v.first;
                int y = v.second;
                if (s[x][y] == '.' and !visited[x][y]) {
                    q.push(v);
                    visited[x][y] = 1;
                    parent[x][y] = u;
                }
            }
        }

        if (visited[n - 1][m - 1]) {
            int x = n - 1, y = m - 1;
            while (x or y) {
                err(x, y);
                s[x][y] = '#';
                std::tie(x, y) = parent[x][y];
            }
            s[n - 1][m - 1] = '.';
        }
        rep(i, n) err(s[i]);

        return visited[n - 1][m - 1];
    };

    out(bfs(0, 0) + bfs(0, 0));
    return 0;
}


#include <math.h>
#include <assert.h>

#include <set>
#include <queue>
#include <vector>
#include <numeric>
#include <iostream>
#include <algorithm>
#include <functional>

template <typename T1, typename T2>
std::istream& operator>>(std::istream& is, std::pair<T1, T2>& v) {
    return is >> v.first >> v.second;
}

template <typename T>
std::istream& operator>>(std::istream& is, std::vector<T>& v) {
    for (T& i: v) is >> i;
    return is;
}

template <typename T1, typename T2>
std::ostream& operator<<(std::ostream& os, const std::pair<T1, T2>& v) {
    return os << v.first << " " << v.second;
}

template <typename T>
std::ostream& operator<<(std::ostream& os, const std::vector<T>& v) {
    int n = (int) v.size();
    for (int i = 0; i < n; ++i) os << v[i] << (i == n - 1 ? "" : " ");
    return os;
}

template <typename T>
void in(T& x) {
    std::cin >> x;
}

template <typename T>
void out(const T H) {
    std::cout << (H);
}

template <typename T1, typename... T2>
void out(const T1 H, const T2... T) {
    std::cout << (H) << " "; out(T...);
}

template <typename T>
void eout(const char *s, const T H) {
    std::cerr << s << "=" << H << "\n";
}

template <typename T1, typename... T2>
void eout(const char *s, const T1 H, const T2... T) {
    while (*s != ',') std::cerr << *s++;
    std::cerr << "=" << H << " | "; eout(++s, T...);
}

#define nl                std::cout << "\n"
#define err(args...)      eout(#args, args)

#define rep(i, n)         for (int i =  0 ; i < (n); ++i)
#define per(i, n)         for (int i = (n) - 1; i > -1; --i)
#define repr(i, l, r)     for (int i = (l); i < (r); ++i)

#define sz(v)             ((int) v.size())
#define all(v)            (v).begin(), (v).end()
#define lla(v)            (v).rbegin(), (v).rend()

#define no                std::cout << "NO\n"
#define yes               std::cout << "YES\n"

const int INF           = 2147483647;
const long long int LNF = 9223372036854775807LL;

using ll  = long long int;
using vi  = std::vector<int>;
using vb  = std::vector<bool>;
using ii  = std::pair<int, int>;
using iii = std::pair< ii, int>;
using vii = std::vector<ii>;

const int N  = 505050;
const int MD = 1000*1000*1000 + 7;

int solve();
int main() {
    std::ios_base::sync_with_stdio(0); std::cin.tie(0);
    //std::cout.tie(0);

    //int t; in(t); repr(tc, 1, t + 1)
    solve();

    return 0;
}

int solve() {
    int n; in(n);
    int m; in(m);
    std::string s[n]; rep(i, n) in(s[i]);

    auto adj = [&](ii u) {
        int i, j; std::tie(i, j) = u;
        vii v;
        if (i) v.push_back({i - 1, j});
        if (j) v.push_back({i, j - 1});
        if (i < n - 1) v.push_back({i + 1, j});
        if (j < m - 1) v.push_back({i, j + 1});
        return v;
    };

    auto bfs = [&](int i, int j) {
        ii parent[n][m];
        bool visited[n][m] = {{0}};

        visited[i][j] = 1;
        parent[i][j] = {i, j};

        std::queue<ii> q; q.push({i, j});
        while (!q.empty()) {
            auto u = q.front(); q.pop();
            for (auto v: adj(u)) {
                int x = v.first;
                int y = v.second;
                if (s[x][y] == '.' and !visited[x][y]) {
                    q.push(v);
                    visited[x][y] = 1;
                    parent[x][y] = u;
                }
            }
        }

        if (visited[n - 1][m - 1]) {
            int x = n - 1, y = m - 1;
            while (x or y) {
                s[x][y] = '#';
                std::tie(x, y) = parent[x][y];
            }
            s[n - 1][m - 1] = '.';
        }

        return visited[n - 1][m - 1];
    };

    auto x = bfs(0, 0);
    auto y = bfs(0, 0);
    out(x + y);
    return 0;
}


int solve() {
    int n; in(n);
    int m; in(m);
    std::string s[n]; rep(i, n) in(s[i]);

    auto adj = [&](ii u) {
        int i, j; std::tie(i, j) = u;
        vii v;
        if (i) v.push_back({i - 1, j});
        if (j) v.push_back({i, j - 1});
        if (i < n - 1) v.push_back({i + 1, j});
        if (j < m - 1) v.push_back({i, j + 1});
        return v;
    };

    auto bfs = [&](int i, int j) {
        ii parent[n][m];
        bool visited[n][m]; rep(i, n) rep(j, m) visited[i][j] = 0;

        visited[i][j] = 1;
        parent[i][j] = {i, j};

        std::queue<ii> q; q.push({i, j});
        while (!q.empty()) {
            auto u = q.front(); q.pop();
            for (auto v: adj(u)) {
                int x = v.first;
                int y = v.second;
                if (s[x][y] == '.' and !visited[x][y]) {

                    q.push(v);
                    visited[x][y] = 1;
                    parent[x][y] = u;
                }
            }
        }

        if (visited[n - 1][m - 1]) {
            int x = n - 1, y = m - 1;
            while (x or y) {
                s[x][y] = '#';
                std::tie(x, y) = parent[x][y];
            }
            s[n - 1][m - 1] = '.';
        }

        return visited[n - 1][m - 1];
    };

    auto x = bfs(0, 0);
    auto y = bfs(0, 0);
    out(x + y);
    return 0;
}


#include <math.h>
#include <assert.h>

#include <bitset>
#include <queue>
#include <vector>
#include <numeric>
#include <iostream>
#include <algorithm>
#include <functional>

template <typename T1, typename T2>
std::istream& operator>>(std::istream& is, std::pair<T1, T2>& v) {
    return is >> v.first >> v.second;
}

template <typename T>
std::istream& operator>>(std::istream& is, std::vector<T>& v) {
    for (T& i: v) is >> i;
    return is;
}

template <typename T1, typename T2>
std::ostream& operator<<(std::ostream& os, const std::pair<T1, T2>& v) {
    return os << v.first << " " << v.second;
}

template <typename T>
std::ostream& operator<<(std::ostream& os, const std::vector<T>& v) {
    int n = (int) v.size();
    for (int i = 0; i < n; ++i) os << v[i] << (i == n - 1 ? "" : " ");
    return os;
}

template <typename T>
void in(T& x) {
    std::cin >> x;
}

template <typename T>
void out(const T H) {
    std::cout << (H);
}

template <typename T1, typename... T2>
void out(const T1 H, const T2... T) {
    std::cout << (H) << " "; out(T...);
}

template <typename T>
void eout(const char *s, const T H) {
    std::cerr << s << "=" << H << "\n";
}

template <typename T1, typename... T2>
void eout(const char *s, const T1 H, const T2... T) {
    while (*s != ',') std::cerr << *s++;
    std::cerr << "=" << H << " | "; eout(++s, T...);
}

#define nl                std::cout << "\n"
#define err(args...)      eout(#args, args)

#define rep(i, n)         for (int i =  0 ; i < (n); ++i)
#define per(i, n)         for (int i = (n) - 1; i > -1; --i)
#define repr(i, l, r)     for (int i = (l); i < (r); ++i)

#define sz(v)             ((int) v.size())
#define all(v)            (v).begin(), (v).end()
#define lla(v)            (v).rbegin(), (v).rend()

#define no                std::cout << "NO\n"
#define yes               std::cout << "YES\n"

const int INF           = 2147483647;
const long long int LNF = 9223372036854775807LL;

using ll  = long long int;
using vi  = std::vector<int>;
using vb  = std::vector<bool>;
using ii  = std::pair<int, int>;
using iii = std::pair< ii, int>;
using vii = std::vector<ii>;

const int N  = 5050505;
const int MD = 1000*1000*1000 + 7;

int solve();
int main() {
    std::ios_base::sync_with_stdio(0); std::cin.tie(0);
    //std::cout.tie(0);

    //int t; in(t); repr(tc, 1, t + 1)
    solve();

    return 0;
}

bool a[N];
bool bfs(int n, int m, int i, int j) {
    bool visited[n + 2][m + 2] = {{0}};
    ii parent[n + 2][m + 2];

    visited[i][j] = 1;
    std::queue<ii> q; q.push({i, j});

    auto adj = [](ii u) {
        int x = u.first;
        int y = u.second;
        return vii{{x - 1, y}, {x, y - 1}, {x + 1, y}, {x, y + 1}};
    };

    while (!q.empty()) {
        auto u = q.front(); q.pop();
        for (auto v: adj(u)) {
            int x = v.first;
            int y = v.second;
            if (a[x*(m + 2) + y] and !visited[x][y]) {
                q.push(v);
                visited[x][y] = 1;
                parent[x][y] = u;
            }
        }
    }

    if (visited[n][m]) {
        int x = n, y = m;
        do {
            a[x*(m + 2) + y] = 0;
            std::tie(x, y) = parent[x][y];
        } while (x != 1 or y != 1);
        a[n*(m + 2) + m] = 1;
    }

    return visited[n][m];
}

int solve() {
    int n; in(n);
    int m; in(m);

    rep(i, n) {
        std::string s; in(s);
        rep(j, m) a[(i + 1)*(m + 2) + j + 1] = (s[j] == '.');
    }

    out(bfs(n, m, 1, 1) + bfs(n, m, 1, 1));
    return 0;
}


#include <math.h>
#include <assert.h>

#include <bitset>
#include <queue>
#include <vector>
#include <numeric>
#include <iostream>
#include <algorithm>
#include <functional>

template <typename T1, typename T2>
std::istream& operator>>(std::istream& is, std::pair<T1, T2>& v) {
    return is >> v.first >> v.second;
}

template <typename T>
std::istream& operator>>(std::istream& is, std::vector<T>& v) {
    for (T& i: v) is >> i;
    return is;
}

template <typename T1, typename T2>
std::ostream& operator<<(std::ostream& os, const std::pair<T1, T2>& v) {
    return os << v.first << " " << v.second;
}

template <typename T>
std::ostream& operator<<(std::ostream& os, const std::vector<T>& v) {
    int n = (int) v.size();
    for (int i = 0; i < n; ++i) os << v[i] << (i == n - 1 ? "" : " ");
    return os;
}

template <typename T>
void in(T& x) {
    std::cin >> x;
}

template <typename T>
void out(const T H) {
    std::cout << (H);
}

template <typename T1, typename... T2>
void out(const T1 H, const T2... T) {
    std::cout << (H) << " "; out(T...);
}

template <typename T>
void eout(const char *s, const T H) {
    std::cerr << s << "=" << H << "\n";
}

template <typename T1, typename... T2>
void eout(const char *s, const T1 H, const T2... T) {
    while (*s != ',') std::cerr << *s++;
    std::cerr << "=" << H << " | "; eout(++s, T...);
}

#define nl                std::cout << "\n"
#define err(args...)      eout(#args, args)

#define rep(i, n)         for (int i =  0 ; i < (n); ++i)
#define per(i, n)         for (int i = (n) - 1; i > -1; --i)
#define repr(i, l, r)     for (int i = (l); i < (r); ++i)

#define sz(v)             ((int) v.size())
#define all(v)            (v).begin(), (v).end()
#define lla(v)            (v).rbegin(), (v).rend()

#define no                std::cout << "NO\n"
#define yes               std::cout << "YES\n"

const int INF           = 2147483647;
const long long int LNF = 9223372036854775807LL;

using ll  = long long int;
using vi  = std::vector<int>;
using vb  = std::vector<bool>;
using ii  = std::pair<int, int>;
using iii = std::pair< ii, int>;
using vii = std::vector<ii>;

const int N  = 1000001;
const int MD = 1000*1000*1000 + 7;

int solve();
int main() {
    std::ios_base::sync_with_stdio(0); std::cin.tie(0);
    //std::cout.tie(0);

    //int t; in(t); repr(tc, 1, t + 1)
    solve();

    return 0;
}

bool a[N];
bool bfs(int n, int m, int i, int j) {
    bool visited[n + 2][m + 2] = {{0}};
    ii parent[n + 2][m + 2];

    visited[i][j] = 1;
    std::queue<ii> q; q.push({i, j});

    auto adj = [](ii u) {
        int x = u.first;
        int y = u.second;
        return vii{{x - 1, y}, {x, y - 1}, {x + 1, y}, {x, y + 1}};
    };

    while (!q.empty()) {
        auto u = q.front(); q.pop();
        for (auto v: adj(u)) {
            int x = v.first;
            int y = v.second;
            if (a[x*(m + 2) + y] and !visited[x][y]) {
                q.push(v);
                visited[x][y] = 1;
                parent[x][y] = u;
            }
        }
    }

    if (visited[n][m]) {
        int x = n, y = m;
        do {
            a[x*(m + 2) + y] = 0;
            std::tie(x, y) = parent[x][y];
        } while (x != 1 or y != 1);
        a[n*(m + 2) + m] = 1;
    }

    return visited[n][m];
}

int solve() {
    int n; in(n);
    int m; in(m);

    rep(i, n) {
        std::string s; in(s);
        rep(j, m) a[(i + 1)*(m + 2) + j + 1] = (s[j] == '.');
    }

    out(bfs(n, m, 1, 1) + bfs(n, m, 1, 1));
    return 0;
}


#include <math.h>
#include <assert.h>

#include <vector>
#include <numeric>
#include <iostream>
#include <algorithm>
#include <functional>

template <typename T1, typename T2>
std::istream& operator>>(std::istream& is, std::pair<T1, T2>& v) {
    return is >> v.first >> v.second;
}

template <typename T>
std::istream& operator>>(std::istream& is, std::vector<T>& v) {
    for (T& i: v) is >> i;
    return is;
}

template <typename T1, typename T2>
std::ostream& operator<<(std::ostream& os, const std::pair<T1, T2>& v) {
    return os << v.first << " " << v.second;
}

template <typename T>
std::ostream& operator<<(std::ostream& os, const std::vector<T>& v) {
    int n = (int) v.size();
    for (int i = 0; i < n; ++i) os << v[i] << (i == n - 1 ? "" : " ");
    return os;
}

template <typename T>
void in(T& x) {
    std::cin >> x;
}

template <typename T>
void out(const T H) {
    std::cout << (H);
}

template <typename T1, typename... T2>
void out(const T1 H, const T2... T) {
    std::cout << (H) << " "; out(T...);
}

template <typename T>
void eout(const char *s, const T H) {
    std::cerr << s << "=" << H << "\n";
}

template <typename T1, typename... T2>
void eout(const char *s, const T1 H, const T2... T) {
    while (*s != ',') std::cerr << *s++;
    std::cerr << "=" << H << " | "; eout(++s, T...);
}

#define nl                std::cout << "\n"
#define err(args...)      eout(#args, args)

#define rep(i, n)         for (int i =  0 ; i < (n); ++i)
#define per(i, n)         for (int i = (n) - 1; i > -1; --i)
#define repr(i, l, r)     for (int i = (l); i < (r); ++i)

#define sz(v)             ((int) v.size())
#define all(v)            (v).begin(), (v).end()
#define lla(v)            (v).rbegin(), (v).rend()

#define no                std::cout << "NO\n"
#define yes               std::cout << "YES\n"

const int INF           = 2147483647;
const long long int LNF = 9223372036854775807LL;

using ll  = long long int;
using vi  = std::vector<int>;
using vb  = std::vector<bool>;
using ii  = std::pair<int, int>;
using iii = std::pair< ii, int>;
using vii = std::vector<ii>;

const int N  = 505050;
const int MD = 1000*1000*1000 + 7;

int solve();
int main() {
    std::ios_base::sync_with_stdio(0); std::cin.tie(0);
    //std::cout.tie(0);

    //int t; in(t); repr(tc, 1, t + 1)
    solve();

    return 0;
}

int solve() {
    int n; in(n);
    int m; in(m);
    std::string s[n]; rep(i, n) in(s[i]);

    std::function<bool(int, int)> dfs = [&](int i, int j) {
        if (i == n - 1 && j == m - 1) return true;
        if (i < n - 1 && s[i + 1][j] == '.' && dfs(i + 1, j))
            return s[i][j] = '#', true;
        if (j < m - 1 && s[i][j + 1] == '.' && dfs(i, j + 1))
            return s[i][j] = '#', true;
        return s[i][j] == '#';
    };

    auto x = dfs(0, 0); s[0][0] = '.';
    out(x + dfs(0, 0));
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define FiOS ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define ll long long
#define int ll
#define pb push_back
#define endl "\n"
#define mp make_pair
#define MOD 1000000007

int32_t main()
{
	FiOS;

    int n,m;
    cin >> n >> m;
    char a[n+1][m+1];
    bool dp[n+1][m+1];
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
            cin >> a[i][j];
    for(int i=0;i<=n;i++)
        for(int j=0;j<=m;j++)
            dp[i][j]=0;
    dp[1][1]=1;
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=m;j++)
        {
            if(i==1 && j==1)
                continue;
            if(a[i][j]=='#')
                dp[i][j]=0;
            else
            {
                if(dp[i-1][j] == 1 || dp[i][j-1]==1)
                    dp[i][j]=1;
                else
                    dp[i][j]=0;
            }
            //cout << dp[i][j] << " " ;
        }
        //cout << endl;
    }
    if(dp[n][m]==0)
        cout << 0;
    else
    {
        if(dp[1][2]==0 && dp[2][1]==1)
            cout << 1;
        else if(dp[1][2]==1 && dp[2][1]==0)
            cout << 1;
        else
        {
            int row[n+1];
            for(int i=1;i<=n;i++)
            {
                int c=0;
                for(int j=1;j<=m;j++)
                    if(a[i][j]=='#')
                        c++;
                if(c==m-1)
                    return cout << 1,0;
            }
            for(int i=1;i<=m;i++)
            {
                int c=0;
                for(int j=1;j<=n;j++)
                    if(a[j][i]=='#')
                        c++;
                if(c==n-1)
                    return cout << 1,0;
            }
            if(dp[n-1][m]==0 || dp[n][m-1]==0)
                return cout << 1,0;
            int pc[n+1][m+1],pr[n+1][m+1];
            for(int j=1;j<=m;j++)
            {
                if(a[n][j]=='#')
                    pc[n][j]=1;
                else
                    pc[n][j]=0;
            }
            for(int i=1;i<=n;i++)
            {
                if(a[i][m]=='#')
                    pr[i][m]=1;
                else
                    pr[i][m]=0;

            }
            for(int j=1;j<=m;j++)
                for(int i=n-1;i>=1;i--)
                    pc[i][j] = pc[i+1][j] + (a[i][j]=='#');

            for(int i=1;i<=n;i++)
                for(int j=m-1;j>=1;j--)
                    pr[i][j] = pr[i][j+1] + (a[i][j]=='#');
            /*for(int i=1;i<=n;i++)
            {
                for(int j=1;j<=m;j++)
                    cout << pc[i][j] << " ";
                cout << endl;
            }
            cout << endl << endl;
            for(int i=1;i<=n;i++)
            {
                for(int j=1;j<=m;j++)
                    cout << pr[i][j] << " ";
                cout << endl;
            }*/

            for(int i=n;i>1;i--)
            {
                for(int j=m-1;j>=1;j--)
                {
                    if(i+pc[i][j] == n+1)
                    {
                        //cout << i << " " << j << m-j << " " << pr[i-1][j+1] <<  endl;
                        if(pr[i-1][j+1]>=m-j-1)
                            return cout << 1,0;
                    }
                }
            }
            for(int j=m;j>1;j--)
            {
                for(int i=n-1;i>=1;i--)
                {
                    if(j+pr[i][j]==m+1)
                        if(pc[i+1][j-1]>=n-i+1)
                            return cout << 1,0;
                }
            }

            return cout << 2,0;
        }

    }

}
/*
6 6
..#...
..#...
......
...#.#
..#...
..#...

*/


#include <bits/stdc++.h>
using namespace std;
#define FiOS ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define ll long long
#define int ll
#define pb push_back
#define endl "\n"
#define mp make_pair
#define MOD 1000000007

map<pair<ll,ll>,ll> m1;

int32_t main()
{
    FiOS;

    int n,m;
    cin >> n >> m;
    char a[n+1][m+1];
    bool dp[n+1][m+1];
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
            cin >> a[i][j];
    for(int i=0;i<=n+1;i++)
        for(int j=0;j<=m+1;j++)
            dp[i][j]=0;
    dp[1][1]=1;
    m1[mp(1,1)]++;
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=m;j++)
        {
            if(i*j==1LL)
                continue;
            if(a[i][j]=='.')
            {
                if(dp[i-1][j] == 1 || dp[i][j-1]==1)
                    dp[i][j]=1,m1[mp(i,j)]++;
                else
                    dp[i][j]=0;
            }
        }
    }
    if(dp[n][m]==0)
        return cout << 0,0;
    if(dp[1][2]==0 || dp[2][1]==0)
        return cout << 1,0;
    for(int i=0;i<=n+1;i++)
        for(int j=0;j<=m+1;j++)
            dp[i][j]=0;
    dp[n][m]=1;
    for(int i=n;i>=1;i--)
    {
        for(int j=m;j>=1;j--)
        {
            if(i==n && j==m)
                continue;
            if(a[i][j]!='.')
                dp[i][j]=0;
            else
            {
                if(dp[i+1][j]==1 || dp[i][j+1]==1)
                    dp[i][j]=1, m1[mp(i,j)]++;
                else
                    dp[i][j]=0;
            }
        }
    }
    queue<pair<int,int> > q;
    int vis[n+1][m+1];
    for(int i=0;i<=n;i++)
        for(int j=0;j<=m;j++)
            vis[i][j]=0;
    q.push(mp(1,1));
    vis[1][1]=1;
    m1[mp(n,m)]=2;
    while(!q.empty())
    {
        pair<int,int> p = q.front();
        if(p.first==n && p.second==m)
            break;
        if(q.size()==1 && !(p.first==1 && p.second==1))
            return cout << 1,0;

        q.pop();
        if(m1[mp(p.first+1,p.second)]>=2 && vis[p.first+1][p.second]==0)
            q.push(mp(p.first+1,p.second)), vis[p.first+1][p.second]=1;
        if(m1[mp(p.first,p.second+1)]>=2 && vis[p.first][p.second+1]==0)
            q.push(mp(p.first,p.second+1)), vis[p.first][p.second+1]=1;;
    }
    cout << 2;
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define FiOS ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define ll long long
#define int ll
#define pb push_back
#define endl "\n"
#define mp make_pair
#define MOD 1000000007

map<pair<ll,ll>,ll> m1;

int32_t main()
{
    FiOS;

    int n,m;
    cin >> n >> m;
    char a[n+1][m+1];
    bool dp[n+2][m+2];
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
            cin >> a[i][j];
    for(int i=0;i<=n+1;i++)
        for(int j=0;j<=m+1;j++)
            dp[i][j]=0;
    dp[1][1]=1;
    m1[mp(1,1)]++;
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=m;j++)
        {
            if(i*j==1LL)
                continue;
            if(a[i][j]=='.')
            {
                if(dp[i-1][j] == 1 || dp[i][j-1]==1)
                    dp[i][j]=1,m1[mp(i,j)]++;
                else
                    dp[i][j]=0;
            }
        }
    }
    if(dp[n][m]==0)
        return cout << 0,0;
    if(dp[1][2]==0 || dp[2][1]==0)
        return cout << 1,0;
    for(int i=0;i<=n+1;i++)
        for(int j=0;j<=m+1;j++)
            dp[i][j]=0;
    dp[n][m]=1;
    for(int i=n;i>=1;i--)
    {
        for(int j=m;j>=1;j--)
        {
            if(i==n && j==m)
                continue;
            if(a[i][j]!='.')
                dp[i][j]=0;
            else
            {
                if(dp[i+1][j]==1 || dp[i][j+1]==1)
                    dp[i][j]=1, m1[mp(i,j)]++;
                else
                    dp[i][j]=0;
            }
        }
    }
    queue<pair<int,int> > q;
    int vis[n+1][m+1];
    for(int i=0;i<=n;i++)
        for(int j=0;j<=m;j++)
            vis[i][j]=0;
    q.push(mp(1,1));
    vis[1][1]=1;
    m1[mp(n,m)]=2;
    while(!q.empty())
    {
        pair<int,int> p = q.front();
        if(p.first==n && p.second==m)
            break;
        if(q.size()==1 && !(p.first==1 && p.second==1))
            return cout << 1,0;

        q.pop();
        if(m1[mp(p.first+1,p.second)]>=2 && vis[p.first+1][p.second]==0)
            q.push(mp(p.first+1,p.second)), vis[p.first+1][p.second]=1;
        if(m1[mp(p.first,p.second+1)]>=2 && vis[p.first][p.second+1]==0)
            q.push(mp(p.first,p.second+1)), vis[p.first][p.second+1]=1;;
    }
    cout << 2;
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define FiOS ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define ll long long
#define int ll
#define pb push_back
#define endl "\n"
#define mp make_pair
#define MOD 1000000007

map<pair<ll,ll>,ll> m1;

int32_t main()
{
	FiOS;

    int n,m;
    cin >> n >> m;
    char a[n+1][m+1];
    bool dp[n+1][m+1];
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
            cin >> a[i][j];
    for(int i=0;i<=n;i++)
        for(int j=0;j<=m;j++)
            dp[i][j]=0;
    dp[1][1]=1;
    m1[mp(1,1)]++;
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=m;j++)
        {
            if(i==1 && j==1)
                continue;
            if(a[i][j]=='#')
                dp[i][j]=0;
            else
            {
                if(dp[i-1][j] == 1 || dp[i][j-1]==1)
                    dp[i][j]=1,m1[mp(i,j)]++;
                else
                    dp[i][j]=0;
            }
            //cout << dp[i][j] << " " ;
        }
        //cout << endl;
    }
    if(dp[n][m]==0)
        return cout << 0,0;
    if(dp[1][2]==0 || dp[2][1]==0)
        return cout << 1,0;
    for(int i=0;i<=n;i++)
        for(int j=0;j<=m;j++)
            dp[i][j]=0;
    dp[n][m]=1;
    for(int i=n;i>=1;i--)
    {
        for(int j=m;j>=1;j--)
        {
            if(i==n && j==m)
                continue;
            if(dp[i+1][j]==1 || dp[i][j+1]==1)
                dp[i][j]=1, m1[mp(i,j)]++;
            else
                dp[i][j]=0;
        }
    }
    queue<pair<int,int> > q;
    int vis[n+1][m+1];
    for(int i=0;i<=n;i++)
        for(int j=0;j<=m;j++)
            vis[i][j]=0;
    q.push(mp(1,1));
    while(!q.empty())
    {
        pair<int,int> p = q.front();
        //cout << p.first << " " << p.second << endl;
        if(q.size()==1 && p.first!=1 && p.second!=1)
            return cout << 1,0;
        q.pop();
        if(m1[mp(p.first+1,p.second)]>=2 && vis[p.first+1][p.second]==0)
            q.push(mp(p.first+1,p.second)), vis[p.first+1][p.second]=1;
        if(m1[mp(p.first,p.second+1)]>=2 && vis[p.first][p.second+1]==0)
            q.push(mp(p.first,p.second+1)), vis[p.first][p.second+1]=1;;
    }
    cout << 2;
    return 0;
}
/*
6 6
..#...
......
....#.
..#..#
..#...
..#...

*/


#include <bits/stdc++.h>
using namespace std;
#define FiOS ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define ll long long
#define int ll
#define pb push_back
#define endl "\n"
#define mp make_pair
#define MOD 1000000007

int32_t main()
{
	//FiOS;

    int n,m;
    cin >> n >> m;
    char a[n+1][m+1];
    bool dp[n+1][m+1];
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
            cin >> a[i][j];
    for(int i=0;i<=n;i++)
        for(int j=0;j<=m;j++)
            dp[i][j]=0;
    dp[1][1]=1;
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=m;j++)
        {
            if(i==1 && j==1)
                continue;
            if(a[i][j]=='#')
                dp[i][j]=0;
            else
            {
                if(dp[i-1][j] == 1 || dp[i][j-1]==1)
                    dp[i][j]=1;
                else
                    dp[i][j]=0;
            }
            //cout << dp[i][j] << " " ;
        }
        //cout << endl;
    }
    if(dp[n][m]==0 || (dp[1][2]==0 && dp[2][1]==0))
        cout << 0;
    else
    {
        if(dp[1][2]==0 && dp[2][1]==1)
            cout << 1;
        else if(dp[1][2]==1 && dp[2][1]==0)
            cout << 1;
        else
            cout << 2;

    }

}


#include <bits/stdc++.h>
using namespace std;
#define FiOS ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define ll long long
#define int ll
#define pb push_back
#define endl "\n"
#define mp make_pair
#define MOD 1000000007

int32_t main()
{
	//FiOS;

    int n,m;
    cin >> n >> m;
    char a[n+1][m+1];
    bool dp[n+1][m+1];
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
            cin >> a[i][j];
    for(int i=0;i<=n;i++)
        for(int j=0;j<=m;j++)
            dp[i][j]=0;
    dp[1][1]=1;
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=m;j++)
        {
            if(i==1 && j==1)
                continue;
            if(a[i][j]=='#')
                dp[i][j]=0;
            else
            {
                if(dp[i-1][j] == 1 || dp[i][j-1]==1)
                    dp[i][j]=1;
                else
                    dp[i][j]=0;
            }
            //cout << dp[i][j] << " " ;
        }
        //cout << endl;
    }
    if(dp[n][m]==0 || (dp[1][2]==0 && dp[2][1]==0))
        cout << 0;
    else
    {
        if(dp[1][2]==0 && dp[2][1]==1)
            cout << 1;
        else if(dp[1][2]==1 && dp[2][1]==0)
            cout << 1;
        else
        {
            int row[n+1];
            for(int i=1;i<=n;i++)
            {
                int c=0;
                for(int j=1;j<=m;j++)
                    if(a[i][j]=='#')
                        c++;
                if(c==m-1)
                    return cout << 1,0;
            }
            if(dp[n-1][m]==0 || dp[n][m-1]==0)
                return cout << 1,0;
            return cout << 2,0;
        }

    }

}


#include <bits/stdc++.h>
using namespace std;
#define FiOS ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define ll long long
#define int ll
#define pb push_back
#define endl "\n"
#define mp make_pair
#define MOD 1000000007

map<pair<ll,ll>,ll> m1;

int32_t main()
{
	FiOS;

    int n,m;
    cin >> n >> m;
    char a[n+5][m+5];
    bool dp[n+5][m+5];
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
            cin >> a[i][j];
    for(int i=0;i<=n+4;i++)
        for(int j=0;j<=m+4;j++)
            dp[i][j]=0;
    dp[1][1]=1;
    m1[mp(1,1)]++;
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=m;j++)
        {
            if(i==1 && j==1)
                continue;
            if(a[i][j]=='#')
                dp[i][j]=0;
            else
            {
                if(dp[i-1][j] == 1 || dp[i][j-1]==1)
                    dp[i][j]=1,m1[mp(i,j)]++;
                else
                    dp[i][j]=0;
            }
            //cout << dp[i][j] << " " ;
        }
        //cout << endl;
    }
    if(dp[n][m]==0)
        return cout << 0,0;
    if(dp[1][2]==0 || dp[2][1]==0)
        return cout << 1,0;
    for(int i=0;i<=n+4;i++)
        for(int j=0;j<=m+4;j++)
            dp[i][j]=0;
    dp[n][m]=1;
    for(int i=n;i>=1;i--)
    {
        for(int j=m;j>=1;j--)
        {
            if(i==n && j==m)
                continue;
            if(a[i][j]=='#')
                dp[i][j]=0;
            else if(dp[i+1][j]==1 || dp[i][j+1]==1)
                dp[i][j]=1, m1[mp(i,j)]++;
            else
                dp[i][j]=0;
        }
    }
    queue<pair<int,int> > q;
    int vis[n+1][m+1];
    for(int i=0;i<=n;i++)
        for(int j=0;j<=m;j++)
            vis[i][j]=0;
    q.push(mp(1,1));
    vis[1][1]=1;
    m1[mp(n,m)]=2;
    //cout << m1[mp(1,3)] << endl;
    while(!q.empty())
    {
        pair<int,int> p = q.front();
        //cout << p.first << " " << p.second << endl;
        if(p.first==n && p.second==m)
            break;
        if(q.size()==1 && p.first!=1 && p.second!=1)
            return cout << 1,0;

        q.pop();
        if(m1[mp(p.first+1,p.second)]>=2 && vis[p.first+1][p.second]==0)
            q.push(mp(p.first+1,p.second)), vis[p.first+1][p.second]=1;
        if(m1[mp(p.first,p.second+1)]>=2 && vis[p.first][p.second+1]==0)
            q.push(mp(p.first,p.second+1)), vis[p.first][p.second+1]=1;;
    }
    cout << 2;
    return 0;
}
/*
6 6
..#...
......
....#.
..#..#
..#...
..#...

*/


#include <bits/stdc++.h>
using namespace std;
#define FiOS ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define ll long long
#define int ll
#define pb push_back
#define endl "\n"
#define mp make_pair
#define MOD 1000000007

map<pair<ll,ll>,ll> m1;

int32_t main()
{
	FiOS;

    int n,m;
    cin >> n >> m;
    char a[n+5][m+5];
    bool dp[n+1][m+1];
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
            cin >> a[i][j];
    for(int i=0;i<=n+4;i++)
        for(int j=0;j<=m+4;j++)
            dp[i][j]=0;
    dp[1][1]=1;
    m1[mp(1,1)]++;
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=m;j++)
        {
            if(i==1 && j==1)
                continue;
            if(a[i][j]=='#')
                dp[i][j]=0;
            else
            {
                if(dp[i-1][j] == 1 || dp[i][j-1]==1)
                    dp[i][j]=1,m1[mp(i,j)]++;
                else
                    dp[i][j]=0;
            }
            //cout << dp[i][j] << " " ;
        }
        //cout << endl;
    }
    if(dp[n][m]==0)
        return cout << 0,0;
    if(dp[1][2]==0 || dp[2][1]==0)
        return cout << 1,0;
    for(int i=0;i<=n+4;i++)
        for(int j=0;j<=m+4;j++)
            dp[i][j]=0;
    dp[n][m]=1;
    for(int i=n;i>=1;i--)
    {
        for(int j=m;j>=1;j--)
        {
            if(i==n && j==m)
                continue;
            if(a[i][j]=='#')
                dp[i][j]=0;
            else if(dp[i+1][j]==1 || dp[i][j+1]==1)
                dp[i][j]=1, m1[mp(i,j)]++;
            else
                dp[i][j]=0;
        }
    }
    queue<pair<int,int> > q;
    int vis[n+1][m+1];
    for(int i=0;i<=n;i++)
        for(int j=0;j<=m;j++)
            vis[i][j]=0;
    q.push(mp(1,1));
    vis[1][1]=1;
    m1[mp(n,m)]=2;
    //cout << m1[mp(1,3)] << endl;
    while(!q.empty())
    {
        pair<int,int> p = q.front();
        //cout << p.first << " " << p.second << endl;
        if(p.first==n && p.second==m)
            break;
        if(q.size()==1 && p.first!=1 && p.second!=1)
            return cout << 1,0;

        q.pop();
        if(m1[mp(p.first+1,p.second)]>=2 && vis[p.first+1][p.second]==0)
            q.push(mp(p.first+1,p.second)), vis[p.first+1][p.second]=1;
        if(m1[mp(p.first,p.second+1)]>=2 && vis[p.first][p.second+1]==0)
            q.push(mp(p.first,p.second+1)), vis[p.first][p.second+1]=1;;
    }
    cout << 2;
    return 0;
}
/*
6 6
..#...
......
....#.
..#..#
..#...
..#...

*/


#include <bits/stdc++.h>
using namespace std;
#define FiOS ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define ll long long
#define int ll
#define pb push_back
#define endl "\n"
#define mp make_pair
#define MOD 1000000007

int32_t main()
{
	//FiOS;

    int n,m;
    cin >> n >> m;
    char a[n+1][m+1];
    bool dp[n+1][m+1];
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
            cin >> a[i][j];
    for(int i=0;i<=n;i++)
        for(int j=0;j<=m;j++)
            dp[i][j]=0;
    dp[1][1]=1;
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=m;j++)
        {
            if(i==1 && j==1)
                continue;
            if(a[i][j]=='#')
                dp[i][j]=0;
            else
            {
                if(dp[i-1][j] == 1 || dp[i][j-1]==1)
                    dp[i][j]=1;
                else
                    dp[i][j]=0;
            }
            //cout << dp[i][j] << " " ;
        }
        //cout << endl;
    }
    if(dp[n][m]==0 || (dp[1][2]==0 && dp[2][1]==0))
        cout << 0;
    else
    {
        if(dp[1][2]==0 && dp[2][1]==1)
            cout << 1;
        else if(dp[1][2]==1 && dp[2][1]==0)
            cout << 1;
        else
        {
            int row[n+1];
            for(int i=1;i<=n;i++)
            {
                int c=0;
                for(int j=1;j<=m;j++)
                    if(a[i][j]=='#')
                        c++;
                if(c==m-1)
                    return cout << 1,0;
            }
            for(int i=1;i<=m;i++)
            {
                int c=0;
                for(int j=1;j<=n;j++)
                    if(a[j][i]=='#')
                        c++;
                if(c==n-1)
                    return cout << 1,0;
            }
            if(dp[n-1][m]==0 || dp[n][m-1]==0)
                return cout << 1,0;
            return cout << 2,0;
        }

    }

}


#include <bits/stdc++.h>
using namespace std;
#define FiOS ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define ll long long
#define int ll
#define pb push_back
#define endl "\n"
#define mp make_pair
#define MOD 1000000007

int32_t main()
{
	FiOS;

    int n,m;
    cin >> n >> m;
    char a[n+1][m+1];
    bool dp[n+1][m+1];
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
            cin >> a[i][j];
    for(int i=0;i<=n;i++)
        for(int j=0;j<=m;j++)
            dp[i][j]=0;
    dp[1][1]=1;
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=m;j++)
        {
            if(i==1 && j==1)
                continue;
            if(a[i][j]=='#')
                dp[i][j]=0;
            else
            {
                if(dp[i-1][j] == 1 || dp[i][j-1]==1)
                    dp[i][j]=1;
                else
                    dp[i][j]=0;
            }
            //cout << dp[i][j] << " " ;
        }
        //cout << endl;
    }
    if(dp[n][m]==0)
        cout << 0;
    else
    {
        if(dp[1][2]==0 && dp[2][1]==1)
            cout << 1;
        else if(dp[1][2]==1 && dp[2][1]==0)
            cout << 1;
        else
        {
            int row[n+1];
            for(int i=1;i<=n;i++)
            {
                int c=0;
                for(int j=1;j<=m;j++)
                    if(a[i][j]=='#')
                        c++;
                if(c==m-1)
                    return cout << 1,0;
            }
            for(int i=1;i<=m;i++)
            {
                int c=0;
                for(int j=1;j<=n;j++)
                    if(a[j][i]=='#')
                        c++;
                if(c==n-1)
                    return cout << 1,0;
            }
            if(dp[n-1][m]==0 || dp[n][m-1]==0)
                return cout << 1,0;
            int pc[n+1][m+1],pr[n+1][m+1];
            for(int j=1;j<=m;j++)
            {
                if(a[n][j]=='#')
                    pc[n][j]=1;
                else
                    pc[n][j]=0;
            }
            for(int i=1;i<=n;i++)
            {
                if(a[i][m]=='#')
                    pr[i][m]=1;
                else
                    pr[i][m]=0;

            }
            for(int j=1;j<=m;j++)
                for(int i=n-1;i>=1;i--)
                    pc[i][j] = pc[i+1][j] + (a[i][j]=='#');

            for(int i=1;i<=n;i++)
                for(int j=m-1;j>=1;j--)
                    pr[i][j] = pr[i][j+1] + (a[i][j]=='#');
            /*for(int i=1;i<=n;i++)
            {
                for(int j=1;j<=m;j++)
                    cout << pc[i][j] << " ";
                cout << endl;
            }
            cout << endl << endl;
            for(int i=1;i<=n;i++)
            {
                for(int j=1;j<=m;j++)
                    cout << pr[i][j] << " ";
                cout << endl;
            }*/

            for(int i=n;i>1;i--)
            {
                for(int j=m-1;j>=1;j--)
                {
                    if(i+pc[i][j] == n+1)
                    {
                        //cout << i << " " << j << m-j << " " << pr[i-1][j+1] <<  endl;
                        if(pr[i-1][j+1]>=m-j-1)
                            return cout << 1,0;
                    }
                }
            }
            for(int j=m;j>1;j--)
            {
                for(int i=n-1;i>=1;i--)
                {
                    if(j+pr[i][j]==m+1)
                    {
                        //cout << i+1 << " " << j-1 << " " << n-i-1 << " " << pc[i+1][j-1] << endl;
                        if(pc[i+1][j-1]>=n-i-1)
                            return cout << 1,0;
                    }
                }
            }

            return cout << 2,0;
        }

    }

}
/*
6 6
..#...
..#...
......
..####
......
..#...

*/


#include <bits/stdc++.h>
using namespace std;
#define FiOS ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define ll long long
#define int ll
#define pb push_back
#define endl "\n"
#define mp make_pair
#define MOD 1000000007

map<pair<ll,ll>,ll> m1;

int32_t main()
{
	FiOS;

    int n,m;
    cin >> n >> m;
    char a[n+5][m+5];
    bool dp[n+1][m+1];
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
            cin >> a[i][j];
    for(int i=0;i<=n;i++)
        for(int j=0;j<=m;j++)
            dp[i][j]=0;
    dp[1][1]=1;
    m1[mp(1,1)]++;
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=m;j++)
        {
            if(i==1 && j==1)
                continue;
            if(a[i][j]=='#')
                dp[i][j]=0;
            else
            {
                if(dp[i-1][j] == 1 || dp[i][j-1]==1)
                    dp[i][j]=1,m1[mp(i,j)]++;
                else
                    dp[i][j]=0;
            }
            //cout << dp[i][j] << " " ;
        }
        //cout << endl;
    }
    if(dp[n][m]==0)
        return cout << 0,0;
    if(dp[1][2]==0 || dp[2][1]==0)
        return cout << 1,0;
    for(int i=0;i<=n;i++)
        for(int j=0;j<=m;j++)
            dp[i][j]=0;
    dp[n][m]=1;
    for(int i=n;i>=1;i--)
    {
        for(int j=m;j>=1;j--)
        {
            if(i==n && j==m)
                continue;
            if(dp[i+1][j]==1 || dp[i][j+1]==1)
                dp[i][j]=1, m1[mp(i,j)]++;
            else
                dp[i][j]=0;
        }
    }
    queue<pair<int,int> > q;
    int vis[n+1][m+1];
    for(int i=0;i<=n;i++)
        for(int j=0;j<=m;j++)
            vis[i][j]=0;
    q.push(mp(1,1));
    vis[1][1]=1;
    m1[mp(n,m)]=2;
    while(!q.empty())
    {
        pair<int,int> p = q.front();
        //cout << p.first << " " << p.second << endl;
        if(p.first==n && p.second==m)
            break;
        if(q.size()==1 && p.first!=1 && p.second!=1)
            return cout << 1,0;

        q.pop();
        if(m1[mp(p.first+1,p.second)]>=2 && vis[p.first+1][p.second]==0)
            q.push(mp(p.first+1,p.second)), vis[p.first+1][p.second]=1;
        if(m1[mp(p.first,p.second+1)]>=2 && vis[p.first][p.second+1]==0)
            q.push(mp(p.first,p.second+1)), vis[p.first][p.second+1]=1;;
    }
    cout << 2;
    return 0;
}
/*
6 6
..#...
......
....#.
..#..#
..#...
..#...

*/


#include <bits/stdc++.h>
using namespace std;
vector<int> dp[1000005];
string ch[1000005];
int N,M;

int solve(int c,int r){
    if(c==N-1 && r==M-1) return 1;
    int& ret = dp[c][r];
    if(ret !=-1) return ret;
    ret = 0;
    if(c+1<N && ch[c+1][r] =='.') ret+=solve(c+1,r);
    if(r+1<M && ch[c][r+1] == '.') ret+=solve(c,r+1);
    return ret;
}
int main(){
    ios::sync_with_stdio(0);
    cin.tie(0);
    cin>>N>>M;
    for(int i =0; i <N; i++) {
        cin>>ch[i];
        dp[i].assign(M+1,-1);
    }
    solve(0,0);
    cout<<min((dp[0][1]>0) +(dp[1][0]>0), (dp[N-1][M-2]>0) +(dp[N-2][M-1]>0));
}


#include <bits/stdc++.h>
using namespace std;
vector<int> dp;
vector<char> ch;
int N,M;
char k;

int solve(int c,int r){
    if(c==N-1 && r==M-1) return 1;
    int& ret = dp[c*N+r];
    if(ret !=-1) return ret;
    ret = 0;
    if(c+1<N && ch[(c+1)*N+r] =='.') ret+=solve(c+1,r);
    if(r+1<M && ch[c*N+r+1] == '.') ret+=solve(c,r+1);
    return ret;
}
int main(){
    ios::sync_with_stdio(0);
    cin.tie(0);
    scanf("%d %d",&N,&M);
    dp.assign(N*M,-1);
    for(int i =0; i <N; i++) for(int j =0; j <M; j++) cin>>k, ch.push_back(k);
    solve(0,0);
    printf("%d",std::min((dp[1]>0) +(dp[N]>0), (dp[(N-1)*N+M-2]>0) +(dp[(N-2)*N+M-1]>0)));
}


#include <bits/stdc++.h>
using namespace std;
vector<int> dp[1000005];
string ch[1000005];
int N,M,a,b,c,d;

int solve(int c,int r){
    if(c==N-1 && r==M-1) return 1;
    int& ret = dp[c][r];
    if(ret !=-1) return ret;
    ret = 0;
    if(c+1<N && ch[c+1][r] =='.') ret+=solve(c+1,r);
    if(r+1<M && ch[c][r+1] == '.') ret+=solve(c,r+1);
    return ret;
}
int main(){
    ios::sync_with_stdio(0);
    cin.tie(0);
    cin>>N>>M;
    for(int i =0; i <N; i++) {
        cin>>ch[i];
        dp[i].assign(M+1,-1);
    }
    solve(0,0);
    if(N!=1){
        b = (dp[1][0]>0);
        d = (dp[N-2][M-1]>0);
    }
    if(M!=1){
        a=(dp[0][1]>0);
        c=(dp[N-1][M-2]>0);
    }
   cout<<std::min((a+b),(c+d));
}


#include <bits/stdc++.h>
using namespace std;
vector<int> dp;
vector<char> ch;
int N,M,r;
char k;

int solve(int c,int r){
    if(c==N-1 && r==M-1) return 1;
    int& ret = dp[c*N+r];
    if(ret !=-1) return ret;
    ret = 0;
    if(c+1<N && ch[(c+1)*N+r] =='.') ret+=solve(c+1,r);
    if(r+1<M && ch[c*N+r+1] == '.') ret+=solve(c,r+1);
    return ret;
}
int main(){
    ios::sync_with_stdio(0);
    cin.tie(0);
    scanf("%d %d",&N,&M);
    dp.assign(N*M,-1);
    for(int i =0; i <N; i++) for(int j =0; j <M; j++) cin>>k, ch.push_back(k);
    solve(0,0);
    printf("%d",std::min((dp[1]>0) +(dp[N]>0), (dp[(N-1)*N+M-2]>0) +(dp[(N-2)*N+M-1]>0)));
}


#include <bits/stdc++.h>
using namespace std;
#define SIZE 1000005
bool visit[SIZE];
string arr[SIZE];
int N,M;

bool solve(int c,int r){
    if(c==N-1 && r== M-1)
        return true;
    if(c>= N || r>= M || visit[c*M+r] || arr[c][r]=='#')
        return false;
    visit[c*M+r] = true;
    return solve(c+1,r) || solve(c,r+1);
}

int main(){
    cin>>N>>M;
    for(int i =0; i <N; i++) cin>>arr[i];
    if(solve(0,0) == 0){
        cout<<0;
    } else{
        visit[0] = 0;
        if(solve(0,0)==0)
            cout<<1;
        else
            cout<<2;
    }
}


#include <bits/stdc++.h>
using namespace std;
int N,M,dp[1000005],a,b,c,d;
char ch[1000005];

int solve(int c,int r){
    if(c==N-1 && r==M-1) return 1;
    int& ret = dp[c*N+r];
    if(ret !=-1) return ret;
    ret = 0;
    if(c+1<N && ch[(c+1)*N+r] =='.') ret+=solve(c+1,r);
    if(r+1<M && ch[c*N+r+1] == '.') ret+=solve(c,r+1);
    return ret;
}
int main(){
    ios::sync_with_stdio(0);
    cin.tie(0);
    cin>>N>>M;
    memset(dp, -1, sizeof(dp));
    for(int i =0; i <N; i++) for(int j =0; j <M; j++) cin>>ch[i*N+j];
    solve(0,0);
    if(N!=1){
        b = (dp[N]>0);
        d = (dp[(N-2)*N+M-1]>0);
    }
    if(M!=1){
        a=(dp[1]>0);
        c=(dp[(N-1)*N+M-2]>0);
    }
    cout<<std::min((a+b),(c+d));
}


#include <bits/stdc++.h>
using namespace std;
vector<int> dp[1000005];
string ch[1000005];
int N,M,a,b,c,d;

bool safe(int x, int y){
    return (x>=0 && y>=0 && x<N && y<M);
}
void init(){
    for(int i =0; i <N; i++)
        dp[i].assign(M+1,-1);
}
int solve(int c,int r){
    if(c==N-1 && r==M-1) return 1;
    int& ret = dp[c][r];
    if(ret !=-1) return ret;
    ret = 0;
    if(c+1<N && ch[c+1][r] =='.') ret+=solve(c+1,r);
    if(r+1<M && ch[c][r+1] == '.') ret+=solve(c,r+1);
    return ret;
}
int main(){
    ios::sync_with_stdio(0);
    cin.tie(0);
    cin>>N>>M;
    int dx[6] = {1, 0, N-1,N-2, 1, N-2}, dy[6] ={0, 1, M-2, M-1, 1,M-2};
    for(int i =0; i <N; i++) {
        cin>>ch[i];
        dp[i].assign(M+1,-1);
    }
   int ret = solve(0,0);
   if(ret ==0)
        cout<<ret;
    else{
        bool ok = false;
        for(int i =0; i <6; i++){
            if(!safe(dx[i],dy[i])) continue;
            if(ch[dx[i]][dy[i]] == '.'){
                ch[dx[i]][dy[i]] = '#';
                init();
                if(solve(0,0) ==0){
                    ok = true;
                    break;
                }
                ch[dx[i]][dy[i]] ='.';
            }
        }
        cout<< (ok ? 1: 2);
    }
}


#include <bits/stdc++.h>
using namespace std;
vector<int> dp[1000005];
string ch[1000005];
int N,M,a,b,c,d;

bool safe(int x, int y){
    return (x>=0 && y>=0 && x<N && y<M);
}
void init(){
    for(int i =0; i <N; i++)
        dp[i].assign(M+1,-1);
}
int solve(int c,int r){
    if(c==N-1 && r==M-1) return 1;
    int& ret = dp[c][r];
    if(ret !=-1) return ret;
    ret = 0;
    if(c+1<N && ch[c+1][r] =='.') ret+=solve(c+1,r);
    if(r+1<M && ch[c][r+1] == '.') ret+=solve(c,r+1);
    return ret;
}
int main(){
    ios::sync_with_stdio(0);
    cin.tie(0);
    cin>>N>>M;
    int dx[6] = {1, 0, N-1,N-2, 1, N-2}, dy[6] ={0, 1, M-2, M-1, 1,M-2};
    for(int i =0; i <N; i++) {
        cin>>ch[i];
        dp[i].assign(M+1,-1);
    }
   int ret = solve(0,0);
   if(ret ==0)
        cout<<ret;
    else{
        bool ok = false;
        for(int i =0; i <6; i++){
            if(!safe(dx[i],dy[i]) || (dx[i]==N-1 && dy[i]==M-1)) continue;
            if(ch[dx[i]][dy[i]] == '.'){
                ch[dx[i]][dy[i]] = '#';
                init();
                if(solve(0,0) ==0){
                    ok = true;
                    break;
                }
                ch[dx[i]][dy[i]] ='.';
            }
        }
        cout<< (ok ? 1: 2);
    }
}


#include <bits/stdc++.h>
using namespace std;
#define SIZE 1000005
bool visit[SIZE];
string arr[SIZE];
int N,M;

bool solve(int c,int r){
    if(c==N-1 || r== M-1)
        return true;
    if(c>= N || r>= M || visit[c*M+r] || arr[c][r]=='#')
        return false;
    visit[c*M+r] = true;
    return solve(c+1,r) || solve(c,r+1);
}

int main(){
    cin>>N>>M;
    for(int i =0; i <N; i++) cin>>arr[i];
    if(solve(0,0) == 0){
        cout<<0;
    } else{
        visit[0] = 0;
        if(solve(0,0)==0)
            cout<<1;
        else
            cout<<2;
    }
}


#include <bits/stdc++.h>
using namespace std;
vector<int> dp;
int N,M;
char ch[1000005];

int solve(int c,int r){
    if(c==N-1 && r==M-1) return 1;
    int& ret = dp[c*N+r];
    if(ret !=-1) return ret;
    ret = 0;
    if(c+1<N && ch[(c+1)*N+r] =='.') ret+=solve(c+1,r);
    if(r+1<M && ch[c*N+r+1] == '.') ret+=solve(c,r+1);
    return ret;
}
int main(){
    ios::sync_with_stdio(0);
    cin.tie(0);
    cin>>N>>M;
    dp.assign(N*M+1,-1);
    for(int i =0; i <N; i++) for(int j =0; j <M; j++) cin>>ch[i*N+j];
    solve(0,0);
    cout<<std::min((dp[1]>0) +(dp[N]>0), (dp[(N-1)*N+M-2]>0) +(dp[(N-2)*N+M-1]>0));
}


#include <bits/stdc++.h>
using namespace std;
vector<int> dp[1000005];
string ch[1000005];
int N,M,a,b,c,d;

bool safe(int x, int y){
    return (x>=0 && y>=0 && x<N && y<M && (y!=M-1 && x!=N-1 ));
}
void init(){
    for(int i =0; i <N; i++)
        dp[i].assign(M+1,-1);
}
int solve(int c,int r){
    if(c==N-1 && r==M-1) return 1;
    int& ret = dp[c][r];
    if(ret !=-1) return ret;
    ret = 0;
    if(c+1<N && ch[c+1][r] =='.') ret+=solve(c+1,r);
    if(r+1<M && ch[c][r+1] == '.') ret+=solve(c,r+1);
    return ret;
}
int main(){
    ios::sync_with_stdio(0);
    cin.tie(0);
    cin>>N>>M;
    int dx[6] = {1, 0, N-1,N-2, 1, N-2}, dy[6] ={0, 1, M-2, M-1, 1,M-2};
    for(int i =0; i <N; i++) {
        cin>>ch[i];
        dp[i].assign(M+1,-1);
    }
   int ret = solve(0,0);
   if(ret ==0)
        cout<<ret;
    else{
        bool ok = false;
        for(int i =0; i <6; i++){
            if(!safe(dx[i],dy[i])) continue;
            if(ch[dx[i]][dy[i]] == '.'){
                ch[dx[i]][dy[i]] = '#';
                init();
                if(solve(0,0) ==0){
                    ok = true;
                    break;
                }
                ch[dx[i]][dy[i]] ='.';
            }
        }
        cout<< (ok ? 1: 2);
    }
}


#include <bits/stdc++.h>
#include <complex>
#include <queue>
#include <set>
#include <unordered_set>
#include <list>
#include <chrono>
#include <random>
#include <iostream>
#include <algorithm>
#include <cmath>
#include <string>
#include <vector>
#include <map>
#include <unordered_map>
#include <stack>
#include <iomanip>
#include <fstream>

using namespace std;

typedef long long ll;
typedef long double ld;
typedef pair<long long int,long long int> p32;
typedef pair<ll,ll> p64;
typedef pair<double,double> pdd;
typedef vector<ll> v64;
typedef vector<long long int> v32;
typedef vector<vector<long long int> > vv32;
typedef vector<vector<ll> > vv64;
typedef vector<vector<p64> > vvp64;
typedef vector<p64> vp64;
typedef vector<p32> vp32;
ll MOD = 998244853;
#define forn(i,e) for(ll i = 0; i < e; i++)
#define forsn(i,s,e) for(ll i = s; i < e; i++)
#define rforn(i,s) for(ll i = s; i >= 0; i--)
#define rforsn(i,s,e) for(ll i = s; i >= e; i--)
#define ln "\n"
#define dbg(x) cout<<#x<<" = "<<x<<ln
#define mp make_pair
#define pb push_back
#define fi first
#define se second
#define INF 1e18
#define fast_cin() ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL)
#define all(x) (x).begin(), (x).end()
#define sz(x) ((ll)(x).size())

ll mpow(ll a, ll b){
	if(b==0) return 1;
	ll t1 = mpow(a,b/2);
	t1 *= t1;
	t1 %= MOD;
	if(b%2) t1 *= a;
	t1 %= MOD;
	return t1;
}

ll mpow(ll a, ll b, ll p){
	if(b==0) return 1;
	ll t1 = mpow(a,b/2);
	t1 *= t1;
	t1 %= p;
	if(b%2) t1 *= a;
	t1 %= p;
	return t1;
}

ll modinverse(ll a, ll m){
	ll m0 = m;
    ll y = 0, x = 1;
    if (m == 1) return 0;
    while (a > 1){
        ll q = a / m;
        ll t = m;
        m = a % m, a = t;
        t = y;
        y = x - q * y;
        x = t;
    }
    if (x < 0) x += m0;
    return x;
}

ll range(ll l, ll r){
	return l + rand()%(r-l+1);
}

void solve(){
	ll n,m;
	cin >> n >> m;
	char arr[n][m];
	forn(i,n){
		forn(j,m){
			cin >> arr[i][j];
		}
	}
	vv64 dp(n,v64(m,0));
	dp[n-1][m-1]=1;
	rforn(i,n-1){
		rforn(j,m-1){
			if(arr[i][j]=='.') {
				dp[i][j] += ((i+1<n) ? dp[i+1][j] : 0) + ((j+1<m) ? dp[i][j+1] : 0);
				dp[i][j] %= MOD;
			}
		}
	}
	vv64 dp1(n,v64(m,0));
	dp1[0][0]=1;
	forn(i,n){
		forn(j,m){
			if(arr[i][j]=='.') {
				dp1[i][j] += ((i-1>=0) ? dp1[i-1][j] : 0) + ((j-1>=0) ? dp1[i][j-1] : 0);
				dp1[i][j] %= MOD;
			}
		}
	}
	if(dp[0][0]==0){
		cout << 0 << ln;
		return;
	}
	forn(i,n){
		forn(j,m){
			if((i==0 && j==0) || (i==n-1 && j==m-1)){
				continue;
			}
			else if((dp[i][j]*dp1[i][j])%MOD==dp[0][0]){
				cout << 1 << ln;
				return;
			}
		}
	}
	cout << 2 << ln;
}

int main()
{
	fast_cin();
    ll t=1;
	// cin >> t;
    forn(i,t) {
    	solve();
    }
    return 0;
}


#include <bits/stdc++.h>
#include <complex>
#include <queue>
#include <set>
#include <unordered_set>
#include <list>
#include <chrono>
#include <random>
#include <iostream>
#include <algorithm>
#include <cmath>
#include <string>
#include <vector>
#include <map>
#include <unordered_map>
#include <stack>
#include <iomanip>
#include <fstream>

using namespace std;

typedef long long ll;
typedef long double ld;
typedef pair<long long int,long long int> p32;
typedef pair<ll,ll> p64;
typedef pair<double,double> pdd;
typedef vector<ll> v64;
typedef vector<long long int> v32;
typedef vector<vector<long long int> > vv32;
typedef vector<vector<ll> > vv64;
typedef vector<vector<p64> > vvp64;
typedef vector<p64> vp64;
typedef vector<p32> vp32;
ll MOD = 1e9+13;
#define forn(i,e) for(ll i = 0; i < e; i++)
#define forsn(i,s,e) for(ll i = s; i < e; i++)
#define rforn(i,s) for(ll i = s; i >= 0; i--)
#define rforsn(i,s,e) for(ll i = s; i >= e; i--)
#define ln "\n"
#define dbg(x) cout<<#x<<" = "<<x<<ln
#define mp make_pair
#define pb push_back
#define fi first
#define se second
#define INF 1e18
#define fast_cin() ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL)
#define all(x) (x).begin(), (x).end()
#define sz(x) ((ll)(x).size())

ll mpow(ll a, ll b){
	if(b==0) return 1;
	ll t1 = mpow(a,b/2);
	t1 *= t1;
	t1 %= MOD;
	if(b%2) t1 *= a;
	t1 %= MOD;
	return t1;
}

ll mpow(ll a, ll b, ll p){
	if(b==0) return 1;
	ll t1 = mpow(a,b/2);
	t1 *= t1;
	t1 %= p;
	if(b%2) t1 *= a;
	t1 %= p;
	return t1;
}

ll modinverse(ll a, ll m){
	ll m0 = m;
    ll y = 0, x = 1;
    if (m == 1) return 0;
    while (a > 1){
        ll q = a / m;
        ll t = m;
        m = a % m, a = t;
        t = y;
        y = x - q * y;
        x = t;
    }
    if (x < 0) x += m0;
    return x;
}

ll range(ll l, ll r){
	return l + rand()%(r-l+1);
}

void solve(){
	ll n,m;
	cin >> n >> m;
	char arr[n][m];
	forn(i,n){
		forn(j,m){
			cin >> arr[i][j];
		}
	}
	vv64 dp(n,v64(m,0));
	dp[n-1][m-1]=1;
	rforn(i,n-1){
		rforn(j,m-1){
			if(arr[i][j]=='.') {
				dp[i][j] += ((i+1<n) ? dp[i+1][j] : 0) + ((j+1<m) ? dp[i][j+1] : 0);
				dp[i][j] %= MOD;
			}
		}
	}
	vv64 dp1(n,v64(m,0));
	dp1[0][0]=1;
	forn(i,n){
		forn(j,m){
			if(arr[i][j]=='.') {
				dp1[i][j] += ((i-1>=0) ? dp1[i-1][j] : 0) + ((j-1>=0) ? dp1[i][j-1] : 0);
				dp1[i][j] %= MOD;
			}
		}
	}
	if(dp[0][0]==0){
		cout << 0 << ln;
		return;
	}
	forn(i,n){
		forn(j,m){
			if((i==0 && j==0) || (i==n-1 && j==m-1)){
				continue;
			}
			else if((dp[i][j]*dp1[i][j])%MOD==dp[0][0]){
				cout << 1 << ln;
				return;
			}
		}
	}
	cout << 2 << ln;
}

int main()
{
	fast_cin();
    ll t=1;
	// cin >> t;
    forn(i,t) {
    	solve();
    }
    return 0;
}


#include <bits/stdc++.h>
#include <complex>
#include <queue>
#include <set>
#include <unordered_set>
#include <list>
#include <chrono>
#include <random>
#include <iostream>
#include <algorithm>
#include <cmath>
#include <string>
#include <vector>
#include <map>
#include <unordered_map>
#include <stack>
#include <iomanip>
#include <fstream>

using namespace std;

typedef long long ll;
typedef long double ld;
typedef pair<long long int,long long int> p32;
typedef pair<ll,ll> p64;
typedef pair<double,double> pdd;
typedef vector<ll> v64;
typedef vector<long long int> v32;
typedef vector<vector<long long int> > vv32;
typedef vector<vector<ll> > vv64;
typedef vector<vector<p64> > vvp64;
typedef vector<p64> vp64;
typedef vector<p32> vp32;
ll MOD = 998244853;
#define forn(i,e) for(ll i = 0; i < e; i++)
#define forsn(i,s,e) for(ll i = s; i < e; i++)
#define rforn(i,s) for(ll i = s; i >= 0; i--)
#define rforsn(i,s,e) for(ll i = s; i >= e; i--)
#define ln "\n"
#define dbg(x) cout<<#x<<" = "<<x<<ln
#define mp make_pair
#define pb push_back
#define fi first
#define se second
#define INF 1e18
#define fast_cin() ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL)
#define all(x) (x).begin(), (x).end()
#define sz(x) ((ll)(x).size())

ll mpow(ll a, ll b){
	if(b==0) return 1;
	ll t1 = mpow(a,b/2);
	t1 *= t1;
	t1 %= MOD;
	if(b%2) t1 *= a;
	t1 %= MOD;
	return t1;
}

ll mpow(ll a, ll b, ll p){
	if(b==0) return 1;
	ll t1 = mpow(a,b/2);
	t1 *= t1;
	t1 %= p;
	if(b%2) t1 *= a;
	t1 %= p;
	return t1;
}

ll modinverse(ll a, ll m){
	ll m0 = m;
    ll y = 0, x = 1;
    if (m == 1) return 0;
    while (a > 1){
        ll q = a / m;
        ll t = m;
        m = a % m, a = t;
        t = y;
        y = x - q * y;
        x = t;
    }
    if (x < 0) x += m0;
    return x;
}

ll range(ll l, ll r){
	return l + rand()%(r-l+1);
}

void solve(){
	ll n,m;
	cin >> n >> m;
	char arr[n][m];
	forn(i,n){
		forn(j,m){
			cin >> arr[i][j];
		}
	}
	vv64 dp(n,v64(m,0));
	dp[n-1][m-1]=1;
	rforn(i,n-1){
		rforn(j,m-1){
			if(arr[i][j]=='.') dp[i][j] += ((i+1<n) ? dp[i+1][j] : 0) + ((j+1<m) ? dp[i][j+1] : 0);
		}
	}
	if(dp[0][0]==0){
		cout << 0 << ln;
		return;
	}
	bool reach[n][m];
	forn(i,n) forn(j,m) reach[i][j]=0;
	reach[0][0]=1;
	forn(i,n-1){
		forn(j,m-1){
			reach[i][j] = ((i-1>=0) ? reach[i-1][j] : 0) | ((j-1>=0) ? reach[i][j-1] : 0);
			if(reach[i][j]==0) continue;
			if((i==0 && j==0) || (i==n-1 && j==m-1)){
				continue;
			}
			else if(dp[i][j]==dp[0][0]){
				cout << 1 << ln;
				return;
			}
		}
	}
	cout << 2 << ln;;
}

int main()
{
	fast_cin();
    ll t=1;
	// cin >> t;
    forn(i,t) {
    	solve();
    }
    return 0;
}


#include <bits/stdc++.h>
#include <complex>
#include <queue>
#include <set>
#include <unordered_set>
#include <list>
#include <chrono>
#include <random>
#include <iostream>
#include <algorithm>
#include <cmath>
#include <string>
#include <vector>
#include <map>
#include <unordered_map>
#include <stack>
#include <iomanip>
#include <fstream>

using namespace std;

typedef long long ll;
typedef long double ld;
typedef pair<long long int,long long int> p32;
typedef pair<ll,ll> p64;
typedef pair<double,double> pdd;
typedef vector<ll> v64;
typedef vector<long long int> v32;
typedef vector<vector<long long int> > vv32;
typedef vector<vector<ll> > vv64;
typedef vector<vector<p64> > vvp64;
typedef vector<p64> vp64;
typedef vector<p32> vp32;
ll MOD = 1e9+11;
#define forn(i,e) for(ll i = 0; i < e; i++)
#define forsn(i,s,e) for(ll i = s; i < e; i++)
#define rforn(i,s) for(ll i = s; i >= 0; i--)
#define rforsn(i,s,e) for(ll i = s; i >= e; i--)
#define ln "\n"
#define dbg(x) cout<<#x<<" = "<<x<<ln
#define mp make_pair
#define pb push_back
#define fi first
#define se second
#define INF 1e18
#define fast_cin() ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL)
#define all(x) (x).begin(), (x).end()
#define sz(x) ((ll)(x).size())

ll mpow(ll a, ll b){
	if(b==0) return 1;
	ll t1 = mpow(a,b/2);
	t1 *= t1;
	t1 %= MOD;
	if(b%2) t1 *= a;
	t1 %= MOD;
	return t1;
}

ll mpow(ll a, ll b, ll p){
	if(b==0) return 1;
	ll t1 = mpow(a,b/2);
	t1 *= t1;
	t1 %= p;
	if(b%2) t1 *= a;
	t1 %= p;
	return t1;
}

ll modinverse(ll a, ll m){
	ll m0 = m;
    ll y = 0, x = 1;
    if (m == 1) return 0;
    while (a > 1){
        ll q = a / m;
        ll t = m;
        m = a % m, a = t;
        t = y;
        y = x - q * y;
        x = t;
    }
    if (x < 0) x += m0;
    return x;
}

ll range(ll l, ll r){
	return l + rand()%(r-l+1);
}

void solve(){
	ll n,m;
	cin >> n >> m;
	char arr[n][m];
	forn(i,n){
		forn(j,m){
			cin >> arr[i][j];
		}
	}
	vv64 dp(n,v64(m,0));
	dp[n-1][m-1]=1;
	rforn(i,n-1){
		rforn(j,m-1){
			if(arr[i][j]=='.') {
				dp[i][j] += ((i+1<n) ? dp[i+1][j] : 0) + ((j+1<m) ? dp[i][j+1] : 0);
				dp[i][j] %= MOD;
			}
		}
	}
	vv64 dp1(n,v64(m,0));
	dp1[0][0]=1;
	forn(i,n){
		forn(j,m){
			if(arr[i][j]=='.') {
				dp1[i][j] += ((i-1>=0) ? dp1[i-1][j] : 0) + ((j-1>=0) ? dp1[i][j-1] : 0);
				dp1[i][j] %= MOD;
			}
		}
	}
	if(dp[0][0]==0){
		cout << 0 << ln;
		return;
	}
	forn(i,n){
		forn(j,m){
			if((i==0 && j==0) || (i==n-1 && j==m-1)){
				continue;
			}
			else if((dp[i][j]*dp1[i][j])%MOD==dp[0][0]){
				cout << 1 << ln;
				return;
			}
		}
	}
	cout << 2 << ln;
}

int main()
{
	fast_cin();
    ll t=1;
	// cin >> t;
    forn(i,t) {
    	solve();
    }
    return 0;
}


#include <bits/stdc++.h>
#include <complex>
#include <queue>
#include <set>
#include <unordered_set>
#include <list>
#include <chrono>
#include <random>
#include <iostream>
#include <algorithm>
#include <cmath>
#include <string>
#include <vector>
#include <map>
#include <unordered_map>
#include <stack>
#include <iomanip>
#include <fstream>

using namespace std;

typedef long long ll;
typedef long double ld;
typedef pair<long long int,long long int> p32;
typedef pair<ll,ll> p64;
typedef pair<double,double> pdd;
typedef vector<ll> v64;
typedef vector<long long int> v32;
typedef vector<vector<long long int> > vv32;
typedef vector<vector<ll> > vv64;
typedef vector<vector<p64> > vvp64;
typedef vector<p64> vp64;
typedef vector<p32> vp32;
ll MOD = 998244853;
#define forn(i,e) for(ll i = 0; i < e; i++)
#define forsn(i,s,e) for(ll i = s; i < e; i++)
#define rforn(i,s) for(ll i = s; i >= 0; i--)
#define rforsn(i,s,e) for(ll i = s; i >= e; i--)
#define ln "\n"
#define dbg(x) cout<<#x<<" = "<<x<<ln
#define mp make_pair
#define pb push_back
#define fi first
#define se second
#define INF 1e18
#define fast_cin() ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL)
#define all(x) (x).begin(), (x).end()
#define sz(x) ((ll)(x).size())

ll mpow(ll a, ll b){
	if(b==0) return 1;
	ll t1 = mpow(a,b/2);
	t1 *= t1;
	t1 %= MOD;
	if(b%2) t1 *= a;
	t1 %= MOD;
	return t1;
}

ll mpow(ll a, ll b, ll p){
	if(b==0) return 1;
	ll t1 = mpow(a,b/2);
	t1 *= t1;
	t1 %= p;
	if(b%2) t1 *= a;
	t1 %= p;
	return t1;
}

ll modinverse(ll a, ll m){
	ll m0 = m;
    ll y = 0, x = 1;
    if (m == 1) return 0;
    while (a > 1){
        ll q = a / m;
        ll t = m;
        m = a % m, a = t;
        t = y;
        y = x - q * y;
        x = t;
    }
    if (x < 0) x += m0;
    return x;
}

ll range(ll l, ll r){
	return l + rand()%(r-l+1);
}

void solve(){
	ll n,m;
	cin >> n >> m;
	char arr[n][m];
	forn(i,n){
		forn(j,m){
			cin >> arr[i][j];
		}
	}
	vv64 dp(n,v64(m,0));
	dp[n-1][m-1]=1;
	rforn(i,n-1){
		rforn(j,m-1){
			if(arr[i][j]=='.') dp[i][j] += ((i+1<n) ? dp[i+1][j] : 0) + ((j+1<m) ? dp[i][j+1] : 0);
		}
	}
	vv64 dp1(n,v64(m,0));
	dp1[0][0]=1;
	forn(i,n){
		forn(j,m){
			if(arr[i][j]=='.') dp1[i][j] += ((i-1>=0) ? dp1[i-1][j] : 0) + ((j-1>=0) ? dp1[i][j-1] : 0);
		}
	}
	if(dp[0][0]==0){
		cout << 0 << ln;
		return;
	}
	forn(i,n){
		forn(j,m){
			if((i==0 && j==0) || (i==n-1 && j==m-1)){
				continue;
			}
			else if(dp1[i][j]!=0 && dp[i][j]==dp[0][0]/dp1[i][j] && dp[0][0]%dp1[i][j]==0){
				cout << 1 << ln;
				return;
			}
		}
	}
	cout << 2 << ln;
}

int main()
{
	fast_cin();
    ll t=1;
	// cin >> t;
    forn(i,t) {
    	solve();
    }
    return 0;
}


#include <bits/stdc++.h>
#include <complex>
#include <queue>
#include <set>
#include <unordered_set>
#include <list>
#include <chrono>
#include <random>
#include <iostream>
#include <algorithm>
#include <cmath>
#include <string>
#include <vector>
#include <map>
#include <unordered_map>
#include <stack>
#include <iomanip>
#include <fstream>

using namespace std;

typedef long long ll;
typedef long double ld;
typedef pair<long long int,long long int> p32;
typedef pair<ll,ll> p64;
typedef pair<double,double> pdd;
typedef vector<ll> v64;
typedef vector<long long int> v32;
typedef vector<vector<long long int> > vv32;
typedef vector<vector<ll> > vv64;
typedef vector<vector<p64> > vvp64;
typedef vector<p64> vp64;
typedef vector<p32> vp32;
ll MOD = 998244853;
#define forn(i,e) for(ll i = 0; i < e; i++)
#define forsn(i,s,e) for(ll i = s; i < e; i++)
#define rforn(i,s) for(ll i = s; i >= 0; i--)
#define rforsn(i,s,e) for(ll i = s; i >= e; i--)
#define ln "\n"
#define dbg(x) cout<<#x<<" = "<<x<<ln
#define mp make_pair
#define pb push_back
#define fi first
#define se second
#define INF 1e18
#define fast_cin() ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL)
#define all(x) (x).begin(), (x).end()
#define sz(x) ((ll)(x).size())

ll mpow(ll a, ll b){
	if(b==0) return 1;
	ll t1 = mpow(a,b/2);
	t1 *= t1;
	t1 %= MOD;
	if(b%2) t1 *= a;
	t1 %= MOD;
	return t1;
}

ll mpow(ll a, ll b, ll p){
	if(b==0) return 1;
	ll t1 = mpow(a,b/2);
	t1 *= t1;
	t1 %= p;
	if(b%2) t1 *= a;
	t1 %= p;
	return t1;
}

ll modinverse(ll a, ll m){
	ll m0 = m;
    ll y = 0, x = 1;
    if (m == 1) return 0;
    while (a > 1){
        ll q = a / m;
        ll t = m;
        m = a % m, a = t;
        t = y;
        y = x - q * y;
        x = t;
    }
    if (x < 0) x += m0;
    return x;
}

ll range(ll l, ll r){
	return l + rand()%(r-l+1);
}

void solve(){
	ll n,m;
	cin >> n >> m;
	char arr[n][m];
	forn(i,n){
		forn(j,m){
			cin >> arr[i][j];
		}
	}
	vv64 dp(n,v64(m,0));
	dp[n-1][m-1]=1;
	rforn(i,n-1){
		rforn(j,m-1){
			if(arr[i][j]=='.') dp[i][j] += ((i+1<n) ? dp[i+1][j] : 0) + ((j+1<m) ? dp[i][j+1] : 0);
		}
	}
	vv64 dp1(n,v64(m,0));
	dp1[0][0]=1;
	forn(i,n){
		forn(j,m){
			if(arr[i][j]=='.') dp1[i][j] += ((i-1>=0) ? dp1[i-1][j] : 0) + ((j-1>=0) ? dp1[i][j-1] : 0);
		}
	}
	if(dp[0][0]==0){
		cout << 0 << ln;
		return;
	}
	forn(i,n-1){
		forn(j,m-1){
			if((i==0 && j==0) || (i==n-1 && j==m-1)){
				continue;
			}
			else if(dp[i][j]*dp1[i][j]==dp[0][0]){
				cout << 1 << ln;
				return;
			}
		}
	}
	cout << 2 << ln;;
}

int main()
{
	fast_cin();
    ll t=1;
	// cin >> t;
    forn(i,t) {
    	solve();
    }
    return 0;
}


#include <bits/stdc++.h>
#include <complex>
#include <queue>
#include <set>
#include <unordered_set>
#include <list>
#include <chrono>
#include <random>
#include <iostream>
#include <algorithm>
#include <cmath>
#include <string>
#include <vector>
#include <map>
#include <unordered_map>
#include <stack>
#include <iomanip>
#include <fstream>

using namespace std;

typedef long long ll;
typedef long double ld;
typedef pair<long long int,long long int> p32;
typedef pair<ll,ll> p64;
typedef pair<double,double> pdd;
typedef vector<ll> v64;
typedef vector<long long int> v32;
typedef vector<vector<long long int> > vv32;
typedef vector<vector<ll> > vv64;
typedef vector<vector<p64> > vvp64;
typedef vector<p64> vp64;
typedef vector<p32> vp32;
ll MOD = 1e9+7;
#define forn(i,e) for(ll i = 0; i < e; i++)
#define forsn(i,s,e) for(ll i = s; i < e; i++)
#define rforn(i,s) for(ll i = s; i >= 0; i--)
#define rforsn(i,s,e) for(ll i = s; i >= e; i--)
#define ln "\n"
#define dbg(x) cout<<#x<<" = "<<x<<ln
#define mp make_pair
#define pb push_back
#define fi first
#define se second
#define INF 1e18
#define fast_cin() ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL)
#define all(x) (x).begin(), (x).end()
#define sz(x) ((ll)(x).size())

ll mpow(ll a, ll b){
	if(b==0) return 1;
	ll t1 = mpow(a,b/2);
	t1 *= t1;
	t1 %= MOD;
	if(b%2) t1 *= a;
	t1 %= MOD;
	return t1;
}

ll mpow(ll a, ll b, ll p){
	if(b==0) return 1;
	ll t1 = mpow(a,b/2);
	t1 *= t1;
	t1 %= p;
	if(b%2) t1 *= a;
	t1 %= p;
	return t1;
}

ll modinverse(ll a, ll m){
	ll m0 = m;
    ll y = 0, x = 1;
    if (m == 1) return 0;
    while (a > 1){
        ll q = a / m;
        ll t = m;
        m = a % m, a = t;
        t = y;
        y = x - q * y;
        x = t;
    }
    if (x < 0) x += m0;
    return x;
}

ll range(ll l, ll r){
	return l + rand()%(r-l+1);
}

void solve(){
	ll n,m;
	cin >> n >> m;
	char arr[n][m];
	forn(i,n){
		forn(j,m){
			cin >> arr[i][j];
		}
	}
	vv64 dp(n,v64(m,0));
	dp[n-1][m-1]=1;
	rforn(i,n-1){
		rforn(j,m-1){
			if(arr[i][j]=='.') {
				dp[i][j] += ((i+1<n) ? dp[i+1][j] : 0) + ((j+1<m) ? dp[i][j+1] : 0);
				dp[i][j] %= MOD;
			}
		}
	}
	vv64 dp1(n,v64(m,0));
	dp1[0][0]=1;
	forn(i,n){
		forn(j,m){
			if(arr[i][j]=='.') {
				dp1[i][j] += ((i-1>=0) ? dp1[i-1][j] : 0) + ((j-1>=0) ? dp1[i][j-1] : 0);
				dp1[i][j] %= MOD;
			}
		}
	}
	if(dp[0][0]==0){
		cout << 0 << ln;
		return;
	}
	forn(i,n){
		forn(j,m){
			if((i==0 && j==0) || (i==n-1 && j==m-1)){
				continue;
			}
			else if((dp[i][j]*dp1[i][j])%MOD==dp[0][0]){
				cout << 1 << ln;
				return;
			}
		}
	}
	cout << 2 << ln;
}

int main()
{
	fast_cin();
    ll t=1;
	// cin >> t;
    forn(i,t) {
    	solve();
    }
    return 0;
}


#include <bits/stdc++.h>
#include <complex>
#include <queue>
#include <set>
#include <unordered_set>
#include <list>
#include <chrono>
#include <random>
#include <iostream>
#include <algorithm>
#include <cmath>
#include <string>
#include <vector>
#include <map>
#include <unordered_map>
#include <stack>
#include <iomanip>
#include <fstream>

using namespace std;

typedef long long ll;
typedef long double ld;
typedef pair<long long int,long long int> p32;
typedef pair<ll,ll> p64;
typedef pair<double,double> pdd;
typedef vector<ll> v64;
typedef vector<long long int> v32;
typedef vector<vector<long long int> > vv32;
typedef vector<vector<ll> > vv64;
typedef vector<vector<p64> > vvp64;
typedef vector<p64> vp64;
typedef vector<p32> vp32;
ll MOD = 998244853;
#define forn(i,e) for(ll i = 0; i < e; i++)
#define forsn(i,s,e) for(ll i = s; i < e; i++)
#define rforn(i,s) for(ll i = s; i >= 0; i--)
#define rforsn(i,s,e) for(ll i = s; i >= e; i--)
#define ln "\n"
#define dbg(x) cout<<#x<<" = "<<x<<ln
#define mp make_pair
#define pb push_back
#define fi first
#define se second
#define INF 1e18
#define fast_cin() ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL)
#define all(x) (x).begin(), (x).end()
#define sz(x) ((ll)(x).size())

ll mpow(ll a, ll b){
	if(b==0) return 1;
	ll t1 = mpow(a,b/2);
	t1 *= t1;
	t1 %= MOD;
	if(b%2) t1 *= a;
	t1 %= MOD;
	return t1;
}

ll mpow(ll a, ll b, ll p){
	if(b==0) return 1;
	ll t1 = mpow(a,b/2);
	t1 *= t1;
	t1 %= p;
	if(b%2) t1 *= a;
	t1 %= p;
	return t1;
}

ll modinverse(ll a, ll m){
	ll m0 = m;
    ll y = 0, x = 1;
    if (m == 1) return 0;
    while (a > 1){
        ll q = a / m;
        ll t = m;
        m = a % m, a = t;
        t = y;
        y = x - q * y;
        x = t;
    }
    if (x < 0) x += m0;
    return x;
}

ll range(ll l, ll r){
	return l + rand()%(r-l+1);
}

void solve(){
	ll n,m;
	cin >> n >> m;
	char arr[n][m];
	forn(i,n){
		forn(j,m){
			cin >> arr[i][j];
		}
	}
	vv64 dp(n,v64(m,0));
	dp[n-1][m-1]=1;
	rforn(i,n-1){
		rforn(j,m-1){
			if(arr[i][j]=='.') {
				dp[i][j] += ((i+1<n) ? dp[i+1][j] : 0) + ((j+1<m) ? dp[i][j+1] : 0);
				dp[i][j] %= MOD;
			}
		}
	}
	vv64 dp1(n,v64(m,0));
	dp1[0][0]=1;
	forn(i,n){
		forn(j,m){
			if(arr[i][j]=='.') {
				dp1[i][j] += ((i-1>=0) ? dp1[i-1][j] : 0) + ((j-1>=0) ? dp1[i][j-1] : 0);
				dp1[i][j] %= MOD;
			}
		}
	}
	if(dp[0][0]==0){
		cout << 0 << ln;
		return;
	}
	forn(i,n){
		forn(j,m){
			if((i==0 && j==0) || (i==n-1 && j==m-1)){
				continue;
			}
			else if(dp1[i][j]!=0 && dp[i][j]==dp[0][0]/dp1[i][j] && dp[0][0]%dp1[i][j]==0){
				cout << 1 << ln;
				return;
			}
		}
	}
	cout << 2 << ln;
}

int main()
{
	fast_cin();
    ll t=1;
	// cin >> t;
    forn(i,t) {
    	solve();
    }
    return 0;
}


#include <bits/stdc++.h>
#include <complex>
#include <queue>
#include <set>
#include <unordered_set>
#include <list>
#include <chrono>
#include <random>
#include <iostream>
#include <algorithm>
#include <cmath>
#include <string>
#include <vector>
#include <map>
#include <unordered_map>
#include <stack>
#include <iomanip>
#include <fstream>

using namespace std;

typedef long long ll;
typedef long double ld;
typedef pair<long long int,long long int> p32;
typedef pair<ll,ll> p64;
typedef pair<double,double> pdd;
typedef vector<ll> v64;
typedef vector<long long int> v32;
typedef vector<vector<long long int> > vv32;
typedef vector<vector<ll> > vv64;
typedef vector<vector<p64> > vvp64;
typedef vector<p64> vp64;
typedef vector<p32> vp32;
ll MOD = 998244853;
#define forn(i,e) for(ll i = 0; i < e; i++)
#define forsn(i,s,e) for(ll i = s; i < e; i++)
#define rforn(i,s) for(ll i = s; i >= 0; i--)
#define rforsn(i,s,e) for(ll i = s; i >= e; i--)
#define ln "\n"
#define dbg(x) cout<<#x<<" = "<<x<<ln
#define mp make_pair
#define pb push_back
#define fi first
#define se second
#define INF 1e18
#define fast_cin() ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL)
#define all(x) (x).begin(), (x).end()
#define sz(x) ((ll)(x).size())

ll mpow(ll a, ll b){
	if(b==0) return 1;
	ll t1 = mpow(a,b/2);
	t1 *= t1;
	t1 %= MOD;
	if(b%2) t1 *= a;
	t1 %= MOD;
	return t1;
}

ll mpow(ll a, ll b, ll p){
	if(b==0) return 1;
	ll t1 = mpow(a,b/2);
	t1 *= t1;
	t1 %= p;
	if(b%2) t1 *= a;
	t1 %= p;
	return t1;
}

ll modinverse(ll a, ll m){
	ll m0 = m;
    ll y = 0, x = 1;
    if (m == 1) return 0;
    while (a > 1){
        ll q = a / m;
        ll t = m;
        m = a % m, a = t;
        t = y;
        y = x - q * y;
        x = t;
    }
    if (x < 0) x += m0;
    return x;
}

ll range(ll l, ll r){
	return l + rand()%(r-l+1);
}

void solve(){
	ll n,m;
	cin >> n >> m;
	char arr[n][m];
	forn(i,n){
		forn(j,m){
			cin >> arr[i][j];
		}
	}
	vv64 dp(n,v64(m,0));
	dp[n-1][m-1]=1;
	rforn(i,n-1){
		rforn(j,m-1){
			if(arr[i][j]=='.') dp[i][j] += ((i+1<n) ? dp[i+1][j] : 0) + ((j+1<m) ? dp[i][j+1] : 0);
		}
	}
	if(dp[0][0]==0){
		cout << 0 << ln;
		return;
	}
	bool reach[n][m];
	forn(i,n) forn(j,m) reach[i][j]=0;
	reach[0][0]=1;
	forn(i,n-1){
		forn(j,m-1){
			// cout << i << " " << j << ln;
			reach[i][j] |= ((i-1>=0) ? reach[i-1][j] : 0) | ((j-1>=0) ? reach[i][j-1] : 0);
			if(reach[i][j]==0) continue;
			// cout << i << " " << j << ln;
			if((i==0 && j==0) || (i==n-1 && j==m-1)){
				continue;
			}
			else if(dp[i][j]==dp[0][0]){
				cout << 1 << ln;
				return;
			}
		}
	}
	cout << 2 << ln;;
}

int main()
{
	fast_cin();
    ll t=1;
	// cin >> t;
    forn(i,t) {
    	solve();
    }
    return 0;
}


#include <bits/stdc++.h>
#include <complex>
#include <queue>
#include <set>
#include <unordered_set>
#include <list>
#include <chrono>
#include <random>
#include <iostream>
#include <algorithm>
#include <cmath>
#include <string>
#include <vector>
#include <map>
#include <unordered_map>
#include <stack>
#include <iomanip>
#include <fstream>

using namespace std;

typedef long long ll;
typedef long double ld;
typedef pair<long long int,long long int> p32;
typedef pair<ll,ll> p64;
typedef pair<double,double> pdd;
typedef vector<ll> v64;
typedef vector<long long int> v32;
typedef vector<vector<long long int> > vv32;
typedef vector<vector<ll> > vv64;
typedef vector<vector<p64> > vvp64;
typedef vector<p64> vp64;
typedef vector<p32> vp32;
ll MOD = 998244853;
#define forn(i,e) for(ll i = 0; i < e; i++)
#define forsn(i,s,e) for(ll i = s; i < e; i++)
#define rforn(i,s) for(ll i = s; i >= 0; i--)
#define rforsn(i,s,e) for(ll i = s; i >= e; i--)
#define ln "\n"
#define dbg(x) cout<<#x<<" = "<<x<<ln
#define mp make_pair
#define pb push_back
#define fi first
#define se second
#define INF 1e18
#define fast_cin() ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL)
#define all(x) (x).begin(), (x).end()
#define sz(x) ((ll)(x).size())

ll mpow(ll a, ll b){
	if(b==0) return 1;
	ll t1 = mpow(a,b/2);
	t1 *= t1;
	t1 %= MOD;
	if(b%2) t1 *= a;
	t1 %= MOD;
	return t1;
}

ll mpow(ll a, ll b, ll p){
	if(b==0) return 1;
	ll t1 = mpow(a,b/2);
	t1 *= t1;
	t1 %= p;
	if(b%2) t1 *= a;
	t1 %= p;
	return t1;
}

ll modinverse(ll a, ll m){
	ll m0 = m;
    ll y = 0, x = 1;
    if (m == 1) return 0;
    while (a > 1){
        ll q = a / m;
        ll t = m;
        m = a % m, a = t;
        t = y;
        y = x - q * y;
        x = t;
    }
    if (x < 0) x += m0;
    return x;
}

ll range(ll l, ll r){
	return l + rand()%(r-l+1);
}

void solve(){
	ll n,m;
	cin >> n >> m;
	char arr[n][m];
	forn(i,n){
		forn(j,m){
			cin >> arr[i][j];
		}
	}
	vv64 dp(n,v64(m,0));
	dp[n-1][m-1]=1;
	rforn(i,n-1){
		rforn(j,m-1){
			if(arr[i][j]=='.') dp[i][j] += ((i+1<n) ? dp[i+1][j] : 0) + ((j+1<m) ? dp[i][j+1] : 0);
		}
	}
	if(dp[0][0]==0){
		cout << 0 << ln;
		return;
	}
	forn(i,n-1){
		forn(j,m-1){
			if((i==0 && j==0) || (i==n-1 && j==m-1)){
				continue;
			}
			else if(dp[i][j]==dp[0][0]){
				cout << 1 << ln;
				return;
			}
		}
	}
	cout << 2 << ln;;
}

int main()
{
	fast_cin();
    ll t=1;
	// cin >> t;
    forn(i,t) {
    	solve();
    }
    return 0;
}


#include <bits/stdc++.h>
#include <complex>
#include <queue>
#include <set>
#include <unordered_set>
#include <list>
#include <chrono>
#include <random>
#include <iostream>
#include <algorithm>
#include <cmath>
#include <string>
#include <vector>
#include <map>
#include <unordered_map>
#include <stack>
#include <iomanip>
#include <fstream>

using namespace std;

typedef long long ll;
typedef long double ld;
typedef pair<long long int,long long int> p32;
typedef pair<ll,ll> p64;
typedef pair<double,double> pdd;
typedef vector<ll> v64;
typedef vector<long long int> v32;
typedef vector<vector<long long int> > vv32;
typedef vector<vector<ll> > vv64;
typedef vector<vector<p64> > vvp64;
typedef vector<p64> vp64;
typedef vector<p32> vp32;
ll MOD = 998244853;
#define forn(i,e) for(ll i = 0; i < e; i++)
#define forsn(i,s,e) for(ll i = s; i < e; i++)
#define rforn(i,s) for(ll i = s; i >= 0; i--)
#define rforsn(i,s,e) for(ll i = s; i >= e; i--)
#define ln "\n"
#define dbg(x) cout<<#x<<" = "<<x<<ln
#define mp make_pair
#define pb push_back
#define fi first
#define se second
#define INF 1e18
#define fast_cin() ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL)
#define all(x) (x).begin(), (x).end()
#define sz(x) ((ll)(x).size())

ll mpow(ll a, ll b){
	if(b==0) return 1;
	ll t1 = mpow(a,b/2);
	t1 *= t1;
	t1 %= MOD;
	if(b%2) t1 *= a;
	t1 %= MOD;
	return t1;
}

ll mpow(ll a, ll b, ll p){
	if(b==0) return 1;
	ll t1 = mpow(a,b/2);
	t1 *= t1;
	t1 %= p;
	if(b%2) t1 *= a;
	t1 %= p;
	return t1;
}

ll modinverse(ll a, ll m){
	ll m0 = m;
    ll y = 0, x = 1;
    if (m == 1) return 0;
    while (a > 1){
        ll q = a / m;
        ll t = m;
        m = a % m, a = t;
        t = y;
        y = x - q * y;
        x = t;
    }
    if (x < 0) x += m0;
    return x;
}

ll range(ll l, ll r){
	return l + rand()%(r-l+1);
}

void solve(){
	ll n,m;
	cin >> n >> m;
	char arr[n][m];
	forn(i,n){
		forn(j,m){
			cin >> arr[i][j];
		}
	}
	vv64 dp(n,v64(m,0));
	dp[n-1][m-1]=1;
	rforn(i,n-1){
		rforn(j,m-1){
			if(arr[i][j]=='.') dp[i][j] += ((i+1<n) ? dp[i+1][j] : 0) + ((j+1<m) ? dp[i][j+1] : 0);
		}
	}
	vv64 dp1(n,v64(m,0));
	dp1[0][0]=1;
	forn(i,n){
		forn(j,m){
			if(arr[i][j]=='.') dp1[i][j] += ((i-1>=0) ? dp1[i-1][j] : 0) + ((j-1>=0) ? dp1[i][j-1] : 0);
		}
	}
	if(dp[0][0]==0){
		cout << 0 << ln;
		return;
	}
	forn(i,n){
		forn(j,m){
			if((i==0 && j==0) || (i==n-1 && j==m-1)){
				continue;
			}
			else if(dp[i][j]*dp1[i][j]==dp[0][0]){
				cout << 1 << ln;
				return;
			}
		}
	}
	cout << 2 << ln;
}

int main()
{
	fast_cin();
    ll t=1;
	// cin >> t;
    forn(i,t) {
    	solve();
    }
    return 0;
}


#pragma GCC optimize("O3")
#include <iostream>
#include <vector>

using namespace std;

const int MAX = 1e6;

int n, m, net;
bool blocked[MAX];

bool dfs(const int k = 0) {
    if (k == net - 1) return true;
    if (k >= net or blocked[k]) return false;
    blocked[k] = true;
    return dfs(k + m) or dfs(k + 1);
}

int main() {
    ios_base::sync_with_stdio(0);

    cin >> n >> m;
    net = n * m;
    for (register int i = 0; i < net; i += m) {
        string row;
        cin >> row;
        for (int j = 0; j < m; j++) {
            blocked[i + j] = row[j] == '#';
        }
    }
    register char res = '0';
    if (dfs()) {
        res = dfs(1) ? '2' : '1';
    }
    cout << res << '\n';
}


#pragma GCC optimize("Ofast")
#include <iostream>

using namespace std;

const int MAX = 1e6;

int n, m, net;
bool blocked[MAX];

bool dfs(const int k = 0) {
    if (k == net - 1) return true;
    if (k >= net or blocked[k]) return false;
    blocked[k] = true;
    return dfs(k + m) or dfs(k + 1);
}

int main() {
    ios_base::sync_with_stdio(0);

    cin >> n >> m;
    net = n * m;
    for (int i = 0; i < net; i += m) {
        string row;
        cin >> row;
        for (int j = 0; j < m; j++) {
            blocked[i + j] = row[j] == '#';
        }
    }

    if (dfs()) cout << (dfs(1) ? '2' : '1');
    else cout << '0';
}