#include <iostream>
#include <string>
#include <algorithm>
#include <vector>
#include <unordered_map>
#include <unordered_set>
#include <functional>
#include <queue>

using namespace std;

typedef unsigned long long ull;
typedef long long ll;
typedef unsigned int uint;
typedef unsigned char uchar;
#define umap unordered_map
const static ull INVALID_DIGIT = ~(ull)0;

enum class MAP_OBJ : int
{
    WAY = 0,
    OBST = 1,
};
MAP_OBJ MAP[2001][2001];

int possibleCountLeftToHere[2001][2001]{ 0 };
int possibleCountRightToHere[2001][2001]{ 0 };
int possibleCountUpToHere[2001][2001]{ 0 };
int possibleCountBottomToHere[2001][2001]{ 0 };

int main()
{
    int H, W;
    cin >> H >> W;

    for (int y = 0; y < H; y++) {
        string s;
        cin >> s;
        for (int x = 0; x < W; x++) {
            if (s[x] == '.') {
                MAP[x][y] = MAP_OBJ::WAY;
            }
            else {
                MAP[x][y] = MAP_OBJ::OBST;
            }
        }
    }

    // Calc possible max laser distance for x-direction

    vector<int> mostLeftIndices(H, 0);
    vector<int> mostRightIndices(H, W-1);
    for (int x = 0; x < W; x++) {
        int leftX = x;
        int rightX = W - x - 1;
        for (int y = 0; y < H; y++) {
            bool isObj = MAP[leftX][y] == MAP_OBJ::OBST;
            if (isObj)
            {
                possibleCountLeftToHere[leftX][y] = 0;
                mostLeftIndices[y] = leftX + 1;
            }
            else
            {
                possibleCountLeftToHere[leftX][y] = leftX - mostLeftIndices[y] + 1;
            }
            isObj = MAP[rightX][y] == MAP_OBJ::OBST;
            if (isObj)
            {
                possibleCountRightToHere[rightX][y] = 0;
                mostRightIndices[y] = rightX - 1;
            }
            else
            {
                possibleCountRightToHere[rightX][y] = mostRightIndices[y] - rightX + 1;
            }
        }
    }

    // Calc possible max laser distance for y-direction
    vector<int> mostTopIndices(W, 0);
    vector<int> mostBottomIndices(W, H - 1);
    for (int y = 0; y < H; y++) {
        int topY = y;
        int bottomY = H - y - 1;
        for (int x = 0; x < W; x++) {
            bool isObj = MAP[x][topY] == MAP_OBJ::OBST;
            if (isObj)
            {
                possibleCountUpToHere[x][topY] = 0;
                mostTopIndices[x] = topY + 1;
            }
            else
            {
                possibleCountUpToHere[x][topY] = topY - mostTopIndices[x] + 1;
            }
            isObj = MAP[x][bottomY] == MAP_OBJ::OBST;
            if (isObj)
            {
                possibleCountBottomToHere[x][bottomY] = 0;
                mostBottomIndices[x] = bottomY - 1;
            }
            else
            {
                possibleCountBottomToHere[x][bottomY] = mostBottomIndices[x] - bottomY + 1;
            }
        }
    }

    int maxValue = 0;
    for (int x = 0; x < W; x++) {
        for (int y = 0; y < H; y++) {
            if (MAP[x][y] == MAP_OBJ::OBST) {
                continue;
            }

            int value = possibleCountLeftToHere[x][y] + possibleCountRightToHere[x][y] + possibleCountUpToHere[x][y] + possibleCountBottomToHere[x][y] - 3;
            maxValue = std::max(value, maxValue);
        }
    }

    cout << maxValue << endl;

    return 0;

}

Measured memory_bytes: 78464