Problem:
Largest Rectangle

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

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.

Constraints

1 ≤ H, W ≤ 1,400

Sample Input

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

Sample Output

6

Solution in C# (judge verdict: Accepted)

using System;
using System.Text;
using System.Collections.Generic;
using System.Linq;
class Solve{
    public Solve(){}
    StringBuilder sb;
    public static int Main(){
        new Solve().Run();
        return 0;
    }
    void Run(){
        sb = new StringBuilder();
        Calc();
        Console.Write(sb.ToString());
    }
    void Calc(){
        string[] str = Console.ReadLine().Split(' ');
        int H = int.Parse(str[0]);
        int W = int.Parse(str[1]);
        bool[,] b = new bool[H,W];
        for(int i=0;i<H;i++){
            str = Console.ReadLine().Split(' ');
            for(int j=0;j<W;j++){
                b[i,j] = str[j] == "1";
            }
        }
        int[,] U = new int[H,W];
        for(int i=0;i<H;i++){
            for(int j=0;j<W;j++){
                if(b[i,j]){
                    U[i,j] = 0;
                }
                else{
                    U[i,j] = i == 0 ? 1 : U[i-1,j] + 1;
                }
            }
        }
        int max = 0;
        for(int i=0;i<H;i++){
            int[] stack = new int[W+1];
            int[] point = new int[W+1];
            int p = 1;
            for(int j=0;j<W;j++){
                int h = U[i,j];
                while(p > 1 && stack[p-1] >= h){
                    max = Math.Max(max,(j-point[p-2])*(stack[p-1]));
                    p--;
                }
                stack[p] = h;
                point[p] = j+1;
                p++;
            }
            {
                for(int j=1;j<p;j++){
                    max = Math.Max(max,(point[p-1]-point[j-1])*(stack[j]));
                }
            }
        }
        sb.Append(max+"\n");
    }
}