#include <bits/stdc++.h>
using namespace std;
void task();
int main() {
  ios_base::sync_with_stdio(0);
  task();
  fflush(stdout);
  return 0;
}
int n, m;
char table[510][510];
const int MOD = 1e9 + 7;
int dp[2][510][510];
int dx[] = {1, 0};
int dy[] = {0, 1};
bool isOk(int x, int y) { return x > 0 && x <= m && y > 0 && y <= n; }
bool intersect(int x1, int y1, int x2, int y2) { return x1 > x2 || y1 > y2; }
void update(int left_x, int right_x, int len) {
  if (left_x > right_x) return;
  int left_y = len - left_x + 1;
  int right_y = n - (len + right_x - m) + 1;
  for (int left = 0; left < 2; ++left)
    for (int right = 0; right < 2; ++right) {
      int nx_l = left_x + dx[left], ny_l = left_y + dy[left],
          nx_r = right_x - dx[right], ny_r = right_y - dy[right];
      if (isOk(nx_l, ny_l) && isOk(nx_r, ny_r) &&
          !intersect(nx_l, ny_l, nx_r, ny_r) &&
          table[ny_l][nx_l] == table[ny_r][nx_r]) {
        dp[1 - len % 2][nx_l][nx_r] =
            (dp[1 - len % 2][nx_l][nx_r] + dp[len % 2][left_x][right_x]) % MOD;
      }
    }
}
void make_new_layer(int len) {
  memset(dp[1 - len % 2], 0, 510 * 510 * sizeof(int));
  for (int l_x = 1; l_x <= len && l_x <= m; l_x++)
    for (int r_x = m, cnt = 1; cnt <= len && r_x > 0; r_x--, cnt++)
      update(l_x, r_x, len);
}
int calc() {
  if (n == m && n == 1) return 1;
  if (table[1][1] != table[n][m]) return 0;
  dp[1][1][m] = 1;
  for (int i = 1; i <= (n + m - 1) / 2; ++i) make_new_layer(i);
  int ret = 0;
  if ((n + m - 1) % 2) {
    int len = (n + m - 1) / 2 + (n + m - 1) % 2;
    for (int x = 1; x <= m; ++x) {
      ret += dp[len % 2][x][x];
      ret %= MOD;
    }
  } else {
    int len = (n + m - 1) / 2;
    for (int x = 1; x <= m; ++x) {
      ret += dp[len % 2][x][x];
      ret %= MOD;
      ret += dp[len % 2][x][x + 1];
      ret %= MOD;
    }
  }
  return ret;
}
void task() {
  scanf("%d%d", &n, &m);
  for (int y = 1; y <= n; ++y) scanf("%s", table[y] + 1);
  cout << calc();
}
