Problem:
Connect
You are playing a solitaire puzzle called "Connect", which uses several letter tiles.
There are
R × C
empty cells.
For each
i
(1 ≤ i ≤ R)
, you must put a string
s
i
(1 ≤ |s
i
| ≤ C)
in the
i
-th row of the table, without changing  the letter order.
In other words, you choose an integer sequence
{a
j
}
such that
1 ≤ a
1
< a
2
< ... < a
|s
i
|
≤ C
, and put the
j
-th character of the string
s
i
in the
a
j
-th column
(1 ≤ j ≤ |s
i
|)
.
For example, when
C = 8
and
s
i
=
"ICPC", you can put
s
i
like followings.
I_C_P_C_
ICPC____
_IC___PC
'_' represents an empty cell.
For each non-empty cell
x
, you get a point equal to the number of adjacent cells which have the same character as
x
.
Two cells are adjacent if they share an edge.
Calculate the maximum total point you can get.
Input
The first line contains two integers
R
and
C
(1 ≤ R ≤ 128, 1 ≤ C ≤ 16)
.
Then
R
lines follow, each of which contains
s
i
(1 ≤ |s
i
| ≤ C)
.
All characters of
s
i
are uppercase letters.
Output
Output the maximum total point in a line.
Sample Input 1
2 4
ACM
ICPC
Output for the Sample Input 1
2
Sample Input 2
2 9
PROBLEMF
CONNECT
Output for the Sample Input 2
6
Sample Input 3
4 16
INTERNATIONAL
COLLEGIATE
PROGRAMMING
CONTEST
Output for the Sample Input 3
18

Submitted solutions:

code_snippet: #include<iostream>
#include<stdio.h>
#include<algorithm>
#include<string.h>
using namespace std;
const int N = 1<<17;
int opt[2][N][17],bn[N][17],rbn[N][17],r,c,len[150];
char s[150][20];
inline int reset(int state,int i){
    return state-(state&(1<<i));
}
inline int set(int state,int i){ return state|(1<<i); }
inline void up(int &a,int b){if(a<b) a=b;}
int main()
{
    for(int i=0;i<N;++i){
        for(int j=0;j<17;++j)
        {
            int t=(j==0?0:bn[i][j-1]);
            bn[i][j]=t+((i>>j)&1);
        }
        rbn[i][16]=0;
        for(int j=15;j>=0;--j)
            rbn[i][j]=rbn[i][j+1]+((i>>j)&1);
    }
//    freopen("1.in","r",stdin);
    while(scanf("%d%d",&r,&c)!=-1&&r)
    {
        int ans=0;
        for(int j=0;j<=c;++j) s[0][j]='$';
        for(int i=1;i<=r;++i)
            scanf("%s",s[i]),len[i]=strlen(s[i]);
        int k1=0,k2=1;
        memset(opt,-1,sizeof opt);
        opt[k1][0][c-1]=0;
        for(int i=1;i<=r;++i)
        {
            memset(opt[k2],-1,sizeof opt[k2]);
            for(int k=0;k<(1<<c);++k)
            {
                if(opt[k1][k][c-1]==-1) continue;
                if(len[i]<c)
                up(opt[k2][reset(k,0)][0],opt[k1][k][c-1]);
                int nk=set(k,0),t=0;
                if((k&1)&&s[i][0]==s[i-1][0]) t=1;
                up(opt[k2][nk][0],opt[k1][k][c-1]+t);
            }
            for(int j=1;j<c;++j)
            {
                for(int k=0;k<(1<<c);++k)
                {
                    if(opt[k2][k][j-1]==-1) continue;
                    if(bn[k][j-1]+c-j>len[i])///
                        up(opt[k2][reset(k,j)][j],opt[k2][k][j-1]);

                    if(bn[k][j-1]==len[i]) continue;
                    int nk=set(k,j),t=0;

                    if((k&(1<<j-1))&&s[i][bn[k][j-1]-1]==s[i][bn[nk][j]-1]) ++t;
//                    if(i==2&&k==3&&j-1==0) cout<<opt[k2][k][j-1]<<" "<<t<<endl;
                    if((k&1<<j)&&s[i-1][len[i-1]-rbn[k][j]]==s[i][bn[nk][j]-1]) ++t;
                    up(opt[k2][nk][j],opt[k2][k][j-1]+t);
                }
            }
//            for(int j=0;j<c;++j)
//                for(int k=0;k<(1<<c);++k)
//                    printf("%d %d %d %d\n",i,k,j,opt[k2][k][j]);
            k1^=1; k2^=1;
        }
        for(int k=0;k<(1<<c);++k)
            up(ans,opt[k1][k][c-1]);
        printf("%d\n",ans*2);
    }
    return 0;
}
accuracy: 1
time_ms: 460
memory_kb: 38356
final_rank: 5

code_snippet: #include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <vector>
#include <cmath>
#include <map>
#define PI (acos(-1.0))
using namespace std;

char str[130][17];
int n,m,s[130];
int ans;
int dp[2][17][1<<20];
int p[1<<20];
int main()
{
    p[0] = 0;
    for(int i=1;i<(1<<18);i++)
    p[i] = p[i>>1] + (i&1);
    while(~scanf("%d%d",&n,&m))
    {
        ans = 0;
        for(int i=0;i<m;i++)
        for(int j=0;j<(1<<m);j++)
        dp[0][i][j]=-1;
        s[0] = m;
        for(int i=0;i<m;i++)
        str[0][i] = 'a';
        for(int i=1;i<=n;i++)
        {
            scanf("%s",str[i]);
            s[i] = strlen(str[i]);
        }
        int id,nxt;
        dp[0][m-1][(1<<m)-1] = 0;
        int j,k;
        int u,v;
        int tu,tv;
        for(int i=1;i<=n;i++)
        {
            id = i&1;
            nxt = (i+1)&1;
            for( j=0;j<m;j++)
            for( k=0;k<(1<<m);k++)
            {
                dp[id][j][k] = -1;
            }
            for( j=1;j<(1<<m);j++)
            {
                if(dp[nxt][m-1][j]==-1) continue;
                dp[id][0][((j>>1)<<1)+1] = max(dp[nxt][m-1][j]+ (((j&1)&&(str[i][0]==str[i-1][0]))?1:0),dp[id][0][((j>>1)<<1)+1]);
                if(s[i]<m) dp[id][0][(j>>1)<<1] = max(dp[nxt][m-1][j] , dp[id][0][(j>>1)<<1]);
            }
            for( j=0;j<m-1;j++)
            for( k=0;k<(1<<m);k++)
            {
                if(dp[id][j][k] == -1) continue;
                u = k>>(j+1); tu = p[u];
                v = k - (u<<(j+1)); tv = p[v];
                int tmp = 0;
                if(tv<s[i]){
                    if((k&(1<<j)) && str[i][tv-1]==str[i][tv]) tmp++;
                    if((k&(1<<(j+1))) && str[i][tv]== str[i-1][s[i-1]-tu] ) tmp++;
                    dp[id][j+1][k|(1<<(j+1))] = max( dp[id][j][k]+tmp , dp[id][j+1][k|(1<<(j+1))]);
                }
                if(j+1-tv < m-s[i]) dp[id][j+1][(k&(1<<(j+1)))^k] = max( dp[id][j][k],dp[id][j+1][(k&(1<<(j+1)))^k]);
            }
        }
        for(int i=0;i<(1<<m);i++)
        ans = max(ans , dp[n&1][m-1][i]);
        ans *=2;
        cout << ans <<endl;
    }
    return 0;
}
accuracy: 1
time_ms: 230
memory_kb: 70044
final_rank: 6

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define all(v) (v).begin(),(v).end()
#define pb(a) push_back(a)
#define rep(i, n) for(int i=0;i<n;i++)
#define foa(e, v) for(auto&& e : v)
using ll = long long;
const ll MOD7 = 1000000007, MOD998 = 998244353, INF = (1LL << 60);
#define dout(a) cout<<fixed<<setprecision(10)<<a<<endl;

