#include <bits/stdc++.h>
using namespace std;
struct IP {
  long long x, y;
  IP() {}
  IP(long long y, long long x) : x(x), y(y) {}
  IP operator+(const IP &rhs) const { return IP(y + rhs.y, x + rhs.x); }
  IP operator-(const IP &rhs) const { return IP(y - rhs.y, x - rhs.x); }
  IP operator-() const { return IP(0, 0) - *this; }
  bool operator<(const IP &rhs) const {
    return (x != rhs.x) ? x < rhs.x : y < rhs.y;
  }
};
int N, M;
char s[1020][1020];
bool vis[1020][1020];
bool cor[1020][1020];
int lg[1020][1020];
bool valid;
vector<IP> pts;
void bfs(int iy, int ix) {
  queue<IP> q;
  q.push(IP(iy, ix));
  valid = true;
  while (!q.empty()) {
    IP p = q.front();
    q.pop();
    if (vis[p.y][p.x]) continue;
    vis[p.y][p.x] = true;
    for (int ay = (p.y - 1); ay <= (int)(p.y + 1); ++ay)
      for (int ax = (p.x - 1); ax <= (int)(p.x + 1); ++ax) {
        if (ay < 0 || ay >= N || ax < 0 || ax >= M) {
          valid = false;
          continue;
        }
        if (s[ay][ax] == '1') {
          pts.push_back(IP(ay, ax));
          continue;
        }
        if (vis[ay][ax]) continue;
        q.push(IP(ay, ax));
      }
  }
}
int main() {
  while (scanf("%d%d", &N, &M) != EOF) {
    for (int y = 0; y < (int)(N); ++y) scanf(" %s", s[y]);
    memset((vis), (false), sizeof(vis));
    memset((cor), (false), sizeof(cor));
    memset((lg), (-1), sizeof(lg));
    int res = 0;
    for (int iy = 0; iy < (int)(N); ++iy)
      for (int ix = 0; ix < (int)(M); ++ix)
        if (s[iy][ix] == '0' && !vis[iy][ix]) {
          pts.clear();
          bfs(iy, ix);
          if (valid) {
            assert((int)((pts).size()) > 0);
            for (__typeof((pts).begin()) ip = (pts).begin(); ip != (pts).end();
                 ++ip) {
              cor[ip->y][ip->x] = true;
            }
            IP curr = pts[0];
            int step = 0;
            for (;;) {
              lg[curr.y][curr.x] = step++;
              for (int dy = (-1); dy <= (int)(1); ++dy)
                for (int dx = (-1); dx <= (int)(1); ++dx) {
                  cor[curr.y][curr.x] = false;
                  if (abs(dy) + abs(dx) != 1) {
                    continue;
                  }
                  IP next = curr + IP(dy, dx);
                  int ay = next.y;
                  int ax = next.x;
                  if (ay < 0 || ay >= N || ax < 0 || ax >= M) {
                    continue;
                  }
                  if (!cor[ay][ax]) {
                    continue;
                  }
                  curr = next;
                  goto UPD;
                }
              break;
            UPD:;
            }
            bool good = true;
            bool closed = false;
            for (__typeof((pts).begin()) ip = (pts).begin(); ip != (pts).end();
                 ++ip) {
              for (int dy = (-1); dy <= (int)(1); ++dy)
                for (int dx = (-1); dx <= (int)(1); ++dx) {
                  if (abs(dy) + abs(dx) != 1) {
                    continue;
                  }
                  IP next = *ip + IP(dy, dx);
                  int ay = next.y;
                  int ax = next.x;
                  if (ay < 0 || ay >= N || ax < 0 || ax >= M) {
                    continue;
                  }
                  if (lg[ay][ax] == -1) {
                    continue;
                  }
                  int A = lg[ip->y][ip->x];
                  int B = lg[ay][ax];
                  if (abs(A - B) == step - 1) {
                    closed = true;
                  }
                  if (abs(A - B) != step - 1 && abs(A - B) != 1) {
                    good = false;
                  }
                }
            }
            if (!closed) good = false;
            for (__typeof((pts).begin()) ip = (pts).begin(); ip != (pts).end();
                 ++ip) {
              lg[ip->y][ip->x] = -1;
              if (cor[ip->y][ip->x]) {
                good = false;
                cor[ip->y][ip->x] = false;
              }
            }
            if (good) {
              res = max(res, step);
            }
          }
        }
    for (int y = 0; y < (int)(N - 1); ++y)
      for (int x = 0; x < (int)(M - 1); ++x) {
        if (s[y][x] == '1' && s[y + 1][x] == '1' && s[y][x + 1] == '1' &&
            s[y + 1][x + 1] == '1') {
          res = max(res, 4);
        }
      }
    printf("%d\n", res);
  }
}
