func_code_string: #include <bits/stdc++.h>   using namespace std;   const int N = 1e3, MOD = 1e9 + 7, UNDEF = -1;   int readInt() {     bool minus = false;     int result = 0;     char ch;     ch = getchar();     while (true) {       if (ch ==  - ) break;       if (ch >=  0  && ch <=  9 ) break;       ch = getchar();     }     if (ch ==  - )       minus = true;     else       result = ch -  0 ;     while (true) {       ch = getchar();       if (ch <  0  || ch >  9 ) break;       result = result * 10 + (ch -  0 );     }     if (minus)       return -result;     else       return result;   }   char readChar() {     char result = getchar();     while (isspace(result)) {       result = getchar();     }     return result;   }   char w[N + 1][N + 1];   pair<pair<short, short>, pair<short, short> > cur;   int n, m;   int dp1[2 * N + 1][2 * N + 1], dp2[2 * N + 1][2 * N + 1];   int S[2 * N + 1], cnt[2 * N + 1];   int curx, cury;   bool ispal(string s) {     string d = s;     reverse(s.begin(), s.end());     return d == s;   }   int o(int x1, int y1) { return x1 + S[x1 + y1] - S[x1 + y1 - 1]; }   void add(int x1, int y1, int x2, int y2) {     dp1[curx][cury] += dp2[o(x1, y1)][o(x2, y2)];     if (dp1[curx][cury] >= MOD) {       dp1[curx][cury] -= MOD;     }   }   vector<pair<short, short> > p1[2 * N + 1], p2[2 * N + 1];   int main() {     n = readInt(), m = readInt();     int s = (n + m - 2) / 2;     for (int i = 1; i <= n; i++) {       for (int j = 1; j <= m; j++) {         cnt[i + j]++;         w[i][j] = readChar();         p1[i + j - 2].push_back(make_pair(i, j));         p2[n + m - 2 - (i + j - 2)].push_back(make_pair(i, j));       }     }     for (int i = 2; i <= n + m; i++) {       S[i] = S[i - 1] + cnt[i];     }     if (w[1][1] != w[n][m]) {       cout << 0;       return 0;     }     int ans = n * n + 2 * (n - 1) * n;     for (int i = s; i >= 0; i--) {       for (int j = 0; j < p1[i].size(); j++) {         for (int k = 0; k < p2[i].size(); k++) {           int x1, y1, x2, y2;           x1 = p1[i][j].first;           y1 = p1[i][j].second;           x2 = p2[i][k].first;           y2 = p2[i][k].second;           if (w[x1][y1] == w[x2][y2]) {             if (x1 <= x2 && y1 <= y2) {               if (x2 - x1 + y2 - y1 <= 1) {                 dp1[o(x1, y1)][o(x2, y2)] = 1;               } else {                 curx = o(x1, y1);                 cury = o(x2, y2);                 if (x1 == x2) {                   add(x1, y1 + 1, x2, y2 - 1);                 } else if (y1 == y2) {                   add(x1 + 1, y1, x2 - 1, y2);                 } else {                   add(x1, y1 + 1, x2 - 1, y2);                   add(x1 + 1, y1, x2, y2 - 1);                   if (y2 - 1 >= y1 + 1) {                     add(x1, y1 + 1, x2, y2 - 1);                   }                   if (x2 - 1 >= x1 + 1) {                     add(x1 + 1, y1, x2 - 1, y2);                   }                 }               }             }           }         }       }       for (int i = 0; i <= 2 * n + m; i++) {         for (int j = 0; j <= 2 * n + m; j++) {           dp2[i][j] = dp1[i][j];           dp1[i][j] = 0;         }       }     }     cout << dp2[o(1, 1)][o(n, m)];   }   