#include <bits/stdc++.h>
using namespace std;
template <class c>
struct rge {
  c b, e;
};
template <class c>
rge<c> range(c i, c j) {
  return rge<c>{i, j};
}
template <class c>
auto dud(c* x) -> decltype(cerr << *x, 0);
template <class c>
char dud(...);
struct debug {
  template <class c>
  debug& operator<<(const c&) {
    return *this;
  }
};
mt19937_64 myrand(time(0));
struct Manachar {
  int n;
  vector<unsigned long long> s;
  vector<bool> valid;
  vector<int> d1, d2;
  Manachar(vector<unsigned long long> v, vector<bool> _valid) {
    n = v.size();
    s = v;
    valid = _valid;
    d1.assign(n, 0);
    d2.assign(n, 0);
  }
  void findPalindrome() {
    for (int i = 0, l = 0, r = -1; i < n; i++) {
      if (!valid[i]) {
        l = i + 1, r = i;
        continue;
      }
      int k = (i > r) ? 1 : min(d1[l + r - i], r - i + 1);
      while (0 <= i - k && i + k < n && s[i - k] == s[i + k] && valid[i - k] &&
             valid[i + k])
        k++;
      d1[i] = k--;
      if (i + k > r) l = i - k, r = i + k;
    }
    for (int i = 0, l = 0, r = -1; i < n; i++) {
      if (!valid[i]) {
        l = i + 1, r = i;
        continue;
      }
      int k = (i > r) ? 0 : min(d2[l + r - i + 1], r - i + 1);
      while (0 <= i - k - 1 && i + k < n && s[i - k - 1] == s[i + k] &&
             valid[i - k] && valid[i + k])
        k++;
      d2[i] = k--;
      if (i + k > r) l = i - k - 1, r = i + k;
    }
  }
  long long totalNumber() {
    findPalindrome();
    long long ret = 0;
    for (int i = 0; i < n; i++) ret += (d1[i] + d2[i]);
    return ret;
  }
};
int main() {
  ios::sync_with_stdio(0);
  cin.tie(), cout.tie();
  int n, m;
  cin >> n >> m;
  string str[n];
  for (int i = 0; i < n; i++) cin >> str[i];
  vector<vector<vector<int>>> cnt(n,
                                  vector<vector<int>>(m, vector<int>(26, 0)));
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < m; j++) {
      if (j != 0) cnt[i][j] = cnt[i][j - 1];
      cnt[i][j][str[i][j] - 'a']++;
    }
  }
  vector<unsigned long long> random(26);
  for (int i = 0; i < 26; i++) random[i] = myrand();
  long long ans = 0;
  for (int l = 0; l < m; l++) {
    for (int r = l; r < m; r++) {
      vector<unsigned long long> v;
      vector<bool> valid(n);
      for (int i = 0; i < n; i++) {
        int sum = 0;
        unsigned long long hashVal = 0;
        vector<int> now(26, 0);
        for (int k = 0; k < 26; k++) {
          now[k] = cnt[i][r][k] - (l == 0 ? 0 : cnt[i][l - 1][k]);
          hashVal += (random[k] * now[k]);
          sum += now[k] & 1;
        }
        valid[i] = 1;
        if ((r - l + 1) & 1 && sum != 1)
          valid[i] = 0;
        else if ((r - l + 1) % 2 == 0 && sum != 0)
          valid[i] = 0;
        v.push_back(hashVal);
      }
      Manachar mc(v, valid);
      long long x = mc.totalNumber();
      ans += x;
    }
  }
  cout << ans << endl;
  return 0;
}
