extern crate core;

use std::fmt;
use std::cmp::{max, min, Ordering};
use std::collections::{BinaryHeap, BTreeMap};
use std::fmt::{Display, Formatter, Error};
macro_rules! read_line{
    () => {{
        let mut line = String::new();
        std::io::stdin().read_line(&mut line).ok();
        line
    }};
    (delimiter: ' ') => {
        read_line!().split_whitespace().map(|x|x.to_string()).collect::<Vec<_>>()
    };
    (delimiter: $p:expr) => {
        read_line!().split($p).map(|x|x.to_string()).collect::<Vec<_>>()
    };
    (' ') => {
        read_line!(delimiter: ' ')
    };
    ($delimiter:expr) => {
        read_line!(delimiter: $delimiter)
    };
    (' '; $ty:ty) => {
        read_line!().split_whitespace().map(|x|x.parse::<$ty>().ok().unwrap()).collect::<Vec<$ty>>()
    };
    ($delimiter:expr; $ty:ty) => {
        read_line!($delimiter).into_iter().map(|x|x.parse::<$ty>().ok().unwrap()).collect::<Vec<$ty>>()
    };
}
macro_rules! let_all {
    ($($n:ident:$t:ty),*) => {
        let line = read_line!(delimiter: ' ');
        let mut iter = line.iter();
        $(let $n:$t = iter.next().unwrap().parse().ok().unwrap();)*
    };
}
#[derive(Copy, Clone)]
struct Coordinate {
    x: i32, y: i32
}
impl Coordinate {
    fn new(x: i32, y: i32) -> Coordinate {
        Coordinate{x: x, y: y}
    }
}
#[derive(Copy, Clone)]
enum Corner {
    Out{coordinate: Coordinate}, In{coordinate: Coordinate},
}
impl Corner {
    fn in_corner(x: usize, y: usize) -> Corner {
        Corner::In{coordinate: Coordinate::new(x as i32, y as i32)}
    }
    fn out_corner(x: usize, y: usize) -> Corner {
        Corner::Out {coordinate: Coordinate::new(x as i32, y as i32)}
    }
}
impl Ord for Corner {
    fn cmp(&self, other: &Self) -> Ordering {
        match (self, other) {
            (&Corner::In {coordinate: i}, &Corner::Out{coordinate: o}) => {
                match (i.x * o.y).cmp(&(o.x * i.y)) {
                    Ordering::Equal => Ordering::Greater,
                    o => o,
                }
            }
            (&Corner::Out {coordinate: i}, &Corner::In {coordinate: o}) => {
                match (i.x * o.y).cmp(&(o.x * i.y)) {
                    Ordering::Equal => Ordering::Less,
                    o => o,
                }
            }
            (&Corner::Out {coordinate: i}, &Corner::Out {coordinate: o}) => {
                (i.x * o.y).cmp(&(o.x * i.y))
            }
            (&Corner::In{coordinate: i}, &Corner::In {coordinate: o}) => {
                (i.x * o.y).cmp(&(o.x * i.y))
            }
        }
    }
}
impl PartialOrd for Corner {
    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
        Some(self.cmp(other))
    }
}
impl PartialEq for Corner {
    fn eq(&self, other: &Self) -> bool {
        self.cmp(other).eq(&Ordering::Equal)
    }
}
impl Eq for Corner {}
impl Display for Corner {
    fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
        match self {
            &Corner::In {coordinate: c} => write!(f, "In(x: {}, y: {})", c.x, c.y),
            &Corner::Out {coordinate: c} => write!(f, "Out(x: {}, y: {})", c.x, c.y),
        }
    }
}
fn main(){
    let_all!(h: usize, w: usize);
    let mut state = Vec::<Vec<char>>::with_capacity(h);
    for _ in 0 .. h{
        state.push(read_line!().chars().collect());
    }
    state.reverse();
    let state = state;
    let mut corners = Vec::new();
    for x in 0 .. w {
        for y in 0 .. h {
            match state[y][x] {
                '#' => {
                    if (x < 1 || state[y][x - 1] == '.') && (y + 1 >= h || state[y + 1][x] == '.') {
                        corners.push(Corner::in_corner(x, y + 1))
                    }
                    if (x + 1 >= w || state[y][x + 1] == '.') && (y < 1 || state[y - 1][x] == '.') {
                        corners.push(Corner::out_corner(x + 1, y))
                    }
                }
                '.' => {
                    if (x >= 1 && state[y][x - 1] == '#') && (y + 1 < h && state[y + 1][x] == '#') {
                        corners.push(Corner::in_corner(x, y + 1))
                    }
                    if (x + 1 < w && state[y][x + 1] == '#') && (y >= 1 && state[y - 1][x] == '#') {
                        corners.push(Corner::out_corner(x + 1, y))
                    }
                }
                _ => unreachable!()
            }
        }
    }
    corners.sort();
    let corners = corners;
    let mut max = 1;
    let mut count = 1;
    for &c in &corners {
        //println!("{}", c);
        match c {
            Corner::In {coordinate: _} => count += 1,
            Corner::Out {coordinate: _} => count -= 1,
        }
        if max < count {
            max = count;
        }
    }
    println!("{}", max);

}




Measured memory_bytes: 9016