Problem:
団子職人(Dango Maker)
あなたは団子を作る職人である．今，あなたは団子に串を刺そうとしているところである．
団子は，縦
N
行，横
M
列に仕切られたマスの中に配置されている．各マスには団子が1 個ずつ入っている．それぞれの団子には，赤(R)，緑(G)， 白(W) のいずれかの色が付いている．あなたは，左から右の方向，または，上から下の方向に連続する3 マスから団子を取り出し，この順に1 本の串にちょうど3個刺すことができる．
今あなたは，赤，緑，白の団子が1 個ずつこの順に刺さった串を可能な限り多く作りたい．串に刺す順番は，マスから取り出した順番と同じでなければならない．また，同じ団子に2 本以上の串を刺すことはできない．
あなたは，団子が刺さった串を最大何本作ることができるだろうか．
課題
マスの中に配置された団子の色の情報が与えられたとき，赤，緑，白の団子が1 個ずつこの順に刺さった串が最大何本作れるかを求めるプログラムを作成せよ．
入力
標準入力から以下の入力を読み込め．
1 行目には，整数
N
と
M
が空白を区切りとして書かれている．
続く
N
行のうちの
i
行目(
1 \leq i \leq N
) には，R, G, W からなる長さ
M
の文字列が書かれている．この文字列の
j
文字目(
1 \leq j \leq M
) は，上から
i
行目，左から
j
列目のマスの団子の色を表す．
出力
標準出力に，団子が刺さった串の本数の最大値を1 行で出力せよ．
制限
すべての入力データは以下の条件を満たす．
1 \leq N \leq 3 000．
1 \leq M \leq 3 000．
入出力例
入力例1
3 4
RGWR
GRGG
RGWW
出力例1
3
次のように串に刺すことで，団子が刺さった串を3 本作ることができる．
上から1 行目，左から1 列目の団子から右方向に3 個の団子を取り出し，この順に串に刺す．
上から1 行目，左から4 列目の団子から下方向に3 個の団子を取り出し，この順に串に刺す．
上から3 行目，左から1 列目の団子から右方向に3 個の団子を取り出し，この順に串に刺す．
4 本以上の串を作ることはできないので，3 を出力する．
入力例2
4 4
RGWR
GRRG
WGGW
WWWR
出力例2
4
次のように串に刺すことで，団子が刺さった串を4 本作ることができる．
上から1 行目，左から1 列目の団子から右方向に3 個の団子を取り出し，この順に串に刺す．
上から1 行目，左から4 列目の団子から下方向に3 個の団子を取り出し，この順に串に刺す．
上から2 行目，左から2 列目の団子から下方向に3 個の団子を取り出し，この順に串に刺す．
上から2 行目，左から3 列目の団子から下方向に3 個の団子を取り出し，この順に串に刺す．
5 本以上の串を作ることはできないので，4 を出力する．
入力例3
5 5
RGRGW
GRRGW
WGGWR
RWRGW
RGWGW
出力例3
6
情報オリンピック日本委員会作 『第17 回日本情報オリンピック(JOI 2017/2018) 本選』

Submitted solutions:

code_snippet: #include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define MOD 1000000007
#define EPS 0.000000001

#define NUM 3000

enum Type {
    TATE,
    YOKO,
    NONE,
};

int H, W;
int dp[3][NUM + 1];
char base_map[NUM][NUM + 1];

bool rangeCheck(int row, int col) {
    return (row >= 0 && row < H && col >= 0 && col < W);
}

int calc(int start_row, int start_col) {
    int ret = 0;

    for (int col = start_col; col < W; col++) {
        dp[TATE][col] = 0;
        dp[YOKO][col] = 0;
        dp[NONE][col] = 0;
    }

    int row = start_row;
    for (int col = start_col; col < W && row >= 0; col++) {
        if (base_map[row][col] != 'G') {
            if (col != start_col) {
                dp[NONE][col] = max(dp[NONE][col - 1], max(dp[TATE][col - 1], dp[YOKO][col - 1]));
            }
        } else {
            if (rangeCheck(row - 1, col) && base_map[row - 1][col] == 'R' && rangeCheck(row + 1, col) && base_map[row + 1][col] == 'W') {
                dp[TATE][col] = (col == start_col) ? 1 : max(dp[TATE][col - 1], dp[NONE][col - 1]) + 1;
                ret = max(ret, dp[TATE][col]);
            }
            if (rangeCheck(row, col - 1) && base_map[row][col - 1] == 'R' && rangeCheck(row, col + 1) && base_map[row][col + 1] == 'W') {
                dp[YOKO][col] = (col == start_col) ? 1 : max(dp[YOKO][col - 1], dp[NONE][col - 1]) + 1;
                ret = max(ret, dp[YOKO][col]);
            }
            if (col != start_col) {
                dp[NONE][col] = max(dp[NONE][col - 1], max(dp[TATE][col - 1], dp[YOKO][col - 1]));
            }
        }
        row--;
    }
    return ret;
}

int main() {
    cin >> H >> W;

    for (int row = 0; row < H; row++) {
        cin >> base_map[row];
    }

    int ans = 0;
    for (int row = 1; row < H; row++) {
        ans += calc(row, 0);
    }
    for (int col = 1; col < W; col++) {
        ans += calc(H - 1, col);
    }

    cout << ans << endl;

    return 0;
}
accuracy: 1
time_ms: 170
memory_kb: 12300
final_rank: 2

code_snippet: #pragma GCC optimize("Ofast")
#include <bits/stdc++.h>
using namespace std;
typedef long long int ll;
typedef unsigned long long int ull;

mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());
ll myRand(ll B) { return (ull)rng() % B; }

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    int h, w;
    cin >> h >> w;
    vector<string> s(h);
    for (int i = 0; i < h; i++) {
        cin >> s[i];
    }
    auto get = [&](int x, int y) -> int {
        if (0 <= x and x < h and 0 <= y and y < w) {
            if (s[x][y] == 'R') return 0;
            else if (s[x][y] == 'G') return 1;
            else if (s[x][y] == 'W') return 2;
            else return -1;
        }
        return -1;
    };
    using P = pair<int, int>;
    vector<vector<P>> v(h + w);
    for (int j = 0; j < w; j++) {
        for (int i = 0; i < h; i++) {
            v[i + j].push_back({i, j});
        }
    }
    int res = 0;
    for (int _ = 0; _ < v.size(); _++) {
        int n = v[_].size();
        vector<vector<int>> dp(1 << 2, vector<int>(1 << 2, -1));
        dp[0][0] = 0;
        for (int i = 0; i < n; i++) {
            vector<vector<int>> ndp(1 << 2, vector<int>(1 << 2, -1));
            int x = v[_][i].first, y = v[_][i].second;
            for (int j = 0; j < (1 << 2); j++) {
                for (int k = 0; k < (1 << 2); k++) {
                    if (dp[j][k] == -1) continue;
                    // 使わない
                    ndp[j / 2][k / 2] = max(ndp[j / 2][k / 2], dp[j][k]);
                    // 使う
                    if (get(x, y) == 0) {
                        // 縦
                        if (get(x + 1, y) == 1 and (j & 1) == 0) {
                            if (get(x + 2, y) == 2 and (k & 1) == 0) {
                                ndp[j / 2][k / 2] = max(ndp[j / 2][k / 2], dp[j][k] + 1);
                            }
                        }
                        // 横
                        if (get(x, y + 1) == 1 and (j & 2) == 0) {
                            if (get(x, y + 2) == 2 and (k & 4) == 0) {
                                ndp[j / 2 + 1][k / 2 + 2] = max(ndp[j / 2 + 1][k / 2 + 2], dp[j][k] + 1);
                            }
                        }
                    }
                }
            }

            swap(dp, ndp);
        }
        int ad = 0;
        for (int i = 0; i < (1 << 2); i++) {
            for (int j = 0; j < (1 << 2); j++) {
                ad = max(ad, dp[i][j]);
            }
        }
        res += ad;
    }
    cout << res << endl;
}
accuracy: 1
time_ms: 970
memory_kb: 105516
final_rank: 13