void chmax(int &a, int b) { a = max(a, b); }
int main() {
    cin.tie(0);
    ios::sync_with_stdio(false);
    int h, c; cin >> h >> c;
    vector<string> s(h);
    rep(i, h) cin >> s[i];
    int inf = 1 << 24;
    vector<int> dp(1 << c, -inf);
    rep(bit, 1 << c) {
        vector<int> vec;
        rep(i, c) if(bit >> i & 1) vec.pb(i);
        if((int)vec.size() != (int)s[0].size()) continue;
        string t(c, '.');
        int sz = s[0].size();
        rep(i, sz) t[vec[i]] = s[0][i];
        int cnt = 0;
        rep(j, c - 1) if(t[j] != '.' and t[j] == t[j + 1]) cnt ++;
        dp[bit] = cnt;
    }
    for(int i = 1; i < h; i ++) {
        int sz1 = s[i - 1].size();
        int sz2 = s[i].size();
        rep(j, c) {
            vector<int> nx(1 << c, -inf);
            rep(bit, 1 << c) {
                int mask = (1 << (c - j)) - 1;
                int cnt1 = __builtin_popcount(bit & mask);
                int cnt2 = __builtin_popcount(bit >> (c - j));
                if(cnt1 > sz1 or cnt2 > sz2) continue;
                if(sz1 - cnt1 > j or sz2 - cnt2 > c - j) continue;
                if(dp[bit] < 0) continue;
                chmax(nx[bit >> 1], dp[bit]);
                // if(j == 4 and bit & 1 and dp[bit] == 2 and cnt1 < sz1 and cnt2 < sz2) {
                //     cout << bit << " " << s[i - 1][sz1 - cnt1] << " " << s[i][cnt2] << endl;
                // }
                // if(i == 1 and j == 2) cout << bit << " " << dp[bit] << " " << cnt1 << endl;
                if(cnt2 != sz2) {
                    int cnt = 0;
                    if(cnt1 <= sz1 and bit & 1 and s[i - 1][sz1 - cnt1] == s[i][cnt2]) {
                        // cout << j << " " << bit << " " << cnt1 << " " << cnt2 << " " << dp[bit] << endl;
                        cnt ++;
                    }
                    if(j > 0 and bit >> (c - 1) and s[i][cnt2 - 1] == s[i][cnt2]) {
                        cnt ++;
                    }
                    // if(dp[bit] + cnt == 4) {
                    //     cout << j << " " << bit << " " << dp[bit] << endl;
                    // }
                    chmax(nx[(bit >> 1) | (1 << (c - 1))], dp[bit] + cnt);
                }
            }
            swap(dp, nx);
            // cout << *max_element(all(dp)) << " " ;
        }
        // cout << endl;
        rep(j, 1 << c) if(__builtin_popcount(j) != sz2) dp[j] = -inf;
    }
    assert(*max_element(all(dp)) >= 0);
    cout << *max_element(all(dp)) * 2 << endl;
    return 0;
}
accuracy: 1
time_ms: 890
memory_kb: 3712
final_rank: 4

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define all(v) (v).begin(),(v).end()
#define pb(a) push_back(a)
#define rep(i, n) for(int i=0;i<n;i++)
#define foa(e, v) for(auto&& e : v)
using ll = long long;
const ll MOD7 = 1000000007, MOD998 = 998244353, INF = (1LL << 60);
#define dout(a) cout<<fixed<<setprecision(10)<<a<<endl;

void chmax(int &a, int b) { a = max(a, b); }
int main() {
    cin.tie(0);
    ios::sync_with_stdio(false);
    int h, c; cin >> h >> c;
    vector<string> s(h);
    rep(i, h) cin >> s[i];
    int inf = 1 << 24;
    vector<int> dp(1 << c, -inf);
    rep(bit, 1 << c) {
        vector<int> vec;
        rep(i, c) if(bit >> i & 1) vec.pb(i);
        if((int)vec.size() != (int)s[0].size()) continue;
        string t(c, '.');
        int sz = s[0].size();
        rep(i, sz) t[vec[i]] = s[0][i];
        int cnt = 0;
        rep(j, c - 1) if(t[j] != '.' and t[j] == t[j + 1]) cnt ++;
        dp[bit] = cnt;
    }
    for(int i = 1; i < h; i ++) {
        int sz1 = s[i - 1].size();
        int sz2 = s[i].size();
        rep(j, c) {
            vector<int> nx(1 << c, -inf);
            rep(bit, 1 << c) {
                int mask = (1 << (c - j)) - 1;
                int cnt1 = __builtin_popcount(bit & mask);
                int cnt2 = __builtin_popcount(bit >> (c - j));
                if(cnt1 > sz1 or cnt2 > sz2) continue;
                if(sz1 - cnt1 > j or sz2 - cnt2 > c - j) continue;
                if(dp[bit] < 0) continue;
                chmax(nx[bit >> 1], dp[bit]);
                // if(i == 1 and j == 2) cout << bit << " " << dp[bit] << " " << cnt1 << endl;
                if(cnt2 != sz2) {
                    int cnt = 0;
                    if(cnt1 < sz1 and bit & 1 and s[i - 1][sz1 - cnt1] == s[i][cnt2]) {
                        cnt ++;
                    }
                    if(j > 0 and bit >> (c - 1) and s[i][cnt2 - 1] == s[i][cnt2]) {
                        cnt ++;
                    }
                    chmax(nx[(bit >> 1) | (1 << (c - 1))], dp[bit] + cnt);
                }
            }
            swap(dp, nx);
            // cout << *max_element(all(dp)) << " " ;
        }
        // cout << endl;
        rep(j, 1 << c) if(__builtin_popcount(j) != sz2) dp[j] = -inf;
    }
    assert(*max_element(all(dp)) >= 0);
    cout << *max_element(all(dp)) * 2 << endl;
    return 0;
}
accuracy: 0.20588235294117646
time_ms: 30
memory_kb: 3452
final_rank: 18

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define all(v) (v).begin(),(v).end()
#define pb(a) push_back(a)
#define rep(i, n) for(int i=0;i<n;i++)
#define foa(e, v) for(auto&& e : v)
using ll = long long;
const ll MOD7 = 1000000007, MOD998 = 998244353, INF = (1LL << 60);
#define dout(a) cout<<fixed<<setprecision(10)<<a<<endl;

void chmax(int &a, int b) { a = max(a, b); }
int main() {
    cin.tie(0);
    ios::sync_with_stdio(false);
    int h, c; cin >> h >> c;
    vector<string> s(h);
    rep(i, h) cin >> s[i];
    int inf = 1 << 24;
    vector<int> dp(1 << c, -inf);
    rep(bit, 1 << c) {
        vector<int> vec;
        rep(i, c) if(bit >> i & 1) vec.pb(i);
        if((int)vec.size() != (int)s[0].size()) continue;
        string t(c, '.');
        int sz = s[0].size();
        rep(i, sz) t[vec[i]] = s[0][i];
        int cnt = 0;
        rep(j, c - 1) if(t[j] != '.' and t[j] == t[j + 1]) cnt ++;
        dp[bit] = cnt;
    }
    for(int i = 1; i < h; i ++) {
        int sz1 = s[i - 1].size();
        int sz2 = s[i].size();
        rep(j, c) {
            vector<int> nx(1 << c, -inf);
            rep(bit, 1 << c) {
                int mask = (1 << (c - j)) - 1;
                int cnt1 = __builtin_popcount(bit & mask);
                int cnt2 = __builtin_popcount(bit >> (c - j));
                if(cnt1 > sz1 or cnt2 > sz2) continue;
                if(sz1 - cnt1 > j or sz2 - cnt2 > c - j) continue;
                if(dp[bit] < 0) continue;
                chmax(nx[(bit >> 1)], dp[bit]);
                if(cnt2 != sz2) {
                    int cnt = 0;
                    if(cnt1 < sz1 and bit & 1 and s[i - 1][sz1 - 1 - cnt1] == s[i][cnt2]) {
                        cnt ++;
                    }
                    if(j > 0 and cnt2 > 0 and bit >> (c - 1) & 1 and s[i][cnt2 - 1] == s[i][cnt2]) {
                        cnt ++;
                    }
                    chmax(nx[(bit >> 1) | (1 << (c - 1))], dp[bit] + cnt);
                }
            }
            swap(dp, nx);
        }
        rep(j, 1 << c) if(__builtin_popcount(j) != sz2) dp[j] = -inf;
    }
    assert(*max_element(all(dp)) >= 0);
    cout << *max_element(all(dp)) * 2 << endl;
    return 0;
}
accuracy: 0.29411764705882354
time_ms: 30
memory_kb: 3500
final_rank: 11

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define all(v) (v).begin(),(v).end()
#define pb(a) push_back(a)
#define rep(i, n) for(int i=0;i<n;i++)
#define foa(e, v) for(auto&& e : v)
using ll = long long;
const ll MOD7 = 1000000007, MOD998 = 998244353, INF = (1LL << 60);
#define dout(a) cout<<fixed<<setprecision(10)<<a<<endl;

