// #define DEBUGGING
#include <bits/stdc++.h>
#define endl '\n'
#define ALL(V) begin(V), end(V)
#define ALLR(V) rbegin(V), rend(V)
using ll = std::int64_t;
using ull = std::uint64_t;
using PLL = std::pair<ll, ll>;
using TLL = std::tuple<ll, ll, ll>;
template <typename T> using V = std::vector<T>;
template <typename T> using VV = V<V<T>>;
template <typename T> const T& var_min(const T &t) { return t; }
template <typename T> const T& var_max(const T &t) { return t; }
template <typename T, typename... Tail> const T& var_min(const T &t, const Tail&... tail) { return std::min(t, var_min(tail...)); }
template <typename T, typename... Tail> const T& var_max(const T &t, const Tail&... tail) { return std::max(t, var_max(tail...)); }
template <typename T, typename... Tail> void chmin(T &t, const Tail&... tail) { t = var_min(t, tail...); }
template <typename T, typename... Tail> void chmax(T &t, const Tail&... tail) { t = var_max(t, tail...); }
template <typename T> const T& clamp(const T &t, const T &low, const T &high) { return std::max(low, std::min(high, t)); }
template <typename T> void chclamp(T &t, const T &low, const T &high) { return t = clamp(t, low, high); }
namespace init__ { struct InitIO { InitIO() { std::cin.tie(nullptr); std::ios_base::sync_with_stdio(false); std::cout << std::fixed << std::setprecision(30); } } init_io; }
#define mv_rec make_v(init, tail...)
template <typename T> T make_v(T init) { return init; }
template <typename T, typename... Tail> auto make_v(T init, size_t s, Tail... tail) { return V<decltype(mv_rec)>(s, mv_rec); }
#undef mv_rec
using namespace std;

#ifdef DEBUGGING
#include "../../debug/debug.cpp"
#else
#define DEBUG(...) 0
#define DEBUG_SEPARATOR_LINE 0
#endif

ll gcd(ll a, ll b) { return b ? gcd(b, a % b) : a; }

using Frac = PLL;

Frac about_f(const Frac &p) {
    ll a, b;
    tie(a, b) = p;
    ll g = gcd(a, b);
    a /= g;
    b /= g;
    return Frac(a, b);
}

Frac make_f(ll a, ll b) { return about_f(Frac(a, b)); }

struct FracID {
    V<Frac> id_v;

    FracID(ll X, ll Y) {
        for (ll x = 1; x <= X; x++) for (ll y = 1; y <= Y; y++) {
            Frac f = make_f(y, x);
            id_v.push_back(f);
        }
        sort(ALL(id_v), [&](const Frac &p, const Frac &q) { return comp(p, q); });
        auto ite = unique(ALL(id_v));
        id_v.erase(ite, id_v.end());
    }

    bool comp(const Frac &p, const Frac &q) {
        ll a, b, c, d;
        tie(a, b) = p;
        tie(c, d) = q;
        // a/b < c/d
        return a * d < b * c;
    }

    ll get_id(const Frac &f) {
        ll a, b;
        tie(a, b) = f;
        if (!a) return 0;
        if (!b) return id_v.size() + 2;
        auto ite = lower_bound(ALL(id_v), f, [&](const Frac &p, const Frac &q) { return comp(p, q); });
        DEBUG(make_tuple(f, *ite));
        return distance(id_v.begin(), ite) + 1;
    }

    ll get_id(ll a, ll b) {
        Frac f = make_f(a, b);
        DEBUG(f);
        return get_id(f);
    }
};

int main() {
    ll Y, X;
    cin >> Y >> X;
    auto grid = make_v<bool>(0, X, Y);
    {
        V<string> vs(Y);
        for (auto &&s : vs) cin >> s;
        for (ll x = 0; x < X; x++) for (ll y = 0; y < Y; y++) grid[x][y] = (vs[Y - y - 1][x] == '#');
    }
    FracID fid(X, Y);
    V<ll> imos(2 * (fid.id_v.size() + 1) + 10);
    imos[0]++;

    auto fix_id = [&](ll fid) { return fid * 2; };

    auto add_imos = [&](ll x1, ll y1, ll x2, ll y2) {
        if (x1 == y1 && x2 == y2) return;
        auto fid1 = fid.get_id(y1, x1);
        auto fid2 = fid.get_id(y2, x2);
        DEBUG(make_tuple(x1, y1, x2, y2));
        if (fid2 < fid1) swap(fid1, fid2);
        DEBUG(make_tuple(fix_id(fid1), fix_id(fid2)));
        imos[fix_id(fid1) + 1]++;
        imos[fix_id(fid2)]--;
    };
    
    for (ll x = 0; x < X; x++) for (ll y = 1; y <= Y; y++) {
        bool down = grid[x][y - 1];
        bool up = (y < Y && grid[x][y]);
        if (!(up ^ down)) continue;
        add_imos(x, y, x + 1, y);
    }
    for (ll x = 1; x <= X; x++) for (ll y = 0; y < Y; y++) {
        bool left = grid[x - 1][y];
        bool right = (x < X && grid[x][y]);
        if (!(left ^ right)) continue;
        add_imos(x, y, x, y + 1);
    }

    DEBUG(imos);
    for (ll i = 0; i + 1 < imos.size(); i++) imos[i + 1] += imos[i];
    DEBUG(imos);
    ll maxv = 0;
    for (ll i = 0; i < imos.size(); i++) chmax(maxv, imos[i]);
    DEBUG(maxv);
    cout << 1 + maxv / 2 << endl;
    return 0;
}



Measured memory_bytes: 12116