1 #include <stdio.h>
2 #include <iostream>
3 #include <cstdlib>
4 #include <cmath>
5 #include <string>
6 #include <cstring>
7 #include <algorithm>
8 #include <stack>
9 #include <queue>
10 #include <set>
11 #include <map>
12 #include <vector>
13 using namespace std;
14 typedef long long ll;
15 typedef unsigned long long ull;
16
17 #define Faster ios::sync_with_stdio(false),cin.tie(0)
18 #define Read freopen("in.txt", "r", stdin),freopen("out.txt", "w", stdout)
19 const int INF = 0x3f3f3f3f;
20 const int maxn = 500 + 5;
21 const int MOD = 1e9 + 7;
22
23 char g[maxn][maxn];
24
25 //f[a][b][c][d] :从(1,1)->(a,b)和从(n,m)->(c,d);
26 //f[a][b][c] :知道a,b,c就能得出d所以降了一个维
27 //f[s][][] 由f[s-1][][]得出,所以可以用滚动数组
28 ll dp[2][maxn][maxn];
29
30 //检查是否满足回文的条件
31 bool check(int a, int b, int c, int d){
32 if(a == c && b == d) return true;
33 if(a+1 == c && b == d) return true;
34 if(a == c && b+1 == d) return true;
35 return false;
36 }
37
38 int main()
39 {
40 Faster;
41 int n, m;
42 scanf("%d%d", &n, &m);
43 for(int i = 1;i <= n;i++){
44 scanf("%s", g[i]+1);
45 }
46 if(g[1][1] == g[n][m]){
47 dp[1][1][n] = 1;
48 }
49 ll ans = 0;
50 for(int i = 1;i <= n;i++){
51 for(int j = 1; (i+j-1) <= (n+m)/2;j++){
52 for(int k = n;n+m+2-i-j-k <= m;k--){
53 int z = n+m+2-i-j-k;
54 if(g[i][j] == g[k][z]){
55 dp[i&1][j][k] += dp[(i-1)&1][j][k+1];
56 dp[i&1][j][k] += dp[(i-1)&1][j][k];
57 dp[i&1][j][k] += dp[i&1][j-1][k+1];
58 dp[i&1][j][k] += dp[i&1][j-1][k];
59 dp[i&1][j][k] %= MOD;
60 if(check(i,j,k,z)){
61 ans = (ans + dp[i&1][j][k])%MOD;
62 }
63 }
64 }
65 }
66 memset(dp[(i-1)&1], 0, sizeof(dp[(i-1)&1]));
67 }
68 cout << ans << endl;
69 return 0;
70 }