void chmax(int &a, int b) { a = max(a, b); }
int main() {
    cin.tie(0);
    ios::sync_with_stdio(false);
    int h, c; cin >> h >> c;
    vector<string> s(h);
    rep(i, h) cin >> s[i];
    int inf = 1 << 24;
    vector<int> dp(1 << c, -inf);
    rep(bit, 1 << c) {
        vector<int> vec;
        rep(i, c) if(bit >> i & 1) vec.pb(i);
        if((int)vec.size() != (int)s[0].size()) continue;
        string t(c, '.');
        int sz = s[0].size();
        rep(i, sz) t[vec[i]] = s[0][i];
        int cnt = 0;
        rep(j, c - 1) if(t[j] != '.' and t[j] == t[j + 1]) cnt ++;
        dp[bit] = cnt;
    }
    for(int i = 1; i < h; i ++) {
        int sz1 = s[i - 1].size();
        int sz2 = s[i].size();
        rep(j, c) {
            vector<int> nx(1 << c, -inf);
            rep(bit, 1 << c) {
                int mask = (1 << (c - j)) - 1;
                int cnt1 = __builtin_popcount(bit & mask);
                int cnt2 = __builtin_popcount(bit >> (c - j));
                if(cnt1 > sz1 or cnt2 > sz2) continue;
                if(sz1 - cnt1 > j or sz2 - cnt2 > c - j) continue;
                if(dp[bit] < 0) continue;
                chmax(nx[(bit >> 1)], dp[bit]);
                if(cnt2 != sz2) {
                    int cnt = 0;
                    if(cnt1 < sz1 and bit & 1 and s[i - 1][sz1 - 1 - cnt1] == s[i][cnt2]) {
                        cnt ++;
                    }
                    if(j > 0 and cnt2 > 0 and bit >> (c - 1) & 1 and s[i][cnt2 - 1] == s[i][cnt2]) {
                        cnt ++;
                    }
                    chmax(nx[(bit >> 1) | (1 << (c - 1))], dp[bit] + cnt);
                }
            }
            dp = move(nx);
        }
        rep(j, 1 << c) if(__builtin_popcount(j) != sz2) dp[j] = -inf;
    }
    assert(*max_element(all(dp)) >= 0);
    cout << *max_element(all(dp)) * 2 << endl;
    return 0;
}
accuracy: 0.29411764705882354
time_ms: 30
memory_kb: 3508
final_rank: 12

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define all(v) (v).begin(),(v).end()
#define pb(a) push_back(a)
#define rep(i, n) for(int i=0;i<n;i++)
#define foa(e, v) for(auto&& e : v)
using ll = long long;
const ll MOD7 = 1000000007, MOD998 = 998244353, INF = (1LL << 60);
#define dout(a) cout<<fixed<<setprecision(10)<<a<<endl;

void chmax(int &a, int b) { a = max(a, b); }
int main() {
    cin.tie(0);
    ios::sync_with_stdio(false);
    int h, c; cin >> h >> c;
    vector<string> s(h);
    rep(i, h) cin >> s[i];
    int inf = 1 << 24;
    vector<int> dp(1 << c, -inf);
    rep(bit, 1 << c) {
        vector<int> vec;
        rep(i, c) if(bit >> i & 1) vec.pb(i);
        if((int)vec.size() != (int)s[0].size()) continue;
        string t(c, '.');
        int sz = s[0].size();
        rep(i, sz) t[vec[i]] = s[0][i];
        int cnt = 0;
        rep(j, c - 1) if(t[j] != '.' and t[j] == t[j + 1]) cnt ++;
        dp[bit] = cnt;
    }
    for(int i = 1; i < h; i ++) {
        int sz1 = s[i - 1].size();
        int sz2 = s[i].size();
        rep(j, c) {
            vector<int> nx(1 << c, -inf);
            rep(bit, 1 << c) {
                int mask = (1 << (c - j)) - 1;
                int cnt1 = __builtin_popcount(bit & mask);
                int cnt2 = __builtin_popcount(bit >> (c - j));
                if(cnt1 > sz1 or cnt2 > sz2) continue;
                if(sz1 - cnt1 > j or sz2 - cnt2 > c - j) continue;
                if(dp[bit] < 0) continue;
                chmax(nx[(bit >> 1)], dp[bit]);
                if(cnt2 != sz2) {
                    int cnt = 0;
                    if(sz1 - 1 - cnt1 >= 0 and bit & 1 and s[i - 1][sz1 - 1 - cnt1] == s[i][cnt2]) {
                        cnt ++;
                    }
                    if(cnt2 < sz2 and j > 0 and cnt2 > 0 and bit >> (c - 1) & 1 and s[i][cnt2 - 1] == s[i][cnt2]) {
                        cnt ++;
                    }
                    chmax(nx[(bit >> 1) | (1 << (c - 1))], dp[bit] + cnt);
                }
            }
            dp = move(nx);
        }
        rep(j, 1 << c) if(__builtin_popcount(j) != sz2) dp[j] = -inf;
    }
    assert(*max_element(all(dp)) >= 0);
    cout << *max_element(all(dp)) * 2 << endl;
    return 0;
}
accuracy: 0.29411764705882354
time_ms: 30
memory_kb: 3456
final_rank: 9

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define all(v) (v).begin(),(v).end()
#define pb(a) push_back(a)
#define rep(i, n) for(int i=0;i<n;i++)
#define foa(e, v) for(auto&& e : v)
using ll = long long;
const ll MOD7 = 1000000007, MOD998 = 998244353, INF = (1LL << 60);
#define dout(a) cout<<fixed<<setprecision(10)<<a<<endl;

void chmax(int &a, int b) { a = max(a, b); }
int main() {
    cin.tie(0);
    ios::sync_with_stdio(false);
    int h, c; cin >> h >> c;
    vector<string> s(h);
    rep(i, h) cin >> s[i];
    int inf = 1 << 24;
    vector<int> dp(1 << c, -inf);
    rep(bit, 1 << c) {
        vector<int> vec;
        rep(i, c) if(bit >> i & 1) vec.pb(i);
        if((int)vec.size() != (int)s[0].size()) continue;
        string t(c, '.');
        int sz = s[0].size();
        rep(i, sz) t[vec[i]] = s[0][i];
        int cnt = 0;
        rep(j, c - 1) if(t[j] != '.' and t[j] == t[j + 1]) cnt ++;
        dp[bit] = cnt;
    }
    for(int i = 1; i < h; i ++) {
        int sz1 = s[i - 1].size();
        int sz2 = s[i].size();
        rep(j, c) {
            vector<int> nx(1 << c, -inf);
            rep(bit, 1 << c) {
                int mask = (1 << (c - j)) - 1;
                int cnt1 = __builtin_popcount(bit & mask);
                int cnt2 = __builtin_popcount(bit >> (c - j));
                if(cnt1 > sz1 or cnt2 > sz2) continue;
                if(sz1 - cnt1 > j or sz2 - cnt2 > c - j) continue;
                if(dp[bit] < 0) continue;
                chmax(nx[(bit >> 1)], dp[bit]);
                if(cnt2 != sz2) {
                    int cnt = 0;
                    if(bit & 1 and s[i - 1][sz1 - 1 - cnt1] == s[i][cnt2]) {
                        cnt ++;
                    }
                    if(cnt2 < sz2 and j > 0 and cnt2 > 0 and bit >> (c - 1) & 1 and s[i][cnt2 - 1] == s[i][cnt2]) {
                        cnt ++;
                    }
                    chmax(nx[(bit >> 1) | (1 << (c - 1))], dp[bit] + cnt);
                }
            }
            dp = move(nx);
        }
        rep(j, 1 << c) if(__builtin_popcount(j) != sz2) dp[j] = -inf;
    }
    assert(*max_element(all(dp)) >= 0);
    cout << *max_element(all(dp)) * 2 << endl;
    return 0;
}
accuracy: 0.29411764705882354
time_ms: 30
memory_kb: 3600
final_rank: 15

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define all(v) (v).begin(),(v).end()
#define pb(a) push_back(a)
#define rep(i, n) for(int i=0;i<n;i++)
#define foa(e, v) for(auto&& e : v)
using ll = long long;
const ll MOD7 = 1000000007, MOD998 = 998244353, INF = (1LL << 60);
#define dout(a) cout<<fixed<<setprecision(10)<<a<<endl;

void chmax(int &a, int b) { a = max(a, b); }
int main() {
    cin.tie(0);
    ios::sync_with_stdio(false);
    int h, c; cin >> h >> c;
    vector<string> s(h);
    rep(i, h) cin >> s[i];
    int inf = 1 << 24;
    vector<int> dp(1 << c, -inf);
    rep(bit, 1 << c) {
        vector<int> vec;
        rep(i, c) if(bit >> i & 1) vec.pb(i);
        if((int)vec.size() != (int)s[0].size()) continue;
        string t(c, '.');
        int sz = s[0].size();
        rep(i, sz) t[vec[i]] = s[0][i];
        int cnt = 0;
        rep(j, c - 1) if(t[j] != '.' and t[j] == t[j + 1]) cnt ++;
        dp[bit] = cnt;
    }
    for(int i = 1; i < h; i ++) {
        int sz1 = s[i - 1].size();
        int sz2 = s[i].size();
        rep(j, c) {
            vector<int> nx(1 << c, -inf);
            rep(bit, 1 << c) {
                int mask = (1 << (c - j)) - 1;
                int cnt1 = __builtin_popcount(bit & mask);
                int cnt2 = __builtin_popcount(bit >> (c - j));
                if(cnt1 > sz1 or cnt2 > sz2) continue;
                if(sz1 - cnt1 > j or sz2 - cnt2 > c - j) continue;
                chmax(nx[(bit >> 1)], dp[bit]);
                if(cnt2 != sz2) {
                    int cnt = 0;
                    if(bit & 1 and s[i - 1][sz1 - 1 - cnt1] == s[i][cnt2]) {
                        cnt ++;
                    }
                    if(cnt2 < sz2 and j > 0 and cnt2 > 0 and bit >> (c - 1) & 1 and s[i][cnt2 - 1] == s[i][cnt2]) {
                        cnt ++;
                    }
                    chmax(nx[(bit >> 1) | (1 << (c - 1))], dp[bit] + cnt);
                }
            }
            dp = move(nx);
        }
        rep(j, 1 << c) if(__builtin_popcount(j) != sz2) dp[j] = -inf;
    }
    assert(*max_element(all(dp)) >= 0);
    cout << *max_element(all(dp)) * 2 << endl;
    return 0;
}
accuracy: 0.29411764705882354
time_ms: 30
memory_kb: 3580
final_rank: 14

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define all(v) (v).begin(),(v).end()
#define pb(a) push_back(a)
#define rep(i, n) for(int i=0;i<n;i++)
#define foa(e, v) for(auto&& e : v)
using ll = long long;
const ll MOD7 = 1000000007, MOD998 = 998244353, INF = (1LL << 60);
#define dout(a) cout<<fixed<<setprecision(10)<<a<<endl;

