#include <bits/stdc++.h>
using namespace std;
const int M7 = 1000000007;
template <class T>
void dumpBetween(const T& a, const T& b) {
  for (T it = a; it != b; it++) cout << *it << " ";
  cout << endl;
}
template <class T>
void dumpAll(const T& a) {
  dumpBetween((a).begin(), (a).end());
}
template <class T>
void minify(T& a, const T& b) {
  if (a > b) a = b;
}
template <class T>
void maxify(T& a, const T& b) {
  if (a < b) a = b;
}
int n, m;
char grid[508][508];
int ways[2][508][508];
int wb = 0;
void readInput() {
  scanf("%d%d", &(n), &(m));
  scanf(" ");
  for (int i = 0; i < ((int)n); i++) {
    fgets(grid[i], 888, stdin);
  }
}
char get(int i, int j) {
  if (0 <= i && i < n && 0 <= j && j < m) {
    return grid[i][j];
  }
  return '\0';
}
bool match(int s, int ai, int aj) {
  char a = get(ai, s - ai);
  char b = get(n - 1 - aj, m - 1 - s + aj);
  return a == b && a != '\0';
}
int getWays(int i, int j) {
  if (0 <= i && i < 508 && 0 <= j && j < 508) {
    return ways[!wb][i][j];
  }
  return 0;
}
int solve() {
  if (grid[0][0] != grid[n - 1][m - 1]) return 0;
  ways[wb][0][0] = 1;
  int hs = (n + m - 2) / 2;
  for (int s = 1; s <= hs; s++) {
    wb = !wb;
    for (int i = 0; i <= s; i++) {
      for (int j = 0; j <= s; j++) {
        if (match(s, i, j)) {
          int x = 0;
          for (int di = -1; di <= 0; di++) {
            for (int dj = -1; dj <= 0; dj++) {
              x += getWays(i + di, j + dj);
              x %= M7;
            }
          }
          ways[wb][i][j] = x;
          ((void)0);
        } else {
          ways[wb][i][j] = 0;
        }
      }
    }
  }
  int res = 0;
  wb = !wb;
  if ((n + m) % 2 == 0) {
    for (int i = 0; i < ((int)n); i++) {
      res += getWays(i, n - 1 - i);
      res %= M7;
    }
  } else {
    for (int i = 0; i < ((int)n); i++) {
      res += getWays(i, n - 1 - i);
      res %= M7;
      res += getWays(i, n - 2 - i);
      res %= M7;
    }
  }
  return res;
}
void tc() {
  readInput();
  printf("%d\n", solve());
}
int main() { tc(); }