code_snippet: #pragma GCC optimize("Ofast")
#include <bits/stdc++.h>
using namespace std;
typedef long long int ll;
typedef unsigned long long int ull;

mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());
ll myRand(ll B) { return (ull)rng() % B; }

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    int h, w;
    cin >> h >> w;
    vector<string> s(h);
    for (int i = 0; i < h; i++) {
        cin >> s[i];
    }
    auto get = [&](int x, int y) -> int {
        if (0 <= x and x < h and 0 <= y and y < w) {
            if (s[x][y] == 'R') return 0;
            else if (s[x][y] == 'G') return 1;
            else if (s[x][y] == 'W') return 2;
            else return -1;
        }
        return -1;
    };
    using P = pair<int, int>;
    vector<vector<P>> v(h + w);
    for (int j = 0; j < w; j++) {
        for (int i = 0; i < h; i++) {
            v[i + j].push_back({i, j});
        }
    }
    int res = 0;
    for (int _ = 0; _ < v.size(); _++) {
        int n = v[_].size();
        vector<vector<int>> dp(1 << 2, vector<int>(1 << 3, -1));
        dp[0][0] = 0;
        for (int i = 0; i < n; i++) {
            vector<vector<int>> ndp(1 << 2, vector<int>(1 << 3, -1));
            int x = v[_][i].first, y = v[_][i].second;
            for (int j = 0; j < (1 << 2); j++) {
                for (int k = 0; k < (1 << 3); k++) {
                    if (dp[j][k] == -1) continue;
                    // 使わない
                    ndp[j / 2][k / 2] = max(ndp[j / 2][k / 2], dp[j][k]);
                    // 使う
                    if (get(x, y) == 0) {
                        // 縦
                        if (get(x + 1, y) == 1 and (j & 1) == 0) {
                            if (get(x + 2, y) == 2 and (k & 1) == 0) {
                                ndp[j / 2][k / 2] = max(ndp[j / 2][k / 2], dp[j][k] + 1);
                            }
                        }
                        // 横
                        if (get(x, y + 1) == 1 and (j & 2) == 0) {
                            if (get(x, y + 2) == 2 and (k & 4) == 0) {
                                ndp[j / 2 + 1][k / 2 + 2] = max(ndp[j / 2 + 1][k / 2 + 2], dp[j][k] + 1);
                            }
                        }
                    }
                }
            }

            swap(dp, ndp);
        }
        int ad = 0;
        for (int i = 0; i < (1 << 2); i++) {
            for (int j = 0; j < (1 << 3); j++) {
                ad = max(ad, dp[i][j]);
            }
        }
        res += ad;
    }
    cout << res << endl;
}
accuracy: 1
time_ms: 1150
memory_kb: 105508
final_rank: 18

code_snippet: #include<bits/stdc++.h>
using namespace std;
int n, m;
char c[3010][3010]={};
int rgw[3010][3010]={};
int dp[3010][3010][4]={};
int main(){
    cin >> n >> m;
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++) scanf(" %c", &c[i][j]);
    }
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            if(i>1 && i<n && c[i-1][j]=='R' && c[i][j]=='G' && c[i+1][j]=='W') rgw[i][j] += 1;
            if(j>1 && j<m && c[i][j-1]=='R' && c[i][j]=='G' && c[i][j+1]=='W') rgw[i][j] += 2;
        }
    }
    int ans=0;
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            for(int k=0;k<4;k++){
                dp[i][j][0] = max(dp[i][j][0], dp[i-1][j+1][k]);
                if(k!=2 && rgw[i][j]&1==1) dp[i][j][1] = max(dp[i][j][1], dp[i-1][j+1][k]+1);
                if(k!=1 && rgw[i][j]>1) dp[i][j][2] = max(dp[i][j][2], dp[i-1][j+1][k]+1);
            }
            if(i==n || j==1) ans += max(max(dp[i][j][0], dp[i][j][1]), max(dp[i][j][2], dp[i][j][3]));
        }
    }
    cout << ans << endl;
    return(0);
}
accuracy: 1
time_ms: 430
memory_kb: 188332
final_rank: 17

code_snippet: #include<bits/stdc++.h>
using namespace std;
int n, m;
char c[3010][3010]={};
int rgw[3010][3010]={};
int dp[3010][3010][4]={};
int main(){
    cin >> n >> m;
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++) scanf(" %c", &c[i][j]);
    }
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            if(i>1 && i<n && c[i-1][j]=='R' && c[i][j]=='G' && c[i+1][j]=='W') rgw[i][j] += 1;
            if(j>1 && j<m && c[i][j-1]=='R' && c[i][j]=='G' && c[i][j+1]=='W') rgw[i][j] += 2;
        }
    }
    int ans=0;
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            for(int k=0;k<4;k++){
                dp[i][j][0] = max(dp[i][j][0], dp[i-1][j+1][k]);
                if(k!=2 && rgw[i][j]%2==1) dp[i][j][1] = max(dp[i][j][1], dp[i-1][j+1][k]+1);
                if(k!=1 && rgw[i][j]>1) dp[i][j][2] = max(dp[i][j][2], dp[i-1][j+1][k]+1);
            }
            if(i==n || j==1) ans += max(max(dp[i][j][0], dp[i][j][1]), max(dp[i][j][2], dp[i][j][3]));
        }
    }
    cout << ans << endl;
    return(0);
}
accuracy: 1
time_ms: 420
memory_kb: 188332
final_rank: 16