void chmax(int &a, int b) { a = max(a, b); }
int main() {
    cin.tie(0);
    ios::sync_with_stdio(false);
    int h, c; cin >> h >> c;
    vector<string> s(h);
    rep(i, h) cin >> s[i];
    int inf = 1 << 24;
    vector<int> dp(1 << c, -inf);
    rep(bit, 1 << c) {
        vector<int> vec;
        rep(i, c) if(bit >> i & 1) vec.pb(i);
        if((int)vec.size() != (int)s[0].size()) continue;
        string t(c, '.');
        int sz = s[0].size();
        rep(i, sz) t[vec[i]] = s[0][i];
        int cnt = 0;
        rep(j, c - 1) if(t[j] != '.' and t[j] == t[j + 1]) cnt ++;
        dp[bit] = cnt;
    }
    for(int i = 1; i < h; i ++) {
        int sz1 = s[i - 1].size();
        int sz2 = s[i].size();
        rep(j, c) {
            vector<int> nx(1 << c, -inf);
            rep(bit, 1 << c) {
                int mask = (1 << (c - j)) - 1;
                int cnt1 = __builtin_popcount(bit & mask);
                int cnt2 = __builtin_popcount(bit >> (c - j));
                if(cnt1 > sz1 or cnt2 > sz2) continue;
                if(sz1 - cnt1 > j or sz2 - cnt2 > c - j) continue;
                chmax(nx[(bit >> 1)], dp[bit]);
                if(cnt2 != sz2) {
                    int cnt = 0;
                    if(bit & 1 and s[i - 1][sz1 - 1 - cnt1] == s[i][cnt2]) {
                        cnt ++;
                    }
                    if(cnt2 < sz2 and j > 0 and cnt2 > 0 and bit >> (c - 1) & 1 and s[i][cnt2 - 1] == s[i][cnt2]) {
                        cnt ++;
                    }
                    chmax(nx[(bit >> 1) | (1 << (c - 1))], dp[bit] + cnt);
                }
            }
            dp = move(nx);
        }
        rep(j, 1 << c) if(__builtin_popcount(j) != sz2) dp[j] = -inf;
    }
    cout << *max_element(all(dp)) * 2 << endl;
    return 0;
}
accuracy: 0.29411764705882354
time_ms: 30
memory_kb: 3452
final_rank: 8

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define all(v) (v).begin(),(v).end()
#define pb(a) push_back(a)
#define rep(i, n) for(int i=0;i<n;i++)
#define foa(e, v) for(auto&& e : v)
using ll = long long;
const ll MOD7 = 1000000007, MOD998 = 998244353, INF = (1LL << 60);
#define dout(a) cout<<fixed<<setprecision(10)<<a<<endl;

void chmax(int &a, int b) { a = max(a, b); }
int main() {
    cin.tie(0);
    ios::sync_with_stdio(false);
    int h, c; cin >> h >> c;
    vector<string> s(h);
    rep(i, h) cin >> s[i];
    int inf = 1 << 24;
    vector<int> dp(1 << c, -inf);
    rep(bit, 1 << c) {
        vector<int> vec;
        rep(i, c) if(bit >> i & 1) vec.pb(i);
        if((int)vec.size() != (int)s[0].size()) continue;
        string t(c, '.');
        int sz = s[0].size();
        rep(i, sz) t[vec[i]] = s[0][i];
        int cnt = 0;
        rep(j, c - 1) if(t[j] != '.' and t[j] == t[j + 1]) cnt ++;
        dp[bit] = cnt;
    }
    for(int i = 1; i < h; i ++) {
        int sz1 = s[i - 1].size();
        int sz2 = s[i].size();
        rep(j, c) {
            vector<int> nx(1 << c, -inf);
            rep(bit, 1 << c) {
                int mask = (1 << (c - j)) - 1;
                int cnt1 = __builtin_popcount(bit & mask);
                int cnt2 = __builtin_popcount(bit >> (c - j));
                if(cnt1 > sz1 or cnt2 > sz2) continue;
                chmax(nx[(bit >> 1)], dp[bit]);
                if(cnt2 != sz2) {
                    int cnt = 0;
                    if(bit & 1 and s[i - 1][sz1 - 1 - cnt1] == s[i][cnt2]) {
                        cnt ++;
                    }
                    if(cnt2 < sz2 and j > 0 and cnt2 > 0 and bit >> (c - 1) & 1 and s[i][cnt2 - 1] == s[i][cnt2]) {
                        cnt ++;
                    }
                    chmax(nx[(bit >> 1) | (1 << (c - 1))], dp[bit] + cnt);
                }
            }
            dp = move(nx);
        }
        // rep(j, 1 << c) if(__builtin_popcount(j) != sz2) dp[j] = -inf;
    }
    cout << *max_element(all(dp)) * 2 << endl;
    return 0;
}
accuracy: 0.058823529411764705
time_ms: 30
memory_kb: 3592
final_rank: 19

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define all(v) (v).begin(),(v).end()
#define pb(a) push_back(a)
#define rep(i, n) for(int i=0;i<n;i++)
#define foa(e, v) for(auto&& e : v)
using ll = long long;
const ll MOD7 = 1000000007, MOD998 = 998244353, INF = (1LL << 60);
#define dout(a) cout<<fixed<<setprecision(10)<<a<<endl;

void chmax(int &a, int b) { a = max(a, b); }
int main() {
    cin.tie(0);
    ios::sync_with_stdio(false);
    int h, c; cin >> h >> c;
    vector<string> s(h);
    rep(i, h) cin >> s[i];
    int inf = 1 << 24;
    vector<int> dp(1 << c, -inf);
    rep(bit, 1 << c) {
        vector<int> vec;
        rep(i, c) if(bit >> i & 1) vec.pb(i);
        if((int)vec.size() != (int)s[0].size()) continue;
        string t(c, '.');
        int sz = s[0].size();
        rep(i, sz) t[vec[i]] = s[0][i];
        int cnt = 0;
        rep(j, c - 1) if(t[j] != '.' and t[j] == t[j + 1]) cnt ++;
        dp[bit] = cnt;
    }
    for(int i = 1; i < h; i ++) {
        int sz1 = s[i - 1].size();
        int sz2 = s[i].size();
        rep(j, c) {
            vector<int> nx(1 << c, -inf);
            rep(bit, 1 << c) {
                int mask = (1 << (c - j)) - 1;
                int cnt1 = __builtin_popcount(bit & mask);
                int cnt2 = __builtin_popcount(bit >> (c - j));
                if(cnt1 > sz1 or cnt2 > sz2) continue;
                chmax(nx[(bit >> 1)], dp[bit]);
                if(cnt2 != sz2) {
                    int cnt = 0;
                    if(bit & 1 and s[i - 1][sz1 - 1 - cnt1] == s[i][cnt2]) {
                        cnt ++;
                    }
                    if(cnt2 < sz2 and j > 0 and cnt2 > 0 and bit >> (c - 1) & 1 and s[i][cnt2 - 1] == s[i][cnt2]) {
                        cnt ++;
                    }
                    chmax(nx[(bit >> 1) | (1 << (c - 1))], dp[bit] + cnt);
                }
            }
            dp = move(nx);
        }
        rep(j, 1 << c) if(__builtin_popcount(j) != sz2) dp[j] = -inf;
    }
    cout << *max_element(all(dp)) * 2 << endl;
    return 0;
}
accuracy: 0.29411764705882354
time_ms: 30
memory_kb: 3456
final_rank: 9

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define all(v) (v).begin(),(v).end()
#define pb(a) push_back(a)
#define rep(i, n) for(int i=0;i<n;i++)
#define foa(e, v) for(auto&& e : v)
using ll = long long;
const ll MOD7 = 1000000007, MOD998 = 998244353, INF = (1LL << 60);
#define dout(a) cout<<fixed<<setprecision(10)<<a<<endl;

