#include <algorithm>
#include <bitset>
#include <cmath>
#include <functional>
#include <iomanip>
#include <iostream>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <utility>
#include <vector>

#define repd(i, a, b) for (ll i = (a); i < (b); i++)
#define rep(i, n) repd(i, 0, n)
typedef long long ll;

using namespace std;

template <typename T> void output(T, int);
int gcd(int a, int b);
void prime_map(map<ll, ll> &, ll);

class UnionFind {
  private:
    int num;
    int *par;
    int *sizes;

  public:
    UnionFind() {}
    UnionFind(int n) {
        num = n;
        par = new int[n];
        sizes = new int[n];
        for (int i = 0; i < n; i++) {
            par[i] = i;
            sizes[i] = 1;
        }
    }

    ~UnionFind() {
        delete[] par;
        delete[] sizes;
    }

    void init(int n) {
        num = n;
        par = new int[n];
        sizes = new int[n];
        for (int i = 0; i < n; i++) {
            par[i] = i;
            sizes[i] = 1;
        }
    }

    int root(int x) {
        if (par[x] == x) {
            return x;
        }
        return root(par[x]);
    }

    void unite(int x, int y) {
        if (x == y) {
            return;
        }
        if (x > y) {
            int temp = y;
            y = x;
            x = temp;
        }
        int rx = root(x);
        int ry = root(y);
        if (rx == ry)
            return;
        par[ry] = rx;
        int temp = sizes[rx] + sizes[ry];
        sizes[rx] = temp;
        sizes[ry] = temp;
    }

    bool same(int x, int y) {
        int rx = root(x);
        int ry = root(y);
        return rx == ry;
    }

    int get_size(int index) {
        if (0 <= index && index <= num) {
            return sizes[index];
        } else {
            return -1;
        }
    }
};

int main() {
    // source
    int h, w;
    cin >> h >> w;
    string s[h];
    rep(i, h) { cin >> s[i]; }

    UnionFind side[h];
    rep(i, h) { side[i].init(w); }

    rep(i, h) {
        int index = 0;
        rep(j, w) {
            if (s[i][j] == '.') {
                index = j + 1;
                while (index != w && s[i][index] == '.') {
                    side[i].unite(j, index);
                    index++;
                }
                j = index;
            }
        }
    }

    UnionFind up[w];
    rep(i, w) { up[i].init(h); }

    rep(i, w) {
        int index = 0;
        rep(j, h) {
            if (s[j][i] == '.') {
                index = j + 1;
                while (index != h && s[index][i] == '.') {
                    up[i].unite(j, index);
                    index++;
                }
                j = index;
            }
        }
    }

    ll ans = 0;
    rep(l0, h) {
        rep(l1, w) {
            if (s[l0][l1] == '.') {
                ll count = side[l0].get_size(side[l0].root(l1));
                count += up[l1].get_size(up[l1].root(l0));
                count--;
                ans = max(ans, count);
            }
        }
    }
    cout << ans << endl;
    return 0;
}

template <typename T> void output(T a, int precision) {
    if (precision > 0) {
        cout << setprecision(precision) << a << "\n";
    } else {
        cout << a << "\n";
    }
}

template <typename T> T min(T a, T b) {

    if (a < b) {
        return a;
    } else {
        return b;
    }
}

int gcd(int a, int b) {
    if (b == 0) {
        return a;
    }
    return gcd(b, a % b);
}

void prime_map(map<ll, ll> &m, ll num) {
    ll cache = num;
    repd(i, 2, sqrt(num) + 2) {
        if (num % i == 0) {
            if (m[i] == 0) {
                m[i] = 1;
            } else {
                m[i]++;
            }

            num /= i;
            break;
        }
    }

    if (cache == num) {
        if (m[num] == 0) {
            m[num] = 1;
        } else {
            m[num]++;
        }
        return;
    } else {
        prime_map(m, num);
    }
}


Measured memory_bytes: 69180