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 OCaml (judge verdict: Accepted)

let split_on_char sep s =
  let open String in
  let r = ref [] in
  let j = ref (length s) in
  for i = length s - 1 downto 0 do
    if get s i = sep then begin
      r := sub s (i + 1) (!j - i - 1) :: !r;
      j := i
    end
  done;
  sub s 0 !j :: !r

let read_ns () = read_line () |> split_on_char ' ' |> List.map int_of_string

let solve ans w v =
  let rec g ans j xs =
    if j = w then (ans, xs)
    else
      match xs with
      | [] -> g ans (j + 1) [(v.(j), j)]
      | (ch, _) :: _ ->
        if ch = v.(j) then g ans (j + 1) xs
        else if ch < v.(j) then g ans (j + 1) ((v.(j), j) :: xs)
        else
          let rec f ans k = function
            | [] -> g ans (j + 1) [(v.(j), k)]
            | (ch, cj) :: tl as ys ->
              if ch >= v.(j) then f (if ch * (j - cj) > ans then ch * (j - cj) else ans) cj tl
              else g ans (j + 1) ((v.(j), k) :: ys) in
          f ans j xs in
  let (ans, xs) = g ans 0 [] in
  List.fold_left (fun acc (ch, cj) -> if ch * (w - cj) > acc then ch * (w - cj) else acc) ans xs

let () =
  match read_ns () with
  | [h; w] ->
    let s = Array.make w 0 in
    let t = Array.make w 0 in
    let rec doit i ans =
      if i = h then ans
      else begin
        read_ns () |> List.iteri (fun j e -> t.(j) <- if e = 1 then 0 else s.(j) + 1);
        Array.iteri (fun i e -> s.(i) <- e) t;
        solve ans w t |> doit (i + 1)
      end in
    doit 0 0 |> Printf.printf "%d\n"
  | _ -> assert false