#include <iostream>
#include <cstdio>
#include <vector>
#include <complex>
#include <algorithm>
#include <set>
#include <map>
#include <queue>
#include <string>
#include <cstring>
#include <stack>
#include <cmath>
#include <iomanip>
#include <sstream>
#include <cassert>

using namespace std;

typedef long long ll;
typedef ll li;
typedef pair<int,int> PInt;
#define EPS (1e-10L)
#define rep(i,n) for(int i=0;i<(int)(n);++i)
#define REP(i,m,n) for(int i=m; i<=(int)(n); ++i)
#define F first
#define S second
#define mp(a,b) make_pair(a,b)
#define pb(a) push_back(a)
#define SZ(a) (int)((a).size())
#define ALL(a) a.begin(),a.end()
#define FOR(it,a) for(__typeof(a.begin())it=a.begin();it!=a.end();++it)
int dx[]={0,1,0,-1,1,1,-1,-1};
int dy[]={1,0,-1,0,-1,1,1,-1};

int dp[2][1<<16];
int main() {
  int R, C;
  cin >> R >> C;
  string A[130];
  rep(i, R) cin >> A[i];
  int cur = 0, next = 1;
  memset(dp, -1, sizeof(dp));
  dp[cur][0] = 0;
  rep(i, R) rep(j, C) {
    //    rep(k, 1<<C) dp[next][k] = 0;
    memset(dp + next, -1, sizeof(dp[0]));
    rep(k, 1<<C) if (dp[cur][k] != -1) {
      int score = 0;
      int ak = k & ~(1<<j);
      dp[next][ak] = max(dp[next][ak], dp[cur][k] + score);

      char c = A[i][__builtin_popcount(k&((1<<j)-1))];
      if (i > 0 && (k>>j&1) && (A[i-1][SZ(A[i-1]) - __builtin_popcount(k>>j)] == c)) score++;
      if (j > 0 && (k>>(j-1)&1) && (A[i][__builtin_popcount(k&((1<<j)-1))-1] == c)) score++;
      ak = k | 1<<j;
      dp[next][ak] = max(dp[next][ak], dp[cur][k] + score);
    }
    swap(cur, next);
    if (j+1 == C) {
      rep(k, 1<<C) if (__builtin_popcount(k) != SZ(A[i])) dp[cur][k] = -1;
    }
  }

  int ans = 0;
  rep(k, 1<<C)
    ans = max(ans, dp[cur][k]);
  cout << ans * 2 << endl;


}