#include <bits/stdc++.h>
using namespace std;
int n, m, ans;
string s[255];
int valid[255];
pair<int, int> hs[255];
int ctr[255][27];
const int p1 = 31, M1 = 1000000007, p2 = 101, M2 = 1000000009, p3 = 433;
int pw1[255], pw2[255], inv1[255], inv2[255];
pair<int, int> operator+(pair<int, int> p1, pair<int, int> p2) {
  return {(p1.first + p2.first) % M1, (p1.second + p2.second) % M2};
}
int mod_pow(int base, int mod) {
  int ret = 1, exp = mod - 2;
  while (exp) {
    if (exp % 2) ret = (ret * 1LL * base) % mod;
    exp = exp >> 1;
    base = (base * 1LL * base) % mod;
  }
  return ret;
}
void buildhash() {
  pw1[0] = pw2[0] = 1;
  for (int i = 1; i <= 250; ++i)
    pw1[i] = (p1 * 1LL * pw1[i - 1]) % M1,
    pw2[i] = (p2 * 1LL * pw2[i - 1]) % M2;
  for (int i = 0; i <= 250; ++i) {
    if (i == 0)
      inv1[i] = 1;
    else if (i == 1)
      inv1[i] = mod_pow(pw1[i], M1);
    else
      inv1[i] = (inv1[1] * 1LL * inv1[i - 1]) % M1;
  }
  for (int i = 0; i <= 250; ++i) {
    if (i == 0)
      inv2[i] = 1;
    else if (i == 1)
      inv2[i] = mod_pow(pw2[i], M2);
    else
      inv2[i] = (inv2[1] * 1LL * inv2[i - 1]) % M2;
  }
}
void cons_hash(int ind) {
  int m1 = 1, m2 = 1;
  for (int i = 1; i <= 26; ++i) {
    if (i == 1)
      hs[ind] = {ctr[ind][1], ctr[ind][1]};
    else {
      pair<int, int> pres = {((ctr[ind][i]) * 1LL * m1) % M1,
                             ((ctr[ind][i]) * 1LL * m2) % M2};
      hs[ind] = hs[ind] + pres;
    }
    m1 = (m1 * 1LL * p1) % M1;
    m2 = (m2 * 1LL * p2) % M2;
  }
}
pair<int, int> fin[1009 * 3];
pair<int, int> Q[1009 * 10];
int P[1009 * 10], tot, ntot;
void convertToNewString() {
  ntot = 0;
  Q[ntot] = make_pair(-6 * n, -6 * n);
  for (int i = 1; i <= tot; ++i) {
    Q[++ntot] = make_pair(-5 * n, -5 * n);
    Q[++ntot] = fin[i];
  }
  Q[++ntot] = make_pair(-5 * n, -5 * n);
  Q[++ntot] = make_pair(-7 * n, -7 * n);
  for (int i = 0; i <= ntot; ++i) {
    P[i] = 0;
  }
}
void longestPalindromeSubstring() {
  convertToNewString();
  int c = 0, r = 0;
  for (int i = 1; i <= ntot - 1; ++i) {
    int iMirror = c - (i - c);
    if (r > i) {
      P[i] = min((int)(r - i), P[iMirror]);
    }
    while (Q[i + 1 + P[i]] == Q[i - 1 - P[i]]) {
      P[i]++;
    }
    if (i + P[i] > r) {
      c = i;
      r = i + P[i];
    }
  }
  int maxPalindrome = 0;
  int centerIndex = 0;
  for (int i = 1; i <= ntot - 1; ++i) {
    int st = (i - 1 - P[i]) / 2;
    int en = st + P[i] - 1;
    if (en < st) continue;
    int ce = (st + en) / 2;
    ans += ce - st + 1;
  }
  return;
}
int od[505];
void solve(int l) {
  int inval = 0;
  for (int i = 1; i <= n; ++i)
    for (int j = 1; j <= 26; ++j) ctr[i][j] = 0;
  for (int i = 1; i <= n; ++i) od[i] = 0, hs[i] = make_pair(0, 0);
  for (int r = l; r <= m; ++r) {
    tot = 0;
    inval = 0;
    for (int i = 1; i <= n; ++i) {
      if (ctr[i][s[i][r] - 'a' + 1] % 2)
        od[i]--;
      else
        od[i]++;
      ctr[i][s[i][r] - 'a' + 1]++;
      int loc = s[i][r] - 'a' + 1;
      if (od[i] > 1) {
        fin[++tot] = make_pair(-i, -i);
        fin[++tot] = make_pair(-i - n, -i - n);
        fin[++tot] = make_pair(-i - 2 * n, -i - 2 * n);
        valid[i] = 0;
        hs[i] = (hs[i] + make_pair(pw1[loc - 1], pw2[loc - 1]));
        inval += 3;
      } else {
        valid[i] = 1;
        hs[i] = (hs[i] + make_pair(pw1[loc - 1], pw2[loc - 1]));
        fin[++tot] = hs[i];
      }
    }
    ans -= inval;
    longestPalindromeSubstring();
  }
}
int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  buildhash();
  cin >> n >> m;
  for (int i = 1; i <= n; ++i) cin >> s[i], s[i] = " " + s[i];
  for (int i = 1; i <= m; ++i) solve(i);
  cout << ans << '\n';
}
