#include<cstdio>
#include<iostream>
#include<algorithm>
#include<vector>
#include<string>
#include<set>
#include<map>

using namespace std;

#define reps(i,f,n) for(int i=f;i<int(n);i++)
#define rep(i,n) reps(i,0,n)
#define pb push_back

const int W = 666;
const int INF = 1000000007;
int h,w;
vector<string> board;

bool input(){
	cin>>h>>w;
	board.clear();
	rep(i,h){
		string s;
		cin>>s;
		board.pb(s);
	}
	return true;
}

int gcd(int n, int m) {
	return (n % m) ? gcd(m, n %m) : m;
}

int isBlock(char c){
	if(c=='#')return 1;
	return 0;
}

int getState(int y,int x){
	int ret = 0;
	ret += (1<<0)*isBlock(board[y][x-1]);
	ret += (1<<1)*isBlock(board[y][x]);
	ret += (1<<2)*isBlock(board[y-1][x-1]);
	ret += (1<<3)*isBlock(board[y-1][x]);
	return ret;
}

int cup[16];
int cdown[16];

int _cup(int state){
	switch(state){
		case 0:return 0;
		case 1:return 2;
		case 2:return 1;
		case 3:return 1;
		case 4:return 1;
		case 5:return 1;
		case 6:return 2;
		case 7:return 0;
		case 8:return 0;
		case 9:return 2;
		case 10:return 1;
		case 11:return 1;
		case 12:return 1;
		case 13:return 1;
		case 14:return 2;
		case 15:return 0;
	}
	return -INF;
	
}

int _cdown(int state){
	switch(state){
		case 0:return 0;
		case 1:return 0;
		case 2:return 1;
		case 3:return 1;
		case 4:return 1;
		case 5:return 1;
		case 6:return 2;
		case 7:return 2;
		case 8:return 2;
		case 9:return 2;
		case 10:return 1;
		case 11:return 1;
		case 12:return 1;
		case 13:return 1;
		case 14:return 0;
		case 15:return 0;
	}
	return -INF;
}

void setCount(){
	rep(i,16)cup[i] = _cup(i);
	rep(i,16)cdown[i] = _cdown(i);
}

int getCountUp(int y,int x){
	int state = getState(y,x);
	
	return cup[state];
	
}

int getCountDown(int y,int x){
	
	int state = getState(y,x);
	
	return cdown[state];
}

int splitCount(int y,int x){
	
	
	
	int countUp = 0;
	int countDown = 0;
	
	double dy = (double)y/x;
	double dx = (double)x/y;
	/*
	reps(i,1,w+1){
        double dy = (double)y/x;
        if(i%x==0){
            int ny = y*(i/x);
            int nx = i;
            if(ny>h)break;
             
            int dup = getCountUp(ny,nx);
            int ddown = getCountDown(ny,nx);
             
            if(x==2 && y==1 || true){
                //printf("nx=%d  ny=%d,  dup=%d  ddown=%d\n",nx,ny,dup,ddown);
            }
             
            countUp += dup;
            countDown += ddown;
        }
    }
     */
     
     for(int i=1;i*x<=w;i++){
            int ny = y*i;
            int nx = x*i;
            if(ny>h)break;
             
            int dup = getCountUp(ny,nx);
            int ddown = getCountDown(ny,nx);
             
             
            countUp += dup;
            countDown += ddown;
    }
	
	
	reps(i,1,w+1){
		if(i%x!=0){
			double ny = dy*i;
			
			int nh = (int)ny;
			if(nh>h)break;
			
			
			char left = board[nh][i-1];
			char right = board[nh][i];
			
			if(left!=right){
				countUp++;
				countDown++;
			}
		}
	}
	reps(i,1,h+1){
		
		if(i%y!=0){
			
			int nh = (int)(dx*i);
			if(nh>w)break;
			
			
			char left = board[i-1][nh];
			char right = board[i][nh];
			
			if(left!=right){
				countUp++;
				countDown++;
			}
		}
	}
	
	int ans1 = (countUp+1)/2 + 1;
	int ans2 = (countDown+1)/2 + 1;
	
	//printf("x=%d y=%d  up=%d  down=%d\n",x,y,countUp, countDown);
	
	return max(ans1, ans2);
}

void addBanpei(){
	reverse(board.begin(), board.end());
	rep(i,board.size()){
		board[i] += ".";
	}
	string tmp = "";
	rep(i,w+1)tmp += ".";
	board.pb(tmp);
}

void solve(){
	
	addBanpei();
	setCount();
	
	int ans = 0;
	reps(i,1,h+1){
		reps(j,1,w+1){
			if(gcd(i,j)==1){
				int sp = splitCount(i,j);
				ans = max(ans, sp);
			}
		}
	}
	
	cout<<ans<<endl;

}

int main(){
	input();
	solve();
}

Measured memory_bytes: 1796