code_snippet: #include<bits/stdc++.h>
using namespace std;
int n, m;
char c[3010][3010]={};
int rgw[3010][3010]={};
int dp[2][3010][4]={};
int main(){
    cin >> n >> m;
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++) cin >> c[i][j];
    }
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            if(i>1 && i<n && c[i-1][j]=='R' && c[i][j]=='G' && c[i+1][j]=='W') rgw[i][j] += 1;
            if(j>1 && j<m && c[i][j-1]=='R' && c[i][j]=='G' && c[i][j+1]=='W') rgw[i][j] += 2;
        }
    }
    int ans=0;
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            for(int k=0;k<4;k++){
                dp[1][j][0] = max(dp[1][j][0], dp[0][j+1][k]);
                if(k!=2 && rgw[i][j]%2==1) dp[1][j][1] = max(dp[1][j][1], dp[0][j+1][k]+1);
                if(k!=1 && rgw[i][j]>1) dp[1][j][2] = max(dp[1][j][2], dp[0][j+1][k]+1);
            }
            if(i==n || j==1) ans += max(max(dp[1][j][0], dp[1][j][1]), max(dp[1][j][2], dp[1][j][3]));
            //cout << max(max(dp[1][j][0], dp[1][j][1]), max(dp[1][j][2], dp[1][j][3]));
        }
        //cout << endl;
        memset(dp[0], 0, sizeof(dp[0]));
        swap(dp[0], dp[1]);
    }
    cout << ans << endl;
    return(0);
}
accuracy: 1
time_ms: 490
memory_kb: 47248
final_rank: 10

code_snippet: #include<bits/stdc++.h>
using namespace std;
int main(){
    int n, m, ans=0;
    char c[3010][3010]={};
    int dp[3010][3010]={};
    cin >> n >> m;
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++) cin >> c[i][j];
    }
    for(int i=3;i<=n+1;i++){
        for(int j=1;i-j>0;j++){
            int prev = dp[i-j+1][j-1];
            dp[i-j][j] = prev;
            if(c[i-j][j] == 'G'){
                if(c[i-j-1][j]=='R' && c[i-j+1][j]=='W') dp[i-j][j] = prev+1;
                else if(c[i-j][j-1]=='R' && c[i-j][j+1]=='W' && !(c[i-j+1][j-1]=='G' && c[i-j+2][j-1]=='W')) dp[i-j][j] = prev+1;
            }
        }
    }
    for(int i=2;i<m;i++){
        for(int j=1;i+j<=m+1;j++){
            int prev = dp[n+2-j][i+j-2];
            dp[n+1-j][i+j-1] = prev;
            if(c[n+1-j][i+j-1] == 'G'){
                if(c[n-j][i+j-1]=='R' && c[n+2-j][i+j-1]=='W') dp[n+1-j][i+j-1] = prev+1;
                else if(c[n+1-j][i+j-2]=='R' && c[n+1-j][i+j]=='W' && !(c[n+2-j][i+j-2]=='G' && c[n+3-j][i+j-2]=='W')) dp[n+1-j][i+j-1] = prev+1;
            }
        }
    }
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            if(i==1 || j==m) ans += dp[i][j];
            //cout << dp[i][j];
        }
        //cout << endl;
    }
    cout << ans << endl;
    return(0);
}
accuracy: 0.08602150537634409
time_ms: 10
memory_kb: 47316
final_rank: 20

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

int main() {
  int n, m;
  std::cin >> n >> m;

  std::vector< std::string > ss(n);
  for (auto &s: ss) std::cin >> s;

  auto check_v = [&](int y, int x) {
    if (y < 0 or n <= y) return false;
    if (x < 0 or m <= x) return false;
    if (x + 2 >= m) return false;
    if (ss[y][x + 0] != 'R') return false;
    if (ss[y][x + 1] != 'G') return false;
    if (ss[y][x + 2] != 'W') return false;
    return true;
  };

  auto check_h = [&](int y, int x) {
    if (y < 0 or n <= y) return false;
    if (x < 0 or m <= x) return false;
    if (y + 2 >= n) return false;
    if (ss[y + 0][x] != 'R') return false;
    if (ss[y + 1][x] != 'G') return false;
    if (ss[y + 2][x] != 'W') return false;
    return true;
  };

  int ans = 0;
  for (int d = 1; d <= n + m - 1; d++) {
    auto dp = std::vector(4, 0);

    //auto dp = std::vector(d, std::vector(2, std::vector(2, 0)));

    for (int i = 0; i < d; i++) {
      int y = d - 1 - i;
      int x = i;

      auto ndp = std::vector(4, 0);
      ndp[0] = std::max(dp[0], dp[1]);
      ndp[1] = std::max(dp[2], dp[3]);
      // for (int j = 0; j < 2; j++) {
      //   if (i) dp[i][0][j] = std::max(dp[i - 1][j][0], dp[i - 1][j][1]);
      // }

      if (check_v(y, x)) {
        for (int j = 0; j < 2; j++) for (int k = 0; k < 2; k++) {
          ndp[2 + j] = std::max(ndp[2 + j], dp[j << 1 | k] + 1);
          // int val = (i == 0 ? 1 : dp[i - 1][j][k] + 1);
          // dp[i][true][j] = std::max(dp[i][true][j], val);
        }
      }

      if (check_h(y, x)) {
        ndp[0] = std::max(ndp[0], dp[0] + 1);
        // dp[i][false][false] = std::max(dp[i][false][false], (i ? dp[i - 1][false][false] : 0) + 1);
      }

      dp = std::move(ndp);
    }

    int max = 0;
    for (int j = 0; j < 2; j++) for (int k = 0; k < 2; k++) {
      max = std::max(max, dp[j << 1 | k]);
    }

    ans += max;
  }

  std::cout << ans << std::endl;
}
accuracy: 1
time_ms: 400
memory_kb: 14836
final_rank: 7

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

using namespace std;

int func(){
    int n;
    int m;
    cin >> n >> m;
    vector<string> table(n);
    for(auto &i:table)cin >> i;

    auto check = [&](int y,int x,char c) -> bool{
        if(y < 0 or y >= n or x < 0 or x >= m)return false;
        return table[y][x] == c;
    };

    int res = 0;
    for(int i=0;i<n+m-1;++i){
        vector<int> dp((n+m+10)*4,-1);
        function<int(int,bool,bool)> rec = [&](int p,bool used_red,bool used_white) -> int {
            int y = p;
            int x = i - p;
            if(x < 0 or y >= n)return 0;
            int &it = dp[(p * 2 + used_red) * 2 + used_white];
            if(it >= 0)return it;
            it = 0;
            if(x >= m or table[y][x] != 'G'){
                it = rec(p+1,false,false);
            }else{
                bool can_vertical = (not used_red) and check(y-1,x,'R') and check(y+1,x,'W');
                bool can_horizontal = (not used_white) and check(y,x-1,'R') and check(y,x+1,'W');
                if(can_vertical){
                    it = max(it, rec(p+1,false, true) + 1);
                }
                if(can_horizontal){
                    it = max(it, rec(p+1,true, false) + 1);
                }
                it = max(it, rec(p+1,false,false));
            }
            return it;
        };
        int ans = rec(0,false,false);
        res += rec(0,false,false);
    }
    return res;
}

