package main
import (
"bufio"
"fmt"
"os"
)
type Point struct {
x, y int
}
func main() {
reader := bufio.NewReader(os.Stdin)
var n, m int
if _, err := fmt.Fscanf(reader, "%d %d\n", &n, &m); err != nil {
return
}
grid := make([]string, n)
for i := 0; i < n; i++ {
fmt.Fscan(reader, &grid[i])
}
max_len := 0
for i := 0; i < n-1; i++ {
for j := 0; j < m-1; j++ {
if grid[i][j] == '1' && grid[i+1][j] == '1' && grid[i][j+1] == '1' && grid[i+1][j+1] == '1' {
if 4 > max_len {
max_len = 4
}
}
}
}
visited := make([][]bool, n)
inS := make([][]bool, n)
visitedS := make([][]bool, n)
for i := 0; i < n; i++ {
visited[i] = make([]bool, m)
inS[i] = make([]bool, m)
visitedS[i] = make([]bool, m)
}
dx8 := []int{-1, -1, -1, 0, 0, 1, 1, 1}
dy8 := []int{-1, 0, 1, -1, 1, -1, 0, 1}
dx4 := []int{-1, 1, 0, 0}
dy4 := []int{0, 0, -1, 1}
var S []Point
var q []Point
var q1 []Point
for i := 0; i < n; i++ {
for j := 0; j < m; j++ {
if grid[i][j] == '0' && !visited[i][j] {
q = q[:0]
q = append(q, Point{i, j})
visited[i][j] = true
touchesBoundary := false
for head := 0; head < len(q); head++ {
curr := q[head]
x, y := curr.x, curr.y
if x == 0 || x == n-1 || y == 0 || y == m-1 {
touchesBoundary = true
}
for d := 0; d < 8; d++ {
nx, ny := x+dx8[d], y+dy8[d]
if nx >= 0 && nx < n && ny >= 0 && ny < m {
if grid[nx][ny] == '0' {
if !visited[nx][ny] {
visited[nx][ny] = true
q = append(q, Point{nx, ny})
}
} else if grid[nx][ny] == '1' {
if !inS[nx][ny] {
inS[nx][ny] = true
S = append(S, Point{nx, ny})
}
}
}
}
}
cleanup := func() {
for _, p := range S {
inS[p.x][p.y] = false
}
S = S[:0]
}
if touchesBoundary {
cleanup()
continue
}
if len(S) < 4 {
cleanup()
continue
}
valid := true
for _, p := range S {
count := 0
for d := 0; d < 4; d++ {
nx, ny := p.x+dx4[d], p.y+dy4[d]
if nx >= 0 && nx < n && ny >= 0 && ny < m {
if inS[nx][ny] {
count++
}
}
}
if count != 2 {
valid = false
break
}
}
if !valid {
cleanup()
continue
}
start := S[0]
q1 = q1[:0]
q1 = append(q1, start)
visitedS[start.x][start.y] = true
visitedCount := 1
for head := 0; head < len(q1); head++ {
curr := q1[head]
for d := 0; d < 4; d++ {
nx, ny := curr.x+dx4[d], curr.y+dy4[d]
if nx >= 0 && nx < n && ny >= 0 && ny < m {
if inS[nx][ny] && !visitedS[nx][ny] {
visitedS[nx][ny] = true
q1 = append(q1, Point{nx, ny})
visitedCount++
}
}
}
}
if visitedCount == len(S) {
if len(S) > max_len {
max_len = len(S)
}
}
for _, p := range q1 {
visitedS[p.x][p.y] = false
}
cleanup()
}
}
}
fmt.Println(max_len)
}