#include <bits/stdc++.h>
using namespace std;
template <class T>
inline T checkmin(T &a, T b) {
  return (a < b) ? a : a = b;
}
template <class T>
inline T checkmax(T &a, T b) {
  return (a > b) ? a : a = b;
}
template <class T>
T GCD(T a, T b) {
  if (a < 0) return GCD(-a, b);
  if (b < 0) return GCD(a, -b);
  return (a == 0) ? b : GCD(b % a, a);
}
template <class T>
T LCM(T a, T b) {
  if (a < 0) return LCM(-a, b);
  if (b < 0) return LCM(a, -b);
  return (a == 0 || b == 0) ? 0 : a / GCD(a, b) * b;
}
template <class T>
inline T sqr(T X) {
  return X * X;
}
namespace Poor {
const int MaxiN = 1005;
int N, M, Ans;
char Map[MaxiN][MaxiN];
bool Known[MaxiN][MaxiN];
vector<int> UFS;
bool InRange(int X, int Y) { return X >= 0 && X < N && Y >= 0 && Y < M; }
int Find(int X) { return (UFS[X] < 0) ? X : (UFS[X] = Find(UFS[X])); }
void Union(int X, int Y) {
  X = Find(X);
  Y = Find(Y);
  if (X == Y) return;
  UFS[X] = Y;
}
void Do(int SX, int SY) {
  deque<pair<int, int> > Q;
  vector<pair<int, int> > Visitor;
  Q.push_back(make_pair(SX, SY));
  while (!Q.empty()) {
    pair<int, int> Cur = Q.front();
    Q.pop_front();
    Visitor.push_back(Cur);
    for (int a = -1; a <= 1; ++a)
      for (int b = -1; b <= 1; ++b)
        if (abs(a) + abs(b) > 0) {
          int NX = Cur.first + a;
          int NY = Cur.second + b;
          if (InRange(NX, NY) && Map[NX][NY] == '0' && !Known[NX][NY]) {
            Known[NX][NY] = 1;
            Q.push_back(make_pair(NX, NY));
          }
        }
  }
  vector<pair<int, int> > One;
  for (typeof(Visitor.begin()) it = Visitor.begin(); it != Visitor.end();
       ++it) {
    for (int a = -1; a <= 1; ++a)
      for (int b = -1; b <= 1; ++b) {
        int NX = it->first + a;
        int NY = it->second + b;
        if (InRange(NX, NY) && Map[NX][NY] == '1')
          One.push_back(make_pair(NX, NY));
      }
  }
  if (One.empty()) return;
  sort(One.begin(), One.end());
  One.erase(unique(One.begin(), One.end()), One.end());
  if ((int)One.size() < Ans) return;
  vector<int> Deg = vector<int>(One.size(), 0);
  for (typeof(One.begin()) it = One.begin(); it != One.end(); ++it) {
    for (int a = -1; a <= 1; ++a)
      for (int b = -1; b <= 1; ++b)
        if (abs(a) + abs(b) == 1) {
          int NX = it->first + a;
          int NY = it->second + b;
          if (binary_search(One.begin(), One.end(), make_pair(NX, NY))) {
            int Pos = lower_bound(One.begin(), One.end(), make_pair(NX, NY)) -
                      One.begin();
            ++Deg[Pos];
          }
        }
  }
  for (typeof(Deg.begin()) it = Deg.begin(); it != Deg.end(); ++it)
    if (*it != 2) return;
  UFS = vector<int>(One.size(), -1);
  for (typeof(One.begin()) it = One.begin(); it != One.end(); ++it) {
    for (int a = -1; a <= 1; ++a)
      for (int b = -1; b <= 1; ++b)
        if (abs(a) + abs(b) == 1) {
          int NX = it->first + a;
          int NY = it->second + b;
          if (binary_search(One.begin(), One.end(), make_pair(NX, NY))) {
            int Pos = lower_bound(One.begin(), One.end(), make_pair(NX, NY)) -
                      One.begin();
            Union(it - One.begin(), Pos);
          }
        }
  }
  for (int i = 0; i < (int)One.size(); ++i)
    if (Find(i) != Find(0)) return;
  checkmax(Ans, (int)One.size());
}
void Run() {
  scanf("%d%d", &N, &M);
  for (int i = 0; i < N; ++i)
    for (int j = 0; j < M; ++j) {
      char Ch = getchar();
      if (!isdigit(Ch)) Ch = getchar();
      Map[i][j] = Ch;
    }
  memset(Known, 0, sizeof(Known));
  for (int i = 0; i < N; ++i)
    for (int j = 0; j < M; ++j)
      if (!Known[i][j] && Map[i][j] == '0' &&
          (i == 0 || i == N - 1 || j == 0 || j == M - 1))
        Do(i, j);
  Ans = 0;
  for (int i = 0; i < N - 1; ++i)
    for (int j = 0; j < M - 1; ++j)
      if (Map[i][j] == '1' && Map[i + 1][j] == '1' && Map[i][j + 1] == '1' &&
          Map[i + 1][j + 1] == '1')
        Ans = 4;
  for (int i = 0; i < N; ++i)
    for (int j = 0; j < M; ++j)
      if (!Known[i][j] && Map[i][j] == '0') Do(i, j);
  printf("%d\n", Ans);
}
}  // namespace Poor
int main() {
  Poor::Run();
  return 0;
}