int main(){
    cout << func() << endl;
}
accuracy: 1
time_ms: 320
memory_kb: 14660
final_rank: 4

code_snippet: #include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <ctime>
#include <cctype>

#include <algorithm>
#include <functional>
#include <set>
#include <map>
#include <vector>
#include <iostream>
#include <limits>
#include <numeric>

#define LOG(FMT...) fprintf(stderr, FMT)

using namespace std;

typedef long long ll;
typedef unsigned long long ull;

const int N = 3010;

int n, m, ans, cnt;
char s[N][N];
bool ab[N][2];
int dp[N][3];

void prog() {
    for (int i = 1; i <= cnt + 1; ++i) {
        dp[i][2] = *max_element(dp[i - 1], dp[i - 1] + 3);
        dp[i][0] = ab[i][0] ? (max(dp[i - 1][0], dp[i - 1][2]) + 1) : 0;
        dp[i][1] = ab[i][1] ? (max(dp[i - 1][1], dp[i - 1][2]) + 1) : 0;
    }
    ans += dp[cnt + 1][2];
}

int main() {

    scanf("%d%d", &n, &m);
    for (int i = 1; i <= n; ++i) scanf("%s", s[i] + 1);
    for (int k = 2; k <= n + m; ++k) {
        for (int i = 1; i <= n; ++i) {
            int j = k - i;
            if (j < 1 || j > m)
                continue;
            if (s[i][j] != 'G') {
                if (cnt)
                    prog();
                cnt = 0;
            } else {
                ++cnt;
                ab[cnt][0] = s[i - 1][j] == 'R' && s[i + 1][j] == 'W';
                ab[cnt][1] = s[i][j - 1] == 'R' && s[i][j + 1] == 'W';
            }
        }
        if (cnt)
            prog();
        cnt = 0;
    }
    printf("%d\n", ans);

    return 0;
}
accuracy: 1
time_ms: 120
memory_kb: 12068
final_rank: 1

code_snippet: #include <iostream>
#include <algorithm>
#include <vector>
#include <string>
#include <functional>

constexpr int INF = 1 << 30;

template <class T>
std::vector<T> vec(int len, T elem) { return std::vector<T>(len, elem); }

void solve() {
    int n, m;
    std::cin >> n >> m;

    std::vector<std::string> ss(n);
    for (auto& s : ss) std::cin >> s;

    // (x, y)から(t ? 縦 : 横)に取れるか判定
    auto judge = [&](int x, int y, int t) {
        if (t == 0) {
            for (int dx = 0; dx < 3; ++dx) {
                int nx = x + dx,
                    ny = y;
                if (nx < 0 || n <= nx || ny < 0 || m <= ny ||
                    ss[nx][ny] != "RGW"[dx]) return false;
            }
        } else {
            for (int dy = 0; dy < 3; ++dy) {
                int nx = x,
                    ny = y + dy;
                if (nx < 0 || n <= nx || ny < 0 || m <= ny ||
                    ss[nx][ny] != "RGW"[dy]) return false;
            }
        }
        return true;
    };

    int ans = 0;
    auto dp = vec(2, vec(2, 0));
    auto ndp = dp;

    // (sx, 0)から斜め上に見る
    for (int sx = 0; sx < n + m; ++sx) {
        for (int t1 = 0; t1 <= 1; ++t1) {
            for (int t2 = 0; t2 <= 1; ++t2) {
                dp[t1][t2] = -INF;
            }
        }
        dp[0][0] = 0;

        for (int y = 0; y <= m + 1; ++y) {
            int x = sx - y;

            for (int t1 = 0; t1 <= 1; ++t1) {
                for (int t2 = 0; t2 <= 1; ++t2) {
                    ndp[t1][t2] = -INF;
                }
            }

            for (int t1 = 0; t1 <= 1; ++t1) {
                for (int t2 = 0; t2 <= 1; ++t2) {
                    // ブロックを取らない
                    ndp[t2][0] = std::max(ndp[t2][0], dp[t1][t2]);

                    // 縦に取る
                    if (!t1 && !t2 && judge(x, y, 0)) {
                        ndp[t2][0] = std::max(ndp[t2][0], dp[t1][t2] + 1);
                    }

                    // 横に取る
                    if (judge(x, y, 1)) {
                        ndp[t2][1] = std::max(ndp[t2][1], dp[t1][t2] + 1);
                    }
                }
            }
            std::swap(dp, ndp);
        }
        ans += dp[0][0];  // yを2だけ余分にカウントすることでdp[0][0]に集約している
    }
    std::cout << ans << std::endl;
}

int main() {
    std::cin.tie(nullptr);
    std::cout.tie(nullptr);
    std::ios::sync_with_stdio(false);

    solve();

    return 0;
}
accuracy: 1
time_ms: 400
memory_kb: 13504
final_rank: 5

code_snippet: #include <iostream>
#include <algorithm>
#include <vector>
#include <string>
#include <functional>

constexpr int INF = 1 << 30;

template <class T>
std::vector<T> vec(int len, T elem) { return std::vector<T>(len, elem); }

int n, m;
std::vector<std::string> ss;

bool judge(int x, int y, int t) {
    if (t == 0) {
        for (int dx = 0; dx < 3; ++dx) {
            int nx = x + dx,
                ny = y;
            if (nx < 0 || n <= nx || ny < 0 || m <= ny ||
                ss[nx][ny] != "RGW"[dx]) return false;
        }
    } else {
        for (int dy = 0; dy < 3; ++dy) {
            int nx = x,
                ny = y + dy;
            if (nx < 0 || n <= nx || ny < 0 || m <= ny ||
                ss[nx][ny] != "RGW"[dy]) return false;
        }
    }
    return true;
};

void solve() {
    std::cin >> n >> m;

    ss.resize(n);
    for (auto& s : ss) std::cin >> s;

    int ans = 0;
    auto dp = vec(2, vec(2, 0));
    auto ndp = dp;

    for (int sx = 0; sx < n + m; ++sx) {
        for (int t1 = 0; t1 <= 1; ++t1) {
            for (int t2 = 0; t2 <= 1; ++t2) {
                dp[t1][t2] = -INF;
            }
        }
        dp[0][0] = 0;

        for (int y = 0; y <= m + 1; ++y) {
            int x = sx - y;

            for (int t1 = 0; t1 <= 1; ++t1) {
                for (int t2 = 0; t2 <= 1; ++t2) {
                    ndp[t1][t2] = -INF;
                }
            }

            for (int t1 = 0; t1 <= 1; ++t1) {
                for (int t2 = 0; t2 <= 1; ++t2) {
                    ndp[t2][0] = std::max(ndp[t2][0], dp[t1][t2]);

                    if (!t1 && !t2 && judge(x, y, 0)) {
                        ndp[t2][0] = std::max(ndp[t2][0], dp[t1][t2] + 1);
                    }
                    if (judge(x, y, 1)) {
                        ndp[t2][1] = std::max(ndp[t2][1], dp[t1][t2] + 1);
                    }
                }
            }
            std::swap(dp, ndp);
        }
        ans += dp[0][0];
    }
    std::cout << ans << std::endl;
}

