#ifdef _WIN32
#define DEBUG	1
#endif

#define _CRT_SECURE_NO_WARNINGS
#define MATH_PI 3.14159265358979323846264338327950288419716939
#include <iostream>
#include <string.h>
#include <fstream>
#include <math.h>
using namespace std;

#ifdef DEBUG
#include "include.h"
#else
inline signed wait(){return 0;}
inline void dout(const char *arg, ...){}
#endif

template<typename T>inline void SWAP(T &a, T &b){T t = a; a = b; b = t;}
inline void CSWAP(char *&a, char *&b){char *t = a; a = b; b = t;}

#define CLIP(ptr, min, max) {if((min)<=(max)){if(ptr<(min)){ptr=(min);}if(ptr>(max)){ptr=(max);}}}
//#define max(a, b) a > b ? a : b;
//#define min(a, b) a > b ? b : a;
#define Sin(deg) sin((deg)*MATH_PI/180)
#define Cos(deg) cos((deg)*MATH_PI/180)
#define Tan(deg) tan((deg)*MATH_PI/180)
#define Rad(deg) ((deg)*MATH_PI/180)
#define ff(param, num) for(int param=0 ; param<num ; ++param)
#define fi(num) for(int i=0 ; i<num ; ++i)
#define fj(num) for(int j=0 ; j<num ; ++j)
#define fk(num) for(int k=0 ; k<num ; ++k)
#define fl(num) for(int l=0 ; l<num ; ++l)
#define fn(num) for(int n=0 ; n<num ; ++n)
#define ffr(param, num) for(int param=num-1 ; param>=0 ; --param)
#define fir(num) for(int i=num-1 ; i>=0 ; --i)
#define fjr(num) for(int j=num-1 ; j>=0 ; --j)
#define fkr(num) for(int k=num-1 ; k>=0 ; --k)
#define flr(num) for(int l=num-1 ; l>=0 ; --l)
#define fnr(num) for(int n=num-1 ; n>=0 ; --n)
#define gi(p) Scanf("%d", p)
#define gi2(p1, p2) Scanf2("%d %d", p1, p2)
#define gi3(p1, p2, p3) Scanf3("%d %d %d", p1, p2, p3)
#define gi4(p1, p2, p3, p4) Scanf4("%d %d %d %d", p1, p2, p3, p4)
#define gll(p) Scanf("%lld", p)
#define gll2(p1, p2) Scanf2("%lld %lld", p1, p2)
#define gll3(p1, p2, p3) Scanf3("%lld %lld %lld", p1, p2, p3)
#define gll4(p1, p2, p3, p4) Scanf4("%lld %lld %lld %lld", p1, p2, p3, p4)
#define gf(p) Scanf("%f", p)
#define gf2(p1, p2) Scanf2("%f %f", p1, p2)
#define gf3(p1, p2, p3) Scanf3("%f %f %f", p1, p2, p3)
#define gf4(p1, p2, p3, p4) Scanf4("%f %f %f %f", p1, p2, p3, p4)
#ifdef DEBUG
#define gc(buf) fscanf(local_in.fp, "%s", buf)
#define Scanf(expr, p) fscanf(local_in.fp, expr, &p)
#define Scanf2(expr, p1, p2) fscanf(local_in.fp, expr, &p1, &p2)
#define Scanf3(expr, p1, p2, p3) fscanf(local_in.fp, expr, &p1, &p2, &p3)
#define Scanf4(expr, p1, p2, p3, p4) fscanf(local_in.fp, expr, &p1, &p2, &p3, &p4)
#else
#define gc(buf) Scanf("%s", buf)
#define Scanf(expr, p) scanf(expr, &p)
#define Scanf2(expr, p1, p2) scanf(expr, &p1, &p2)
#define Scanf3(expr, p1, p2, p3) scanf(expr, &p1, &p2, &p3)
#define Scanf4(expr, p1, p2, p3, p4) scanf(expr, &p1, &p2, &p3, &p4)
#endif
#define ans(p) cout << p << endl;
void CombSort(int N, int *ar, int order_ascending = 1) { int h = int(N / 1.3); int flag; int i; while (true) { flag = 0; for (i = 0; i + h < N; ++i) { if ((order_ascending&&ar[i] > ar[i + h]) || (!order_ascending&&ar[i] < ar[i + h])) { swap<int>(ar[i], ar[i + h]); flag = 1; } }if (h == 1 && !flag)break; if (h == 9 || h == 10) h = 11; if (h > 1)h = int(h / 1.3); } }
//int EuclideanAlgorithm(int N, int *ar) { fn(N - 1) { while (true) { if (ar[n] % ar[n + 1] == 0 || ar[n + 1] % ar[n] == 0) { ar[n + 1] = min(ar[n], ar[n + 1]); break; }if (ar[n] > ar[n + 1]) { ar[n] %= ar[n + 1]; } else { ar[n + 1] %= ar[n]; } } }return ar[N - 1]; }
template<typename T>void CombSort(int N, T *ar, int order_ascending = 1) {
	int i, flag;
	int h = int(N / 1.3);
	while (true) {
		flag = 0;
		for (i = 0; i + h < N; ++i) {
			if (
				order_ascending && ar[i].SortValue > ar[i + h].SortValue ||
				!order_ascending && ar[i].SortValue < ar[i + h].SortValue
				) {
				swap<T>(ar[i], ar[i + h]);
				flag = 1;
			}
		}
		if (h > 1) {
			h = int(h / 1.3);
			if (h == 9 || h == 10) h = 11;
		}
		else {
			if (!flag) break;
		}
	}
}
#include <vector>
#include <algorithm>

