#include <bits/stdc++.h>
using namespace std;
const int MAX = 1200;
int n, m, vist[MAX][MAX], mark[MAX][MAX], vist2[MAX][MAX];
char s[MAX][MAX];
int dir[4][2] = {{-1, 0}, {1, 0}, {0, 1}, {0, -1}};
int dir2[8][2] = {{-1, 0}, {1, 0},   {0, 1}, {0, -1},
                  {-1, 1}, {-1, -1}, {1, 1}, {1, -1}};
struct node {
  int row, col;
  node(int a = 0, int b = 0) : row(a), col(b) {}
  bool operator<(const node &b) const {
    if (row != b.row)
      return row < b.row;
    else
      return col < b.col;
  }
};
inline bool in(int r, int c) { return r >= 0 && r < n && c >= 0 && c < m; };
void dfs(int r, int c, set<node> &mm) {
  vist[r][c] = 1;
  mm.insert(node(r, c));
  for (int i = 0; i < 8; i++) {
    int r1 = r + dir2[i][0], c1 = c + dir2[i][1];
    if (in(r1, c1) && !vist[r1][c1] && s[r1][c1] == '0') {
      dfs(r1, c1, mm);
    }
  }
};
int zb;
void dfs2(int r, int c) {
  vist2[r][c] = zb;
  for (int i = 0; i < 4; i++) {
    int r1 = r + dir[i][0], c1 = c + dir[i][1];
    if (in(r1, c1) && s[r1][c1] == '1' && vist2[r1][c1] == -1) {
      dfs2(r1, c1);
    }
  }
}
int main() {
  scanf("%d%d", &n, &m);
  for (int i = 0; i < n; i++) scanf("%s", s[i]);
  memset(vist, 0, sizeof(vist)), memset(mark, 0, sizeof(mark)),
      memset(vist2, -1, sizeof(vist2));
  int ans = 0, cnt = 0;
  for (int i = 0; i < n - 1; i++) {
    for (int j = 0; j < m - 1; j++) {
      int i1 = i + 1, j1 = j + 1;
      if (s[i][j] == '1' && s[i1][j] == '1' && s[i][j1] == '1' &&
          s[i1][j1] == '1')
        ans = 4;
    }
  }
  zb = 0;
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < m; j++) {
      if (s[i][j] == '1' && vist2[i][j] == -1) {
        dfs2(i, j);
        zb++;
      }
    }
  }
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < m; j++) {
      if (!vist[i][j] && s[i][j] == '0') {
        cnt++;
        set<node> mm;
        dfs(i, j, mm);
        bool ok = 1;
        for (auto &ele : mm) {
          int row = ele.row, col = ele.col;
          for (int i = 0; i < 8; i++) {
            int r1 = row + dir2[i][0], c1 = col + dir2[i][1];
            if (!in(r1, c1)) ok = 0;
          }
        }
        if (ok) {
          int count = 0;
          set<node> ss;
          for (auto &ele : mm) {
            int rowid = ele.row, col = ele.col;
            for (int o = 0; o < 8; o++) {
              int r1 = rowid + dir2[o][0], c1 = col + dir2[o][1];
              if (mm.find({r1, c1}) != mm.end())
                continue;
              else {
                if (mark[r1][c1] != cnt)
                  mark[r1][c1] = cnt, count++, ss.insert(node(r1, c1));
              }
            }
          }
          node one = *ss.begin();
          int color = vist2[one.row][one.col];
          for (auto &ele : ss) {
            if (color != vist2[ele.row][ele.col]) {
              ok = 0;
              break;
            }
          }
          if (ok) {
            for (auto &ele : ss) {
              int row = ele.row, col = ele.col;
              int ct = 0;
              for (int o = 0; o < 4; o++) {
                int r1 = row + dir[o][0], c1 = col + dir[o][1];
                if (ss.find({r1, c1}) != ss.end()) ct++;
              }
              if (ct != 2) {
                ok = 0;
                break;
              }
            }
            if (ok) {
              ans = max(ans, count);
            }
          }
        }
      }
    }
  }
  printf("%d\n", ans);
  return 0;
}