int main() {
    std::cin.tie(nullptr);
    std::cout.tie(nullptr);
    std::ios::sync_with_stdio(false);

    solve();

    return 0;
}
accuracy: 1
time_ms: 560
memory_kb: 13508
final_rank: 9

code_snippet: #include <iostream>
#include <algorithm>
#include <vector>
#include <string>
#include <functional>

constexpr int INF = 1 << 30;

template <class T>
std::vector<T> vec(int len, T elem) { return std::vector<T>(len, elem); }

void solve() {
    int n, m;
    std::cin >> n >> m;

    std::vector<std::string> ss(n);
    for (auto& s : ss) std::cin >> s;

    auto judge = [&](int x, int y, int t) {
        if (t == 0) {
            for (int dx = 0; dx < 3; ++dx) {
                int nx = x + dx,
                    ny = y;
                if (nx < 0 || n <= nx || ny < 0 || m <= ny ||
                    ss[nx][ny] != "RGW"[dx]) return false;
            }
        } else {
            for (int dy = 0; dy < 3; ++dy) {
                int nx = x,
                    ny = y + dy;
                if (nx < 0 || n <= nx || ny < 0 || m <= ny ||
                    ss[nx][ny] != "RGW"[dy]) return false;
            }
        }
        return true;
    };

    int ans = 0;
    for (int sx = 0; sx < n + m; ++sx) {
        auto dp = vec(2, vec(2, -INF));
        dp[0][0] = 0;

        for (int y = 0; y <= m + 1; ++y) {
            int x = sx - y;

            auto ndp = vec(2, vec(2, -INF));
            for (int t1 = 0; t1 <= 1; ++t1) {
                for (int t2 = 0; t2 <= 1; ++t2) {
                    ndp[t2][0] = std::max(ndp[t2][0], dp[t1][t2]);

                    if (!t1 && !t2 && judge(x, y, 0)) {
                        ndp[t2][0] = std::max(ndp[t2][0], dp[t1][t2] + 1);
                    }
                    if (judge(x, y, 1)) {
                        ndp[t2][1] = std::max(ndp[t2][1], dp[t1][t2] + 1);
                    }
                }
            }
            std::swap(dp, ndp);
        }
        ans += dp[0][0];
    }
    std::cout << ans << std::endl;
}

int main() {
    std::cin.tie(nullptr);
    std::cout.tie(nullptr);
    std::ios::sync_with_stdio(false);

    solve();

    return 0;
}
accuracy: 1
time_ms: 1820
memory_kb: 13508
final_rank: 15

code_snippet: #include <iostream>
#include <algorithm>
#include <vector>
#include <string>
#include <functional>

constexpr int INF = 1 << 30;

template <class T>
std::vector<T> vec(int len, T elem) { return std::vector<T>(len, elem); }

void solve() {
    int n, m;
    std::cin >> n >> m;

    std::vector<std::string> ss(n);
    for (auto& s : ss) std::cin >> s;

    auto judge = [&](int x, int y, int t) {
        if (t == 0) {
            for (int dx = 0; dx < 3; ++dx) {
                int nx = x + dx,
                    ny = y;
                if (nx < 0 || n <= nx || ny < 0 || m <= ny ||
                    ss[nx][ny] != "RGW"[dx]) return false;
            }
        } else {
            for (int dy = 0; dy < 3; ++dy) {
                int nx = x,
                    ny = y + dy;
                if (nx < 0 || n <= nx || ny < 0 || m <= ny ||
                    ss[nx][ny] != "RGW"[dy]) return false;
            }
        }
        return true;
    };

    int ans = 0;
    auto dp = vec(2, vec(2, -INF));
    auto ndp = dp;

    for (int sx = 0; sx < n + m; ++sx) {
        for (int t1 = 0; t1 <= 1; ++t1) {
            for (int t2 = 0; t2 <= 1; ++t2) {
                dp[t1][t2] = -INF;
            }
        }
        dp[0][0] = 0;

        for (int y = 0; y <= m + 1; ++y) {
            for (int t1 = 0; t1 <= 1; ++t1) {
                for (int t2 = 0; t2 <= 1; ++t2) {
                    ndp[t1][t2] = -INF;
                }
            }

            int x = sx - y;

            for (int t1 = 0; t1 <= 1; ++t1) {
                for (int t2 = 0; t2 <= 1; ++t2) {
                    ndp[t2][0] = std::max(ndp[t2][0], dp[t1][t2]);
                    if (!t1 && !t2 && judge(x, y, 0)) {
                        ndp[t2][0] = std::max(ndp[t2][0], dp[t1][t2] + 1);
                    }
                    if (judge(x, y, 1)) {
                        ndp[t2][1] = std::max(ndp[t2][1], dp[t1][t2] + 1);
                    }
                }
            }
            std::swap(dp, ndp);
        }

        ans += dp[0][0];
    }
    std::cout << ans << std::endl;
}

int main() {
    std::cin.tie(nullptr);
    std::cout.tie(nullptr);
    std::ios::sync_with_stdio(false);

    solve();

    return 0;
}
accuracy: 1
time_ms: 400
memory_kb: 13504
final_rank: 5

code_snippet: #include <iostream>
#include <vector>
#include <string>
#include <deque>
#include <tuple>

