#define _CRT_SECURE_NO_WARNINGS
#include <algorithm>
#include <bitset>
#include <cassert>
#include <ciso646>
#include <climits>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <ctime>
#include <cstring>
#include <deque>
#include <initializer_list>
#include <iostream>
#include <iomanip>
#include <limits>
#include <list>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>
using namespace std;
typedef long long ll;
typedef long double ld;
time_t _timer;

void _pre()
{
	_timer = clock();
	ios_base::sync_with_stdio(false);
	cin.tie(nullptr);
#ifdef ANDREIKKAA
	assert(freopen("input.txt", "r", stdin) != nullptr);
	//freopen("output.txt", "w", stdout);
#else
	assert(freopen("video.in", "r", stdin) != nullptr);
	assert(freopen("video.out", "w", stdout) != nullptr);
#endif
}

void _post()
{
#ifdef ANDREIKKAA
	cout << "\n\n\nTime: " << (clock() - _timer) / (ld)CLOCKS_PER_SEC << endl;
	while (228);
#endif
}

void _solve()
{
	int n, m;
	cin >> n >> m;

	const int MAX_S = 2007;
	static char a[MAX_S][MAX_S];
	static int dp[MAX_S][MAX_S];
	for (int i = 1; i <= n; ++i)
	{
		for (int j = 1; j <= m; ++j)
		{
			char c;
			cin >> c;
			a[i][j] = a[n + i][j] = a[i][j + m] = a[i + n][j + m] = c;
		}
	}

	for (int i = 1; i <= (n << 1); ++i)
	{
		for (int j = 1; j <= (m << 1); ++j)
		{
			dp[i][j] = dp[i - 1][j] + dp[i][j - 1] - dp[i - 1][j - 1] +
				(a[i][j] == a[i - 1][j] and a[i][j] == a[i][j - 1] and a[i][j] == a[i - 1][j - 1]);
		}
	}

	int ans = 0;
	for (int i = n; i <= (n << 1); ++i)
	{
		for (int j = m; j <= (m << 1); ++j)
		{
			ans = max(ans, dp[i][j] - dp[i - n + 1][j] - dp[i][j - m + 1] + dp[i - n + 1][j - m + 1]);
		}
	}
	cout << ans << endl;
}

int main()
{
	_pre();
	_solve();
	_post();
}