import std.stdio;
import std.ascii;
import std.range;
import std.array;
import std.functional;
import std.algorithm;
import std.conv;
import std.container;
import std.math;
import std.numeric;
import std.string;
import std.c.string;
import std.random;
import std.regex;
import std.typecons;
import core.bitop;

const INF = 1 << 28;

int R, C;
string[] F;

void input() {
    scanf("%d %d\n", &R, &C);
    F = new string[R];
    foreach (i; 0 .. R) {
        F[i] = readln.chomp;
    }
}

int calc() {
    auto dp = new int[][](2, 1 << C);
    foreach (i; 0 .. 2) dp[i][] = -INF;
    int p = 0, q = 1;
    dp[p][0] = 0;
    foreach (y; 0 .. R) {
        foreach (x; 0 .. C) {
            dp[q][] = -INF;
            for (int bit = 0; bit < (1 << C); bit++) {
                if (dp[p][bit] < 0) continue;
                int l = (bit & ((1 << x) - 1)).popcnt,
                    r = (bit & ~((1 << x) - 1)).popcnt;

                int f() {
                    int ret = 0;
                    if (x >= 1 && l >= 1 && (bit & (1 << (x - 1))) && F[y][l - 1] == F[y][l]) ret++;
                    if (y >= 1 && r >= 1 && (bit & (1 << x)) && F[y - 1][$ - r] == F[y][l]) ret++;
                    return ret;
                }

                if (l + 1 <= F[y].length) {
                    int nbit = bit | 1 << x;
                    dp[q][nbit] = max(dp[q][nbit], dp[p][bit] + f());
                }
                if (C - x - 1 >= F[y].length - l) {
                    int nbit = bit & ~(1 << x);
                    dp[q][nbit] = max(dp[q][nbit], dp[p][bit]);
                }
            }
            p = !p; q = !q;
            //writeln(dp[p].reduce!max);
        }
    }
    return dp[p].reduce!max;
}

void solve() {
    writeln(calc * 2);
}

void main() {
    input; solve;
}