#![allow(unused_imports)]
use std::cmp::{self, Ord, Ordering};
use std::collections::{BTreeMap, BTreeSet, BinaryHeap, HashMap, HashSet, VecDeque};

fn main() {
    let stdin = std::io::stdin();
    let mut sc = nyan::Scanner::new(stdin.lock());

    let h: usize = sc.read();
    let w: usize = sc.read();
    let b: Vec<Vec<char>> = sc.read_lines(h);

    // // h 行目の障害物の数
    // let mut ho = Vec::with_capacity(h);
    // // w 列目の障害物の数
    // let mut wo = vec![0 as usize; w];
    // for i in 0..h {
    //     let mut l: usize = 0;
    //     for j in 0..w {
    //         if b[i][j] == '#' {
    //             l = l + 1;
    //             wo[j] = wo[j] + 1;
    //         }
    //     }
    //     ho.push(l);
    // }
    // println!("ho = {:?}", ho);
    // println!("wo = {:?}", wo);

    let mut t = Vec::with_capacity(h);
    // 横方向の探索
    for i in 0..h {
        t.push(vec![0 as usize; w]);

        let mut j: usize = 0;
        while j < w {
            // 横方向の障害物がないマスを数える
            let mut jj: usize = j;
            while jj < w && b[i][jj] == '.' {
                jj = jj + 1;
            }

            for k in j..jj {
                t[i][k] = jj - j;
            }
            j = jj + 1;
        }
    }

    // 縦方向の探索
    for j in 0..w {
        let mut i: usize = 0;
        while i < h {
            // 横方向の障害物がないマスを数える
            let mut ii: usize = i;
            while ii < h && b[ii][j] == '.' {
                ii = ii + 1;
            }

            for k in i..ii {
                t[k][j] = t[k][j] + (ii - i);
            }
            i = ii + 1;
        }
    }

    // println!("{:?}", t);

    let mut max: usize = 0;
    for i in 0..h {
        for j in 0..w {
            max = cmp::max(t[i][j], max);
        }
    }

    println!("{}", max - 1);
}

#[allow(dead_code)]
mod nyan {
    use std::fmt::Debug;
    use std::io::Read;
    use std::iter::FromIterator;
    use std::str::FromStr;

    pub struct Scanner<R: Read> {
        reader: R,
    }

    impl<R: Read> Scanner<R> {
        pub fn new(reader: R) -> Scanner<R> {
            Scanner { reader: reader }
        }

        fn chars<'a>(&'a mut self) -> Box<Iterator<Item = char> + 'a> {
            Box::new(self.reader.by_ref().bytes().map(|b| b.unwrap() as char))
        }

        // since Rust 1.26
        // fn chars<'a>(&'a mut self) -> impl Iterator<Item = char> + 'a {
        //     self.reader.by_ref().bytes().map(|b| b.unwrap() as char)
        // }

        pub fn next<T: FromIterator<char>>(&mut self) -> T {
            self.chars()
                .skip_while(|c| c.is_whitespace())
                .take_while(|c| !c.is_whitespace())
                .collect()
        }

        pub fn next_line<T: FromIterator<char>>(&mut self) -> T {
            self.chars()
                .skip_while(|c| c.is_whitespace())
                .take_while(|c| !c.is_whitespace() || c == &' ')
                .collect()
        }

        pub fn read<T>(&mut self) -> T
        where
            T: FromStr,
            <T as FromStr>::Err: Debug,
        {
            self.next::<String>().parse().unwrap()
        }

        pub fn read_vec<T, U>(&mut self, n: usize) -> T
        where
            T: FromIterator<U>,
            U: FromStr,
            <U as FromStr>::Err: Debug,
        {
            (0..n).map(|_| self.read()).collect()
        }

        pub fn read_vec2d<T, U, V>(&mut self, m: usize, n: usize) -> T
        where
            T: FromIterator<U>,
            U: FromIterator<V>,
            V: FromStr,
            <V as FromStr>::Err: Debug,
        {
            (0..m).map(|_| self.read_vec(n)).collect()
        }

        pub fn read_line<T: FromIterator<char>>(&mut self) -> T {
            self.next_line()
        }

        pub fn read_lines<T, U>(&mut self, n: usize) -> T
        where
            T: FromIterator<U>,
            U: FromIterator<char>,
        {
            (0..n).map(|_| self.read_line()).collect()
        }
    }
}


Measured memory_bytes: 61692