#define _CRT_SECURE_NO_WARNINGS
#pragma comment(linker, "/STACK:256000000")
#include<iostream>
#include<fstream>
#include<cmath>
#include<ctime>
#include<cstring>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<string>
#include<vector>
#include<map>
#include<set>
#include<unordered_map>
#include<unordered_set>

using namespace std;

typedef long long ll;
#define forn(i, n) for (int i = 0; i < n; ++i)
#define forq(i, q, n) for (int i = q; i < n; ++i)
#define mk make_pair
#define psh push_back
#define vi vector<int>
#define vll vector<ll>
#define pii pair<int, int>
#define pll pair<ll, ll>
#define vii vector<pii>
#define vpll vector<pll>
#define x first
#define y second

const int MOD = 1e9 + 7;
const int MAXN = 1e3 + 7;
const ll INf = 1e15 + 7;

char a[MAXN][MAXN], b[MAXN][MAXN], c[MAXN][MAXN], d[MAXN][MAXN];

int main()
{
	/*freopen("input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);*/
	freopen("video.in", "r", stdin);
	freopen("video.out", "w", stdout);
	int n, m;
	cin >> n >> m;
	multiset<int> s1, s2;
	forn(i, n)
		forn(j, m)
			cin >> a[i][j];
	ll ans1 = 0, ans2 = 0;
	for (int j = 0; j < m; ++j)
	{
		int lans1 = 0;
		int j1 = j;
		int j2 = (j + 1) % m;
		for (int i = 0; i < n - 1; ++i)
		{
			int i1 = i;
			int i2 = (i + 1) % n;
			if (a[i1][j1] == a[i1][j2] && a[i1][j1] == a[i2][j1] && a[i1][j1] == a[i2][j2])
				lans1++;
		}
		lans1 = min(lans1, n - 1);
		s1.insert(lans1);
	}
	s1.erase(s1.begin());
	for (auto it = s1.begin(); it != s1.end(); ++it)
		ans1 += *it;

	for (int j = 0; j < m; ++j)
	{
		int lans2 = 0;
		int j1 = j;
		int j2 = (j + 1) % m;
		for (int i = 1; i < n ; ++i)
		{
			int i1 = i;
			int i2 = (i + 1) % n;
			if (a[i1][j1] == a[i1][j2] && a[i1][j1] == a[i2][j1] && a[i1][j1] == a[i2][j2])
				lans2++;
		}
		lans2 = min(lans2, n - 1);
		s2.insert(lans2);
	}
	s2.erase(s2.begin());
	for (auto it = s2.begin(); it != s2.end(); ++it)
		ans2 += *it;
	cout << max(ans1, ans2);
	return 0;
}