#include<iostream>
#include<math.h>
#include<vector>
#include<string>
#include<stack>
#include<queue>
#include<map>
#include<algorithm>
#include<bitset>
#include <climits>
using namespace std;
#define _GLIBCXX_DEBUG
#define pq priority_queue
#define mp make_pair
#define pb push_back
#define ff first
#define ss second
#define pii pair<long long,long long>
#define ppii pair<long long,pair<long long,long long>>
#define all(x) (x).begin(),(x).end()
#define rep(x) for(int i = 0;i < (x);i++)
#define repj(x) for(int j = 0;j < (x);j++)
#define REP(i,x) for(int (i) = 0;(i) < (x);(i)++)
#define rrep(x) for(int i = (x);i >= 0;i--)
#define mins(x,y) x = min(x,y)
#define maxs(x,y) x = max(x,y)
#define mod 1000000007
#define dump(x)  cerr << #x << " = " << (x) << endl;
#define debug(x) cerr << #x << " = " << (x) << " (L" << __LINE__ << ")" << " " << __FILE__ << endl;
#define pyes cout << "Yes" << endl
#define pno cout << "No" << endl
typedef vector<vector<long long>> vii;
typedef long long lint;
typedef long long ll;
lint qp(int a, ll b) { int ans = 1; do { if (b & 1)ans = 1ll * ans*a; a = 1ll * a*a; } while (b >>= 1); return ans; }
lint qp(int a, ll b, int mo) { int ans = 1; do { if (b & 1)ans = 1ll * ans*a%mo; a = 1ll * a*a%mo; } while (b >>= 1); return ans; }
lint gcd(int a, int b) { return b ? gcd(b, a%b) : a; }
int dx[4] = { 1,0,-1,0 };
int dy[4] = { 0,1,0,-1 };
long long INF = 1e14;
const int MAX_N = 1 << 17;
const int cf = 100010;
///////////////////////////////////////////////////////////////////////////////
//最頻値とランレングス圧縮
template<class T>
vector<pair<T, int>> runlength(vector<T> arr) {
	int i = 0;
	int n = arr.size();
	vector<pair<T, int>> run;
	while (i < arr.size()) {
		T t = arr[i];
		int k = 0;
		while (i + k < n && arr[i + k] == t) k++;
		run.push_back(pair<T, int>(t, k));
		i += k;
	}
	return run;
}

template<class T>
int freq(vector<T> arr) {
	//最頻値の個数を知りたければ,int freq & return first
	//最頻値そのものを知りたければ T freq & return second
	vector<T> vec = arr;
	int n = arr.size();
	sort(all(vec));
	int i = 0;
	vector<pair<int, T>> run;
	while (i < arr.size()) {
		T t = arr[i];
		int k = 0;
		while (i + k < n && arr[i + k] == t) k++;
		run.push_back(pair<int, T>(k, t));
		i += k;
	}
	sort(all(run));
	reverse(all(run));
	return run[0].first;
}

char grid[2010][2010];
int ramp[2010][2010];
int main(void) {
	int h, w; cin >> h >> w;
	//縦横にランレングス圧縮をする
	vector<vector<pair<char, int>>> yoko(h);
	vector<vector<pair<char, int>>> tate(w);

	for (int tate = 0; tate < h; tate++)
	{
		for (int yoko = 0; yoko < w; yoko++)
		{
			cin >> grid[tate][yoko];
		}
	}

	for (int height = 0; height < h; height++)
	{
		vector<char> yokoretu(w);
		rep(w) yokoretu[i] = grid[height][i];
		yoko[height] = runlength(yokoretu);
		int k = 0,idx = 0; 
		for (int j = 0; j < yoko[height].size(); j++)
		{
			rep(yoko[height][j].second) {
				if (grid[height][k] == '#') {
					ramp[height][k++] = -1000000;
					continue;
				}
				ramp[height][k++] += yoko[height][j].second;
			}
		}
	}
	for (int width = 0; width < w; width++)
	{
		vector<char> tateretu(h);
		rep(h) tateretu[i] = grid[i][width];
		tate[width] = runlength(tateretu);
		int k = 0, idx = 0;
		for (int j = 0; j < tate[width].size(); j++)
		{	
			
			rep(tate[width][j].second) { 
				if (grid[k][width] == '#') {
					ramp[k++][width] = -1000000;
					continue;
				}
				ramp[k++][width] += tate[width][j].second; 
			}
		}
	}

	int ans = -1;
	for (int i = 0; i < h; i++)
	{
		for (int j = 0; j < w; j++)
		{
			//printf("%d ", ramp[i][j]);
			maxs(ans, ramp[i][j]);
		}
		//cout << endl;
	}
	cout << ans - 1 << endl;
	return 0;
}

Measured memory_bytes: 52096