int table[40] = {0};
long long int dat[100010] = {0};

using namespace std;
struct UnionFind {
	vector<int> par; // par[i]:iの親の番号　(例) par[3] = 2 : 3の親が2

	UnionFind(int N) : par(N) { //最初は全てが根であるとして初期化
		for (int i = 0; i < N; i++) par[i] = i;
	}

	int root(int x) { // データxが属する木の根を再帰で得る：root(x) = {xの木の根}
		if (par[x] == x) return x;
		return par[x] = root(par[x]);
	}

	void unite(int x, int y) { // xとyの木を併合
		int rx = root(x); //xの根をrx
		int ry = root(y); //yの根をry
		if (rx == ry) return; //xとyの根が同じ(=同じ木にある)時はそのまま
		par[rx] = ry; //xとyの根が同じでない(=同じ木にない)時：xの根rxをyの根ryにつける
	}

	bool same(int x, int y) { // 2つのデータx, yが属する木が同じならtrueを返す
		int rx = root(x);
		int ry = root(y);
		return rx == ry;
	}
};

int lst[2001], nlst;
char d[2001][2001];
int c1[2001][2001];
int c2[2001][2001];
signed main() {

	int w, h;
	gi2(h, w);

	fi(h){
		gc(d[i]);
	}

	int mm;

	int cnt;
	fn(h){
		nlst = 0;
		cnt = 0;
		fi(w){
			if(d[n][i] == '#'){
				lst[nlst] = cnt;
				cnt = 0;
				++nlst;
			}
			else if (i == w - 1) {
				cnt++;
				lst[nlst] = cnt;
			}else{
				cnt++;
			}
		}

		nlst = 0;
		fi(w) {
			if (d[n][i] == '#') {
				++nlst;
			}
			else {
				c1[n][i] = lst[nlst];
			}
		}
	}

	
	fn(w) {
		nlst = 0;
		cnt = 0;
		fi(h) {
			if (d[i][n] == '#') {
				lst[nlst] = cnt;
				cnt = 0;
				++nlst;
			}
			else if(i == h - 1){
				cnt++;
				lst[nlst] = cnt;
			}
			else {
				cnt++;
			}
		}

		nlst = 0;
		fi(h) {
			if (d[i][n] == '#') {
				++nlst;
			}
			else {
				c2[i][n] = lst[nlst];
			}
		}
	}

	int a = 0;
	fn(h){
		fi(w){
			cnt = c1[n][i] + c2[n][i];
			a = max(a, cnt - 1);
		}
	}

	ans(a);

	return wait();
}

Measured memory_bytes: 35456