void chmax(int &a, int b) { a = max(a, b); }
int main() {
    cin.tie(0);
    ios::sync_with_stdio(false);
    int h, c; cin >> h >> c;
    vector<string> s(h);
    rep(i, h) cin >> s[i];
    int inf = 1 << 24;
    vector<int> dp(1 << c, -inf);
    rep(bit, 1 << c) {
        vector<int> vec;
        rep(i, c) if(bit >> i & 1) vec.pb(i);
        if((int)vec.size() != (int)s[0].size()) continue;
        string t(c, '.');
        int sz = s[0].size();
        rep(i, sz) t[vec[i]] = s[0][i];
        int cnt = 0;
        rep(j, c - 1) if(t[j] != '.' and t[j] == t[j + 1]) cnt ++;
        dp[bit] = cnt;
    }
    for(int i = 1; i < h; i ++) {
        int sz1 = s[i - 1].size();
        int sz2 = s[i].size();
        rep(j, c) {
            vector<int> nx(1 << c, -inf);
            rep(bit, 1 << c) {
                int mask = (1 << (c - j)) - 1;
                int cnt1 = __builtin_popcount(bit & mask);
                int cnt2 = __builtin_popcount(bit >> (c - j));
                if(cnt1 > sz1 or cnt2 > sz2) continue;
                chmax(nx[(bit >> 1)], dp[bit]);
                if(cnt2 != sz2) {
                    int cnt = 0;
                    if(bit & 1 and s[i - 1][sz1 - 1 - cnt1] == s[i][cnt2]) {
                        cnt ++;
                    }
                    if(j > 0 and cnt2 > 0 and bit >> (c - 1) & 1 and s[i][cnt2 - 1] == s[i][cnt2]) {
                        cnt ++;
                    }
                    chmax(nx[(bit >> 1) | (1 << (c - 1))], dp[bit] + cnt);
                }
            }
            dp = move(nx);
        }
        rep(j, 1 << c) if(__builtin_popcount(j) != sz2) dp[j] = -inf;
    }
    cout << *max_element(all(dp)) * 2 << endl;
    return 0;
}
accuracy: 0.29411764705882354
time_ms: 30
memory_kb: 3448
final_rank: 7

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define all(v) (v).begin(),(v).end()
#define pb(a) push_back(a)
#define rep(i, n) for(int i=0;i<n;i++)
#define foa(e, v) for(auto&& e : v)
using ll = long long;
const ll MOD7 = 1000000007, MOD998 = 998244353, INF = (1LL << 60);
#define dout(a) cout<<fixed<<setprecision(10)<<a<<endl;

void chmax(int &a, int b) { a = max(a, b); }
int main() {
    cin.tie(0);
    ios::sync_with_stdio(false);
    int h, c; cin >> h >> c;
    vector<string> s(h);
    rep(i, h) cin >> s[i];
    int inf = 1 << 28;
    vector<int> dp(1 << c, -inf);
    rep(bit, 1 << c) {
        vector<int> vec;
        rep(i, c) if(bit >> i & 1) vec.pb(i);
        if((int)vec.size() != (int)s[0].size()) continue;
        string t(c, '.');
        int sz = s[0].size();
        rep(i, sz) t[vec[i]] = s[0][i];
        int cnt = 0;
        rep(j, c - 1) if(t[j] != '.' and t[j] == t[j + 1]) cnt ++;
        dp[bit] = cnt;
    }
    for(int i = 1; i < h; i ++) {
        int sz1 = s[i - 1].size();
        int sz2 = s[i].size();
        rep(j, c) {
            vector<int> nx(1 << c, -inf);
            rep(bit, 1 << c) {
                int mask = (1 << (c - j)) - 1;
                int cnt1 = __builtin_popcount(bit & mask);
                int cnt2 = __builtin_popcount(bit >> (c - j));
                if(cnt1 > sz1 or cnt2 > sz2) continue;
                chmax(nx[(bit >> 1)], dp[bit]);
                if(cnt2 != sz2) {
                    int cnt = 0;
                    if(bit & 1 and s[i - 1][sz1 - 1 - cnt1] == s[i][cnt2]) {
                        cnt ++;
                    }
                    if(j > 0 and cnt2 > 0 and bit >> (c - 1) & 1 and s[i][cnt2 - 1] == s[i][cnt2]) {
                        cnt ++;
                    }
                    chmax(nx[(bit >> 1) | (1 << (c - 1))], dp[bit] + cnt);
                }
            }
            dp = move(nx);
        }
        rep(j, 1 << c) if(__builtin_popcount(j) != sz2) dp[j] = -inf;
    }
    cout << *max_element(all(dp)) * 2 << endl;
    return 0;
}
accuracy: 0.29411764705882354
time_ms: 30
memory_kb: 3608
final_rank: 16

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define all(v) (v).begin(),(v).end()
#define pb(a) push_back(a)
#define rep(i, n) for(int i=0;i<n;i++)
#define foa(e, v) for(auto&& e : v)
using ll = long long;
const ll MOD7 = 1000000007, MOD998 = 998244353, INF = (1LL << 60);
#define dout(a) cout<<fixed<<setprecision(10)<<a<<endl;

void chmax(int &a, int b) { a = max(a, b); }
int main() {
    cin.tie(0);
    ios::sync_with_stdio(false);
    int h, c; cin >> h >> c;
    vector<string> s(h);
    rep(i, h) cin >> s[i];
    int inf = 1 << 28;
    vector<int> dp(1 << c, -inf);
    rep(bit, 1 << c) {
        vector<int> vec;
        rep(i, c) if(bit >> i & 1) vec.pb(i);
        if((int)vec.size() != (int)s[0].size()) continue;
        string t(c, '.');
        int sz = s[0].size();
        rep(i, sz) t[vec[i]] = s[0][i];
        int cnt = 0;
        rep(j, c - 1) if(t[j] != '.' and t[j] == t[j + 1]) cnt ++;
        dp[bit] = cnt;
    }
    for(int i = 1; i < h; i ++) {
        int sz1 = s[i - 1].size();
        int sz2 = s[i].size();
        rep(j, c) {
            vector<int> nx(1 << c, -inf);
            rep(bit, 1 << c) {
                int mask = (1 << (c - j)) - 1;
                int cnt1 = __builtin_popcount(bit & mask);
                int cnt2 = __builtin_popcount(bit >> (c - j));
                if(cnt1 > sz1 or cnt2 > sz2) continue;
                chmax(nx[(bit >> 1)], dp[bit]);
                if(cnt2 != sz2) {
                    int cnt = 0;
                    if(bit & 1 and s[i - 1][sz1 - 1 - cnt1] == s[i][cnt2]) {
                        cnt ++;
                    }
                    if(cnt2 > 0 and bit >> (c - 1) & 1 and s[i][cnt2 - 1] == s[i][cnt2]) {
                        cnt ++;
                    }
                    chmax(nx[(bit >> 1) | (1 << (c - 1))], dp[bit] + cnt);
                }
            }
            dp = move(nx);
        }
        rep(j, 1 << c) if(__builtin_popcount(j) != sz2) dp[j] = -inf;
    }
    cout << *max_element(all(dp)) * 2 << endl;
    return 0;
}
accuracy: 0.29411764705882354
time_ms: 30
memory_kb: 3508
final_rank: 12

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define all(v) (v).begin(),(v).end()
#define pb(a) push_back(a)
#define rep(i, n) for(int i=0;i<n;i++)
#define foa(e, v) for(auto&& e : v)
using ll = long long;
const ll MOD7 = 1000000007, MOD998 = 998244353, INF = (1LL << 60);
#define dout(a) cout<<fixed<<setprecision(10)<<a<<endl;

void chmax(int &a, int b) { a = max(a, b); }
int main() {
    cin.tie(0);
    ios::sync_with_stdio(false);
    int h, c; cin >> h >> c;
    vector<string> s(h);
    rep(i, h) cin >> s[i];
    int inf = 1 << 28;
    vector<int> dp(1 << c, -inf);
    rep(bit, 1 << c) {
        vector<int> vec;
        rep(i, c) if(bit >> i & 1) vec.pb(i);
        if((int)vec.size() != (int)s[0].size()) continue;
        string t(c, '.');
        int sz = s[0].size();
        rep(i, sz) t[vec[i]] = s[0][i];
        int cnt = 0;
        rep(j, c - 1) if(t[j] != '.' and t[j] == t[j + 1]) cnt ++;
        dp[bit] = cnt;
    }
    for(int i = 1; i < h; i ++) {
        int sz1 = s[i - 1].size();
        int sz2 = s[i].size();
        rep(j, c) {
            vector<int> nx(1 << c, -inf);
            rep(bit, 1 << c) {
                bool ng = 0;
                string t1(c, '.'), t2(c, '_');
                int idx = sz1;
                {
                    rep(k, c - j) {
                        if(bit >> (c - j - k - 1) & 1) {
                            if(idx == 0) {
                                ng = 1;
                                break;
                            }
                            t1[c - k - 1] = s[i - 1][-- idx];
                        }
                    }
                    if(ng) continue;
                    idx = 0;
                    rep(k, j) {
                        if(bit >> (c - j + k) & 1) {
                            if(idx == sz2) {
                                ng = 1;
                                break;
                            }
                            t2[k] = s[i][idx ++];
                        } 
                    }
                    if(ng) continue;
                }
                if(idx != sz2) {
                    int cnt = 0;
                    if(t1[j] == s[i][idx]) cnt ++;
                    if(j > 0 and t2[j - 1] == s[i][idx]) cnt ++; 
                    chmax(nx[(bit >> 1) | (1 << (c - 1))], dp[bit] + cnt);
                }
                {
                    chmax(nx[(bit >> 1)], dp[bit]);
                }
            }
            dp = move(nx);
        }
    }
    cout << *max_element(all(dp)) * 2 << endl;
    return 0;
}
accuracy: 0.058823529411764705
time_ms: 210
memory_kb: 3392
final_rank: 20

