#include <iostream>
#include <vector>
#include <algorithm>
#include <cstdio>
#include <set>
//#include <tuple>
#include <map>
#include <cmath>
#include <numeric>
#include <sstream>
#include <complex>
#include <iostream>

#include <vector>
#include <algorithm>
#include <cstdio>
#include <set>
//#include <tuple>
#include <map>
#include <cmath>
#include <numeric>
#include <complex>
#include <cassert>

using namespace std;
typedef long long ll;
//typedef pair<int, int> P;
//typedef tuple<int, int, int> T;
typedef pair<ll, ll> Pl;
//typedef tuple<ll, ll, ll> Tl;


#define BR "\n"
#define ALL(c) (c).begin(),(c).end()
#define REP(i,n) for(int i=0;i<(int)(n);++i)
#define FOR(i,l,r) for(int i=(int)l;i<(int)(r);++i)
#define EACH(it,o) for(auto it = (o).begin(); it != (o).end(); ++it)
#define IN(l,v,r) ((l)<=(v) && (v)<(r))

//config
//#define NDEBUG

//debug
#ifdef NDEBUG
#define DUMP(x)
#define DUMPLN(x)
#define DEBUG(x)
#define DEBUGLN(x)
#define LINE()
#define LINELN()
#define CHECK(exp,act)
#define STOP(e)
#else
#define DUMP(x)  cerr << #x << " = " << (x)
#define DUMPLN(x)  DUMP(x) <<endl
#define DEBUG(x) DUMP(x) << LINE() << " " << __FILE__
#define DEBUGLN(x) DEBUG(x)<<endl
#define LINE()    cerr<< " (L" << __LINE__ << ")"
#define LINELN()    LINE()<<endl
#define CHECK(exp,act)  if(exp!=act){DUMPLN(exp);DEBUGLN(act);}
#define STOP(e)  CHECK(e,true);if(!(e)) exit(1);
#endif

template<class T> inline string toString(const vector<T>& x) {
	stringstream ss;
	REP(i,x.size()){
		if(i!=0)ss<<" ";
		ss<< x[i];
	}
	return ss.str();
}

template<class T> inline string toString(const vector<vector<T> >& map) {
	stringstream ss;
	REP(i,map.size()){
		if(i!=0)ss<<BR;
		ss<< toString(map[i]);
	}
	return ss.str();
}
template<class K,class V>  string toString(map<K,V>& x) {
	string res;stringstream ss;
	for(auto& p:x)ss<< p.first<<":" << p.second<<" ";
	return ss.str();
}



namespace Ps{
	const double EPS=1e-8,INF=1e12;
#define X real()
#define Y imag()
	typedef complex<double> P;
}
using namespace Ps;
namespace Ls{
	struct L:public vector<P>{
		L(const P&a,const P&b){
			push_back(a);push_back(b);
		}
	};
}
using namespace Ls;


class Seg{
public:
	double l,r;
	Seg(double l,double r):l(l),r(r){
	}

	bool operator < (const Seg& rt) const{
		return l<rt.l;
	}
};

int main() {
	int H,W;cin >> H >> W;
	vector<string> board(H+2);
	
	{
		stringstream ss;string s;
		for(int x=0;x<W+1;x++)ss<<".";
		ss>> s;
	board[0]=s;
	board[H+1]=s;

	}
	for(int y=1;y<=H;y++){
		stringstream ss;string s;
		ss<<".";
		cin >> s;
		ss<< s;
		ss<<".";
		board[y]=ss.str();
	}


	vector<L> ls;

	// -
	for(int y=0;y<=H;y++){
		int x=1;
		for(;x<=W;x++){
			if(board[y][x]=='.' && board[y+1][x]=='#'){
				P p1(H-y,x-1);
				x++;
				while(board[y][x]=='.' && board[y+1][x]=='#'){
					x++;
				}
				P p2(H-y,x-1);
				ls.push_back(L(p1,p2));
				x--;
			}
			if(board[y][x]=='#' && board[y+1][x]=='.'){
				P p1(H-y,x-1);
				x++;
				while(board[y][x]=='#' && board[y+1][x]=='.'){
					x++;
				}
				P p2(H-y,x-1);
				ls.push_back(L(p1,p2));
				x--;
			}
		}
	}

	// |
	for(int x=0;x<=W;x++){
		int y=0;
		for(;y<=H;y++){
			if(board[y][x]=='.' && board[y][x+1]=='#'){
				P p1(H+1-y,x);
				y++;
				while(board[y][x]=='.' && board[y][x+1]=='#'){
					y++;
				}
				P p2(H+1-y,x);
				ls.push_back(L(p1,p2));
				y--;
			}
			if(board[y][x]=='#' && board[y][x+1]=='.'){
				P p1(H+1-y,x);
				y++;
				while(board[y][x]=='#' && board[y][x+1]=='.'){
					y++;
				}
				P p2(H+1-y,x);
				ls.push_back(L(p1,p2));
				y--;
			} 
		}
	}

	// for(int i=0;i<ls.size();i++){
	// 	cout << ls[i][0]<<" " <<ls[i][1]<<endl;
	// }

	// DUMP(ls.size());
	// //DUMP(toString())

	vector<Seg> ss;
	for(int i=0;i<ls.size();i++){
		ss.push_back(Seg(min(arg(ls[i][0]),arg(ls[i][1])+EPS),1));
		ss.push_back(Seg(max(arg(ls[i][0]),arg(ls[i][1])-EPS),-1));		
	} 
	sort(ss.begin(),ss.end());


	int Mv=0,v=0;
	for(int i=0;i<ss.size();i++){
		v+=ss[i].r;
		Mv=max(Mv,v);
	}

	cout << (Mv/2 + 1)<<endl;
}

Measured memory_bytes: 26644