void solve() {
    int n, m;
    std::cin >> n >> m;

    std::vector<std::string> ss(n);
    for (auto& s : ss) std::cin >> s;

    std::deque<std::pair<int, int>> que;
    std::vector<std::vector<int>> deg(n, std::vector<int>(m, 0));
    for (int x = 0; x < n; ++x) {
        for (int y = 0; y < m; ++y) {
            bool judge;

            judge = true;
            for (int i = 0; i < 3; ++i) {
                int nx = x + i - 1,
                    ny = y;
                if (nx < 0 || n <= nx || ny < 0 || m <= ny ||
                    ss[nx][ny] != "RGW"[i]) judge = false;
            }
            deg[x][y] |= (judge << 0);

            judge = true;
            for (int i = 0; i < 3; ++i) {
                int nx = x,
                    ny = y + i - 1;
                if (nx < 0 || n <= nx || ny < 0 || m <= ny ||
                    ss[nx][ny] != "RGW"[i]) judge = false;
            }
            deg[x][y] |= (judge << 1);

            if (__builtin_popcount(deg[x][y]) == 1) {
                que.emplace_front(x, y);
            } else if (__builtin_popcount(deg[x][y]) == 2) {
                que.emplace_back(x, y);
            }
        }
    }

    int ans = 0;
    std::vector<std::vector<bool>> put(n, std::vector<bool>(m, false));
    while (!que.empty()) {
        int x, y;
        std::tie(x, y) = que.front();
        que.pop_front();
        if (deg[x][y] == 0) continue;

        if (deg[x][y] & 1) {
            for (int i = 0; i < 3; ++i) {
                int nx = x + i - 1,
                    ny = y;
                put[nx][ny] = true;
            }
            ++ans;

            for (int p = 0; p < 2; ++p) {
                int px = x + (p * 2 - 1),
                    py = y - (p * 2 - 1);
                if (px < 0 || n <= px || py < 0 || m <= py) continue;

                if (deg[px][py] & 2) {
                    deg[px][py] ^= 2;
                    if (deg[px][py] & 1) {
                        que.emplace_front(px, py);
                    }
                }
            }
        } else {
            for (int i = 0; i < 3; ++i) {
                int nx = x,
                    ny = y + i - 1;
                put[nx][ny] = true;
            }
            ++ans;

            for (int p = 0; p < 2; ++p) {
                int px = x + (p * 2 - 1),
                    py = y - (p * 2 - 1);
                if (px < 0 || n <= px || py < 0 || m <= py) continue;

                if (deg[px][py] & 1) {
                    deg[px][py] ^= 1;
                    if (deg[px][py] & 2) {
                        que.emplace_front(px, py);
                    }
                }
            }
        }
        deg[x][y] = 0;
    }

    std::cout << ans << std::endl;
}

int main() {
    std::cin.tie(nullptr);
    std::cout.tie(nullptr);
    std::ios::sync_with_stdio(false);

    solve();

    return 0;
}
accuracy: 1
time_ms: 260
memory_kb: 74344
final_rank: 11

code_snippet: #include <bits/stdc++.h>
 
//    #include <boost/multiprecision/cpp_int.hpp>
 #define int long long
 #define inf  1000000007
 #define pa pair<int,int>
 #define ll long long
 #define pal pair<double,double>
 #define ppap pair<pa,int>
  #define PI 3.14159265358979323846
  #define paa pair<int,char>
  #define  mp make_pair
  #define  pb push_back
  #define EPS (1e-8)
                                          
    int dx[8]={0,1,0,-1,1,1,-1,-1};
    int dy[8]={1,0,-1,0,-1,1,1,-1};
                                            using namespace std;
                                   			class pa3{
                                            	public:
                                            	int x;
                                   				int y,z;
                                            	pa3(int x=0,int y=0,int z=0):x(x),y(y),z(z) {}
                                            	bool operator < (const pa3 &p) const{
                                            		if(x!=p.x) return x<p.x;
                                            		if(y!=p.y) return y<p.y;
                                            		 return z<p.z;
                                            		//return x != p.x ? x<p.x: y<p.y;
                                            	}
                                   				bool operator > (const pa3 &p) const{
                                            		if(x!=p.x) return x>p.x;
                                            		if(y!=p.y) return y>p.y;
                                            		 return z>p.z;
                                            		//return x != p.x ? x<p.x: y<p.y;
                                            	}
                                            	bool operator == (const pa3 &p) const{
                                            		return x==p.x && y==p.y && z==p.z;
                                            	}
                                            		bool operator != (const pa3 &p) const{
                                            			return !( x==p.x && y==p.y && z==p.z);
                                            	}
                                            
                                            };
                                            
                                            class pa4{
                                            	public:
                                            	int x;
                                            	int y,z,w;
                                            	pa4(int x=0,int y=0,int z=0,int w=0):x(x),y(y),z(z),w(w) {}
                                            	bool operator < (const pa4 &p) const{
                                            		if(x!=p.x) return x<p.x;
                                            		if(y!=p.y) return y<p.y;
                                            		if(z!=p.z)return z<p.z;
                                            		return w<p.w;
                                            		//return x != p.x ? x<p.x: y<p.y;
                                            	}
                                            	bool operator > (const pa4 &p) const{
                                            		if(x!=p.x) return x>p.x;
                                            		if(y!=p.y) return y>p.y;
                                            		if(z!=p.z)return z>p.z;
                                            		return w>p.w;
                                            		//return x != p.x ? x<p.x: y<p.y;
                                            	}
                                            	bool operator == (const pa4 &p) const{
                                            		return x==p.x && y==p.y && z==p.z &&w==p.w;
                                            	}
                                            		
                                            
                                            };
                                            class pa2{
                                            	public:
                                            	int x,y;
                                            	pa2(int x=0,int y=0):x(x),y(y) {}
                                            	pa2 operator + (pa2 p) {return pa2(x+p.x,y+p.y);}
                                            	pa2 operator - (pa2 p) {return pa2(x-p.x,y-p.y);}
                                            	bool operator < (const pa2 &p) const{
                                            		return y != p.y ? y<p.y: x<p.x;
                                            	}
                                            	bool operator > (const pa2 &p) const{
                                            		return x != p.x ? x<p.x: y<p.y;
                                            	}
                                            	bool operator == (const pa2 &p) const{
                                            		return abs(x-p.x)==0 && abs(y-p.y)==0;
                                            	}
                                            	bool operator != (const pa2 &p) const{
                                            		return !(abs(x-p.x)==0 && abs(y-p.y)==0);
                                            	}
                                            		
                                            
                                            };
                                            
 
                      
                                string itos( int i ) {
                                ostringstream s ;
                                s << i ;
                                return s.str() ;
                                }
                                 
                                int gcd(int v,int b){
                                	if(v==0) return b;
                                	if(b==0) return v;
                                	if(v>b) return gcd(b,v);
                                	if(v==b) return b;
                                	if(b%v==0) return v;
                                	return gcd(v,b%v);
                                }
                 
                            
                                int mod;
int extgcd(int a, int b, int &x, int &y) {
    if (b == 0) {
        x = 1;
        y = 0;
        return a;
    }
    int d = extgcd(b, a%b, y, x);
    y -= a/b * x;
    return d;
}
pa operator+(const pa & l,const pa & r) {   
    return {l.first+r.first,l.second+r.second};                                    
}    
pa operator-(const pa & l,const pa & r) {   
    return {l.first-r.first,l.second-r.second};                                    
}  
                                
                int pr[10000100];
                int inv[10000010];
                
                int beki(int wa,int rr,int warukazu){
                	if(rr==0) return 1%warukazu;
                	if(rr==1) return wa%warukazu;
                	wa%=warukazu;
                	if(rr%2==1) return ((ll)beki(wa,rr-1,warukazu)*(ll)wa)%warukazu;
                	ll zx=beki(wa,rr/2,warukazu);
                	return (zx*zx)%warukazu;
                }
 
                
    			int comb(int nn,int rr){
    				if(rr<0 || rr>nn || nn<0) return 0;
    				int r=pr[nn]*inv[rr];
    				r%=mod;
    				r*=inv[nn-rr];
    				r%=mod;
    				return r;
    			}
               
                void gya(int ert){
                	pr[0]=1;
                	for(int i=1;i<=ert;i++){
                		pr[i]=(pr[i-1]*i)%mod;
                	}
                		inv[ert]=beki(pr[ert],mod-2,mod);
                	for(int i=ert-1;i>=0;i--){
                		inv[i]=inv[i+1]*(i+1)%mod;
                	}
                }
                
              //   cin.tie(0);
    		//	ios::sync_with_stdio(false);
    			//priority_queue<pa3,vector<pa3>,greater<pa3>> pq;            
                 //sort(ve.begin(),ve.end(),greater<int>());
 //   mt19937(clock_per_sec);
  //  mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count()) ;
      
       
