#include <bits/stdc++.h>
using namespace std;
const unsigned long long BASE = 257;
const long long INF = 1LL << 60;
int opt = 0;
struct Node;
char S[300][300];
int N, M;
char str[1000];
long long ans;
int F[300][26];
unsigned long long C[300];
char G[1000];
map<vector<int>, int> H;
int NH;
void Clear() {
  H.clear();
  NH = 0;
}
int get(vector<int> &v) {
  if (H.count(v)) return H[v];
  ++NH;
  H[v] = NH;
  return NH;
}
unsigned long long Hash(int i) {
  unsigned long long h = 0;
  int c = 0;
  for (int p = 0; p < 26; ++p) {
    if ((F[i][p] & 1) == 1) {
      ++c;
    }
    if (c > 1) return 0;
    h = h * BASE + F[i][p];
  }
  return h;
}
template <class T>
void move(vector<T> &a, int &lo, int &hi) {
  int n = ((int)((a).size()));
  while (lo - 1 >= 0 && hi + 1 < n && a[lo - 1] == a[hi + 1]) {
    --lo;
    ++hi;
  }
}
void update(int &lo, int &hi, int &l, int &r) {
  if (hi > r) {
    l = lo;
    r = hi;
  }
}
template <class T>
vector<int> manacker(vector<T> &a, int even = 0) {
  int n = a.size();
  vector<int> d(n);
  int l = 0, r = -1;
  for (int i = 0; i < n; ++i) {
    int lo = i, hi = i - even;
    if (r >= i) {
      int j = r - i + l;
      int len = d[j + even];
      if (i + len - 1 < r) {
        hi = i + len - 1;
      } else {
        hi = r;
      }
      lo = 2 * i - hi - even;
    }
    move(a, lo, hi);
    d[i] = hi - i + 1;
    update(lo, hi, l, r);
  }
  return d;
}
int calc(char C[], int n) {
  vector<char> a(C, C + n);
  vector<int> d1 = manacker<char>(a, 0);
  vector<int> d2 = manacker<char>(a, 1);
  int s1 = accumulate(d1.begin(), d1.end(), 0);
  int s2 = accumulate(d2.begin(), d2.end(), 0);
  return s1 + s2;
}
int next(map<unsigned long long, int> &m, unsigned long long &h, int &cur) {
  if (m.count(h)) {
    return m[h];
  } else {
    ++cur;
    m[h] = cur;
    return cur;
  }
}
long long Calc() {
  map<unsigned long long, int> m;
  int cur = 0;
  int res = 0;
  for (int i = 0; i < N; ++i) {
    if (C[i]) {
      int j = i;
      int k = 0;
      while (j < N && C[j]) {
        G[k++] = next(m, C[j], cur);
        j++;
      }
      res += calc(G, k);
      i = j;
    }
  }
  return res;
}
void read() {
  cin >> N >> M;
  for (int i = 1; i <= N; ++i) {
    scanf("%s", str);
    for (int j = 1; j <= M; ++j) {
      S[i][j] = str[j - 1];
      int t = S[i][j] - 'a';
    }
  }
}
void gen() {
  N = M = 250;
  for (int i = 1; i <= N; ++i) {
    for (int j = 1; j <= M; ++j) {
      S[i][j] = rand() % 1 + 'a';
    }
  }
}
int main() {
  read();
  for (int len = 1; len <= M; ++len) {
    memset(F, 0, sizeof(F));
    Clear();
    for (int i = 1; i <= N; ++i) {
      for (int j = 1; j <= len; ++j) {
        F[i][S[i][j] - 'a']++;
      }
      C[i - 1] = Hash(i);
    }
    long long cur = Calc();
    ans += cur;
    for (int j = len + 1; j <= M; ++j) {
      Clear();
      for (int i = 1; i <= N; ++i) {
        F[i][S[i][j] - 'a']++;
        F[i][S[i][j - len] - 'a']--;
        if (F[i][S[i][j] - 'a'] > 250) {
          puts("sdfsd");
        }
        C[i - 1] = Hash(i);
      }
      cur = Calc();
      ans += cur;
    }
  }
  cout << ans << endl;
  return 0;
}
