#include using namespace std; #define ll long long #define ld long double #define pb push_back #define mp make_pair #define pii pair #define pll pair #define pdd pair #define all(x) (x).begin(), (x).end() #define fi first #define se second const int NMAX = 505; const int INF = 1 << 20; int c[NMAX]; char s[NMAX][NMAX]; int X, Y, Val; int A[4 * NMAX], Lazy[4 * NMAX], S; void Update(int Node, int L, int R) { int M = (L + R) / 2; int LS = 2 * Node; int RS = 2 * Node + 1; if (Lazy[Node]) { A[Node] += Lazy[Node]; if (L < R) { Lazy[LS] += Lazy[Node]; Lazy[RS] += Lazy[Node]; } Lazy[Node] = 0; } if (L > Y || R < X) return; if (L >= X && R <= Y) { A[Node] += Val; if (L < R) { Lazy[LS] += Val; Lazy[RS] += Val; } return; } Update(LS, L, M); Update(RS, M + 1, R); A[Node] = max(A[LS], A[RS]); } void Query(int Node, int L, int R) { int M = (L + R) / 2; int LS = 2 * Node; int RS = 2 * Node + 1; if (Lazy[Node]) { A[Node] += Lazy[Node]; if (L < R) { Lazy[LS] += Lazy[Node]; Lazy[RS] += Lazy[Node]; } Lazy[Node] = 0; } if (L > Y || R < X) return; if (L >= X && R <= Y) { S = max(S, A[Node]); return; } Query(LS, L, M); Query(RS, M + 1, R); } int main() { cin.sync_with_stdio(false); int n, m; cin >> n >> m; for (int i = 1; i <= n; i++) cin >> (s[i] + 1); int ans = 0; for (int i = 1; i <= n; i++) { int l = 1; memset(A, 0, sizeof(A)); for (int j = 1; j <= m; j++) { if (s[i][j] == '1') { c[j]++; X = l; Y = j - 1; Val = 1; if (X <= Y) Update(1, 1, m); if (c[j] > 1) { S = 0; X = l; Y = j; Query(1, 1, m); if (S) ans = max(ans, S + c[j]); S = 0; X = j; Y = j; Query(1, 1, m); X = j; Y = j; Val = -S; Update(1, 1, m); X = j; Y = j; Val = c[j]; Update(1, 1, m); } } else { c[j] = 0; l = j + 1; } } } cout << max(0, ans - 1) << '\n'; return 0; }