int h,w;

int ban[3010][3010];
int vis[3010][3010]={};


vector<pa> ve;
void dfs(int x,int y){
	if(vis[x][y]) return;
	ve.pb(mp(x,y));
	vis[x][y]=1;
	for(int i=0;i<4;i++){
		int xx=x+dx[i];
		int yy=y+dy[i];
		if(xx<0 || yy<0 ||xx>=h || yy>=w) continue;
		if(vis[xx][yy])continue;
		if(i<=1 && ban[x][y]+1!=ban[xx][yy])continue;
		if(i>1 && ban[x][y]-1!=ban[xx][yy])continue;
		dfs(xx,yy);
	}
}

int memo[3010][3];
int dp[3010][5];
int solve(){
	sort(ve.begin(),ve.end());
	int d=ve[0].first;
	int e1=inf,e2=-inf;
	for(auto &v:ve){
		v.second+=v.first-d;
		e1=min(e1,v.second);
		e2=max(e2,v.second);
	}
	if(e2-e1!=2)return 0;
	for(auto &v:ve){
		v.first-=d;
		v.second-=e1;
	}
	
	int R=ve.back().first+1;
	for(int i=0;i<=R;i++)for(int j=0;j<3;j++){
		memo[i][j]=0;
		
	}	
	for(int i=0;i<=R;i++)for(int j=0;j<=3;j++){
		dp[i][j]=0;
		
	}	
	for(auto v:ve)memo[v.first][v.second]=1;
	
	
	for(int i=0;i<R;i++){
		
		if(memo[i][0]+memo[i][1]+memo[i][2]==3){
			
			dp[i+1][0]=max(dp[i+1][0],max({dp[i][0],dp[i][1],dp[i][2],dp[i][3]})+1);
		}
		
		if(i>=2){
			if(memo[i-2][0]+memo[i-1][1]+memo[i][2]==3){
				
				dp[i+1][3]=max(dp[i+1][3],max({dp[i][2],dp[i][3]})+1);
			}
		}
		
		dp[i+1][1]=max(dp[i+1][1],dp[i][0]);
		dp[i+1][2]=max(dp[i+1][2],dp[i][1]);
		dp[i+1][3]=max({dp[i+1][3],dp[i][2],dp[i][3]});
		

		
	}
/*
	for(int i=0;i<R;i++){
		for(int j=0;j<3;j++){
		cout<<memo[i][j]<<" ";
		}
		cout<<endl;
	}
	cout<<endl;
	
	cout<<max({dp[R][0],dp[R][1],dp[R][2],dp[R][3]})<<endl;
	cout<<endl;
*/
	return max({dp[R][0],dp[R][1],dp[R][2],dp[R][3]});
	
}

signed main(){
	
	
   cin.tie(0);
	ios::sync_with_stdio(false);
	
	cin>>h>>w;
	for(int i=0;i<h;i++){
		string s;
		cin>>s;
		for(int j=0;j<w;j++){
			if(s[j]=='R')ban[i][j]=0;
			else if(s[j]=='G')ban[i][j]=1;
			else if(s[j]=='W')ban[i][j]=2;
			else ban[i][j]=inf;
		//cout<<i<<" "<<j<<" "<<ban[i][j]<<endl;	
		}
		
	}
	int ans=0;
	for(int i=0;i<h;i++)for(int j=0;j<w;j++)if(!vis[i][j])if(ban[i][j]==0){
	//	cout<<i<<" "<<j<<endl;
		ve.clear();
		dfs(i,j);
		//cout<<"d"<<endl;
		int y=solve();
		ans+=y;
	}
	cout<<ans<<endl;
	
return 0;
	

 
 }
accuracy: 1
time_ms: 690
memory_kb: 145024
final_rank: 14

code_snippet: #include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
#define Maxn 3010

int n, m, Row[Maxn][Maxn], Col[Maxn][Maxn], f[Maxn][Maxn][2][2], Res;
char D[Maxn][Maxn];

int main()
{
    scanf("%d%d", &n, &m); getchar();
    for (int i=1; i<=n; i++)
    {
        for (int j=1; j<=m; j++)
        {
            scanf("%c", &D[i][j]);
            if (D[i][j]=='W')
            {
                if ((i>=3) && (D[i-2][j]=='R') && (D[i-1][j]=='G'))
                    Row[i-2][j]=1;
                if ((j>=3) && (D[i][j-2]=='R') && (D[i][j-1]=='G'))
                    Col[i][j-2]=1;
            }
        }
        getchar();
    }
    /*
    for (int i=1; i<=n; i++)
    {
        for (int j=1; j<=m; j++) printf("(%d %d)", Row[i][j], Col[i][j]); printf("\n");
    }
    */
    for (int i=1; i<=n; i++)
    {
        for (int j=2; j<=m; j++)
        {
            f[i+1][j-1][0][0]=max(f[i][j][0][1], f[i][j][0][0]+Col[i][j]);
            f[i+1][j-1][1][0]=max(f[i][j][0][1], f[i][j][0][0])+Row[i][j];
            f[i+1][j-1][0][1]=max(f[i][j][1][0], f[i][j][1][1]);
            f[i+1][j-1][1][1]=max(f[i][j][1][0], f[i][j][1][1])+Row[i][j];
        }
        int L = max(max(f[i][1][0][0], f[i][1][0][1]), max(f[i][1][1][0], f[i][1][1][1]))+Row[i][1];
        Res+=max(f[i][1][0][0]+Col[i][1], L);
    }
    for (int i=1; i<=m; i++) Res+=f[n+1][i][0][0];
    printf("%d\n", Res);
}
accuracy: 1
time_ms: 310
memory_kb: 223168
final_rank: 19

code_snippet: #include <bits/stdc++.h>
#define FOR(i,k,n) for(int i=(k);i<(int)(n);++i)
#define REP(i,n) FOR(i,0,n)
#define ALL(x) begin(x),end(x)

using namespace std;
using ll = int64_t;

