Given a matrix (H × W) which contains only 1 and 0, find the area of the largest rectangle which only contains 0s.

Constraints

* 1 ≤ H, W ≤ 1,400

Input


H W
c1,1 c1,2 ... c1,W
c2,1 c2,2 ... c2,W
:
cH,1 cH,2 ... cH,W


In the first line, two integers H and W separated by a space character are given. In the following H lines, ci,j, elements of the H × W matrix, are given.

Output

Print the area (the number of 0s) of the largest rectangle.

Example

Input

4 5
0 0 1 0 0
1 0 0 0 0
0 0 0 1 0
0 0 0 1 0


Output

6
#include<iostream>
#include<vector>
#include<algorithm>
#include<utility>
#include<string>
#include<cmath>
#include<cstring>
#include<queue>
#include<map>
#include<climits>
#include<set>
#include<tuple>
#include<stack>


using namespace std;
typedef pair<int, int> pii;
typedef long long int ll;
typedef pair<ll, ll> pll;
typedef tuple<int, int, int> tpl;
int dx[4] = { 1,0,0,-1 };
int dy[4] = { 0,1,-1,0 };

#define ARRAY_MAX 1500

const int INF = 1 << 30;
const int MOD = 1e9 + 7;

template<typename T>
T histArea(vector<T>& h) {

	T N = h.size();
	h.push_back(0);
	N++;

	T ans = 0;
	stack<pii> st;

	for (T i = 0; i < N; i++)
	{
		if (st.empty())
		{
			//スタックが空の場合は長方形を追加
			st.push(pii(h[i], i));
		}
		else if (st.top().first < h[i])
		{
			//今見ている長方形がスタックの頂点の長方形の高さより高い場合はスタックに追加
			st.push(pii(h[i], i));
		}
		else if (st.top().first > h[i])
		{
			//今見ている長方形がスタックの頂点の長方形の高さより低い場合はスタックから取り出す作業を行う
			int lastpos = 0;

			while (!st.empty() && st.top().first >= h[i]) {
				//スタックが空でなく、スタックの頂点にある長方形の高さが今見ている長方形の高さ以上
				//の場合はスタックから長方形を取り出してその都度面積を計算して最大値を更新する
				lastpos = st.top().second;
				ans = max(ans, st.top().first * (i - lastpos));
				st.pop();
			}
			//取り出す作業が終わったら今見ている長方形をスタックに追加する
			//追加位置は最後に取り出した長方形の位置
			st.push(pii(h[i], lastpos));
		}
	}
	return ans;
}

template<typename T>
T maxRectangle(vector< vector<T> >& board) {
	T H = board.size(), W = board[0].size();
	vector< vector<T> > dp(H, vector<T>(W, 0));

	T ret = 0;
	for (int i = 0; i < H; i++)
	{
		for (int j = 0; j < W; j++)
		{
			if (board[i][j] == 1) continue;
			if (i > 0)
			{
				dp[i][j] = dp[i - 1][j] + 1;//縦の長さを保持
			}
			else
			{
				dp[i][j] = 1;
			}
		}
	}

	for (int i = 0; i < H; i++)
	{
		ret = max(ret, histArea(dp[i]));
	}
	return ret;
}


int main() {

	int h, w;
	cin >> h >> w;
	vector<vector<int> > mp(h, vector<int>(w, 0));
	for (int i = 0; i < h; i++)
	{
		for (int j = 0; j < w; j++)
		{
			cin >> mp[i][j];
		}
	}

	cout << maxRectangle(mp) << endl;
}
