#include <bits/stdc++.h>
using namespace std;
const int MOD = 1e9 + 7;
const int N = 252;
int count_palindromes(const vector<long long>& s) {
  int n = s.size();
  int d[2][n];
  for (int z = 0; z < 2; z++) {
    for (int i = 0, l = 0, r = -1; i < n; i++) {
      int k = (i > r) ? !z : min(d[z][l + r - i + z], r - i + 1);
      while (0 <= i - k - z && i + k < n && s[i - k - z] == s[i + k]) {
        k++;
      }
      d[z][i] = k--;
      if (i + k > r) {
        l = i - k - z;
        r = i + k;
      }
    }
  }
  long long res = 0;
  for (int i = 0; i < n; i++) res += d[0][i] + d[1][i];
  return res;
}
bool two(int n) {
  n -= n & -n;
  return n > 0;
}
int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  cout.tie(0);
  int n, m;
  cin >> n >> m;
  string grid[n];
  for (int i = 0; i < n; i++) cin >> grid[i];
  int p[26];
  p[0] = 1;
  for (int i = 1; i < 26; i++) p[i] = p[i - 1] * 37;
  long long res = 0;
  for (int i = 0; i < m; i++) {
    int msk[n];
    int hsh[n];
    memset(msk, 0, sizeof(msk));
    memset(hsh, 0, sizeof(hsh));
    for (int j = i; j < m; j++) {
      vector<long long> s;
      for (int k = 0; k < n; k++) {
        msk[k] ^= (1 << (grid[k][j] - 'a'));
        hsh[k] += p[grid[k][j] - 'a'];
        if (two(msk[k])) {
          res += count_palindromes(s);
          s.clear();
        } else {
          s.push_back(hsh[k]);
        }
      }
      res += count_palindromes(s);
    }
  }
  cout << res << endl;
  return 0;
}