code_snippet: #include <bits/stdc++.h>

using namespace std;

#define rep(i, a, b) for (ll i = (ll)(a); i < (ll)(b); i++)
#define rrep(i, a, b) for (ll i = (ll)(b)-1; i >= (ll)(a); i--)
#define ALL(v) (v).begin(), (v).end()
#define UNIQUE(v) sort(ALL(v)), (v).erase(unique(ALL(v)), (v).end())
#define SZ(v) (int)v.size()
#define MIN(v) *min_element(ALL(v))
#define MAX(v) *max_element(ALL(v))
#define LB(v, x) int(lower_bound(ALL(v), (x)) - (v).begin())
#define UB(v, x) int(upper_bound(ALL(v), (x)) - (v).begin())

using uint = unsigned int;
using ll = long long int;
using ull = unsigned long long;
using i128 = __int128_t;
using u128 = __uint128_t;
const int inf = 0x3fffffff;
const ll INF = 0x1fffffffffffffff;

template <typename T> inline bool chmax(T &a, T b) {
    if (a < b) {
        a = b;
        return 1;
    }
    return 0;
}
template <typename T> inline bool chmin(T &a, T b) {
    if (a > b) {
        a = b;
        return 1;
    }
    return 0;
}
template <typename T, typename U> T ceil(T x, U y) {
    assert(y != 0);
    if (y < 0)
        x = -x, y = -y;
    return (x > 0 ? (x + y - 1) / y : x / y);
}
template <typename T, typename U> T floor(T x, U y) {
    assert(y != 0);
    if (y < 0)
        x = -x, y = -y;
    return (x > 0 ? x / y : (x - y + 1) / y);
}
template <typename T> int popcnt(T x) {
    return __builtin_popcountll(x);
}
template <typename T> int topbit(T x) {
    return (x == 0 ? -1 : 63 - __builtin_clzll(x));
}
template <typename T> int lowbit(T x) {
    return (x == 0 ? -1 : __builtin_ctzll(x));
}

