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

// conj(x) : complex conjugate,(0,1)->(0,-1)
// abs(x) : dist between(0,0) and x
// norm(x) : abs(x) * abs(x)
// arg(x) : argment,[-PI,PI]
using CP = complex<long double>;
#define X real()
#define Y imag()
const long double PI = acos(-1.0L);
const long double EPS = 1e-10;
// cos a
long double costh(long double a, long double b,
                  long double c) {
  return (b * b + c * c - a * a) / (2.0L * b * c);
}

// dot(a,b) = |a||b|cos x
long double dot(CP a, CP b) { return (conj(a) * b).X; }
// cross(a,b) : area of parallelogram
// sign : a-> b ,counter clockwise? + : -
long double cross(CP a, CP b) { return (conj(a) * b).Y; }
long double corner(CP a, CP b) {
  //[0,PI]
  return acos(dot(a, b) / (abs(a) * abs(b)));
}

CP projection(CP s, CP t, CP p) {
  CP base = t - s;
  long double r = dot(p - s, base) / norm(base);
  return s + base * r;
}

CP reflection(CP s, CP t, CP p) {
  CP tmp = (projection(s, t, p) - p);
  tmp *= 2;
  return p + tmp;
}

CP intersectionLL(CP a, CP b, CP c, CP d) {
  return a + (b - a) * (cross(d - c, c - a) /
                        cross(d - c, b - a));
}

bool on_seg(CP s, CP t, CP p) {
  // if not use end point, dot(s - p, t - p) < 0
  return abs(cross(s - p, t - p)) <= 1e-10 &&
         dot(s - p, t - p) <= 0;
}

// crossing lines? (a,b) and (c,d)
bool iscross(CP a, CP b, CP c, CP d) {
  // parallel
  if(abs(cross(a - b, c - d)) <= 1e-10) {
    return on_seg(a, b, c) || on_seg(a, b, d) ||
           on_seg(c, d, a) || on_seg(c, d, b);
  }
  CP isp = intersectionLL(a, b, c, d);
  return on_seg(a, b, isp) && on_seg(c, d, isp);
}

long long calc_clockwise(CP s, CP t, CP p) {
  t -= s;
  p -= s;
  if(cross(t, p) > EPS) return 1;   // "COUNTER_CLOCKWISE"
  if(cross(t, p) < -EPS) return -1; //"CLOCK_WISE"
  if(dot(t, p) < 0) return 2;       // ONLINE_BACK
  if(norm(t) < norm(p)) return -2;  // ONLINE_FRONT
  return 0;                         // ON_SEGMENT
}

struct line {
  CP s, t;
};

struct corn {
  CP a, b, c;
  bool operator<(const corn &x) const {
    return arg(a) < arg(x.a);
  }
};

int h, w;
int d[4] = {-1, 0, 1, 0};
vector<string> s;
vector<line> edges;

long long solve();
bool isvalid(long long x, long long y, long long nd) {
  if(nd == 0) --x, --y;
  if(nd == 1) --y;
  if(nd == 3) --x;
  return x >= 0 && x < h && y >= 0 && y < w &&
         s[x][y] == '#';
}

int main() {
  cin >> h >> w;
  s.resize(h);
  for(int i = 0; i < h; ++i) cin >> s[i];

  cout << solve() << endl;
  return 0;
}

long long solve() {
  long long res = 0, sx = -1, sy = -1, nx = -1, ny = -1,
            nd = 2;
  for(int i = 0; i < h; ++i)
    if(sx == -1)
      for(int j = 0; j < w; ++j)
        if(s[i][j] == '#') {
          nx = sx = i;
          ny = sy = j;
          break;
        }
  do {
    long long tx = nx, ty = ny;
    while(1) {
      tx += d[nd];
      ty += d[1 ^ nd];
      if(!isvalid(tx, ty, nd)) break;
      if(isvalid(tx, ty, (nd + 3) % 4)) {
        nd += 2;
        break;
      }
    }
    if(nx != tx || ny != ty)
      edges.push_back({CP(nx, ny), CP(tx, ty)});
    nx = tx;
    ny = ty;
    (++nd) %= 4;
  } while(sx != nx || sy != ny || nd != 2);
  long long n = edges.size(), cnt = 0;
  vector<corn> corners;
  for(int i = 0; i < n; ++i)
    corners.push_back({edges[i].t - CP(h, 0), edges[i].s,
                       edges[(i + 1) % n].t});
  sort(corners.begin(), corners.end());
  for(long long i = 0; i < n;) {
    CP nows(h, 0), nowt;
    long double nowarg = arg(corners[i].a);
    while(i < n && abs(nowarg - arg(corners[i].a)) <= EPS) {
      if(norm(corners[i].a) <= EPS * EPS) {
        ++cnt;
        ++i;
        continue;
      }
      nowt = corners[i].a + nows;
      int ch = calc_clockwise(nows, nowt, corners[i].b);
      if(ch == 1)
        ++cnt;
      else if(ch == -1)
        --cnt;
      ch = calc_clockwise(nows, nowt, corners[i].c);
      if(ch == 1)
        ++cnt;
      else if(ch == -1)
        --cnt;
      ++i;
    }
    res = max(res, cnt / 2);
  }
  return res + 1;
}


Measured memory_bytes: 49108