#include<iostream>
#include<algorithm>
#include<string>
#include<vector>
#include<cmath>
#include<map>
#include<iomanip>
#include<queue>
#include<stack>
#include<time.h>
#define rep(i,n)for(int i=0;i<n;i++)
#define int long long
#define ggr getchar();getchar();return 0;
#define prique priority_queue
#define mod 1000000007
#define inf 1e15
#define key 1e9
using namespace std;
typedef pair<int, int>P;
void yes() { cout << "Yay!" << endl; }
void no() { cout << ":(" << endl; }
template<class T> inline void chmax(T& a, T b) {
	a = std::max(a, b);
}
template<class T> inline void chmin(T& a, T b) {
	a = std::min(a, b);
}
const int MAX = 330000;
int fac[MAX], finv[MAX], inv[MAX];
// テーブルを作る前処理
void COMinit() {
	fac[0] = fac[1] = 1;
	finv[0] = finv[1] = 1;
	inv[1] = 1;
	for (int i = 2; i < MAX; i++) {
		fac[i] = fac[i - 1] * i % mod;
		inv[i] = mod - inv[mod % i] * (mod / i) % mod;
		finv[i] = finv[i - 1] * inv[i] % mod;
	}
}

// 二項係数計算
long long COMB(int n, int k) {
	if (n < k) return 0;
	if (n < 0 || k < 0) return 0;
	return fac[n] * (finv[k] * finv[n - k] % mod) % mod;
}
bool prime(int n) {
	int cnt = 0;
	for (int i = 1; i <= sqrt(n); i++) {
		if (n % i == 0)cnt++;
	}
	if (cnt != 1)return false;
	else return n != 1;
}
int gcd(int x, int y) {
	if (y == 0)return x;
	return gcd(y, x % y);
}
int lcm(int x, int y) {
	return x / gcd(x, y) * y;
}
int kai(int x, int y) {
	int res = 1;
	for (int i = x - y + 1; i <= x; i++) {
		res *= i; res %= mod;
	}
	return res;
}
int mod_pow(int x, int y, int m) {
	int res = 1;
	while (y) {
		if (y & 1) {
			res = res * x % m;
		}
		x = x * x % m;
		y >>= 1;
	}
	return res;
}
int comb(int x, int y) {
	if (y > x)return 0;
	return kai(x, y)* mod_pow(kai(y, y), mod - 2, mod) % mod;
}
void debug_out() { cerr << endl; }

template <typename Head, typename... Tail>
void debug_out(Head H, Tail... T) {
	cerr << " " << to_string(H);
	debug_out(T...);
}

#define debug(...) cerr << "[" << #__VA_ARGS__ << "]:", debug_out(__VA_ARGS__)
struct edge { int to, cost; };
int par[114514], rrank[114514];//親、木の深さ
void init(int n) {
	rep(i, n) {
		par[i] = i;
		rrank[i] = 0;
	}
}
int find(int x) {
	if (par[x] == x) {
		return x;
	}
	else return par[x] = find(par[x]);
}
void unite(int x, int y) {
	x = find(x);
	y = find(y);
	if (x == y)return;
	if (rrank[x] < rrank[y]) {
		par[x] = y;
	}
	else {
		par[y] = x;
		if (rrank[x] == rrank[y])rrank[x]++;
	}
}
bool same(int x, int y) {
	return find(x) == find(y);
}
int h, w;
char c[2222][2222];
int l[2222][2222];
int r[2222][2222];
int u[2222][2222];
int d[2222][2222];
signed main() {
	cin >> h >> w;
	rep(i, h) { rep(j, w)cin >> c[i][j]; }
	rep(i, h) {
		rep(j, w) {
			if (c[i][j] == '.')l[i + 1][j + 1] = l[i + 1][j] + 1;
			else l[i + 1][j + 1] = 0;
		}
	}
	rep(i, h) {
		for (int j = w - 1; j >= 0; j--) {
			if (c[i][j] == '.')r[i + 1][j + 1] = r[i + 1][j + 2] + 1;
			else r[i + 1][j + 1] = 0;
		}
	}
	rep(i, w) {
		rep(j, h) {
			if (c[j][i] == '.')u[j + 1][i + 1] = u[j][i + 1] + 1;
			else u[j + 1][i + 1] = 0;
		}
	}
	rep(i, w) {
		for (int j = h - 1; j >= 0; j--) {
			if (c[j][i] == '.')d[j + 1][i + 1] = d[j + 2][i + 1] + 1;
			else d[j + 1][i + 1] = 0;
		}
	}
	int ans = 0;
	rep(i, h+1) {
		rep(j, w+1) {
			chmax(ans, l[i][j] + r[i][j] + u[i][j] + d[i][j] + 1);
		}
	}
	//cout << l[2][2] << " " << r[2][2] << " " << u[2][2] << " " << d[2][2] << endl;
	cout << ans - 4 << endl;
	ggr
}


Measured memory_bytes: 151808