template <class T, class U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
    os << "P(" << p.first << ", " << p.second << ")";
    return os;
}
template <typename T> ostream &operator<<(ostream &os, const vector<T> &vec) {
    os << "{";
    for (int i = 0; i < vec.size(); i++) {
        os << vec[i] << (i + 1 == vec.size() ? "" : ", ");
    }
    os << "}";
    return os;
}
template <typename T, typename U>
ostream &operator<<(ostream &os, const map<T, U> &map_var) {
    os << "{";
    for (auto itr = map_var.begin(); itr != map_var.end(); itr++) {
        os << "(" << itr->first << ", " << itr->second << ")";
        itr++;
        if (itr != map_var.end())
            os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
template <typename T> ostream &operator<<(ostream &os, const set<T> &set_var) {
    os << "{";
    for (auto itr = set_var.begin(); itr != set_var.end(); itr++) {
        os << *itr;
        ++itr;
        if (itr != set_var.end())
            os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
#ifdef LOCAL
#define show(...) _show(0, #__VA_ARGS__, __VA_ARGS__)
#else
#define show(...) true
#endif
template <typename T> void _show(int i, T name) {
    cerr << '\n';
}
template <typename T1, typename T2, typename... T3>
void _show(int i, const T1 &a, const T2 &b, const T3 &...c) {
    for (; a[i] != ',' && a[i] != '\0'; i++)
        cerr << a[i];
    cerr << ":" << b << " ";
    _show(i + 1, a, c...);
}

/**
 * @brief template
 */

int main() {
    int N, M;
    cin >> N >> M;
    vector<string> S(N+1);
    S[0] = "";
    rep(i,0,N) cin >> S[i+1];
    vector<ll> DP(1<<M,-INF);
    DP[0] = 0;
    rep(i,1,N+1) {
        rep(j,0,M) {
            vector<ll> NewDP(1<<M,-INF);
            rep(k,0,1<<M) {
                if (DP[k] < 0) continue;
                chmax(NewDP[k&((1<<M)-1-(1<<j))],DP[k]);
                int Left = 0, Right = 0;
                rep(l,0,j) if (k&(1<<l)) Left++;
                rep(l,j,M) if (k&(1<<l)) Right++;
                if (Left >= S[i].size()) continue;
                int Plus = 0;
                if (j != 0) {
                    if (k & (1<<(j-1))) {
                        if (S[i][Left-1] == S[i][Left]) Plus++;
                    }
                }
                if (k & (1<<j)) {
                    if (S[i-1][S[i-1].size()-Right] == S[i][Left]) Plus++;
                }
                chmax(NewDP[k|(1<<j)],DP[k]+Plus);
            }
            swap(DP,NewDP);
        }
        rep(j,0,1<<M) {
            if (popcnt(j) != (int)S[i].size()) DP[j] = -INF;
        }
    }
    ll ANS = -INF;
    rep(i,0,1<<M) chmax(ANS,DP[i]);
    cout << ANS*2 << endl;
}
accuracy: 1
time_ms: 850
memory_kb: 4460
final_rank: 3

code_snippet: #include <bits/stdc++.h>
using namespace std;

int main() {
	// step #1. input
	int R, C;
	cin >> R >> C;
	vector<string> S(R);
	for (int i = 0; i < R; i++) {
		cin >> S[i];
	}

	// step #2. dynamic programming
	const int INF = 1012345678;
	vector<int> dp(1 << C, -INF);
	dp[0] = 0;
	for (int i = 0; i < R * C; i++) {
		int sr = i / C;
		int sc = i % C;
		vector<int> ndp(1 << C, -INF);
		for (int j = 0; j < (1 << C); j++) {
			if (dp[j] != -INF) {
				int s = (j * 2) % (1 << C);
				// case: doesn't put
				ndp[s + 0] = max(ndp[s + 0], dp[j]);
				// case: put
				int idxd = __builtin_popcount(j % (1 << sc));
				int idxu = (sr == 0 ? 0 : S[sr - 1].size() - __builtin_popcount(j / (1 << sc)));
				if (idxd != S[sr].size()) {
					int score = 0;
					if (idxd >= 1 && (j & 1) == 1 && S[sr][idxd - 1] == S[sr][idxd]) {
						score += 1;
					}
					if (((j >> (C - 1)) & 1) == 1 && S[sr - 1][idxu] == S[sr][idxd]) {
						score += 1;
					}
					ndp[s + 1] = max(ndp[s + 1], dp[j] + score);
				}
			}
		}
		if (sc == C - 1) {
			for (int j = 0; j < (1 << C); j++) {
				if (__builtin_popcount(j) != S[sr].size()) {
					ndp[j] = -INF;
				}
			}
		}
		dp = ndp;
	}

	// step #3. calculate answer & output
	int ans = *max_element(dp.begin(), dp.end()) * 2;
	cout << ans << endl;

	return 0;
}
accuracy: 1
time_ms: 740
memory_kb: 3668
final_rank: 2

code_snippet: #include <bits/stdc++.h>
using namespace std;

int main() {
	// step #1. input
	int R, C;
	cin >> R >> C;
	vector<string> S(R);
	for (int i = 0; i < R; i++) {
		cin >> S[i];
	}

	// step #2. dynamic programming
	const int INF = 1012345678;
	vector<int> dp(1 << C, -INF);
	dp[0] = 0;
	for (int i = 0; i < R * C; i++) {
		int sr = i / C;
		int sc = i % C;
		vector<int> ndp(1 << C, -INF);
		for (int j = 0; j < (1 << C); j++) {
			if (dp[j] != -INF) {
				int s = (j * 2) % (1 << C);
				// case: doesn't put
				ndp[s + 0] = max(ndp[s + 0], dp[j]);
				// case: put
				int idxd = __builtin_popcount(s % (1 << sc));
				int idxu = (sr == 0 ? 0 : S[sr - 1].size() - __builtin_popcount(s / (1 << sc)));
				if (idxd != S[sr].size()) {
					int score = 0;
					if (idxd >= 1 && (j & 1) == 1 && S[sr][idxd - 1] == S[sr][idxd]) {
						score += 1;
					}
					if (((j >> (C - 1)) & 1) == 1 && S[sr - 1][idxu] == S[sr][idxd]) {
						score += 1;
					}
					ndp[s + 1] = max(ndp[s + 1], dp[j] + score);
				}
			}
		}
		if (sc == C - 1) {
			for (int j = 0; j < (1 << C); j++) {
				if (__builtin_popcount(j) != S[sr].size()) {
					ndp[j] = -INF;
				}
			}
		}
		dp = ndp;
	}

	// step #3. calculate answer & output
	int ans = *max_element(dp.begin(), dp.end()) * 2;
	cout << ans << endl;

	return 0;
}
accuracy: 0.20588235294117646
time_ms: 20
memory_kb: 3600
final_rank: 17

code_snippet: #line 1 "a.cpp"
/*	author:  Kite_kuma
	created: 2022.06.15 21:43:49 */

#line 2 "SPJ-Library/template/kuma.hpp"

#line 2 "SPJ-Library/template/basic_func.hpp"

#include <algorithm>
#include <cassert>
#include <iostream>
#include <vector>

template <class T0, class T1, class T2>
inline bool in_range(T0 x, T1 lef, T2 rig) {
	return ((lef <= x) && (x < rig));
}

template <class T>
inline bool chmin(T &a, T b) {
	if(a > b) {
		a = b;
		return true;
	}
	return false;
}
template <class T>
inline bool chmax(T &a, T b) {
	if(a < b) {
		a = b;
		return true;
	}
	return false;
}

void Yes(bool flag = true) { std::cout << (flag ? "Yes" : "No") << '\n'; }
void YES(bool flag = true) { std::cout << (flag ? "YES" : "NO") << '\n'; }

template <class T>
void drop(T answer) {
	std::cout << answer << '\n';
	exit(0);
}

template <class T>
void vout(std::vector<T> const &v, bool vertically = 0) {
	if(vertically) {
		for(auto const &a : v) {
			std::cout << a << '\n';
		}
		return;
	}
	for(auto it = v.begin(); it != v.end(); it++) {
		std::cout << (*it);
		if(it != v.end() - 1) {
			std::cout << ' ';
		}
	}
	std::cout << '\n';
	return;
}

inline void print() { std::cout << '\n'; }
template <class T>
inline void print(const T &x) {
	std::cout << x << '\n';
	return;
}
template <typename Head, typename... Tail>
void print(const Head &H, const Tail &... T) {
	std::cout << H << " ";
	print(T...);
}

template <class T>
void add(std::vector<T> &v, T value) {
	for(auto &a : v) a += value;
	return;
}

template <class T>
T greatest_lower_multiple(T x, T d) {
	if(d == 0) return 0;
	if(d < 0) d *= -1;
	T y = x % d;
	if(y < 0) y += d;
	return x - y;
}

template <class T>
T least_upper_multiple(T x, T d) {
	return -greatest_lower_multiple(-x, d);
}

// ceil(a / b);
template <class T>
T dup(T a, T b) {
	assert(b);
	if(b < 0) {
		a *= -1;
		b *= -1;
	}
	return least_upper_multiple(a, b) / b;
}

long long pow_ll(long long a, long long n) {
	assert(n >= 0LL);
	if(n == 0) return 1LL;
	if(a == 0) return 0LL;
	if(a == 1) return 1LL;
	if(a == -1) return (n & 1LL) ? -1LL : 1LL;
	long long res = 1;
	while(n > 1LL) {
		if(n & 1LL) res *= a;
		a *= a;
		n >>= 1;
	}
	return res * a;
}

long long modpow(long long a, long long n, long long mod) {	 // a^n mod
	assert(n >= 0 && mod);
	if(mod == 1) return 0LL;
	long long res = 1;
	a %= mod;
	while(n > 0) {
		if(n & 1) res = res * a % mod;
		a = a * a % mod;
		n >>= 1;
	}
	return res < 0 ? res + mod : res;
}

// return x which satisfies a * x % mod == gcd(a, mod)
// not (mod | a)
long long modinv(long long a, const long long mod) {
	long long b = mod, u = 1, v = 0;
	while(b) {
		long long t = a / b;
		a -= t * b;
		std::swap(a, b);
		u -= t * v;
		std::swap(u, v);
	}
	u %= mod;
	if(u < 0) u += mod;
	return u;
}

template <class T>
int lb(const std::vector<T> &a, const T x) {
	return (int)std::distance(a.begin(), std::lower_bound(a.begin(), a.end(), x));
}
template <class T>
int ub(const std::vector<T> &a, const T x) {
	return (int)std::distance(a.begin(), std::upper_bound(a.begin(), a.end(), x));
}
template <class T>
void unq_sort(std::vector<T> &a) {
	std::sort(a.begin(), a.end());
	a.erase(std::unique(a.begin(), a.end()), a.end());
}
template <class T>
std::vector<int> press(const std::vector<T> &a) {
	std::vector<T> vec = a;
	unq_sort(vec);
	std::vector<int> ret;
	for(const auto &v : a) ret.push_back(lb(vec, v));
	return ret;
}
#line 1 "SPJ-Library/template/header.hpp"
#include <bits/stdc++.h>
#line 2 "SPJ-Library/template/io.hpp"

#line 4 "SPJ-Library/template/io.hpp"

#line 8 "SPJ-Library/template/debug.hpp"

#line 3 "SPJ-Library/template/constants.hpp"

constexpr int inf = 1000'000'000;
constexpr long long INF = 1'000'000'000'000'000'000LL;
constexpr int mod_1000000007 = 1000000007;
constexpr int mod_998244353 = 998244353;
const long double pi = acosl(-1.);
constexpr int dx[8] = {1, 0, -1, 0, 1, -1, -1, 1};
constexpr int dy[8] = {0, 1, 0, -1, 1, 1, -1, -1};
#line 10 "SPJ-Library/template/debug.hpp"

namespace viewer {

template <typename T, typename U>
void view(const std::pair<T, U> &p);

template <class T0, class T1, class T2>
void view(const std::tuple<T0, T1, T2> &p);

template <class T0, class T1, class T2, class T3>
void view(const std::tuple<T0, T1, T2, T3> &p);

void view(const long long &e);

void view(const int &e);

template <typename T>
void view(const T &e);

template <typename T>
void view(const std::set<T> &s);

template <typename T>
void view(const std::unordered_set<T> &s);

template <typename T>
void view(const std::multiset<T> &s);

template <typename T>
void view(const std::unordered_multiset<T> &s);

template <typename T>
void view(const std::vector<T> &v);

template <typename T, std::size_t ary_size>
void view(const std::array<T, ary_size> &v);

template <typename T>
void view(const std::vector<std::vector<T>> &vv);

template <typename T, typename U>
void view(const std::vector<std::pair<T, U>> &v);

template <class T0, class T1, class T2>
void view(const std::vector<std::tuple<T0, T1, T2>> &v);

template <class T0, class T1, class T2, class T3>
void view(const std::vector<std::tuple<T0, T1, T2, T3>> &v);

template <typename map_type>
void view_map_container(const map_type &m);

template <typename T, typename U>
void view(const std::map<T, U> &m);

template <typename T, typename U>
void view(const std::unordered_map<T, U> &m);

template <typename container_type>
void view_container(const container_type &c, bool vertically = false) {
	typename container_type::const_iterator begin = c.begin();
	const typename container_type::const_iterator end = c.end();
	if(vertically) {
		std::cerr << "{\n";
		while(begin != end) {
			std::cerr << '\t';
			view(*(begin++));
			if(begin != end) std::cerr << ',';
			std::cerr << '\n';
		}
		std::cerr << '}';
		return;
	}
	std::cerr << "{ ";
	while(begin != end) {
		view(*(begin++));
		if(begin != end) std::cerr << ',';
		std::cerr << ' ';
	}
	std::cerr << '}';
}

template <typename T, typename U>
void view(const std::pair<T, U> &p) {
	std::cerr << '(';
	view(p.first);
	std::cerr << ", ";
	view(p.second);
	std::cerr << ')';
}

template <class T0, class T1, class T2>
void view(const std::tuple<T0, T1, T2> &p) {
	std::cerr << '(';
	view(std::get<0>(p));
	std::cerr << ", ";
	view(std::get<1>(p));
	std::cerr << ", ";
	view(std::get<2>(p));
	std::cerr << ')';
}

template <class T0, class T1, class T2, class T3>
void view(const std::tuple<T0, T1, T2, T3> &p) {
	std::cerr << '(';
	view(std::get<0>(p));
	std::cerr << ", ";
	view(std::get<1>(p));
	std::cerr << ", ";
	view(std::get<2>(p));
	std::cerr << ", ";
	view(std::get<3>(p));
	std::cerr << ')';
}

void view(const long long &e) {
	if(e == INF)
		std::cerr << "INF";
	else if(e == -INF)
		std::cerr << "-INF";
	else
		std::cerr << e;
}

void view(const int &e) {
	if(e == inf)
		std::cerr << "inf";
	else if(e == -inf)
		std::cerr << "-inf";
	else
		std::cerr << e;
}

template <typename T>
void view(const T &e) {
	std::cerr << e;
}

template <typename T>
void view(const std::set<T> &s) {
	view_container(s);
}

template <typename T>
void view(const std::unordered_set<T> &s) {
	view_container(s);
}

template <typename T>
void view(const std::multiset<T> &s) {
	view_container(s);
}

template <typename T>
void view(const std::unordered_multiset<T> &s) {
	view_container(s);
}

template <typename T>
void view(const std::vector<T> &v) {
	view_container(v);
}

template <typename T, std::size_t ary_size>
void view(const std::array<T, ary_size> &v) {
	view_container(v);
}

template <typename T>
void view(const std::vector<std::vector<T>> &vv) {
	view_container(vv, true);
}

template <typename T, typename U>
void view(const std::vector<std::pair<T, U>> &v) {
	view_container(v, true);
}

template <class T0, class T1, class T2>
void view(const std::vector<std::tuple<T0, T1, T2>> &v) {
	view_container(v, true);
}

template <class T0, class T1, class T2, class T3>
void view(const std::vector<std::tuple<T0, T1, T2, T3>> &v) {
	view_container(v, true);
}

template <typename map_type>
void view_map_container(const map_type &m) {
	std::cerr << "{\n";
	for(typename map_type::const_iterator it = m.begin(); it != m.end(); it++) {
		std::cerr << "\t[";
		view(it->first);
		std::cerr << "] : ";
		view(it->second);
		std::cerr << '\n';
	}
	std::cerr << "}";
}

template <typename T, typename U>
void view(const std::map<T, U> &m) {
	view_map_container(m);
}

template <typename T, typename U>
void view(const std::unordered_map<T, U> &m) {
	view_map_container(m);
}

}  // namespace viewer

// when compiling : g++ foo.cpp -DLOCAL
#ifdef LOCAL
void debug_out() {}
template <typename T>
void debug_out(const T &x) {
	viewer::view(x);
}
template <typename Head, typename... Tail>
void debug_out(const Head &H, const Tail &... T) {
	viewer::view(H);
	std::cerr << ", ";
	debug_out(T...);
}
#define debug(...)                                                \
	do {                                                          \
		std::cerr << __LINE__ << " [" << #__VA_ARGS__ << "] : ["; \
		debug_out(__VA_ARGS__);                                   \
		std::cerr << "]\n";                                       \
	} while(0)
#else
#define debug(...) (void(0))
#endif
#line 2 "SPJ-Library/template/scanner.hpp"

#line 6 "SPJ-Library/template/scanner.hpp"

namespace scanner {
template <class T>
void scan(T &a) {
	std::cin >> a;
}

template <class T, class L>
void scan(std::pair<T, L> &p) {
	scan(p.first);
	scan(p.second);
}

template <class T0, class T1, class T2>
void scan(std::tuple<T0, T1, T2> &p) {
	T0 t0;
	T1 t1;
	T2 t2;
	scan(t0);
	scan(t1);
	scan(t2);
	p = std::make_tuple(t0, t1, t2);
}

template <class T0, class T1, class T2, class T3>
void scan(std::tuple<T0, T1, T2, T3> &p) {
	T0 t0;
	T1 t1;
	T2 t2;
	T3 t3;
	scan(t0);
	scan(t1);
	scan(t2);
	scan(t3);
	p = std::make_tuple(t0, t1, t2, t3);
}

template <class T>
void scan(std::vector<T> &a) {
	for(auto &i : a) scan(i);
}

void INPUT() {}
template <class Head, class... Tail>
void INPUT(Head &head, Tail &... tail) {
	scan(head);
	INPUT(tail...);
}
}  // namespace scanner
#line 7 "SPJ-Library/template/io.hpp"

#define VEC(type, name, size) \
	vector<type> name(size);  \
	scanner::INPUT(name)
#define VVEC(type, name, h, w)                     \
	vector<vector<type>> name(h, vector<type>(w)); \
	scanner::INPUT(name)
#define INT(...)     \
	int __VA_ARGS__; \
	scanner::INPUT(__VA_ARGS__)
#define LL(...)            \
	long long __VA_ARGS__; \
	scanner::INPUT(__VA_ARGS__)
#define STR(...)        \
	string __VA_ARGS__; \
	scanner::INPUT(__VA_ARGS__)
#define CHR(...)      \
	char __VA_ARGS__; \
	scanner::INPUT(__VA_ARGS__)
#define DBL(...)        \
	double __VA_ARGS__; \
	scanner::INPUT(__VA_ARGS__)
#define LD(...)              \
	long double __VA_ARGS__; \
	scanner::INPUT(__VA_ARGS__)
#define TPL3(type0, type1, type2, name)   \
	std::tuple<type0, type1, type2> name; \
	scanner::INPUT(name);
#define TPL4(type0, type1, type2, type3, name)   \
	std::tuple<type0, type1, type2, type3> name; \
	scanner::INPUT(name);

template <typename T1, typename T2>
std::istream &operator>>(std::istream &is, std::pair<T1, T2> &p) {
	is >> p.first >> p.second;
	return is;
}

template <typename T1, typename T2>
std::ostream &std::operator<<(std::ostream &os, const std::pair<T1, T2> &p) {
	os << p.first << ' ' << p.second;
	return os;
}
template <class T>
std::ostream &std::operator<<(std::ostream &os, const std::vector<T> &v) {
	for(typename std::vector<T>::const_iterator it = v.begin(); it != v.end(); it++) {
		if(it != v.begin()) std::cerr << ' ';
		os << *it;
	}
	return os;
}

struct fast_io {
	fast_io() {
		std::ios::sync_with_stdio(false);
		std::cin.tie(nullptr);
		std::cout << std::fixed << std::setprecision(15);
		srand((unsigned)time(NULL));
	}
} fast_io_;
#line 2 "SPJ-Library/template/macros.hpp"

#define foa(s, v) for(auto &s : v)
#define all(v) (v).begin(), (v).end()
#define rall(v) (v).rbegin(), (v).rend()
#define pcnt(n) __builtin_popcountll((long long)n)

#define REPname(a, b, c, d, e, ...) e
#define rep(...) REPname(__VA_ARGS__, REP3, REP2, REP1, REP0)(__VA_ARGS__)
#define REP0(x) for(int Counter_in_rep_macro = 0; Counter_in_rep_macro < (x); ++Counter_in_rep_macro)
#define REP1(i, x) for(int i = 0; i < (x); ++i)
#define REP2(i, l, r) for(int i = (l); i < (r); ++i)
#define REP3(i, l, r, c) for(int i = (l); i < (r); i += (c))
#define DREPname(a, b, c, d, e, ...) e
#define drep(...) DREPname(__VA_ARGS__, DREP3, DREP2, DREP1)(__VA_ARGS__)
#define DREP1(i, x) for(int i = (x)-1; i >= 0; --i)
#define DREP2(i, l, r) for(int i = (r)-1; i >= (l); --i)
#define DREP3(i, l, r, c) for(int i = (r)-1; i >= (l); i -= (c))

using ll = long long;
using ld = long double;
using ull = unsigned long long;
using vi = std::vector<int>;
using vvi = std::vector<std::vector<int>>;
using vvvi = std::vector<std::vector<std::vector<int>>>;
using vll = std::vector<ll>;
using vvll = std::vector<vll>;
using vvvll = std::vector<vvll>;
template <class T = ll>
using V = std::vector<T>;
template <class T = ll>
using VV = V<V<T>>;
template <class T = ll>
using VVV = V<V<V<T>>>;
template <class T = ll>
using pqup = std::priority_queue<T, std::vector<T>, std::greater<T>>;
template <class T = ll>
using pqdn = std::priority_queue<T>;
#line 7 "SPJ-Library/template/kuma.hpp"

using namespace std;
#line 5 "a.cpp"

int main() {
	int n;
	cin >> n;
	int width;
	cin >> width;
	VEC(string, s, n);
	const char fin = '$';
	foa(t, s) t += fin;
	const int datasize = 1 << width;
	vector<int> res(datasize, -inf);
	res[0] = 0;
	rep(row, n) {
		rep(col, width) {
			const int samerow_mask = (1 << col) - 1;
			vector<int> tmp(datasize, -inf);
			rep(bits, datasize) {
				int pre_result = res[bits];
				if(pre_result < 0) continue;
				int nxtbit = (bits << 1) % datasize;
				chmax(tmp[nxtbit], pre_result);
				const int samerow = samerow_mask & bits;
				const int samerow_count = pcnt(samerow);
				const char nxtch = s[row][samerow_count];
				if(nxtch == fin) continue;
				if(samerow & 1) {  // left is filled
					if(s[row][samerow_count - 1] == nxtch) {
						pre_result++;
					}
				}
				if(bits & (datasize >> 1)) {
					const int uprow_count = pcnt(bits) - samerow_count;
					const int uplen = int(s[row - 1].size()) - 1;
					if(nxtch == s[row - 1][uplen - uprow_count]) {
						pre_result++;
					}
				}
				chmax(tmp[nxtbit | 1], pre_result);
			}
			swap(res, tmp);
		}
		rep(bits, datasize) {
			if(pcnt(bits) != int(s[row].size()) - 1) {
				res[bits] = -inf;
			}
		}
	}
	int ans = *max_element(all(res));
	drop(ans * 2);
	return 0;
}
accuracy: 1
time_ms: 510
memory_kb: 3892
final_rank: 1