#include <bits/stdc++.h>
const int MOD = 1e9 + 7;
using namespace std;
int n, m;
char table[502][502];
int dp[2][502][502];
void read() {
  cin.tie(0);
  ios_base::sync_with_stdio(0);
  cin >> n >> m;
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < m; j++) {
      cin >> table[i][j];
    }
  }
}
struct Point {
  Point() {}
  Point(int _x, int _y) : x(_x), y(_y) {}
  int x, y;
};
bool check(Point a) { return 0 <= a.x && a.x < n && 0 <= a.y && a.y < m; }
void sol() {
  cin.tie(0);
  ios_base::sync_with_stdio(0);
  int fst = 0, snd = 1;
  int maxdep = (n + m) / 2 - 1;
  for (int dep = maxdep; dep >= 0; dep--) {
    memset(dp[fst], 0, sizeof(int) * 502 * 502);
    for (int i = 0; i < n; i++) {
      for (int j = 0; j < n; j++) {
        Point a(i, dep - i);
        Point b(n - 1 - j, m - 1 - (dep - j));
        if (!check(a) || !check(b)) continue;
        if (a.x > b.x || a.y > b.y)
          dp[fst][a.x][b.x] = 0;
        else if (abs(a.x - b.x) + abs(a.y - b.y) <= 1 &&
                 table[a.x][a.y] == table[b.x][b.y])
          dp[fst][a.x][b.x] = 1;
        else if (table[a.x][a.y] == table[b.x][b.y]) {
          dp[fst][a.x][b.x] += dp[snd][a.x + 1][b.x];
          dp[fst][a.x][b.x] += dp[snd][a.x + 1][b.x - 1];
          dp[fst][a.x][b.x] %= MOD;
          dp[fst][a.x][b.x] += dp[snd][a.x][b.x - 1];
          dp[fst][a.x][b.x] %= MOD;
          dp[fst][a.x][b.x] += dp[snd][a.x][b.x];
          dp[fst][a.x][b.x] %= MOD;
        }
      }
    }
    swap(fst, snd);
  }
  cout << dp[snd][0][n - 1] % MOD << "\n";
}
int main() {
  read();
  sol();
  return 0;
}