int main() {
  int n,m;
  cin>>n>>m;
  vector<string> t(n);
  REP(i,n) cin>>t[i];
  vector<vector<bool>> th(n, vector<bool>(m, false));
  vector<vector<bool>> tv(n, vector<bool>(m, false));
  REP(i,n)REP(j,m) {
    if (i+2 < n) {
      if (t[i][j] == 'R' && t[i+1][j] == 'G' && t[i+2][j] == 'W') {
        tv[i][j] = true;
      }
    }
    if (j+2 < m) {
      if (t[i][j] == 'R' && t[i][j+1] == 'G' && t[i][j+2] == 'W') {
        th[i][j] = true;
      }
    }
  }
  ll sum = 0;
  REP(d,n+m) {
    vector<vector<ll>> dp(max(n, m)+1, vector<ll>(4, 0));
    REP(i,n) {
      int j = d - i;
      if (j >= m || j < 0) continue;
      REP(k,2)REP(l,2) {
        int index = k + 2*l;
        if (tv[i][j]) {
          int index2 = 1 + 2*k;
          dp[i+1][index2] = max(dp[i+1][index2], dp[i][index] + 1);
        }
        if (th[i][j]) {
          int index2 = 0 + 2*k;
          if (!k && !l) {
            dp[i+1][index2] = max(dp[i+1][index2], dp[i][index] + 1);
          }
        }
        int index2 = 0 + 2*k;
        dp[i+1][index2] = max(dp[i+1][index2], dp[i][index] + 0);
      }
    }
    ll mx = 0;
    for(auto&& v : dp)
      for (ll e : v)
        mx = max(mx, e);
    sum += mx;
  }
  cout << sum << endl;
  return 0;
}
accuracy: 1
time_ms: 1320
memory_kb: 26516
final_rank: 12

code_snippet: #include <iostream>
#include <iomanip>
#include <fstream>
#include <stdio.h>
#include <math.h>
#include <time.h>
#include <string>
#include <tuple>
#include <vector>
#include <map>
#include <unordered_map>
#include <list>
#include <set>
#include <stack>
#include <queue>
#include <cstdlib>
#include <algorithm>
#include <random>
#include <cassert>
using namespace std;
#define LL long long
#define MP(a, b) make_pair(a, b)
#define POWER9 1000000000
#define MOD POWER9+7
#undef INT_MIN
#undef INT_MAX
#define INT_MIN -2147483647
#define INT_MAX 2147483647
#define LL_MIN (LL)-9223372036854775807
#define LL_MAX (LL)9223372036854775807
#define PI 3.14159265359

int N,M,A[3000][3000];

int tmp;
int dp2[3000][2][2];
int solve2(int now, int old1, int old2){
	int x = now+tmp-N+1;
	int y = N-1-now;
	if(tmp < N-1){
		y -= N-tmp-1;
		x += N-tmp-1;
	}
	if(x == M || y == -1) return 0;
	if(dp2[now][old1][old2] != -1) return dp2[now][old1][old2];
	if(A[y][x] != 0) return solve2(now+1,0,old1);
	int re = solve2(now+1,0,old1);
	if(y+2<N && A[y+1][x]==1 && A[y+2][x]==2 && old1==0 && old2==0){
		re = max(re, solve2(now+1,0,old1)+1);
	}
	if(x+2<M && A[y][x+1]==1 && A[y][x+2]==2){
		re = max(re, solve2(now+1,1,old1)+1);
	}
	//cout << re << endl;
	return dp2[now][old1][old2] = re;
}

int dp1[6000];
int solve1(int now){
	if(now == N+M-3) return 0;
	if(dp1[now] != -1) return dp1[now];
	tmp = now;
	for(int i=0; i<min(N,M); i++){
		dp2[i][0][0] = -1;
		dp2[i][0][1] = -1;
		dp2[i][1][0] = -1;
		dp2[i][1][1] = -1;
	}
	dp1[now] = solve2(0,0,0);
	dp1[now] += solve1(now+1);
	//cout << dp1[now] << endl;
	return dp1[now];
}



int main(){
	cin.tie(0);
	ios::sync_with_stdio(false);
	cout << setprecision(9);

	

	cin >> N >> M;
	/*for(int i=0; i<6; i++){
		for(int j=0; j<3; j++){
			int x =j+i-N+1;
			int y = N-1-j;
			if(i < N-1){
				y -= N-i-1;
				x += N-i-1;
			}
			cout << x << " " << y << endl;
		}
	}*/
	for(int i=0; i<N; i++){
		string S;
		cin >> S;
		for(int j=0; j<M; j++){
			if(S[j] == 'R') A[i][j] = 0;
			if(S[j] == 'G') A[i][j] = 1;
			if(S[j] == 'W') A[i][j] = 2;
		}
	}
	for(int i=0; i<N+M-3; i++) dp1[i] = -1;
	cout << solve1(0) << endl;

	return 0;
}
accuracy: 1
time_ms: 280
memory_kb: 38828
final_rank: 8

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

using namespace std;
typedef long long ll;
typedef pair<int,int> P;

int N, M;
char field[3005][3005];
ll ans;

int main() {
	cin.tie(0);
	ios::sync_with_stdio(false);

	cin >> N >> M;

	for (int i = 0;i < N;i++){
		for (int j = 0;j < M;j++){
			cin >> field[i][j];
		}
	}

	ans = 0;

	for (int si = 1;si <= N+M-3;si++){
		int i,j;
		if(si <= N-1){
			i = si; j = 0;
		} else {
			i = N-1; j = si-(N-1);
		}

		ll dp[3005][2][2]; memset(dp, 0, sizeof(dp));
		int idx = 0;

		while(i >= 0 && j < M){
			for (int k = 0;k < 2;k++){
				for (int l = 0;l < 2;l++){
					if(idx == 0 && !(k == 0 && l == 0)) continue;
					if(l == 1 && k == 1) continue;
					dp[idx+1][0][0] = max(dp[idx+1][0][0], dp[idx][k][l]);
					if(field[i][j] != 'G') continue;
					if(i-1 >= 0 && i+1 < N && field[i-1][j] == 'R' && field[i+1][j] == 'W' && l == 0){
						dp[idx+1][1][0] = max(dp[idx+1][1][0], dp[idx][k][l] + 1);
					}
					if(j-1 >= 0 && j+1 < M && field[i][j-1] == 'R' && field[i][j+1] == 'W' && k == 0){
						dp[idx+1][0][1] = max(dp[idx+1][0][1], dp[idx][k][l] + 1);
					}
				}
			}
			i--; j++;
			idx++;
		}

		ll MAX = -1;;
		for (int k = 0;k < 2;k++){
			for (int l = 0;l < 2;l++){
				MAX = max(MAX, dp[idx][k][l]);
			}
		}

		ans += MAX;
	}

	cout << ans << endl;

	return 0;

}
accuracy: 1
time_ms: 210
memory_kb: 12080
final_rank: 3