#include <bits/stdc++.h>
using namespace std;
unsigned long long p = 1e9 + 7;
int debug = 0;
int n, m, tpe;
char str[510][510];
int mv[2][2] = {{0, 1}, {1, 0}};
int num[512][512];
int used[512][512];
long long dp[2][2002][510];
int flag;
bool checkInt(pair<int, int> now) {
  return 0 <= now.first && now.first < n && 0 <= now.second && now.second < m;
}
bool checkChar(pair<int, int> a, pair<int, int> b) {
  return str[a.first][a.second] == str[b.first][b.second];
}
void BFS() {
  int lv[5000];
  memset(lv, 0, sizeof(lv));
  memset(used, 0, sizeof(used));
  lv[0] = 1;
  num[0][0] = 0;
  queue<pair<pair<int, int>, int> > arr;
  arr.push(make_pair(pair<int, int>(0, 0), 1));
  while (int(arr.size()) > 0) {
    pair<pair<int, int>, int> now = arr.front();
    arr.pop();
    for (int k = 0; k < 2; k++) {
      pair<int, int> tar = pair<int, int>(now.first.first + mv[k][0],
                                          now.first.second + mv[k][1]);
      if (checkInt(tar) && used[tar.first][tar.second] == 0) {
        used[tar.first][tar.second] = 1;
        num[tar.first][tar.second] = lv[now.second];
        lv[now.second]++;
        arr.push(make_pair(tar, now.second + 1));
      }
    }
  }
  for (int i = 0; i < n && debug; i++) {
    for (int j = 0; j < m; j++) printf(" %d", num[i][j]);
    puts("");
  }
}
void update(long long verI, int a, int b, int c, long long val) {
  int flaI = verI % 2;
  int gridNum = num[a][b];
  dp[flaI][gridNum][c] += val;
  dp[flaI][gridNum][c] %= p;
  if (debug)
    printf("dp ver %lld flag %d a %d b %d c %d val %lld dp %lld\n", verI, flaI,
           a, b, c, val, dp[flaI][gridNum][c]);
}
void clearNextLine(int dis, int ver) {
  for (int i = 0; i < n + m; i++) {
    for (int j = 0; j < m + 2; j++) {
      dp[ver % 2][i][j] = 0;
    }
  }
}
int main() {
  cin >> n >> m;
  for (int i = 0; i < n; i++) cin >> str[i];
  flag = 0;
  tpe = (n + m) % 2;
  BFS();
  for (int dis = (n + m - 2) / 2, i = 0; dis > 0; dis--, i++) {
    if (debug) printf("=============dis %d i %d===========\n", dis, i);
    flag = i % 2;
    pair<int, int> LUs = pair<int, int>(dis - min(dis, m - 1), min(dis, m - 1));
    pair<int, int> RDs = pair<int, int>((n - 1) - min(dis, n - 1),
                                        (m - 1) - (dis - min(dis, n - 1)));
    if (debug)
      printf("LU (%d, %d) RD (%d, %d)\n", LUs.first, LUs.second, RDs.first,
             RDs.second);
    if (i == 0) {
      for (pair<int, int> LUitr = LUs; checkInt(LUitr);
           LUitr = pair<int, int>(LUitr.first + 1, LUitr.second - 1)) {
        for (pair<int, int> RDitr = RDs; checkInt(RDitr);
             RDitr = pair<int, int>(RDitr.first + 1, RDitr.second - 1)) {
          if (LUitr.first <= RDitr.first && LUitr.second <= RDitr.second &&
              (RDitr.first - LUitr.first) + (RDitr.second - LUitr.second) ==
                  (tpe + i * 2) &&
              checkChar(LUitr, RDitr)) {
            update(i, LUitr.first, LUitr.second, RDitr.first - LUitr.first, 1);
          }
        }
      }
    }
    clearNextLine(dis - 1, i + 1);
    for (pair<int, int> LUitr = LUs; checkInt(LUitr);
         LUitr = pair<int, int>(LUitr.first + 1, LUitr.second - 1)) {
      for (pair<int, int> RDitr = RDs; checkInt(RDitr);
           RDitr = pair<int, int>(RDitr.first + 1, RDitr.second - 1)) {
        if (LUitr.first <= RDitr.first && LUitr.second <= RDitr.second &&
            (RDitr.first - LUitr.first) + (RDitr.second - LUitr.second) ==
                (tpe + i * 2)) {
          if (debug)
            printf("LU (%d, %d) RD (%d, %d) dp %lld\n", LUitr.first,
                   LUitr.second, RDitr.first, RDitr.second,
                   dp[flag][num[LUitr.first][LUitr.second]]
                     [RDitr.first - RDitr.first]);
          for (int k = 0; k < 2; k++) {
            for (int l = 0; l < 2; l++) {
              pair<int, int> aa = pair<int, int>(LUitr.first - mv[k][0],
                                                 LUitr.second - mv[k][1]);
              pair<int, int> bb = pair<int, int>(RDitr.first + mv[l][0],
                                                 RDitr.second + mv[l][1]);
              if (aa.first <= bb.first && aa.second <= bb.second &&
                  checkInt(aa) && checkInt(bb) && checkChar(aa, bb)) {
                if (debug)
                  printf("put aa (%d, %d) bb (%d, %d)\n", aa.first, aa.second,
                         bb.first, bb.second);
                update(i + 1, aa.first, aa.second, bb.first - aa.first,
                       dp[flag][num[LUitr.first][LUitr.second]]
                         [RDitr.first - LUitr.first]);
              }
            }
          }
        }
      }
    }
  }
  cout << dp[flag ^ 1][0][n - 1] << endl;
  return 0;
}
