#include <bits/stdc++.h>
using namespace std;
template <class F, class T>
T convert(F a, int p = -1) {
  stringstream ss;
  if (p >= 0) ss << fixed << setprecision(p);
  ss << a;
  T r;
  ss >> r;
  return r;
}
template <class T>
T gcd(T a, T b) {
  T r;
  while (b != 0) {
    r = a % b;
    a = b;
    b = r;
  }
  return a;
}
template <class T>
T lcm(T a, T b) {
  return a / gcd(a, b) * b;
}
template <class T>
T sqr(T x) {
  return x * x;
}
template <class T>
T cube(T x) {
  return x * x * x;
}
template <class T>
int getbit(T s, int i) {
  return (s >> i) & 1;
}
template <class T>
T onbit(T s, int i) {
  return s | (T(1) << i);
}
template <class T>
T offbit(T s, int i) {
  return s & (~(T(1) << i));
}
template <class T>
int cntbit(T s) {
  return s == 0 ? 0 : cntbit(s >> 1) + (s & 1);
}
const long double PI = acos(-1.0);
const long double eps = 1e-9;
const int dr[] = {-1, 0, +1, 0};
const int dc[] = {0, +1, 0, -1};
const int inf = (int)1e9 + 5;
const long long linf = (long long)1e16 + 5;
const long long mod = (long long)1e9 + 7;
void disp(int arr[], int narr) {
  for (int i = (1); i <= (narr); ++i) cout << arr[i] << " ";
  cout << '\n';
}
void disp(vector<int> v) {
  int nv = v.size(), nn = min(nv, 15);
  for (int i = (0); i <= (nn - 1); ++i) cout << v[i] << " ";
  cout << '\n';
}
long long ans = 0ll, z;
int n, m;
int N = 1000;
pair<int, int> x, y;
pair<int, int> p[1005][1005];
vector<long long> v, t;
int vt[505][505];
int cnt[2000];
char c[505][505];
int sol() {
  cin >> n >> m;
  for (int i = (1); i <= (n); ++i)
    for (int j = (1); j <= (m); ++j) cin >> c[i][j];
  for (int i = (1); i <= (n); ++i)
    for (int j = (1); j <= (m); ++j)
      cnt[i + j]++, p[i + j][cnt[i + j]] = make_pair(i, j),
                                     vt[i][j] = cnt[i + j];
  if (c[1][1] == c[n][m])
    v.push_back(1ll);
  else {
    cout << 0 << '\n';
    return 0;
  }
  for (int i = (3); i <= ((m + n + 2) / 2); ++i) {
    for (int j = (1); j <= (cnt[i]); ++j) {
      for (int k = (1); k <= (cnt[i]); ++k) {
        x = p[i][j];
        y = p[m + n + 2 - i][k];
        z = 0ll;
        if (x.first <= y.first && x.second <= y.second &&
            c[x.first][x.second] == c[y.first][y.second]) {
          if (x.first > 1 && y.first < n)
            z += v[(vt[x.first - 1][x.second] - 1) * cnt[i - 1] +
                   vt[y.first + 1][y.second] - 1];
          if (x.first > 1 && y.second < m)
            z += v[(vt[x.first - 1][x.second] - 1) * cnt[i - 1] +
                   vt[y.first][y.second + 1] - 1];
          if (x.second > 1 && y.first < n)
            z += v[(vt[x.first][x.second - 1] - 1) * cnt[i - 1] +
                   vt[y.first + 1][y.second] - 1];
          if (x.second > 1 && y.second < m)
            z += v[(vt[x.first][x.second - 1] - 1) * cnt[i - 1] +
                   vt[y.first][y.second + 1] - 1];
          if (i == (m + n + 2) / 2) ans = (ans + z) % mod;
        }
        t.push_back(z % mod);
      }
    }
    v = t;
    t.clear();
  }
  cout << ans << '\n';
}
int xtest = 1;
int main() {
  std::ios::sync_with_stdio(false);
  while (xtest--) sol();
  return 0;
}
