#include<bits/stdc++.h>
#define INF 1000010000
#define nl '\n'
#define pb push_back
#define ppb pop_back
#define mp make_pair
#define fi first
#define se second
#define pii pair<int,int>
#define pdd pair<double,double>
#define all(c) (c).begin(), (c).end()
#define SORT(c) sort(all(c))
#define sz(c) (c).size()
#define rep(i,n) for( int i = 0; i < n; ++i )
#define repi(i,n) for( int i = 1 ; i <= n; ++i )
#define repn(i,n) for( int i = n - 1 ; i >= 0 ; --i )
#define repf(j,i,n) for( int j = i ; j < n ; ++j )
#define die(s) {std::cout << s << nl;}
#define dier(s) {std::cout << s; return 0;}
#define dbg(var) {std::cout << #var << " = " << var << nl;}
#define vi vector<int>
typedef long long ll;
using namespace std;
int cnt[1111][1111][27];
int main() {
ios_base::sync_with_stdio(false);
cin.tie(NULL);
cout.precision(0);
int n , m;
cin >> n >> m;
vector<string> v(n);
for(auto& el : v) cin >> el;
rep(i , n)
{
rep(j , m)
{
++cnt[i][j][v[i][j] - 'a'];
rep(k , 26)
{
if(i > 0) cnt[i][j][k] += cnt[i - 1][j][k];
if(j > 0) cnt[i][j][k] += cnt[i][j - 1][k];
if(i > 0 && j > 0) cnt[i][j][k] -= cnt[i - 1][j - 1][k];
}
}
}
auto get = [&](int x1 , int y1 , int x2 , int y2 , int k)
{
int res = cnt[x1][y1][k];
if(y2 > 0) res -= cnt[x1][y2 - 1][k];
if(x2 > 0) res -= cnt[x2 - 1][y1][k];
if(x2 > 0 && y2 > 0) res += cnt[x2 - 1][y2 - 1][k];
return res;
};
ll ans = 0;
rep(i , n)
{
rep(j , m)
{
int lh = 1 , rh = n - i - 1;
while(rh - lh > 1)
{
int mid = (rh + lh) / 2;
if(get(i + mid - 1, j , i , j , v[i][j] - 'a') != mid)
{
rh = mid;
}
else
{
lh = mid;
}
}
if(get(i + lh - 1, j , i , j , v[i][j] - 'a') != lh) continue;
const int h = lh;
if(i + 3 * h - 1 < n)
{
char c1 = v[i][j];
char c2 = v[i + h][j];
char c3 = v[i + 2 * h][j];
if(c1 == c2 || c2 == c3) break;
bool good = true;
if(get(i + h - 1, j , i , j , c1 - 'a') != h) good = false;
if(get(i + 2 * h - 1 , j , i + h , j , c2 - 'a') != h) good = false;
if(get(i + 3 * h - 1 , j , i + 2 * h , j , c3 - 'a') != h) good = false;
if(good)
{
int l = j , r = m;
while(r - l > 1)
{
int mid = (r + l) / 2;
if(
get(i + h - 1 , mid , i , j , c1 - 'a') != h * (mid - j + 1) ||
get(i + 2 * h - 1 , mid , i + h , j , c2 - 'a') != h * (mid - j + 1) ||
get(i + 3 * h - 1 , mid , i + 2 * h , j , c3 - 'a') != h * (mid - j + 1)
)
{
r = mid;
}
else
{
l = mid;
}
}
ans += l - j + 1;
}
}
}
}
cout << ans << endl;
return 0;
}
I2luY2x1ZGU8Yml0cy9zdGRjKysuaD4KCiNkZWZpbmUgSU5GIDEwMDAwMTAwMDAKI2RlZmluZSBubCAnXG4nCiNkZWZpbmUgcGIgcHVzaF9iYWNrCiNkZWZpbmUgcHBiIHBvcF9iYWNrCiNkZWZpbmUgbXAgbWFrZV9wYWlyCiNkZWZpbmUgZmkgZmlyc3QKI2RlZmluZSBzZSBzZWNvbmQKI2RlZmluZSBwaWkgcGFpcjxpbnQsaW50PgojZGVmaW5lIHBkZCBwYWlyPGRvdWJsZSxkb3VibGU+CiNkZWZpbmUgYWxsKGMpIChjKS5iZWdpbigpLCAoYykuZW5kKCkKI2RlZmluZSBTT1JUKGMpIHNvcnQoYWxsKGMpKQojZGVmaW5lIHN6KGMpIChjKS5zaXplKCkKI2RlZmluZSByZXAoaSxuKSBmb3IoIGludCBpID0gMDsgaSA8IG47ICsraSApCiNkZWZpbmUgcmVwaShpLG4pIGZvciggaW50IGkgPSAxIDsgaSA8PSBuOyArK2kgKQojZGVmaW5lIHJlcG4oaSxuKSBmb3IoIGludCBpID0gbiAtIDEgOyBpID49IDAgOyAtLWkgKQojZGVmaW5lIHJlcGYoaixpLG4pIGZvciggaW50IGogPSBpIDsgaiA8IG4gOyArK2ogKQojZGVmaW5lIGRpZShzKSB7c3RkOjpjb3V0IDw8IHMgPDwgbmw7fQojZGVmaW5lIGRpZXIocykge3N0ZDo6Y291dCA8PCBzOyByZXR1cm4gMDt9CiNkZWZpbmUgZGJnKHZhcikge3N0ZDo6Y291dCA8PCAjdmFyIDw8ICIgID0gIiA8PCB2YXIgPDwgbmw7fQojZGVmaW5lIHZpIHZlY3RvcjxpbnQ+CnR5cGVkZWYgbG9uZyBsb25nIGxsOwoKdXNpbmcgbmFtZXNwYWNlIHN0ZDsKCmludCBjbnRbMTExMV1bMTExMV1bMjddOwoKaW50IG1haW4oKSB7Cglpb3NfYmFzZTo6c3luY193aXRoX3N0ZGlvKGZhbHNlKTsKCWNpbi50aWUoTlVMTCk7Cgljb3V0LnByZWNpc2lvbigwKTsgCgoJaW50IG4gLCBtOwoJY2luID4+IG4gPj4gbTsKCQoJdmVjdG9yPHN0cmluZz4gdihuKTsKCWZvcihhdXRvJiBlbCA6IHYpIGNpbiA+PiBlbDsKCQoJcmVwKGkgLCBuKQoJewoJCXJlcChqICwgbSkKCQl7CgkJCSsrY250W2ldW2pdW3ZbaV1bal0gLSAnYSddOwoJCQlyZXAoayAsIDI2KQoJCQl7CgkJCQlpZihpID4gMCkgY250W2ldW2pdW2tdICs9IGNudFtpIC0gMV1bal1ba107CgkJCQlpZihqID4gMCkgY250W2ldW2pdW2tdICs9IGNudFtpXVtqIC0gMV1ba107CgkJCQlpZihpID4gMCAmJiBqID4gMCkgY250W2ldW2pdW2tdIC09IGNudFtpIC0gMV1baiAtIDFdW2tdOwoJCQl9CgkJfQoJfQoJCglhdXRvIGdldCA9IFsmXShpbnQgeDEgLCBpbnQgeTEgLCBpbnQgeDIgLCBpbnQgeTIgLCBpbnQgaykKCXsKCQlpbnQgcmVzID0gY250W3gxXVt5MV1ba107CgkJaWYoeTIgPiAwKSByZXMgLT0gY250W3gxXVt5MiAtIDFdW2tdOwoJCWlmKHgyID4gMCkgcmVzIC09IGNudFt4MiAtIDFdW3kxXVtrXTsKCQlpZih4MiA+IDAgJiYgeTIgPiAwKSByZXMgKz0gY250W3gyIC0gMV1beTIgLSAxXVtrXTsKCQlyZXR1cm4gcmVzOwoJfTsKCQoJbGwgYW5zID0gMDsKCXJlcChpICwgbikKCXsKCQlyZXAoaiAsIG0pCgkJewoJCQlpbnQgbGggPSAxICwgcmggPSBuIC0gaSAtIDE7CgkJCXdoaWxlKHJoIC0gbGggPiAxKQoJCQl7CgkJCQlpbnQgbWlkID0gKHJoICsgbGgpIC8gMjsKCQkJCWlmKGdldChpICsgbWlkIC0gMSwgaiAsIGkgLCBqICwgdltpXVtqXSAtICdhJykgIT0gbWlkKQoJCQkJewoJCQkJCXJoID0gbWlkOwoJCQkJfQoJCQkJZWxzZQoJCQkJewoJCQkJCWxoID0gbWlkOwoJCQkJfQoJCQl9CgkJCQoJCQlpZihnZXQoaSArIGxoIC0gMSwgaiAsIGkgLCBqICwgdltpXVtqXSAtICdhJykgIT0gbGgpIGNvbnRpbnVlOwoJCQkKCQkJY29uc3QgaW50IGggPSBsaDsKCQkJaWYoaSArIDMgKiBoIC0gMSA8IG4pCgkJCXsKCQkJCWNoYXIgYzEgPSB2W2ldW2pdOwoJCQkJY2hhciBjMiA9IHZbaSArIGhdW2pdOwoJCQkJY2hhciBjMyA9IHZbaSArIDIgKiBoXVtqXTsKCQkJCQoJCQkJaWYoYzEgPT0gYzIgfHwgYzIgPT0gYzMpIGJyZWFrOwoJCQkJCgkJCQlib29sIGdvb2QgPSB0cnVlOwoJCQkJaWYoZ2V0KGkgKyBoIC0gMSwgaiAsIGkgLCBqICwgYzEgLSAnYScpICE9IGgpIGdvb2QgPSBmYWxzZTsKCQkJCWlmKGdldChpICsgMiAqIGggLSAxICwgaiAsIGkgKyBoICwgaiAsIGMyIC0gJ2EnKSAhPSBoKSBnb29kID0gZmFsc2U7CgkJCQlpZihnZXQoaSArIDMgKiBoIC0gMSAsIGogLCBpICsgMiAqIGggLCBqICwgYzMgLSAnYScpICE9IGgpIGdvb2QgPSBmYWxzZTsKCQkJCQoJCQkJCgkJCQlpZihnb29kKQoJCQkJewoJCQkJCWludCBsID0gaiAsIHIgPSBtOwoJCQkJCXdoaWxlKHIgLSBsID4gMSkKCQkJCQl7CgkJCQkJCWludCBtaWQgPSAociArIGwpIC8gMjsKCQkJCQkJaWYoCgkJCQkJCQlnZXQoaSArIGggLSAxICwgbWlkICwgaSAsIGogLCBjMSAtICdhJykgIT0gaCAqIChtaWQgLSBqICsgMSkgfHwKCQkJCQkJCWdldChpICsgMiAqIGggLSAxICwgbWlkICwgaSArIGggLCBqICwgYzIgLSAnYScpICE9IGggKiAobWlkIC0gaiArIDEpIHx8CgkJCQkJCQlnZXQoaSArIDMgKiBoIC0gMSAsIG1pZCAsIGkgKyAyICogaCAsIGogLCBjMyAtICdhJykgIT0gaCAqIChtaWQgLSBqICsgMSkKCQkJCQkJICApCgkJCQkJCXsKCQkJCQkJCXIgPSBtaWQ7ICAJCgkJCQkJCX0KCQkJCQkJZWxzZQoJCQkJCQl7CgkJCQkJCQlsID0gbWlkOwoJCQkJCQl9CgkJCQkJfQoJCQkJCQoJCQkJCWFucyArPSBsIC0gaiArIDE7CgkJCQl9CgkJCX0KCQl9Cgl9CgkKCWNvdXQgPDwgYW5zIDw8IGVuZGw7CgoJcmV0dXJuIDA7Cn0=