#include <bits/stdc++.h>

using namespace std;

#define uniq(xs) ((xs).erase(unique((xs).begin(), (xs).end()), (xs).end()))

namespace {

    template<class T> ostream& operator<<(ostream& os, const vector<T>& vs) {
        if (vs.empty()) return os << "[]";
        os << "[" << vs[0];
        for (int i = 1; i < vs.size(); i++) os << " " << vs[i];
        return os << "]";
    }

    const double EPS = 1e-5;

    bool EQ(double x, double y) { return abs(x - y) < EPS; }

    struct Point {
        double x, y;
        Point() {}
        Point(double x, double y) : x(x), y(y) {}
        Point operator+(const Point& p) const { return Point(x + p.x, y + p.y); }
        Point operator-(const Point& p) const { return Point(x - p.x, y - p.y); }
        Point operator*(double k) const { return Point(k * x, k * y); }
        Point operator/(double k) const { return Point(x / k, y / k); }
        bool operator==(const Point& p) const { return EQ(x, p.x) && EQ(y, p.y); }
        bool operator<(const Point& p) const { return EQ(x, p.x) ? y < p.y : x < p.x; }
    };
    double dot(const Point& a, const Point& b) { return a.x * b.x + a.y * b.y; }
    double cross(const Point& a, const Point& b) { return a.x * b.y - a.y * b.x; }
    double norm(const Point& a) { return sqrt(dot(a, a)); }
    double angle(const Point& a) { return atan2(a.y, a.x); }
    Point rot90(const Point& p) { return Point(-p.y, p.x); } // 反時計回りに90度回転 
    ostream& operator<<(ostream& os, const Point& p) { return os << "(" << p.x << "," << p.y << ")"; }
    istream& operator>>(istream& is, Point& p) { return is >> p.x >> p.y; }

    int H, W;
    vector<string> F;
    void input() {
        cin >> H >> W;
        F.clear(); F.resize(H);
        for (int i = 0; i < H; i++) {
            cin >> F[i];
        }
    }

    struct E {
        Point p;
        bool type;
        E() {}
        E(Point p, bool type) : p(p), type(type) { }
        bool operator<(const E& e) const {
            double a = angle(p), b = angle(e.p);
            return (EQ(a, b) ? type > e.type : a > b);
        }
    };
    ostream& operator<<(ostream& os, const E& e) {
        return os << "E(" << e.p << "->" << e.type << ")";
    }

    void C(int y, int x, priority_queue<E>& Q) {
        string s, t;
        for (int i = 0; i < 2; i++) {
            for (int j = 0; j < 2; j++) {
                int ny = y - i, nx = x - j;
                if (ny < 0 || nx < 0) {
                    s.push_back('.');
                } else {
                    s.push_back(F[ny][nx]);
                }
                ny = y + i, nx = x + j;
                if (ny >= H || nx >= W) {
                    t.push_back('.');
                } else {
                    t.push_back(F[ny][nx]);
                }
            }
        }

        if (false) {
            cout << y << " " << x << endl;
            cout << s << " " << t << endl;
        }
        if (s == "#..." || s == "###.") {
            Point p(x, H - y);
            Q.push(E(p, s == "###."));
        }
        if (t == "#..." || t == "###.") {
            Point p(x + 1, H - (y + 1));
            Q.push(E(p, t == "#..."));
        }
    }

    void solve() {
        priority_queue<E> Q;
        for (int i = 0; i < H; i++) {
            for (int j = 0; j < W; j++) {
                C(i, j, Q);
            }
        }
        int ans = 1;
        int c = 1;
        while (!Q.empty()) {
            E e = Q.top(); Q.pop();
            c += (e.type ? +1 : -1);
            ans = max(ans, c);
        }
        cout << ans << endl;
    }
}

int main() {
    input(); solve();
    return 0;
}

Measured memory_bytes: 5636