#include <bits/stdc++.h>
#define _ ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);
#define int long long
#define pb push_back
#define sz(i) (int)(i.size())
#define F first
#define S second
#define L long double
#define P pair<int, int>
const int inf = 0x3f3f3f3f3f3f3f3LL;
const int mod = (int)1e9 + 7;
using namespace std;
#if LOCAL
#include "../../tr.h"
#else
#define tr(...)
#define endl '\n'
#endif
template<class T> void smin(T& a, T val) {if (a > val) a = val;}template<class T> void smax(T& a, T val) {if (a < val) a = val;}
const int N = 2000 + 10;

int n, m;
char c[N][N];
int row[N][N], col[N][N];

int32_t main(){_

   cin>>n>>m;

   for (int i = 1; i <= n; ++i)
   {
      for (int j = 1; j <= m; ++j)
      {
         cin>>c[i][j];
      }
   }
      
   for (int i = 1; i <= n; ++i)
   {
      for (int j = 1; j <= m;)
      {
         if(c[i][j] == '#'){
            ++j;
            continue;
         }
         int k = j;
         while(k <= m and c[i][k] == c[i][j])++k;
         int t = j;
         int vals = k-j;
         while(t < k){
            assert(c[i][t] == '.');
            row[i][t] = vals;
            ++t;
         }
         j = k;
      }
   }

   for (int j = 1; j <= m; ++j)
   {
      for (int i = 1; i <= n;)
      {
         if(c[i][j] == '#'){
            ++i;
            continue;
         }
         int k = i;
         while(k <= n and c[k][j] == c[i][j])++k;
         int t = i;
         int vals = k-i;
         while(t < k){
            col[t][j] = vals;
            ++t;
         }
         i = k;
      }
   }   

   int ans = 0;
   for (int i = 1; i <= n; ++i)
   {
      for (int j = 1; j <= m; ++j)
      {
         // cout<<col[i][j]<<' ';
         if(c[i][j] == '#')continue;
         smax(ans, row[i][j] + col[i][j] - 1);
      }
      // cout<<endl;
   }

   cout<<ans;

   // int col = 1;
   // for (int i = 1; i <= n; ++i)
   // {
   //    for (int j = 1; j <= m; ++j)
   //    {
   //       if(c[i][j] == '#')continue;
   //       if(vis[i][j])continue;
   //       dfs(i, j, col);
   //       col++;
   //    }
   // }

   // for (int i = 1; i <= n; ++i)
   // {
   //    for (int j = 1; j <= m; ++j)
   //    {
   //       cout<<color[i][j]<<' ';
   //       if(c[i][j] == '#')continue;
   //       M[color[i][j]]++;
   //    }
   //    cout<<endl;
   // }

   // int ans = 0;
   // for(auto it: M){
   //    smax(ans, it.S);
   // }

   // cout<<ans;


   return 0;
}

// Common sense: do smth instead of nothing
// Even a single second counts...
// If other's can do it, even I can do it. It wouldn't be that tough. Let me give it a try.
// Mistakes made in past
// -Ques. ask for max-min => think binary_search, DP, greedy
// -not reading question properly / skipping to read & understand all samples properly & wasting time in wrong direction.
// -Using wrong indexing in nested loops something like a[i], when it is supposed to be a[j](WA)
// -value of const int N is not correct (WA/RTE).
// -Did you memset dp to -1 ?
// -check for small edges cases and work on small test cases manually if WA
// -not deallocating memory to pointers can lead to MLE. Use delete :))
// -not reading problem statements of harder problems E,..., thinking it couldn't be solved, but it isn't the case.
// -Avoid using #define int long long as much as possible when it's dp problem and requires high memory say, O(N^2, N=5000) (MLE)
// -Check Bitwise Operator Precedence 
// -Use pragmas to optimize (by constant factor) when necessary..
// -Think before coding & starting to debug. Have patience to look inside code and actually see how it works

Measured memory_bytes: 67328