use std::io::{self, Read};
fn main() {
let mut stdin = io::stdin();
let mut buf: String = String::new();
stdin.read_to_string(&mut buf).unwrap();
let trees: Vec<Vec<i8>> = buf.split("\n").map(|f| f.chars().map(|c| c.to_digit(10).unwrap() as i8).collect::<Vec<i8>>()).collect();
// let mut visible: Vec<Vec<bool>> = vec![vec![false; trees.len()]; trees.len()];
// // from top
// for i in 0..trees.len() {
// let mut most: i8 = -1;
// for j in 0..trees[i].len() {
// if most < trees[i][j] {
// visible[i][j] = true;
// most = trees[i][j];
// }
// }
// }
// // from left
// for j in 0..trees[0].len() {
// let mut most: i8 = -1;
// for i in 0..trees.len() {
// if most < trees[i][j] {
// visible[i][j] = true;
// most = trees[i][j];
// }
// }
// }
// // from bottom
// for i in 0..trees.len() {
// let mut most: i8 = -1;
// for j in (0..trees[i].len()).rev() {
// if most < trees[i][j] {
// visible[i][j] = true;
// most = trees[i][j];
// }
// }
// }
// // from right
// for j in 0..trees[0].len() {
// let mut most: i8 = -1;
// for i in (0..trees.len()).rev() {
// if most < trees[i][j] {
// visible[i][j] = true;
// most = trees[i][j];
// }
// }
// }
// let visible_rows = visible.iter().map(|v| v.iter().fold(0, |a, b| if *b {a+1} else {a}));
// let visible_total = visible_rows.reduce(|a, b| a+b);
// println!("{}", visible_total.unwrap());
let mut best_score = 0;
for i in 0..trees.len() {
for j in 0..trees[i].len() {
let mut right: usize = 0;
let lowest = trees[i][j];
loop {
if j+right == trees[i].len() - 1 { break; }
right += 1;
if lowest <= trees[i][j+right] { break; }
}
let mut left: usize = 0;
loop {
if j-left == 0 { break; }
left += 1;
if lowest <= trees[i][j-left] { break; }
}
let mut down: usize = 0;
loop {
if i+down == trees.len() - 1 { break; }
down += 1;
if lowest <= trees[i+down][j] { break; }
}
let mut up: usize = 0;
loop {
if i-up == 0 { break; }
up += 1;
if lowest <= trees[i-up][j] { break; }
}
let result = right * left * down * up;
if result > best_score { best_score = result; }
}
}
println!("{}", best_score);
}