//new.cpp
/*
Author : Jennie Kim (김제니)
BLΛƆKPIИK in your area !

*/

#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cassert>
#include <cstring>
#include <iomanip>
#include <cstdio>
#include <limits>
#include <string>
#include <vector>
#include <cmath>
#include <deque>
#include <queue>
#include <stack>
#include <map>
#include <set>
using namespace std;

typedef pair<int,int> PII;
typedef double D;
typedef long long LL;
typedef unsigned long long ULL;
typedef long double LD;

#define fi first
#define se second
#define pb push_back
#define pf push_front
#define popb pop_back
#define popf pop_front
#define remove erase
#define endl '\n'

const double eps = 1e-9;
const int INF = 1061109567;
const LL LINF = 4557430888798830399LL;
const LL MOD = 1000000007;
const int dx[8] = {1,0,-1,0,1,1,-1,-1};
const int dy[8] = {0,1,0,-1,1,-1,1,-1};
const double PI = 3.141592653589793;

inline void fasterios(){
	ios_base::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
}

const LL hashConstant = 10;
LL n,m;
string s;
LL arr[1005][1005];
LL hashsum[1005][1005][10];
LL hashfactor[10] = {29,31,37,41,43,47,53,57,59,61};

int main(){
	fasterios();
	cin >> n >> m;
	for(int i = 1;i <= n;i++){
		for(int j = 1;j <= m;j++){
			char ch; cin >> ch;
			arr[i][j] = (ch-'a'+1);
		}
	}
	for(int j = 1;j <= m;j++){
		LL PoweredHash[hashConstant];
		for(int i = 0;i < hashConstant;i++) PoweredHash[i] = 1;
		for(int i = 1;i <= n;i++){
			for(int k = 0;k < hashConstant;k++){
				hashsum[i][j][k] = (arr[i][j]*PoweredHash[k])%MOD;
				PoweredHash[k] = (PoweredHash[k]*hashfactor[k])%MOD;
			}
		}
	}
	for(int i = 1;i <= n;i++){
		for(int j = 1;j <= m;j++){
			for(int k = 0;k < hashConstant;k++){
				hashsum[i][j][k] = (hashsum[i][j][k]+hashsum[i][j-1][k]+hashsum[i-1][j][k])%MOD;
				hashsum[i][j][k] += (MOD-hashsum[i-1][j-1][k]);
				hashsum[i][j][k] %= MOD;
			}
		}
	}
	LL ans = 0;
	vector <PII> segt;
	for(int j = 1;j <= m;j++){
		segt.clear();
		for(int i = 1;i <= n;i++){
			if(arr[i-1][j] == arr[i][j]){
				segt.back().se = i;
			}else{
				segt.pb({i,i});
			}
		}
		// for(int i = 0;i < segt.size();i++) cout << segt[i].fi << " " << segt[i].se << endl;
		LL sz = segt.size();
		sz -= 2;
		for(int i = 1;i <= sz;i++){
			LL presz = segt[i-1].se-segt[i-1].fi+1;
			LL cursz = segt[i].se-segt[i].fi+1;
			LL nxsz = segt[i+1].se-segt[i+1].fi+1;
			if(cursz > presz || cursz > nxsz) continue;
			LL Furthest = segt[i+1].fi+cursz-1;
			LL Nearest = segt[i-1].se-cursz+1;
			LL curhashsum[hashConstant];
			for(int k = 0;k < hashConstant;k++){
				curhashsum[k] = (hashsum[Furthest][j][k]+hashsum[Nearest-1][j-1][k])%MOD;
				curhashsum[k] += (2*MOD)-hashsum[Furthest][j-1][k]-hashsum[Nearest-1][j][k];
				curhashsum[k] %= MOD;
			}
			// for(int mid = j;mid <= m;mid++){
			// 	bool flag = 1;
			// 	// cout << mid << endl;
			// 	for(int k = 0;k < 1;k++){
			// 		LL nowhashsum = hashsum[Furthest][mid][k]-hashsum[Furthest][mid-1][k]-hashsum[Nearest-1][mid][k]+hashsum[Nearest-1][mid-1][k];
			// 		if(nowhashsum != curhashsum[k]){
			// 			flag = 0;
			// 			break;
			// 		}
			// 	}
			// 	if(flag) ans++;
			// 	else break;
			// }
			LL left_ = j;
			LL right_ = m;
			while(left_ < right_){
				LL mid = (left_+right_+1)>>1;
				bool flag = 1;
				for(int k = 0;k < hashConstant;k++){
					LL nowhashsum = (hashsum[Furthest][mid][k]+hashsum[Nearest-1][j-1][k])%MOD;
					nowhashsum += (2*MOD)-hashsum[Furthest][j-1][k]-hashsum[Nearest-1][mid][k];
					nowhashsum %= MOD;
					LL tmp = (curhashsum[k]*(mid-j+1))%MOD;
					if(nowhashsum != tmp){
						flag = 0;
						break;
					}
				}
				if(flag) left_ = mid;
				else right_ = mid-1;
			}
			ans += (left_-j+1);
		}
	}
	cout << ans << endl;
    return 0;
}


//new.cpp
/*
Author : Jennie Kim (김제니)
BLΛƆKPIИK in your area !

*/

#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cassert>
#include <cstring>
#include <iomanip>
#include <cstdio>
#include <limits>
#include <string>
#include <vector>
#include <cmath>
#include <deque>
#include <queue>
#include <stack>
#include <map>
#include <set>
using namespace std;

typedef pair<int,int> PII;
typedef double D;
typedef long long LL;
typedef unsigned long long ULL;
typedef long double LD;

#define fi first
#define se second
#define pb push_back
#define pf push_front
#define popb pop_back
#define popf pop_front
#define remove erase
#define endl '\n'

const double eps = 1e-9;
const int INF = 1061109567;
const LL LINF = 4557430888798830399LL;
const LL MOD = 1000000007;
const int dx[8] = {1,0,-1,0,1,1,-1,-1};
const int dy[8] = {0,1,0,-1,1,-1,1,-1};
const double PI = 3.141592653589793;

inline void fasterios(){
	ios_base::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
}

struct coor{
	LL x,y;
};
LL n,m;
LL arr[1005][1005];
LL hashsum[1005][1005][6];
LL hashfactor[6] = {29,31,37,41,43,47};

int main(){
	fasterios();
	cin >> n >> m;
	for(int i = 1;i <= n;i++){
		for(int j = 1;j <= m;j++){
			char ch; cin >> ch;
			arr[i][j] = (ch-'a'+1);
		}
	}
	for(int j = 1;j <= m;j++){
		LL PoweredHash[6] = {1,1,1,1,1,1};
		for(int i = 1;i <= n;i++){
			for(int k = 0;k < 6;k++){
				hashsum[i][j][k] = arr[i][j]*PoweredHash[k];
				PoweredHash[k] *= hashfactor[k];
			}
		}
	}
	for(int i = 1;i <= n;i++){
		for(int j = 1;j <= m;j++){
			for(int k = 0;k < 6;k++){
				hashsum[i][j][k] += hashsum[i][j-1][k]+hashsum[i-1][j][k]-hashsum[i-1][j-1][k];
			}
		}
	}
	// for(int i = 1;i <= n;i++){
	// 	for(int j = 1;j <= 2;j++){
	// 		cout << hashsum[i][j][0] << " \n"[j == 2];
	// 	}
	// }
	LL ans = 0;
	vector <PII> segt;
	for(int j = 1;j <= m;j++){
		segt.clear();
		for(int i = 1;i <= n;i++){
			if(arr[i-1][j] == arr[i][j]){
				segt.back().se = i;
			}else{
				segt.pb({i,i});
			}
		}
		LL sz = segt.size();
		sz -= 2;
		for(int i = 1;i <= sz;i++){
			LL presz = segt[i-1].se-segt[i-1].fi+1;
			LL cursz = segt[i].se-segt[i].fi+1;
			LL nxsz = segt[i+1].se-segt[i+1].fi+1;
			if(cursz > presz || cursz > nxsz) continue;
			LL Furthest = segt[i+1].fi+cursz-1;
			LL Nearest = segt[i-1].se-cursz+1;
			// cout << Furthest << " " << Nearest << endl;
			LL curhashsum[6];
			for(int k = 0;k < 6;k++){
				curhashsum[k] = hashsum[Furthest][j][k]-hashsum[Furthest][j-1][k]-hashsum[Nearest-1][j][k]+hashsum[Nearest-1][j-1][k];
			}
			LL left_ = j;
			LL right_ = m;
			while(left_ < right_){
				LL mid = (left_+right_+1)>>1;
				// cout << "Currently Checking " << mid << endl;
				bool flag = 1;
				for(int k = 0;k < 4;k++){
					LL nowhashsum = hashsum[Furthest][mid][k]-hashsum[Furthest][j-1][k]-hashsum[Nearest-1][mid][k]+hashsum[Nearest-1][j-1][k];
					// cout << nowhashsum << " " << curhashsum[k]*(mid-j+1) << endl;
					if(nowhashsum != curhashsum[k]*(mid-j+1)){
						flag = 0;
						break;
					}
				}
				if(flag){
					left_ = mid;
				}else{
					right_ = mid-1;
				}
			}
			// cout << segt[i].fi << " " << segt[i].se << " " << j << " " << left_-j+1 << endl;
			ans += left_-j+1;
		}
	}
	cout << ans << endl;
    return 0;
}


//new.cpp
/*
Author : Jennie Kim (김제니)
BLΛƆKPIИK in your area !

*/

#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cassert>
#include <cstring>
#include <iomanip>
#include <cstdio>
#include <limits>
#include <string>
#include <vector>
#include <cmath>
#include <deque>
#include <queue>
#include <stack>
#include <map>
#include <set>
using namespace std;

typedef pair<int,int> PII;
typedef double D;
typedef long long LL;
typedef unsigned long long ULL;
typedef long double LD;

#define fi first
#define se second
#define pb push_back
#define pf push_front
#define popb pop_back
#define popf pop_front
#define remove erase
#define endl '\n'

const double eps = 1e-9;
const int INF = 1061109567;
const LL LINF = 4557430888798830399LL;
const LL MOD = 1000000007;
const int dx[8] = {1,0,-1,0,1,1,-1,-1};
const int dy[8] = {0,1,0,-1,1,-1,1,-1};
const double PI = 3.141592653589793;

inline void fasterios(){
	ios_base::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
}

struct coor{
	LL x,y;
};
LL n,m;
LL arr[1005][1005];
LL hashsum[1005][1005][6];
LL hashfactor[6] = {29,31,37,41,43,47};

int main(){
	fasterios();
	cin >> n >> m;
	for(int i = 1;i <= n;i++){
		for(int j = 1;j <= m;j++){
			char ch; cin >> ch;
			arr[i][j] = (ch-'a'+1);
		}
	}
	for(int j = 1;j <= m;j++){
		LL PoweredHash[6] = {1,1,1,1,1,1};
		for(int i = 1;i <= n;i++){
			for(int k = 0;k < 6;k++){
				hashsum[i][j][k] = (arr[i][j]*PoweredHash[k])%MOD;
				PoweredHash[k] *= hashfactor[k];
				PoweredHash[k] %= MOD;
			}
		}
	}
	for(int i = 1;i <= n;i++){
		for(int j = 1;j <= m;j++){
			for(int k = 0;k < 6;k++){
				hashsum[i][j][k] += (hashsum[i][j-1][k]+hashsum[i-1][j][k])%MOD;
				hashsum[i][j][k] %= MOD;
				hashsum[i][j][k] -= hashsum[i-1][j-1][k];
				hashsum[i][j][k] += MOD;
				hashsum[i][j][k] %= MOD;
			}
		}
	}
	LL ans = 0;
	vector <PII> segt;
	for(int j = 1;j <= m;j++){
		segt.clear();
		for(int i = 1;i <= n;i++){
			if(arr[i-1][j] == arr[i][j]){
				segt.back().se = i;
			}else{
				segt.pb({i,i});
			}
		}
		LL sz = segt.size();
		sz -= 2;
		for(int i = 1;i <= sz;i++){
			LL presz = segt[i-1].se-segt[i-1].fi+1;
			LL cursz = segt[i].se-segt[i].fi+1;
			LL nxsz = segt[i+1].se-segt[i+1].fi+1;
			if(cursz > presz || cursz > nxsz) continue;
			LL Furthest = segt[i+1].fi+cursz-1;
			LL Nearest = segt[i-1].se-cursz+1;
			LL curhashsum[6];
			for(int k = 0;k < 6;k++){
				curhashsum[k] = hashsum[Furthest][j][k]-hashsum[Furthest][j-1][k]+MOD;
				curhashsum[k] %= MOD;
				curhashsum[k] -= hashsum[Nearest-1][j][k];
				curhashsum[k] += MOD;
				curhashsum[k] %= MOD;
				curhashsum[k] += hashsum[Nearest-1][j-1][k];
				curhashsum[k] %= MOD;
			}
			LL left_ = j;
			LL right_ = m;
			while(left_ < right_){
				LL mid = (left_+right_+1)>>1;
				// cout << "Currently Checking " << mid << endl;
				bool flag = 1;
				for(int k = 0;k < 6;k++){
					LL nowhashsum = (hashsum[Furthest][mid][k]+hashsum[Nearest-1][j-1][k])%MOD;
					// cout << nowhashsum << " " << curhashsum[k]*(mid-j+1) << endl;
					nowhashsum += (2*MOD)-hashsum[Furthest][j-1][k]-hashsum[Nearest-1][mid][k];
					nowhashsum %= MOD;
					if(nowhashsum != (curhashsum[k]*(mid-j+1))%MOD){
						flag = 0;
						break;
					}
				}
				if(flag){
					left_ = mid;
				}else{
					right_ = mid-1;
				}
			}
			// cout << segt[i].fi << " " << segt[i].se << " " << j << " " << left_-j+1 << endl;
			ans += left_-j+1;
		}
	}
	cout << ans << endl;
    return 0;
}


//new.cpp
/*
Author : Jennie Kim (김제니)
BLΛƆKPIИK in your area !

*/

#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cassert>
#include <cstring>
#include <iomanip>
#include <cstdio>
#include <limits>
#include <string>
#include <vector>
#include <cmath>
#include <deque>
#include <queue>
#include <stack>
#include <map>
#include <set>
using namespace std;

typedef pair<int,int> PII;
typedef double D;
typedef long long LL;
typedef unsigned long long ULL;
typedef long double LD;

#define fi first
#define se second
#define pb push_back
#define pf push_front
#define popb pop_back
#define popf pop_front
#define remove erase
#define endl '\n'

const double eps = 1e-9;
const int INF = 1061109567;
const LL LINF = 4557430888798830399LL;
const LL MOD = 1000000007;
const int dx[8] = {1,0,-1,0,1,1,-1,-1};
const int dy[8] = {0,1,0,-1,1,-1,1,-1};
const double PI = 3.141592653589793;

inline void fasterios(){
	ios_base::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
}

struct coor{
	LL x,y;
};
LL n,m;
LL arr[1005][1005];
LL hashsum[1005][1005][4];
LL hashfactor[4] = {29,31,37,41};

int main(){
	fasterios();
	cin >> n >> m;
	for(int i = 1;i <= n;i++){
		for(int j = 1;j <= m;j++){
			char ch; cin >> ch;
			arr[i][j] = (ch-'a'+1);
		}
	}
	for(int j = 1;j <= m;j++){
		for(int i = 1;i <= n;i++){
			for(int k = 0;k < 4;k++){
				hashsum[i][j][k] = hashsum[i-1][j][k]*hashfactor[k]+arr[i][j];
			}
		}
	}
	for(int i = 1;i <= n;i++){
		for(int j = 1;j <= m;j++){
			for(int k = 0;k < 4;k++){
				hashsum[i][j][k] += hashsum[i][j-1][k]+hashsum[i-1][j][k]-hashsum[i-1][j-1][k];
			}
		}
	}
	LL ans = 0;
	vector <PII> segt;
	for(int j = 1;j <= m;j++){
		segt.clear();
		for(int i = 1;i <= n;i++){
			if(arr[i-1][j] == arr[i][j]){
				segt.back().se = i;
			}else{
				segt.pb({i,i});
			}
		}
		LL sz = segt.size();
		sz -= 2;
		for(int i = 1;i <= sz;i++){
			LL presz = segt[i-1].se-segt[i-1].fi+1;
			LL cursz = segt[i].se-segt[i].fi+1;
			LL nxsz = segt[i+1].se-segt[i+1].fi+1;
			if(cursz > presz || cursz > nxsz) continue;
			LL curhashsum[4];
			for(int k = 0;k < 4;k++){
				curhashsum[k] = hashsum[segt[i+1].se][j][k]-hashsum[segt[i+1].se][j-1][k]-hashsum[segt[i-1].fi-1][j][k]+hashsum[segt[i-1].fi-1][j-1][k];
			}
			LL left_ = j;
			LL right_ = m;
			while(left_ < right_){
				LL mid = (left_+right_+1)>>1;
				bool flag = 1;
				for(int k = 0;k < 4;k++){
					LL nowhashsum = hashsum[segt[i+1].se][mid][k]-hashsum[segt[i+1].se][j-1][k]-hashsum[segt[i-1].fi-1][mid][k]+hashsum[segt[i-1].fi-1][j-1][k];
					if(nowhashsum != curhashsum[k]*(mid-j+1)){
						flag = 0;
						break;
					}
				}
				if(flag){
					left_ = mid;
				}else{
					right_ = mid-1;
				}
			}
			ans += left_-j+1;
		}
	}
	cout << ans << endl;
    return 0;
}


//new.cpp
/*
Author : Jennie Kim (김제니)
BLΛƆKPIИK in your area !

*/

#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cassert>
#include <cstring>
#include <iomanip>
#include <cstdio>
#include <limits>
#include <string>
#include <vector>
#include <cmath>
#include <deque>
#include <queue>
#include <stack>
#include <map>
#include <set>
using namespace std;

typedef pair<int,int> PII;
typedef double D;
typedef long long LL;
typedef unsigned long long ULL;
typedef long double LD;

#define fi first
#define se second
#define pb push_back
#define pf push_front
#define popb pop_back
#define popf pop_front
#define remove erase
#define endl '\n'

const double eps = 1e-9;
const int INF = 1061109567;
const LL LINF = 4557430888798830399LL;
const LL MOD = 1000000007;
const int dx[8] = {1,0,-1,0,1,1,-1,-1};
const int dy[8] = {0,1,0,-1,1,-1,1,-1};
const double PI = 3.141592653589793;

inline void fasterios(){
	ios_base::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
}

const LL hashConstant = 4;
LL n,m;
string s;
LL arr[1005][1005];
LL hashsum[1005][1005][10];
LL hashfactor[10] = {29,31,37,41,43,47,53,57,59,61};

int main(){
	fasterios();
	cin >> n >> m;
	for(int i = 1;i <= n;i++){
		for(int j = 1;j <= m;j++){
			char ch; cin >> ch;
			arr[i][j] = (ch-'a'+1);
		}
	}
	for(int j = 1;j <= m;j++){
		LL PoweredHash[hashConstant];
		for(int i = 0;i < hashConstant;i++) PoweredHash[i] = 1;
		for(int i = 1;i <= n;i++){
			for(int k = 0;k < hashConstant;k++){
				hashsum[i][j][k] = (arr[i][j]*PoweredHash[k])%MOD;
				PoweredHash[k] = (PoweredHash[k]*hashfactor[k])%MOD;
			}
		}
	}
	for(int i = 1;i <= n;i++){
		for(int j = 1;j <= m;j++){
			for(int k = 0;k < hashConstant;k++){
				hashsum[i][j][k] = (hashsum[i][j][k]+hashsum[i][j-1][k]+hashsum[i-1][j][k])%MOD;
				hashsum[i][j][k] += (MOD-hashsum[i-1][j-1][k]);
				hashsum[i][j][k] %= MOD;
			}
		}
	}
	LL ans = 0;
	vector <PII> segt;
	for(int j = 1;j <= m;j++){
		segt.clear();
		for(int i = 1;i <= n;i++){
			if(arr[i-1][j] == arr[i][j]){
				segt.back().se = i;
			}else{
				segt.pb({i,i});
			}
		}
		// for(int i = 0;i < segt.size();i++) cout << segt[i].fi << " " << segt[i].se << endl;
		LL sz = segt.size();
		sz -= 2;
		for(int i = 1;i <= sz;i++){
			LL presz = segt[i-1].se-segt[i-1].fi+1;
			LL cursz = segt[i].se-segt[i].fi+1;
			LL nxsz = segt[i+1].se-segt[i+1].fi+1;
			if(cursz > presz || cursz > nxsz) continue;
			LL Furthest = segt[i+1].fi+cursz-1;
			LL Nearest = segt[i-1].se-cursz+1;
			LL curhashsum[hashConstant];
			for(int k = 0;k < hashConstant;k++){
				curhashsum[k] = (hashsum[Furthest][j][k]+hashsum[Nearest-1][j-1][k])%MOD;
				curhashsum[k] += (2*MOD)-hashsum[Furthest][j-1][k]-hashsum[Nearest-1][j][k];
				curhashsum[k] %= MOD;
			}
			// for(int mid = j;mid <= m;mid++){
			// 	bool flag = 1;
			// 	// cout << mid << endl;
			// 	for(int k = 0;k < 1;k++){
			// 		LL nowhashsum = hashsum[Furthest][mid][k]-hashsum[Furthest][mid-1][k]-hashsum[Nearest-1][mid][k]+hashsum[Nearest-1][mid-1][k];
			// 		if(nowhashsum != curhashsum[k]){
			// 			flag = 0;
			// 			break;
			// 		}
			// 	}
			// 	if(flag) ans++;
			// 	else break;
			// }
			LL left_ = j;
			LL right_ = m;
			while(left_ < right_){
				LL mid = (left_+right_+1)>>1;
				bool flag = 1;
				for(int k = 0;k < hashConstant;k++){
					LL nowhashsum = (hashsum[Furthest][mid][k]+hashsum[Nearest-1][j-1][k])%MOD;
					nowhashsum += (2*MOD)-hashsum[Furthest][j-1][k]-hashsum[Nearest-1][mid][k];
					nowhashsum %= MOD;
					LL tmp = (curhashsum[k]*(mid-j+1))%MOD;
					if(nowhashsum != tmp){
						flag = 0;
						break;
					}
				}
				if(flag) left_ = mid;
				else right_ = mid-1;
			}
			ans += (left_-j+1);
		}
	}
	cout << ans << endl;
    return 0;
}


#include<bits/stdc++.h>

using namespace std;

using ll   = long long;
using ii   = pair   < int , int >;
using i3   = pair   < int , ii  >;
using li   = pair   < ll  , int >;
using lii  = pair   < ll  , ii  >;
using pll  = pair   < ll  , ll  >;
using vi   = vector < int       >;
using vl   = vector < ll        >;
using vii  = vector < ii        >;
using vpll = vector < pll       >;
using vi3  = vector < i3        >;
using vlii = vector < lii       >;

const int N = 1000 + 5;
const ll INF = 1e17 + 7;
const double eps = 1e-9 , PI = acos(-1);

int n , m;

struct cell{
    char val;
    int L , R , U , D;

    call(){};
};

cell a[N][N];
bool vis[N][N];

int dis(cell c){
    return c.D - c.U + 1;
}

int width(cell c , int col){
    return c.R - col + 1;
}

void solve(int testCase){

    scanf("%d %d" , &n , &m);

    for(int i = 1 ; i <= n ; i ++){
            for(int j = 1 ; j <= m ; j ++){
                    cin >> a[i][j].val;
            }
    }

    for(int i = 1 ; i <= n ; i ++){
            for(int j = m ; j >= 1 ; j --){
                    a[i][j].R = j;
                    if(j < m){
                            if(a[i][j+1].val == a[i][j].val){
                                    a[i][j].R = a[i][j+1].R;
                            }
                    }
            }
    }

    for(int j = 1 ; j <= m ; j ++){
            for(int i = 1 ; i <= n ; i ++){
                    a[i][j].U = i;

                    if(i > 1){
                            if(a[i][j].val == a[i-1][j].val){
                                    a[i][j].U = a[i-1][j].U;
                            }
                    }
            }

            for(int i = n ; i >= 1 ; i --){
                    a[i][j].D = i;

                    if(i < n){
                            if(a[i][j].val == a[i+1][j].val){
                                    a[i][j].D = a[i+1][j].D;
                            }
                    }

            }
    }

    ll ans = 0;
    for(int i = 1 ; i <= n ; i ++){
            for(int j = 1 ; j <= m ; j ++){

                if(vis[i][j])continue;

                int dx1 = a[i][j].U - 1;
                int dx2 = a[i][j].D + 1;

                if((dx1 < 1) || (dx2 > n))continue;

                int L1 = dis(a[dx1][j]);
                int L2 = dis(a[i][j]);
                int L3 = dis(a[dx2][j]);

                if((L1 < L2) || (L3 < L2) )continue;

                int W1 = width(a[dx1][j] , j);
                int W2 = width(a[i][j] , j);
                int W3 = width(a[dx2][j] , j);

                ans += 1ll * min({W1 , W2 , W3});

                for(int k = a[i][j].U ; k <= a[i][j].D ; k ++){
                        vis[k][j] = 1;
                }
            }
    }

    printf("%lld\n" , ans);

}

main(){

    int t = 1;
    // scanf("%d" , &t);

    for(int testCase = 1 ; testCase <= t ; testCase ++){
            solve(testCase);
    }

    return 0;
}

/**
3 3
aba
cba
caa

*/


#include<bits/stdc++.h>

using namespace std;

using ll   = long long;
using ii   = pair   < int , int >;
using i3   = pair   < int , ii  >;
using li   = pair   < ll  , int >;
using lii  = pair   < ll  , ii  >;
using pll  = pair   < ll  , ll  >;
using vi   = vector < int       >;
using vl   = vector < ll        >;
using vii  = vector < ii        >;
using vpll = vector < pll       >;
using vi3  = vector < i3        >;
using vlii = vector < lii       >;

const int N = 2000 + 5;
const ll INF = 1e17 + 7;
const double eps = 1e-9 , PI = acos(-1);

int n , m;

struct cell{
    char val;
    int L , R , U , D;

    call(){};
};

cell a[N][N];
bool vis[N][N];

int dis(cell c){
    return c.D - c.U + 1;
}

int width(cell c , int col){
    return c.R - col + 1;
}

void solve(int testCase){

    scanf("%d %d" , &n , &m);

    for(int i = 1 ; i <= n ; i ++){
            for(int j = 1 ; j <= m ; j ++){
                    cin >> a[i][j].val;
            }
    }

    for(int i = 1 ; i <= n ; i ++){
            for(int j = m ; j >= 1 ; j --){
                    a[i][j].R = j;

                    if(j < m){
                            if(a[i][j+1].val == a[i][j].val){
                                    a[i][j].R = a[i][j+1].R;
                            }
                    }
            }
    }

    for(int j = 1 ; j <= m ; j ++){
            for(int i = 1 ; i <= n ; i ++){
                    a[i][j].U = i;

                    if(i > 1){
                            if(a[i][j].val == a[i-1][j].val){
                                    a[i][j].U = a[i-1][j].U;
                            }
                    }
            }

            for(int i = n ; i >= 1 ; i --){
                    a[i][j].D = i;

                    if(i < n){
                            if(a[i][j].val == a[i+1][j].val){
                                    a[i][j].D = a[i+1][j].D;
                            }
                    }

            }
    }

    ll ans = 0;
    for(int i = 1 ; i <= n ; i ++){
            for(int j = 1 ; j <= m ; j ++){

                if(vis[i][j])continue;
                for(int k = a[i][j].U ; k <= a[i][j].D ; k ++){
                        vis[k][j] = 1;
                }

                int dx1 = a[i][j].U - 1;
                int dx2 = a[i][j].D + 1;

                if((dx1 < 1) || (dx2 > n))continue;

                int L1 = dis(a[dx1][j]);
                int L2 = dis(a[i][j]);
                int L3 = dis(a[dx2][j]);

                if((L1 < L2) || (L3 < L2) )continue;

                int W = 1e9;
                for(int k = a[i][j].U - L2 ; k <= a[i][j].D + L2 ; k ++){
                        W = min(W , width(a[k][j] , j));
                }

                ans += 1ll * W;

            }
    }

    printf("%lld\n" , ans);

}

main(){

    int t = 1;
    // scanf("%d" , &t);

    for(int testCase = 1 ; testCase <= t ; testCase ++){
            solve(testCase);
    }

    return 0;
}

/**
3 3
aba
cba
caa

*/


4 3
aaa
bbb
ccb
ddd
#include<bits/stdc++.h>

using namespace std;

using ll   = long long;
using ii   = pair   < int , int >;
using i3   = pair   < int , ii  >;
using li   = pair   < ll  , int >;
using lii  = pair   < ll  , ii  >;
using pll  = pair   < ll  , ll  >;
using vi   = vector < int       >;
using vl   = vector < ll        >;
using vii  = vector < ii        >;
using vpll = vector < pll       >;
using vi3  = vector < i3        >;
using vlii = vector < lii       >;

const int N = 2000 + 5;
const ll INF = 1e17 + 7;
const double eps = 1e-9 , PI = acos(-1);

int n , m;

struct cell{
    char val;
    int L , R , U , D;

    call(){};
};

cell a[N][N];
bool vis[N][N];

int dis(cell c){
    return c.D - c.U + 1;
}

int width(cell c , int col){
    return c.R - col + 1;
}

void solve(int testCase){

    scanf("%d %d" , &n , &m);

    for(int i = 1 ; i <= n ; i ++){
            for(int j = 1 ; j <= m ; j ++){
                    cin >> a[i][j].val;
            }
    }

    for(int i = 1 ; i <= n ; i ++){
            for(int j = m ; j >= 1 ; j --){
                    a[i][j].R = j;

                    if(j < m){
                            if(a[i][j+1].val == a[i][j].val){
                                    a[i][j].R = a[i][j+1].R;
                            }
                    }
            }
    }

    for(int j = 1 ; j <= m ; j ++){
            for(int i = 1 ; i <= n ; i ++){
                    a[i][j].U = i;

                    if(i > 1){
                            if(a[i][j].val == a[i-1][j].val){
                                    a[i][j].U = a[i-1][j].U;
                            }
                    }
            }

            for(int i = n ; i >= 1 ; i --){
                    a[i][j].D = i;

                    if(i < n){
                            if(a[i][j].val == a[i+1][j].val){
                                    a[i][j].D = a[i+1][j].D;
                            }
                    }

            }
    }

    ll ans = 0;
    for(int i = 1 ; i <= n ; i ++){
            for(int j = 1 ; j <= m ; j ++){

                if(vis[i][j])continue;
                for(int k = a[i][j].U ; k <= a[i][j].D ; k ++){
                        vis[k][j] = 1;
                }

                int dx1 = a[i][j].U - 1;
                int dx2 = a[i][j].D + 1;

                if((dx1 < 1) || (dx2 > n))continue;

                int L1 = dis(a[dx1][j]);
                int L2 = dis(a[i][j]);
                int L3 = dis(a[dx2][j]);

                if((L1 < L2) || (L3 < L2) )continue;

                int W = 1e9;
                for(int k = a[dx1][j].U ; k <= a[dx2][j].D ; k ++){
                        W = min(W , width(a[k][j] , j));
                }

                ans += 1ll * W;

            }
    }

    printf("%lld\n" , ans);

}

main(){

    int t = 1;
    // scanf("%d" , &t);

    for(int testCase = 1 ; testCase <= t ; testCase ++){
            solve(testCase);
    }

    return 0;
}

/**
3 3
aba
cba
caa

*/


#include<bits/stdc++.h>

using namespace std;

using ll   = long long;
using ii   = pair   < int , int >;
using i3   = pair   < int , ii  >;
using li   = pair   < ll  , int >;
using lii  = pair   < ll  , ii  >;
using pll  = pair   < ll  , ll  >;
using vi   = vector < int       >;
using vl   = vector < ll        >;
using vii  = vector < ii        >;
using vpll = vector < pll       >;
using vi3  = vector < i3        >;
using vlii = vector < lii       >;

const int N = 2000 + 5;
const ll INF = 1e17 + 7;
const double eps = 1e-9 , PI = acos(-1);

int n , m;

struct cell{
    char val;
    int L , R , U , D;

    call(){};
};

cell a[N][N];
bool vis[N][N];

int dis(cell c){
    return c.D - c.U + 1;
}

int width(cell c , int col){
    return c.R - col + 1;
}

void solve(int testCase){

    scanf("%d %d" , &n , &m);

    for(int i = 1 ; i <= n ; i ++){
            for(int j = 1 ; j <= m ; j ++){
                    cin >> a[i][j].val;
            }
    }

    for(int i = 1 ; i <= n ; i ++){
            for(int j = m ; j >= 1 ; j --){
                    a[i][j].R = j;

                    if(j < m){
                            if(a[i][j+1].val == a[i][j].val){
                                    a[i][j].R = a[i][j+1].R;
                            }
                    }
            }
    }

    for(int j = 1 ; j <= m ; j ++){
            for(int i = 1 ; i <= n ; i ++){
                    a[i][j].U = i;

                    if(i > 1){
                            if(a[i][j].val == a[i-1][j].val){
                                    a[i][j].U = a[i-1][j].U;
                            }
                    }
            }

            for(int i = n ; i >= 1 ; i --){
                    a[i][j].D = i;

                    if(i < n){
                            if(a[i][j].val == a[i+1][j].val){
                                    a[i][j].D = a[i+1][j].D;
                            }
                    }

            }
    }

    ll ans = 0;
    for(int i = 1 ; i <= n ; i ++){
            for(int j = 1 ; j <= m ; j ++){

                if(vis[i][j])continue;
                for(int k = a[i][j].U ; k <= a[i][j].D ; k ++){
                        vis[k][j] = 1;
                }

                int dx1 = a[i][j].U - 1;
                int dx2 = a[i][j].D + 1;

                if((dx1 < 1) || (dx2 > n))continue;

                int L1 = dis(a[dx1][j]);
                int L2 = dis(a[i][j]);
                int L3 = dis(a[dx2][j]);

                if((L1 < L2) || (L3 < L2) )continue;

                int W1 = width(a[dx1][j] , j);
                int W2 = width(a[i][j] , j);
                int W3 = width(a[dx2][j] , j);

                ans += 1ll * min({W1 , W2 , W3});

            }
    }

    printf("%lld\n" , ans);

}

main(){

    int t = 1;
    // scanf("%d" , &t);

    for(int testCase = 1 ; testCase <= t ; testCase ++){
            solve(testCase);
    }

    return 0;
}

/**
3 3
aba
cba
caa

*/


#include<bits/stdc++.h>

using namespace std;

using ll   = long long;
using ii   = pair   < int , int >;
using i3   = pair   < int , ii  >;
using li   = pair   < ll  , int >;
using lii  = pair   < ll  , ii  >;
using pll  = pair   < ll  , ll  >;
using vi   = vector < int       >;
using vl   = vector < ll        >;
using vii  = vector < ii        >;
using vpll = vector < pll       >;
using vi3  = vector < i3        >;
using vlii = vector < lii       >;

const int N = 2000 + 5;
const ll INF = 1e17 + 7;
const double eps = 1e-9 , PI = acos(-1);

int n , m;

struct cell{
    char val;
    int L , R , U , D;

    call(){};
};

cell a[N][N];
bool vis[N][N];

int dis(cell c){
    return c.D - c.U + 1;
}

int width(cell c , int col){
    return c.R - col + 1;
}

void solve(int testCase){

    scanf("%d %d" , &n , &m);

    for(int i = 1 ; i <= n ; i ++){
            for(int j = 1 ; j <= m ; j ++){
                    cin >> a[i][j].val;
            }
    }

    for(int i = 1 ; i <= n ; i ++){
            for(int j = m ; j >= 1 ; j --){
                    a[i][j].R = j;

                    if(j < m){
                            if(a[i][j+1].val == a[i][j].val){
                                    a[i][j].R = a[i][j+1].R;
                            }
                    }
            }
    }

    for(int j = 1 ; j <= m ; j ++){
            for(int i = 1 ; i <= n ; i ++){
                    a[i][j].U = i;

                    if(i > 1){
                            if(a[i][j].val == a[i-1][j].val){
                                    a[i][j].U = a[i-1][j].U;
                            }
                    }
            }

            for(int i = n ; i >= 1 ; i --){
                    a[i][j].D = i;

                    if(i < n){
                            if(a[i][j].val == a[i+1][j].val){
                                    a[i][j].D = a[i+1][j].D;
                            }
                    }

            }
    }

    ll ans = 0;
    for(int i = 1 ; i <= n ; i ++){
            for(int j = 1 ; j <= m ; j ++){

                if(vis[i][j])continue;
                for(int k = a[i][j].U ; k <= a[i][j].D ; k ++){
                        vis[k][j] = 1;
                }

                int dx1 = a[i][j].U - 1;
                int dx2 = a[i][j].D + 1;

                if((dx1 < 1) || (dx2 > n))continue;

                int L1 = dis(a[dx1][j]);
                int L2 = dis(a[i][j]);
                int L3 = dis(a[dx2][j]);

                if((L1 < L2) || (L3 < L2) )continue;

                int W = 1e9;
                for(int k = a[dx1][j].U ; k <= a[dx2][j].D ; k ++){
                        W = min(W , width(a[k][j] , j));
                }

                ans += 1ll * W;

            }
    }

    printf("%lld\n" , ans);

}

main(){

    int t = 1;
    // scanf("%d" , &t);

    for(int testCase = 1 ; testCase <= t ; testCase ++){
            solve(testCase);
    }

    return 0;
}

/**
3 3
aba
cba
caa

*/


#include<bits/stdc++.h>

using namespace std;

using ll   = long long;
using ii   = pair   < int , int >;
using i3   = pair   < int , ii  >;
using li   = pair   < ll  , int >;
using lii  = pair   < ll  , ii  >;
using pll  = pair   < ll  , ll  >;
using vi   = vector < int       >;
using vl   = vector < ll        >;
using vii  = vector < ii        >;
using vpll = vector < pll       >;
using vi3  = vector < i3        >;
using vlii = vector < lii       >;

const int N = 2000 + 5;
const ll INF = 1e17 + 7;
const double eps = 1e-9 , PI = acos(-1);

int n , m;

struct cell{
    char val;
    int L , R , U , D;

    call(){};
};

cell a[N][N];
bool vis[N][N];

int dis(cell c){
    return c.D - c.U + 1;
}

int width(cell c , int col){
    return c.R - col + 1;
}

void solve(int testCase){

    scanf("%d %d" , &n , &m);

    for(int i = 1 ; i <= n ; i ++){
            for(int j = 1 ; j <= m ; j ++){
                    cin >> a[i][j].val;
            }
    }

    for(int i = 1 ; i <= n ; i ++){
            for(int j = m ; j >= 1 ; j --){
                    a[i][j].R = j;
                    if(j < m){
                            if(a[i][j+1].val == a[i][j].val){
                                    a[i][j].R = a[i][j+1].R;
                            }
                    }
            }
    }

    for(int j = 1 ; j <= m ; j ++){
            for(int i = 1 ; i <= n ; i ++){
                    a[i][j].U = i;

                    if(i > 1){
                            if(a[i][j].val == a[i-1][j].val){
                                    a[i][j].U = a[i-1][j].U;
                            }
                    }
            }

            for(int i = n ; i >= 1 ; i --){
                    a[i][j].D = i;

                    if(i < n){
                            if(a[i][j].val == a[i+1][j].val){
                                    a[i][j].D = a[i+1][j].D;
                            }
                    }

            }
    }

    ll ans = 0;
    for(int i = 1 ; i <= n ; i ++){
            for(int j = 1 ; j <= m ; j ++){

                if(vis[i][j])continue;

                int dx1 = a[i][j].U - 1;
                int dx2 = a[i][j].D + 1;

                if((dx1 < 1) || (dx2 > n))continue;

                int L1 = dis(a[dx1][j]);
                int L2 = dis(a[i][j]);
                int L3 = dis(a[dx2][j]);

                if((L1 < L2) || (L3 < L2) )continue;

                int W1 = width(a[dx1][j] , j);
                int W2 = width(a[i][j] , j);
                int W3 = width(a[dx2][j] , j);

                ans += 1ll * min({W1 , W2 , W3});

                for(int k = a[i][j].U ; k <= a[i][j].D ; k ++){
                        vis[k][j] = 1;
                }
            }
    }

    printf("%lld\n" , ans);

}

main(){

    int t = 1;
    // scanf("%d" , &t);

    for(int testCase = 1 ; testCase <= t ; testCase ++){
            solve(testCase);
    }

    return 0;
}

/**
3 3
aba
cba
caa

*/


#include<bits/stdc++.h>

using namespace std;

using ll   = long long;
using ii   = pair   < int , int >;
using i3   = pair   < int , ii  >;
using li   = pair   < ll  , int >;
using lii  = pair   < ll  , ii  >;
using pll  = pair   < ll  , ll  >;
using vi   = vector < int       >;
using vl   = vector < ll        >;
using vii  = vector < ii        >;
using vpll = vector < pll       >;
using vi3  = vector < i3        >;
using vlii = vector < lii       >;

const int N = 1000 + 5;
const ll INF = 1e17 + 7;
const double eps = 1e-9 , PI = acos(-1);

int n , m;

struct cell{
    char val;
    int L , R , U , D;

    call(){};
};

cell a[N][N];
bool vis[N][N];

int dis(cell c){
    return c.D - c.U + 1;
}

int width(cell c , int col){
    return c.R - col + 1;
}

void solve(int testCase){

    scanf("%d %d" , &n , &m);

    for(int i = 1 ; i <= n ; i ++){
            for(int j = 1 ; j <= m ; j ++){
                    cin >> a[i][j].val;
            }
    }

    for(int i = 1 ; i <= n ; i ++){
            for(int j = m ; j >= 1 ; j --){
                    a[i][j].R = j;
                    if(j < m){
                            if(a[i][j+1].val == a[i][j].val){
                                    a[i][j].R = a[i][j+1].R;
                            }
                    }
            }
    }

    for(int j = 1 ; j <= m ; j ++){
            for(int i = 1 ; i <= n ; i ++){
                    a[i][j].U = i;

                    if(i > 1){
                            if(a[i][j].val == a[i-1][j].val){
                                    a[i][j].U = a[i-1][j].U;
                            }
                    }
            }

            for(int i = n ; i >= 1 ; i --){
                    a[i][j].D = i;

                    if(i < n){
                            if(a[i][j].val == a[i+1][j].val){
                                    a[i][j].D = a[i+1][j].D;
                            }
                    }

            }
    }

    ll ans = 0;
    for(int i = 1 ; i <= n ; i ++){
            for(int j = 1 ; j <= m ; j ++){

                if(vis[i][j])continue;

                int dx1 = a[i][j].U - 1;
                int dx2 = a[i][j].D + 1;

                if(dx1 < 1 || dx2 > n)continue;

                int L1 = dis(a[dx1][j]);
                int L2 = dis(a[i][j]);
                int L3 = dis(a[dx2][j]);

                if(L1 < L2 || L3 < L2)continue;

                int W1 = width(a[dx1][j] , j);
                int W2 = width(a[i][j] , j);
                int W3 = width(a[dx2][j] , j);

                ans += 1ll * min({W1 , W2 , W3});

                for(int k = a[i][j].U ; k <= a[i][j].D ; k ++){
                        vis[k][j] = 1;
                }
            }
    }

    printf("%lld\n" , ans);

}

main(){

    int t = 1;
    // scanf("%d" , &t);

    for(int testCase = 1 ; testCase <= t ; testCase ++){
            solve(testCase);
    }

    return 0;
}

/**
3 3
aba
cba
caa

*/


#pragma GCC optimize("O3")

#include "bits/stdc++.h"
#include "ext/pb_ds/tree_policy.hpp"
#include "ext/pb_ds/assoc_container.hpp"
#include "ext/rope"

using namespace std;
using namespace __gnu_pbds;
using namespace __gnu_cxx;

typedef long long ll;
typedef pair<int, int> pii;
#define FOR(i, a, b) for (int i = (a); i < (b); i++)
#define F0R(i, a) for(int i = 0; i < (a); ++i)
#define pb push_back
#define mp make_pair
#define sz(x) (int)x.size()
#define f first
#define s second

template <class T> using Tree = tree<T, null_type, less<T>, rb_tree_tag,tree_order_statistics_node_update>;

struct custom_hash
{
    static uint64_t splitmix64(uint64_t x)
    {
        x += 0x9e3779b97f4a7c15;
        x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9;
        x = (x ^ (x >> 27)) * 0x94d049bb133111eb;
        return x ^ (x >> 31);
    }

    size_t operator()(uint64_t x) const
    {
        static const uint64_t FIXED_RANDOM = chrono::steady_clock::now().time_since_epoch().count();
        return splitmix64(x + FIXED_RANDOM);
    }
};
vector<string> st;
vector<vector<pair<int, int>>> b;
int main()
{
    // freopen("input.txt", "r", stdin);
    // freopen("output.txt", "w", stdout);
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    int n, m;
    cin >> n >> m;
    st.assign(n, "");
    F0R(i, n) cin >> st[i];
    b.assign(n, vector<pair<int, int>> (m, {0, 0}));
    F0R(i, n)
    {
        F0R(j, m)
        {
            if(b[i][j].f != 0) continue;
            int k = 0;
            char c = st[i][j];
            while(j + k < m && st[i][j + k] == c) k++;
            for(int x = k; x >= 1; --x) b[i][j + k - x].f = x;
        }
    }
    F0R(j, m)
    {
        F0R(i, n)
        {
            if(b[i][j].s != 0) continue;
            int k = 0;
            char c = st[i][j];
            while(i + k < n && st[i + k][j] == c) k++;
            for(int x = k; x >= 1; --x) b[i + k - x][j].s = x;
        }
    }
    // F0R(i, n)
    // {
    //     F0R(j, m) cout << b[i][j].f << " ";
    //     cout << "\n";
    // }
    // cout << "\n";
    // F0R(i, n)
    // {
    //     F0R(j, m) cout << b[i][j].s << " ";
    //     cout << "\n";
    // }
    ll res = 0;
    F0R(i, n)
    {
        F0R(j, m)
        {
            vector<char> c;
            c.assign(3, 0);
            c[0] = st[i][j];
            pair<int, int> cur = b[i][j];
            if(i + cur.s < n)
            {
                pair<int, int> nxt = b[i + cur.s][j];
                c[1] = st[i + cur.s][j];
                if(i + cur.s + nxt.s < n)
                {
                    pair<int, int> nxt2 = b[i + cur.s + nxt.s][j];
                    c[2] = st[i + cur.s + nxt.s][j];
                    if(cur.s == nxt.s && nxt2.s >= cur.s)
                    {
                        int cx = min(cur.f, min(nxt2.f, nxt.f));
                        if(c[0] == c[1] || c[1] == c[2]) continue;
                        res += cx;
                    }
                }
            }
        }
    }
    cout << res;
    return 0;
}


#pragma GCC optimize("O3")

#include "bits/stdc++.h"
#include "ext/pb_ds/tree_policy.hpp"
#include "ext/pb_ds/assoc_container.hpp"
#include "ext/rope"

using namespace std;
using namespace __gnu_pbds;
using namespace __gnu_cxx;

typedef long long ll;
typedef pair<int, int> pii;
#define FOR(i, a, b) for (int i = (a); i < (b); i++)
#define F0R(i, a) for(int i = 0; i < (a); ++i)
#define pb push_back
#define mp make_pair
#define sz(x) (int)x.size()
#define f first
#define s second

template <class T> using Tree = tree<T, null_type, less<T>, rb_tree_tag,tree_order_statistics_node_update>;

struct custom_hash
{
    static uint64_t splitmix64(uint64_t x)
    {
        x += 0x9e3779b97f4a7c15;
        x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9;
        x = (x ^ (x >> 27)) * 0x94d049bb133111eb;
        return x ^ (x >> 31);
    }

    size_t operator()(uint64_t x) const
    {
        static const uint64_t FIXED_RANDOM = chrono::steady_clock::now().time_since_epoch().count();
        return splitmix64(x + FIXED_RANDOM);
    }
};
vector<string> st;
vector<vector<pair<int, int>>> b;
int main()
{
    // freopen("input.txt", "r", stdin);
    // freopen("output.txt", "w", stdout);
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    int n, m;
    cin >> n >> m;
    st.assign(n, "");
    F0R(i, n) cin >> st[i];
    b.assign(n, vector<pair<int, int>> (m, {0, 0}));
    //horizontal
    F0R(i, n)
    {
        F0R(j, m)
        {
            if(b[i][j].f != 0) continue;
            int k = 0;
            char c = st[i][j];
            while(j + k < m && st[i][j + k] == c) k++;
            for(int x = k; x >= 1; --x) b[i][j + k - x].f = x;
        }
    }
    F0R(j, m)
    {
        F0R(i, n)
        {
            if(b[i][j].s != 0) continue;
            int k = 0;
            char c = st[i][j];
            while(i + k < n && st[i + k][j] == c) k++;
            for(int x = k; x >= 1; --x) b[i + k - x][j].s = x;
        }
    }
    // F0R(i, n)
    // {
    //     F0R(j, m) cout << b[i][j].f << " ";
    //     cout << "\n";
    // }
    // cout << "\n";
    // F0R(i, n)
    // {
    //     F0R(j, m) cout << b[i][j].s << " ";
    //     cout << "\n";
    // }
    ll res = 0;
    F0R(i, n)
    {
        F0R(j, m)
        {
            vector<char> c;
            c.assign(3, 0);
            c[0] = st[i][j];
            pair<int, int> cur = b[i][j];
            if(i + b[i][j].s < n)
            {
                pair<int, int> nxt = b[i + b[i][j].s][j];
                c[1] = st[i + b[i][j].s][j];
                if(i + b[i][j].s + nxt.s < n)
                {
                    pair<int, int> nxt2 = b[i + b[i][j].s + nxt.s][j];
                    c[2] = st[i + b[i][j].s + nxt.s][j];
                    if(cur.s == nxt.s && nxt2.s >= cur.s)
                    {
                        int r = cur.s;
                        int cx = min(cur.f, min(nxt2.f, nxt.f));
                        if(c[0] == c[1] || c[1] == c[2] || c[0] == c[2]) continue;
                        res += cx;
                    }
                }
            }
        }
    }
    cout << res;
    return 0;
}


#pragma GCC optimize("O3")

#include "bits/stdc++.h"
#include "ext/pb_ds/tree_policy.hpp"
#include "ext/pb_ds/assoc_container.hpp"
#include "ext/rope"

using namespace std;
using namespace __gnu_pbds;
using namespace __gnu_cxx;

typedef long long ll;
typedef pair<int, int> pii;
#define FOR(i, a, b) for (int i = (a); i < (b); i++)
#define F0R(i, a) for(int i = 0; i < (a); ++i)
#define pb push_back
#define mp make_pair
#define sz(x) (int)x.size()
#define f first
#define s second

template <class T> using Tree = tree<T, null_type, less<T>, rb_tree_tag,tree_order_statistics_node_update>;

struct custom_hash
{
    static uint64_t splitmix64(uint64_t x)
    {
        x += 0x9e3779b97f4a7c15;
        x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9;
        x = (x ^ (x >> 27)) * 0x94d049bb133111eb;
        return x ^ (x >> 31);
    }

    size_t operator()(uint64_t x) const
    {
        static const uint64_t FIXED_RANDOM = chrono::steady_clock::now().time_since_epoch().count();
        return splitmix64(x + FIXED_RANDOM);
    }
};
vector<string> st;
vector<int> t;
vector<vector<pair<int, int>>> b;
void build(int v, int tl, int tr, vector<pair<int, int>> &arr)
{
    if(tl == tr) t[v] = arr[tr].f;
    else
    {
        int tm = (tl + tr)/2;
        build(v * 2, tl, tm, arr);
        build(v * 2 + 1, tm + 1, tr, arr);
        t[v] = min(t[v * 2], t[v * 2 + 1]);
    }
}
int qry(int v, int tl, int tr, int l, int r)
{
    if(l > r) return INT_MAX;
    if(tl == l && tr == r) return t[v];
    int tm = (tl + tr)/2;
    return min(qry(v * 2, tl, tm, l, min(r, tm)), qry(v * 2 + 1, tm + 1, tr, max(l, tm + 1), r));
}
int main()
{
    // freopen("input.txt", "r", stdin);
    // freopen("output.txt", "w", stdout);
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    int n, m;
    cin >> n >> m;
    st.assign(n, "");
    t.assign(4 * n + 1, INT_MAX);
    F0R(i, n) cin >> st[i];
    b.assign(n, vector<pair<int, int>> (m, {0, 0}));
    F0R(i, n)
    {
        F0R(j, m)
        {
            if(b[i][j].f != 0) continue;
            int k = 0;
            char c = st[i][j];
            while(j + k < m && st[i][j + k] == c) k++;
            for(int x = k; x >= 1; --x) b[i][j + k - x].f = x;
        }
    }
    F0R(j, m)
    {
        F0R(i, n)
        {
            if(b[i][j].s != 0) continue;
            int k = 0;
            char c = st[i][j];
            while(i + k < n && st[i + k][j] == c) k++;
            for(int x = k; x >= 1; --x) b[i + k - x][j].s = x;
        }
    }
    // F0R(i, n)
    // {
    //     F0R(j, m) cout << b[i][j].f << " ";
    //     cout << "\n";
    // }
    // cout << "\n";
    // F0R(i, n)
    // {
    //     F0R(j, m) cout << b[i][j].s << " ";
    //     cout << "\n";
    // }
    ll res = 0;
    F0R(j, m)
    {
        vector<pair<int, int>> tx;
        F0R(i, n) tx.pb(b[i][j]);
        build(1, 0, n - 1, tx);
        F0R(i, n)
        {
            vector<char> c;
            c.assign(3, 0);
            c[0] = st[i][j];
            pair<int, int> cur = b[i][j];
            if(i + cur.s < n)
            {
                pair<int, int> nxt = b[i + cur.s][j];
                c[1] = st[i + cur.s][j];
                if(i + cur.s + nxt.s < n)
                {
                    pair<int, int> nxt2 = b[i + cur.s + nxt.s][j];
                    c[2] = st[i + cur.s + nxt.s][j];
                    if(cur.s == nxt.s && nxt2.s >= cur.s)
                    {
                        int cx = qry(1, 0, n - 1, i, i + cur.s + nxt.s + nxt2.s - 1);
                        if(c[0] == c[1] || c[1] == c[2]) continue;
                        // cout << cx << " ";
                        res += cx;
                    }
                }
            }
        }
    }
    cout << res;
    return 0;
}


#pragma GCC optimize("O3")

#include "bits/stdc++.h"
#include "ext/pb_ds/tree_policy.hpp"
#include "ext/pb_ds/assoc_container.hpp"
#include "ext/rope"

using namespace std;
using namespace __gnu_pbds;
using namespace __gnu_cxx;

typedef long long ll;
typedef pair<int, int> pii;
#define FOR(i, a, b) for (int i = (a); i < (b); i++)
#define F0R(i, a) for(int i = 0; i < (a); ++i)
#define pb push_back
#define mp make_pair
#define sz(x) (int)x.size()
#define f first
#define s second

template <class T> using Tree = tree<T, null_type, less<T>, rb_tree_tag,tree_order_statistics_node_update>;

struct custom_hash
{
    static uint64_t splitmix64(uint64_t x)
    {
        x += 0x9e3779b97f4a7c15;
        x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9;
        x = (x ^ (x >> 27)) * 0x94d049bb133111eb;
        return x ^ (x >> 31);
    }

    size_t operator()(uint64_t x) const
    {
        static const uint64_t FIXED_RANDOM = chrono::steady_clock::now().time_since_epoch().count();
        return splitmix64(x + FIXED_RANDOM);
    }
};
vector<string> st;
vector<vector<pair<int, int>>> b;
int main()
{
    // freopen("input.txt", "r", stdin);
    // freopen("output.txt", "w", stdout);
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    int n, m;
    cin >> n >> m;
    st.assign(n, "");
    F0R(i, n) cin >> st[i];
    b.assign(n, vector<pair<int, int>> (m, {0, 0}));
    //horizontal
    F0R(i, n)
    {
        F0R(j, m)
        {
            if(b[i][j].f != 0) continue;
            int k = 0;
            char c = st[i][j];
            while(j + k < m && st[i][j + k] == c) k++;
            for(int x = k; x >= 1; --x) b[i][j + k - x].f = x;
        }
    }
    F0R(j, m)
    {
        F0R(i, n)
        {
            if(b[i][j].s != 0) continue;
            int k = 0;
            char c = st[i][j];
            while(i + k < n && st[i + k][j] == c) k++;
            for(int x = k; x >= 1; --x) b[i + k - x][j].s = x;
        }
    }
    // F0R(i, n)
    // {
    //     F0R(j, m) cout << b[i][j].f << " ";
    //     cout << "\n";
    // }
    // cout << "\n";
    // F0R(i, n)
    // {
    //     F0R(j, m) cout << b[i][j].s << " ";
    //     cout << "\n";
    // }
    ll res = 0;
    F0R(i, n)
    {
        F0R(j, m)
        {
            vector<char> c;
            c.assign(3, 0);
            c[0] = st[i][j];
            pair<int, int> cur = b[i][j];
            if(i + b[i][j].s < n)
            {
                pair<int, int> nxt = b[i + b[i][j].s][j];
                c[1] = st[i + b[i][j].s][j];
                if(i + b[i][j].s + nxt.s < n)
                {
                    pair<int, int> nxt2 = b[i + b[i][j].s + nxt.s][j];
                    c[2] = st[i + b[i][j].s + nxt.s][j];
                    if(cur.s == nxt.s && nxt2.s >= cur.s)
                    {
                        int cx = min(cur.f, min(nxt2.f, nxt.f));
                        if(c[0] == c[1] || c[1] == c[2]) continue;
                        res += cx;
                    }
                }
            }
        }
    }
    cout << res;
    return 0;
}


#pragma GCC optimize("O3")

#include "bits/stdc++.h"
#include "ext/pb_ds/tree_policy.hpp"
#include "ext/pb_ds/assoc_container.hpp"
#include "ext/rope"

using namespace std;
using namespace __gnu_pbds;
using namespace __gnu_cxx;

typedef long long ll;
typedef pair<int, int> pii;
#define FOR(i, a, b) for (int i = (a); i < (b); i++)
#define F0R(i, a) for(int i = 0; i < (a); ++i)
#define pb push_back
#define mp make_pair
#define sz(x) (int)x.size()
#define f first
#define s second

template <class T> using Tree = tree<T, null_type, less<T>, rb_tree_tag,tree_order_statistics_node_update>;

struct custom_hash
{
    static uint64_t splitmix64(uint64_t x)
    {
        x += 0x9e3779b97f4a7c15;
        x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9;
        x = (x ^ (x >> 27)) * 0x94d049bb133111eb;
        return x ^ (x >> 31);
    }

    size_t operator()(uint64_t x) const
    {
        static const uint64_t FIXED_RANDOM = chrono::steady_clock::now().time_since_epoch().count();
        return splitmix64(x + FIXED_RANDOM);
    }
};
vector<string> st;
vector<int> t;
vector<vector<pair<int, int>>> b;
void build(int v, int tl, int tr, vector<pair<int, int>> &arr)
{
    if(tl == tr) t[v] = arr[tr].f;
    else
    {
        int tm = (tl + tr)/2;
        build(v * 2, tl, tm, arr);
        build(v * 2 + 1, tm + 1, tr, arr);
        t[v] = min(t[v * 2], t[v * 2 + 1]);
    }
}
int qry(int v, int tl, int tr, int l, int r)
{
    if(l > r) return INT_MAX;
    if(tl == l && tr == r) return t[v];
    int tm = (tl + tr)/2;
    return min(qry(v * 2, tl, tm, l, min(r, tm)), qry(v * 2 + 1, tm + 1, tr, max(l, tm + 1), r));
}
int main()
{
    // freopen("input.txt", "r", stdin);
    // freopen("output.txt", "w", stdout);
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    int n, m;
    cin >> n >> m;
    st.assign(n, "");
    t.assign(4 * n + 1, INT_MAX);
    F0R(i, n) cin >> st[i];
    b.assign(n, vector<pair<int, int>> (m, {0, 0}));
    F0R(i, n)
    {
        F0R(j, m)
        {
            if(b[i][j].f != 0) continue;
            int k = 0;
            char c = st[i][j];
            while(j + k < m && st[i][j + k] == c) k++;
            for(int x = k; x >= 1; --x) b[i][j + k - x].f = x;
        }
    }
    F0R(j, m)
    {
        F0R(i, n)
        {
            if(b[i][j].s != 0) continue;
            int k = 0;
            char c = st[i][j];
            while(i + k < n && st[i + k][j] == c) k++;
            for(int x = k; x >= 1; --x) b[i + k - x][j].s = x;
        }
    }
    // F0R(i, n)
    // {
    //     F0R(j, m) cout << b[i][j].f << " ";
    //     cout << "\n";
    // }
    // cout << "\n";
    // F0R(i, n)
    // {
    //     F0R(j, m) cout << b[i][j].s << " ";
    //     cout << "\n";
    // }
    ll res = 0;
    F0R(j, m)
    {
        vector<pair<int, int>> tx;
        F0R(i, n) tx.pb(b[i][j]);
        build(1, 0, n - 1, tx);
        F0R(i, n)
        {
            vector<char> c;
            c.assign(3, 0);
            c[0] = st[i][j];
            pair<int, int> cur = b[i][j];
            if(i + cur.s < n)
            {
                pair<int, int> nxt = b[i + cur.s][j];
                c[1] = st[i + cur.s][j];
                if(i + cur.s + nxt.s < n)
                {
                    pair<int, int> nxt2 = b[i + cur.s + nxt.s][j];
                    c[2] = st[i + cur.s + nxt.s][j];
                    if(cur.s == nxt.s && nxt2.s >= cur.s)
                    {
                        int cx = qry(1, 0, n - 1, i, i + cur.s * 3 - 1);
                        if(c[0] == c[1] || c[1] == c[2]) continue;
                        // cout << cx << " ";
                        res += cx;
                    }
                }
            }
        }
    }
    cout << res;
    return 0;
}


/*input
6 1
a
a
b
b
c
c

*/
#include <bits/stdc++.h>
using namespace std;

#define int long long
#define pii pair<int,int>
#define pb push_back
#define f first
#define s second
#define IOS ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
pii A[1001][1001];
int B[1001][1001];
int calc(vector<pii> v){
	int mn = min(v[0].s,min(v[1].s,v[2].s));
	return mn;
}
signed main() {
	IOS;
	int n,m;
	cin>>n>>m;
	char a[n][m];

	for(int i=0;i<n;i++){
		for(int j=0;j<m;j++)
			cin>>a[i][j];
	}
	for(int i=0;i<n;i++){
		for(int j=m-1;j>=0;j--){
			if(j == (m-1)){
				A[i][j].s = 1 ;
				B[i][j] = 1 ;
			}
			else{
				if(a[i][j]==a[i][j+1]){
					A[i][j].s = A[i][j+1].s+1;
					B[i][j] = B[i][j+1] + 1 ;
				}
				else{
					A[i][j].s = 1 ;
					B[i][j]=1;
				}
			}
		}
	}
	for(int j=0;j<m;j++){
		for(int i=0;i<n;i++){
			if(i==0){
				A[i][j].f=1;
			}
			else{
				if(a[i][j]==a[i-1][j]){
					A[i][j].f = A[i-1][j].f+1;
					A[i][j].s = min(A[i][j].s,A[i-1][j].s);
				}
				else{
					A[i][j].f = 1 ;
				}
			}
		}
		for(int i=n-1;i>=0;i--){
			if(i==0){
				continue;
			}
			else{
				if(a[i][j]==a[i+1][j]){
					B[i][j] = min(B[i][j],B[i+1][j]);
				}
			}
		}
	}
	int ans = 0 ;
	// for(int i=0;i<n;i++){
	// 	for(int j=0;j<m;j++){
	// 		// cout << A[i][j].f << " " << A[i][j].s << " ch ";
	// 		// cout << B[i][j] << " ";
	// 	}
	// 	cout << endl;
	// }
	for(int j=0;j<m;j++){
		for(int i=n-1;i>=2;i-=A[i][j].f){
			vector<pii> v;
			v.pb(A[i][j]);
			int k = i-A[i][j].f;
			if(k == 0 )continue;
			v.pb(A[k][j]);
			int l = k-A[k][j].f;
			if(l < 0 ) continue;
			v.pb(A[l][j]);
			if((v[1].f>v[0].f)||(v[1].f>v[2].f)){
				continue;
			}
			int mn = v[1].f;
			v[0].s = A[k+mn-1][j].s;
			v[2].s = B[l-mn+1][j];
			ans += calc(v);
		}
	}
	cout << ans << endl;
return 0;
}


/*input
6 1
a
a
b
b
c
c

*/
#include <bits/stdc++.h>
using namespace std;

#define int long long
#define pii pair<int,int>
#define pb push_back
#define f first
#define s second
#define IOS ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
pii A[1001][1001];
int B[1001][1001];
int calc(vector<pii> v){

	int mn = min(v[0].s,min(v[1].s,v[2].s));
	return mn;
}
signed main() {
	IOS;
	int n,m;
	cin>>n>>m;
	char a[n][m];

	for(int i=0;i<n;i++){
		for(int j=0;j<m;j++)
			cin>>a[i][j];
	}
	for(int i=0;i<n;i++){
		for(int j=m-1;j>=0;j--){
			if(j == (m-1)){
				A[i][j].s = 1 ;
				B[i][j] = 1 ;
			}
			else{
				if(a[i][j]==a[i][j+1]){
					A[i][j].s = A[i][j+1].s+1;
					B[i][j] = B[i][j+1] + 1 ;
				}
				else{
					A[i][j].s = 1 ;
					B[i][j]=1;
				}
			}
		}
	}
	for(int j=0;j<m;j++){
		for(int i=0;i<n;i++){
			if(i==0){
				A[i][j].f=1;
			}
			else{
				if(a[i][j]==a[i-1][j]){
					A[i][j].f = A[i-1][j].f+1;
					A[i][j].s = min(A[i][j].s,A[i-1][j].s);
				}
				else{
					A[i][j].f = 1 ;
				}
			}
		}
		for(int i=n-1;i>=0;i--){
			if(i==0){
				continue;
			}
			else{
				if(a[i][j]==a[i+1][j]){
					B[i][j] = min(B[i][j],B[i+1][j]);
				}
			}
		}
	}
	int ans = 0 ;
	// for(int i=0;i<n;i++){
	// 	for(int j=0;j<m;j++){
	// 		// cout << A[i][j].f << " " << A[i][j].s << " ch ";
	// 		// cout << B[i][j] << " ";
	// 	}
	// 	cout << endl;
	// }
	for(int j=0;j<m;j++){
		for(int i=n-1;i>=2;i-=A[i][j].f){
			vector<pii> v;
			v.pb(A[i][j]);
			int k = i-A[i][j].f;
			if(k == 0 )continue;
			v.pb(A[k][j]);
			int l = k-A[k][j].f;
			if(l < 0 ) continue;
			v.pb(A[l][j]);
			if((v[1].f>v[0].f)||(v[1].f>v[2].f)){
				continue;
			}
			int mn = v[1].f;
			if(k+mn >= n  ){
				continue;
			}
			v[0].s = A[k+mn][j].s;
			if(l - mn + 1 < 0 ){
				continue;
			}
			v[2].s = B[l-mn+1][j];
			ans += calc(v);
		}
	}
	cout << ans << endl;
return 0;
}


/*input
6 1
a
a
b
b
c
c

*/
#include <bits/stdc++.h>
using namespace std;

#define int long long
#define pii pair<int,int>
#define pb push_back
#define f first
#define s second
#define IOS ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
pii A[1001][1001];
int B[1001][1001];
int calc(vector<pii> v){

	int mn = min(v[0].s,min(v[1].s,v[2].s));
	return mn;
}
signed main() {
	IOS;
	int n,m;
	cin>>n>>m;
	char a[n][m];

	for(int i=0;i<n;i++){
		for(int j=0;j<m;j++)
			cin>>a[i][j];
	}
	for(int i=0;i<n;i++){
		for(int j=m-1;j>=0;j--){
			if(j == (m-1)){
				A[i][j].s = 1 ;
				B[i][j] = 1 ;
			}
			else{
				if(a[i][j]==a[i][j+1]){
					A[i][j].s = A[i][j+1].s+1;
					B[i][j] = B[i][j+1] + 1 ;
				}
				else{
					A[i][j].s = 1 ;
					B[i][j]=1;
				}
			}
		}
	}
	for(int j=0;j<m;j++){
		for(int i=0;i<n;i++){
			if(i==0){
				A[i][j].f=1;
			}
			else{
				if(a[i][j]==a[i-1][j]){
					A[i][j].f = A[i-1][j].f+1;
					A[i][j].s = min(A[i][j].s,A[i-1][j].s);
				}
				else{
					A[i][j].f = 1 ;
				}
			}
		}
		for(int i=n-1;i>=0;i--){
			if(i==0){
				continue;
			}
			else{
				if(a[i][j]==a[i+1][j]){
					B[i][j] = min(B[i][j],B[i+1][j]);
				}
			}
		}
	}
	int ans = 0 ;
	// for(int i=0;i<n;i++){
	// 	for(int j=0;j<m;j++){
	// 		// cout << A[i][j].f << " " << A[i][j].s << " ch ";
	// 		// cout << B[i][j] << " ";
	// 	}
	// 	cout << endl;
	// }
	for(int j=0;j<m;j++){
		for(int i=n-1;i>=2;i-=A[i][j].f){
			vector<pii> v;
			v.pb(A[i][j]);
			int k = i-A[i][j].f;
			if(k == 0 )continue;
			v.pb(A[k][j]);
			int l = k-A[k][j].f;
			if(l < 0 ) continue;
			v.pb(A[l][j]);
			if(v[1].f>v[0].f||v[1].f>v[2].f){
				continue;
			}
			int mn = v[1].f;
			v[0].s = A[k+mn][j].s;
			if(l - mn + 1 < 0 ){
				continue;
			}
			v[2].s = B[l-mn+1][j];
			// cout << "at : " << i << " " << j <<  endl;
			// for(auto x : v){
			// 	cout << x.f << " " << x.s << endl;
			// }
			ans += calc(v);
		}
	}
	cout << ans << endl;
return 0;
}


/*input
4 3
aaa
bbb
ccb
ddd
*/
#include <bits/stdc++.h>
using namespace std;

#define int long long
#define pii pair<int,int>
#define pb push_back
#define f first
#define s second
#define IOS ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
pii A[2001][2001];
int B[2001][2001];
// inline int calc(vector<pii> v){
// 	int mn = min(v[0].s,min(v[1].s,v[2].s));
// 	return mn;
// }
char a[2001][2001];
signed main() {
	IOS;
	int n,m;
	cin>>n>>m;

	for(int i=0;i<n;i++){
		for(int j=0;j<m;j++)
			cin>>a[i][j];
	}
	for(int i=0;i<n;i++){
		for(int j=m-1;j>=0;j--){
			if(j == (m-1)){
				A[i][j].s = 1 ;
				B[i][j] = 1 ;
			}
			else{
				if(a[i][j]==a[i][j+1]){
					A[i][j].s = A[i][j+1].s+1;
					B[i][j] = B[i][j+1] + 1 ;
				}
				else{
					A[i][j].s = 1 ;
					B[i][j]=1;
				}
			}
		}
	}
	for(int j=0;j<m;j++){
		for(int i=0;i<n;i++){
			if(i==0){
				A[i][j].f=1;
			}
			else{
				if(a[i][j]==a[i-1][j]){
					A[i][j].f = A[i-1][j].f+1;
					A[i][j].s = min(A[i][j].s,A[i-1][j].s);
				}
				else{
					A[i][j].f = 1 ;
				}
			}
		}
		for(int i=n-1;i>=0;i--){
			if(i==0){
				continue;
			}
			else{
				if(a[i][j]==a[i+1][j]){
					B[i][j] = min(B[i][j],B[i+1][j]);
				}
			}
		}
	}
	int ans = 0 ;
	// for(int i=0;i<n;i++){
	// 	for(int j=0;j<m;j++){
	// 		// cout << A[i][j].f << " " << A[i][j].s << " ch ";
	// 		// cout << B[i][j] << " ";
	// 	}
	// 	cout << endl;
	// }
	for(int j=0;j<m;j++){
		for(int i=n-1;i>=2;i-=A[i][j].f){
			vector<pii> v;
			v.pb(A[i][j]);
			int k = i-A[i][j].f;
			if(k == 0 )continue;
			v.pb(A[k][j]);
			int l = k-A[k][j].f;
			if(l < 0 ) continue;
			v.pb(A[l][j]);
			if(v.size() < 3 )continue;
			if((v[1].f>v[0].f)||(v[1].f>v[2].f)){
				continue;
			}
			int mn = v[1].f;
			v[0].s = A[k+mn][j].s;
			v[2].s = B[l-mn+1][j];
			ans +=  min(v[0].s,min(v[1].s,v[2].s));
		}
	}
	cout << ans << endl;
return 0;
}


/*input
6 1
a
a
b
b
c
c

*/
#include <bits/stdc++.h>
using namespace std;

#define int long long
#define pii pair<int,int>
#define pb push_back
#define f first
#define s second
#define IOS ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
pii A[1001][1001];
int B[1001][1001];
int calc(vector<pii> v){

	int mn = min(v[0].s,min(v[1].s,v[2].s));
	return mn;
}
signed main() {
	IOS;
	int n,m;
	cin>>n>>m;
	char a[n][m];

	for(int i=0;i<n;i++){
		for(int j=0;j<m;j++)
			cin>>a[i][j];
	}
	for(int i=0;i<n;i++){
		for(int j=m-1;j>=0;j--){
			if(j == (m-1)){
				A[i][j].s = 1 ;
				B[i][j] = 1 ;
			}
			else{
				if(a[i][j]==a[i][j+1]){
					A[i][j].s = A[i][j+1].s+1;
					B[i][j] = B[i][j+1] + 1 ;
				}
				else{
					A[i][j].s = 1 ;
					B[i][j]=1;
				}
			}
		}
	}
	for(int j=0;j<m;j++){
		for(int i=0;i<n;i++){
			if(i==0){
				A[i][j].f=1;
			}
			else{
				if(a[i][j]==a[i-1][j]){
					A[i][j].f = A[i-1][j].f+1;
					A[i][j].s = min(A[i][j].s,A[i-1][j].s);
				}
				else{
					A[i][j].f = 1 ;
				}
			}
		}
		for(int i=n-1;i>=0;i--){
			if(i==0){
				continue;
			}
			else{
				if(a[i][j]==a[i+1][j]){
					B[i][j] = min(B[i][j],B[i+1][j]);
				}
			}
		}
	}
	int ans = 0 ;
	// for(int i=0;i<n;i++){
	// 	for(int j=0;j<m;j++){
	// 		// cout << A[i][j].f << " " << A[i][j].s << " ch ";
	// 		// cout << B[i][j] << " ";
	// 	}
	// 	cout << endl;
	// }
	for(int j=0;j<m;j++){
		for(int i=n-1;i>=2;i-=A[i][j].f){
			vector<pii> v;
			v.pb(A[i][j]);
			int k = i-A[i][j].f;
			if(k == 0 )continue;
			v.pb(A[k][j]);
			int l = k-A[k][j].f;
			if(l < 0 ) continue;
			v.pb(A[l][j]);
			if(v[1].f>v[0].f||v[1].f>v[2].f){
				continue;
			}
			int mn = v[1].f;
			if(k+mn >= n  ){
				continue;
			}
			v[0].s = A[k+mn][j].s;
			if(l - mn + 1 < 0 ){
				continue;
			}
			v[2].s = B[l-mn+1][j];
			ans += calc(v);
		}
	}
	cout << ans << endl;
return 0;
}


/*input
6 1
a
a
b
b
c
c

*/
#include <bits/stdc++.h>
using namespace std;

#define int long long
#define pii pair<int,int>
#define pb push_back
#define f first
#define s second
#define IOS ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
pii A[1001][1001];
int B[1001][1001];
int calc(vector<pii> v){

	int mn = min(v[0].s,min(v[1].s,v[2].s));
	return mn;
}
signed main() {
	IOS;
	int n,m;
	cin>>n>>m;
	char a[n][m];

	for(int i=0;i<n;i++){
		for(int j=0;j<m;j++)
			cin>>a[i][j];
	}
	for(int i=0;i<n;i++){
		for(int j=m-1;j>=0;j--){
			if(j == (m-1)){
				A[i][j].s = 1 ;
				B[i][j] = 1 ;
			}
			else{
				if(a[i][j]==a[i][j+1]){
					A[i][j].s = A[i][j+1].s+1;
					B[i][j] = B[i][j+1] + 1 ;
				}
				else{
					A[i][j].s = 1 ;
					B[i][j]=1;
				}
			}
		}
	}
	for(int j=0;j<m;j++){
		for(int i=0;i<n;i++){
			if(i==0){
				A[i][j].f=1;
			}
			else{
				if(a[i][j]==a[i-1][j]){
					A[i][j].f = A[i-1][j].f+1;
					A[i][j].s = min(A[i][j].s,A[i-1][j].s);
				}
				else{
					A[i][j].f = 1 ;
				}
			}
		}
		for(int i=n-1;i>=0;i--){
			if(i==0){
				continue;
			}
			else{
				if(a[i][j]==a[i+1][j]){
					B[i][j] = min(B[i][j],B[i+1][j]);
				}
			}
		}
	}
	int ans = 0 ;
	// for(int i=0;i<n;i++){
	// 	for(int j=0;j<m;j++){
	// 		// cout << A[i][j].f << " " << A[i][j].s << " ch ";
	// 		// cout << B[i][j] << " ";
	// 	}
	// 	cout << endl;
	// }
	for(int j=0;j<m;j++){
		for(int i=n-1;i>=2;i-=A[i][j].f){
			vector<pii> v;
			v.pb(A[i][j]);
			int k = i-A[i][j].f;
			if(k == 0 )continue;
			v.pb(A[k][j]);
			int l = k-A[k][j].f;
			if(l < 0 ) continue;
			v.pb(A[l][j]);
			if(v[1].f>v[0].f||v[1].f>v[2].f){
				continue;
			}
			int mn = v[1].f;
			v[0].s = A[k+mn][j].s;
			v[2].s = B[l+mn][j];
			// cout << "at : " << i << " " << j <<  endl;
			// for(auto x : v){
			// 	cout << x.f << " " << x.s << endl;
			// }
			ans += calc(v);
		}
	}
	cout << ans << endl;
return 0;
}


/*input
6 1
a
a
b
b
c
c

*/
#include <bits/stdc++.h>
using namespace std;

#define int long long
#define pii pair<int,int>
#define pb push_back
#define f first
#define s second
#define IOS ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
pii A[1001][1001];
int B[1001][1001];
int calc(vector<pii> v){

	int mn = min(v[0].s,min(v[1].s,v[2].s));
	return mn;
}
signed main() {
	IOS;
	int n,m;
	cin>>n>>m;
	char a[n][m];

	for(int i=0;i<n;i++){
		for(int j=0;j<m;j++)
			cin>>a[i][j];
	}
	for(int i=0;i<n;i++){
		for(int j=m-1;j>=0;j--){
			if(j == (m-1)){
				A[i][j].s = 1 ;
				B[i][j] = 1 ;
			}
			else{
				if(a[i][j]==a[i][j+1]){
					A[i][j].s = A[i][j+1].s+1;
					B[i][j] = B[i][j+1] + 1 ;
				}
				else{
					A[i][j].s = 1 ;
					B[i][j]=1;
				}
			}
		}
	}
	for(int j=0;j<m;j++){
		for(int i=0;i<n;i++){
			if(i==0){
				A[i][j].f=1;
			}
			else{
				if(a[i][j]==a[i-1][j]){
					A[i][j].f = A[i-1][j].f+1;
					A[i][j].s = min(A[i][j].s,A[i-1][j].s);
				}
				else{
					A[i][j].f = 1 ;
				}
			}
		}
		for(int i=n-1;i>=0;i--){
			if(i==0){
				continue;
			}
			else{
				if(a[i][j]==a[i+1][j]){
					B[i][j] = min(B[i][j],B[i+1][j]);
				}
			}
		}
	}
	int ans = 0 ;
	// for(int i=0;i<n;i++){
	// 	for(int j=0;j<m;j++){
	// 		// cout << A[i][j].f << " " << A[i][j].s << " ch ";
	// 		// cout << B[i][j] << " ";
	// 	}
	// 	cout << endl;
	// }
	for(int j=0;j<m;j++){
		for(int i=n-1;i>=2;i-=A[i][j].f){
			vector<pii> v;
			v.pb(A[i][j]);
			int k = i-A[i][j].f;
			if(k == 0 )continue;
			v.pb(A[k][j]);
			int l = k-A[k][j].f;
			if(l < 0 ) continue;
			v.pb(A[l][j]);
			if(v[1].f>v[0].f||v[1].f>v[2].f){
				continue;
			}
			int mn = v[1].f;
			v[0].s = A[k+mn][j].s;
			v[2].s = B[l-mn+1][j];
			// cout << "at : " << i << " " << j <<  endl;
			// for(auto x : v){
			// 	cout << x.f << " " << x.s << endl;
			// }
			ans += calc(v);
		}
	}
	cout << ans << endl;
return 0;
}


/*input
4 3
aaa
bbb
ccb
ddd
*/
#include <bits/stdc++.h>
using namespace std;

#define int long long
#define pii pair<int,int>
#define pb push_back
#define f first
#define s second
#define IOS ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
pii A[2001][2001];
int B[2001][2001];
int calc(vector<pii> v){
	int mn = min(v[0].s,min(v[1].s,v[2].s));
	return mn;
}
signed main() {
	IOS;
	int n,m;
	cin>>n>>m;
	char a[n][m];

	for(int i=0;i<n;i++){
		for(int j=0;j<m;j++)
			cin>>a[i][j];
	}
	for(int i=0;i<n;i++){
		for(int j=m-1;j>=0;j--){
			if(j == (m-1)){
				A[i][j].s = 1 ;
				B[i][j] = 1 ;
			}
			else{
				if(a[i][j]==a[i][j+1]){
					A[i][j].s = A[i][j+1].s+1;
					B[i][j] = B[i][j+1] + 1 ;
				}
				else{
					A[i][j].s = 1 ;
					B[i][j]=1;
				}
			}
		}
	}
	for(int j=0;j<m;j++){
		for(int i=0;i<n;i++){
			if(i==0){
				A[i][j].f=1;
			}
			else{
				if(a[i][j]==a[i-1][j]){
					A[i][j].f = A[i-1][j].f+1;
					A[i][j].s = min(A[i][j].s,A[i-1][j].s);
				}
				else{
					A[i][j].f = 1 ;
				}
			}
		}
		for(int i=n-1;i>=0;i--){
			if(i==0){
				continue;
			}
			else{
				if(a[i][j]==a[i+1][j]){
					B[i][j] = min(B[i][j],B[i+1][j]);
				}
			}
		}
	}
	int ans = 0 ;
	// for(int i=0;i<n;i++){
	// 	for(int j=0;j<m;j++){
	// 		// cout << A[i][j].f << " " << A[i][j].s << " ch ";
	// 		// cout << B[i][j] << " ";
	// 	}
	// 	cout << endl;
	// }
	for(int j=0;j<m;j++){
		for(int i=n-1;i>=2;i-=A[i][j].f){
			vector<pii> v;
			v.pb(A[i][j]);
			int k = i-A[i][j].f;
			if(k == 0 )continue;
			v.pb(A[k][j]);
			int l = k-A[k][j].f;
			if(l < 0 ) continue;
			v.pb(A[l][j]);
			if((v[1].f>v[0].f)||(v[1].f>v[2].f)){
				continue;
			}
			int mn = v[1].f;
			v[0].s = A[k+mn][j].s;
			v[2].s = B[l-mn+1][j];
			ans +=  min(v[0].s,min(v[1].s,v[2].s));
		}
	}
	cout << ans << endl;
return 0;
}


/*input
4 3
aaa
bbb
ccb
ddd
*/
#include <bits/stdc++.h>
using namespace std;

#define int long long
#define pii pair<int,int>
#define pb push_back
#define f first
#define s second
#define IOS ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
pii A[2001][2001];
int B[2001][2001];
// inline int calc(vector<pii> v){
// 	int mn = min(v[0].s,min(v[1].s,v[2].s));
// 	return mn;
// }
signed main() {
	IOS;
	int n,m;
	cin>>n>>m;
	char a[n][m];

	for(int i=0;i<n;i++){
		for(int j=0;j<m;j++)
			cin>>a[i][j];
	}
	for(int i=0;i<n;i++){
		for(int j=m-1;j>=0;j--){
			if(j == (m-1)){
				A[i][j].s = 1 ;
				B[i][j] = 1 ;
			}
			else{
				if(a[i][j]==a[i][j+1]){
					A[i][j].s = A[i][j+1].s+1;
					B[i][j] = B[i][j+1] + 1 ;
				}
				else{
					A[i][j].s = 1 ;
					B[i][j]=1;
				}
			}
		}
	}
	for(int j=0;j<m;j++){
		for(int i=0;i<n;i++){
			if(i==0){
				A[i][j].f=1;
			}
			else{
				if(a[i][j]==a[i-1][j]){
					A[i][j].f = A[i-1][j].f+1;
					A[i][j].s = min(A[i][j].s,A[i-1][j].s);
				}
				else{
					A[i][j].f = 1 ;
				}
			}
		}
		for(int i=n-1;i>=0;i--){
			if(i==0){
				continue;
			}
			else{
				if(a[i][j]==a[i+1][j]){
					B[i][j] = min(B[i][j],B[i+1][j]);
				}
			}
		}
	}
	int ans = 0 ;
	// for(int i=0;i<n;i++){
	// 	for(int j=0;j<m;j++){
	// 		// cout << A[i][j].f << " " << A[i][j].s << " ch ";
	// 		// cout << B[i][j] << " ";
	// 	}
	// 	cout << endl;
	// }
	for(int j=0;j<m;j++){
		for(int i=n-1;i>=2;i-=A[i][j].f){
			vector<pii> v;
			v.pb(A[i][j]);
			int k = i-A[i][j].f;
			if(k == 0 )continue;
			v.pb(A[k][j]);
			int l = k-A[k][j].f;
			if(l < 0 ) continue;
			v.pb(A[l][j]);
			if((v[1].f>v[0].f)||(v[1].f>v[2].f)){
				continue;
			}
			int mn = v[1].f;
			v[0].s = A[k+mn][j].s;
			v[2].s = B[l-mn+1][j];
			ans +=  min(v[0].s,min(v[1].s,v[2].s));
		}
	}
	cout << ans << endl;
return 0;
}


/*input
4 3
aaa
bbb
ccb
ddd
*/
#include <bits/stdc++.h>
using namespace std;

#define int long long
#define pii pair<int,int>
#define pb push_back
#define f first
#define s second
#define IOS ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
pii A[2001][2001];
int B[2001][2001];
// inline int calc(vector<pii> v){
// 	int mn = min(v[0].s,min(v[1].s,v[2].s));
// 	return mn;
// }
signed main() {
	IOS;
	int n,m;
	cin>>n>>m;
	char a[n][m];

	for(int i=0;i<n;i++){
		for(int j=0;j<m;j++)
			cin>>a[i][j];
	}
	for(int i=0;i<n;i++){
		for(int j=m-1;j>=0;j--){
			if(j == (m-1)){
				A[i][j].s = 1 ;
				B[i][j] = 1 ;
			}
			else{
				if(a[i][j]==a[i][j+1]){
					A[i][j].s = A[i][j+1].s+1;
					B[i][j] = B[i][j+1] + 1 ;
				}
				else{
					A[i][j].s = 1 ;
					B[i][j]=1;
				}
			}
		}
	}
	for(int j=0;j<m;j++){
		for(int i=0;i<n;i++){
			if(i==0){
				A[i][j].f=1;
			}
			else{
				if(a[i][j]==a[i-1][j]){
					A[i][j].f = A[i-1][j].f+1;
					A[i][j].s = min(A[i][j].s,A[i-1][j].s);
				}
				else{
					A[i][j].f = 1 ;
				}
			}
		}
		for(int i=n-1;i>=0;i--){
			if(i==0){
				continue;
			}
			else{
				if(a[i][j]==a[i+1][j]){
					B[i][j] = min(B[i][j],B[i+1][j]);
				}
			}
		}
	}
	int ans = 0 ;
	// for(int i=0;i<n;i++){
	// 	for(int j=0;j<m;j++){
	// 		// cout << A[i][j].f << " " << A[i][j].s << " ch ";
	// 		// cout << B[i][j] << " ";
	// 	}
	// 	cout << endl;
	// }
	for(int j=0;j<m;j++){
		for(int i=n-1;i>=2;i-=A[i][j].f){
			vector<pii> v;
			v.pb(A[i][j]);
			int k = i-A[i][j].f;
			if(k == 0 )continue;
			v.pb(A[k][j]);
			int l = k-A[k][j].f;
			if(l < 0 ) continue;
			v.pb(A[l][j]);
			if(v.size() < 3 )continue;
			if((v[1].f>v[0].f)||(v[1].f>v[2].f)){
				continue;
			}
			int mn = v[1].f;
			v[0].s = A[k+mn][j].s;
			v[2].s = B[l-mn+1][j];
			ans +=  min(v[0].s,min(v[1].s,v[2].s));
		}
	}
	cout << ans << endl;
return 0;
}


/*input
4 3
aaa
bbb
ccb
ddd

*/
#include <bits/stdc++.h>
using namespace std;

#define int long long
#define pii pair<int,int>
#define pb push_back
#define f first
#define s second
#define IOS ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
pii A[1001][1001];
int calc(vector<pii> v){
	if(v[1].f>v[0].f||v[1].f>v[2].f){
		return 0 ;
	}
	int mn = min(v[0].s,min(v[1].s,v[2].s));
	return mn;
}
signed main() {
	IOS;
	int n,m;
	cin>>n>>m;
	char a[n][m];

	for(int i=0;i<n;i++){
		for(int j=0;j<m;j++)
			cin>>a[i][j];
	}
	for(int i=0;i<n;i++){
		for(int j=m-1;j>=0;j--){
			if(j == (m-1)){
				A[i][j].s = 1 ;
			}
			else{
				if(a[i][j]==a[i][j+1]){
					A[i][j].s = A[i][j+1].s+1;
				}
				else{
					A[i][j].s = 1 ;
				}
			}
		}
	}
	for(int j=0;j<m;j++){
		for(int i=0;i<n;i++){
			if(i==0){
				A[i][j].f = 1 ;
			}
			else{
				if(a[i][j]==a[i-1][j]){
					A[i][j].f = A[i-1][j].f+1;
					A[i][j].s = min(A[i][j].s,A[i-1][j].s);
				}
				else{
					A[i][j].f = 1 ;
				}
			}
		}
	}
	int ans = 0 ;
	// for(int i=0;i<n;i++){
	// 	for(int j=0;j<m;j++){
	// 		cout << A[i][j].f << " " << A[i][j].s << " ch ";
	// 	}
	// 	cout << endl;
	// }
	for(int j=0;j<m;j++){
		for(int i=n-1;i>=2;i-=A[i][j].f){
			vector<pii> v;
			v.pb(A[i][j]);
			int k = i-A[i][j].f;
			if(k == 0 )continue;
			v.pb(A[k][j]);
			int l = k-A[k][j].f;
			if(l < 0 ) continue;
			v.pb(A[l][j]);
			// cout << "at : " << i << " " << j <<  endl;
			// for(auto x : v){
			// 	cout << x.f << " " << x.s << endl;
			// }
			ans += calc(v);
		}
	}
	cout << ans << endl;
return 0;
}


/*input
4 3
aaa
bbb
ccb
ddd
*/
#include <bits/stdc++.h>
using namespace std;

#define int long long
#define pii pair<int,int>
#define pb push_back
#define f first
#define s second
#define IOS ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
pii A[2001][2001];
int B[2001][2001];
inline int calc(vector<pii> v){
	int mn = min(v[0].s,min(v[1].s,v[2].s));
	return mn;
}
signed main() {
	IOS;
	int n,m;
	cin>>n>>m;
	char a[n][m];

	for(int i=0;i<n;i++){
		for(int j=0;j<m;j++)
			cin>>a[i][j];
	}
	for(int i=0;i<n;i++){
		for(int j=m-1;j>=0;j--){
			if(j == (m-1)){
				A[i][j].s = 1 ;
				B[i][j] = 1 ;
			}
			else{
				if(a[i][j]==a[i][j+1]){
					A[i][j].s = A[i][j+1].s+1;
					B[i][j] = B[i][j+1] + 1 ;
				}
				else{
					A[i][j].s = 1 ;
					B[i][j]=1;
				}
			}
		}
	}
	for(int j=0;j<m;j++){
		for(int i=0;i<n;i++){
			if(i==0){
				A[i][j].f=1;
			}
			else{
				if(a[i][j]==a[i-1][j]){
					A[i][j].f = A[i-1][j].f+1;
					A[i][j].s = min(A[i][j].s,A[i-1][j].s);
				}
				else{
					A[i][j].f = 1 ;
				}
			}
		}
		for(int i=n-1;i>=0;i--){
			if(i==0){
				continue;
			}
			else{
				if(a[i][j]==a[i+1][j]){
					B[i][j] = min(B[i][j],B[i+1][j]);
				}
			}
		}
	}
	int ans = 0 ;
	// for(int i=0;i<n;i++){
	// 	for(int j=0;j<m;j++){
	// 		// cout << A[i][j].f << " " << A[i][j].s << " ch ";
	// 		// cout << B[i][j] << " ";
	// 	}
	// 	cout << endl;
	// }
	for(int j=0;j<m;j++){
		for(int i=n-1;i>=2;i-=A[i][j].f){
			vector<pii> v;
			v.pb(A[i][j]);
			int k = i-A[i][j].f;
			if(k == 0 )continue;
			v.pb(A[k][j]);
			int l = k-A[k][j].f;
			if(l < 0 ) continue;
			v.pb(A[l][j]);
			if((v[1].f>v[0].f)||(v[1].f>v[2].f)){
				continue;
			}
			int mn = v[1].f;
			v[0].s = A[k+mn][j].s;
			v[2].s = B[l-mn+1][j];
			ans +=  min(v[0].s,min(v[1].s,v[2].s));
		}
	}
	cout << ans << endl;
return 0;
}


#define __USE_MINGW_ANSI_STDIO 0
#include <bits/stdc++.h>
#define IOS ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
#define endl '\n'
#define INF (1LL<<59)
#define ff first
#define ss second
#define mod 1000000007
#define pb push_back
#define mp make_pair
#define int long long
#define all(a) a.begin(), a.end()
#define inf (1LL<<61)
#define ull unsigned long long
#define debug1(x) cerr << #x << ": " << x <<'\n'
#define debug2(x, y) cerr << #x << ": " << x << '\t' << #y << ": " << y <<'\n'
#define debug3(x, y, z) cerr << #x << ": " << x << '\t' << #y << ": " << y << '\t' << #z << ": " << z <<'\n'
using namespace std;
int dx[]={1,0,-1,0};int dy[]={0,1,0,-1}; //4 Direction
//int dx[]={1,1,0,-1,-1,-1,0,1};int dy[]={0,1,1,1,0,-1,-1,-1};//8 direction
int gcd(int x,int y)
{
    if(y==0)
        return x;
    else
        return gcd(y,x%y);
}
int expo(int n,int m,int p)   //modULAR EXPONENTIATION
{
    int r=1;
    n=n%p;
    while(m>0)
    {
        if(m%2)
            r=(r*n)%p;
        n=(n*n)%p;
        m=m/2;
    }
    return r%p;
}
bool isPrime(int n)
{
    // Corner cases
    if (n <= 1)  return false;
    if (n <= 3)  return true;

    // This is checked so that we can skip
    // middle five numbers in below loop
    if (n%2 == 0 || n%3 == 0) return false;

    for (int i=5; i*i<=n; i=i+6)
        if (n%i == 0 || n%(i+2) == 0)
           return false;

    return true;
}
bool comp(string x,string y)
{
	if(x.size()!=y.size())
		return x.size()<y.size();
	return x<y;
}
int32_t main()
{
   IOS;
   #ifndef ONLINE_JUDGE
   freopen("input.txt","r",stdin);
   freopen("output.txt","w",stdout);
   #endif
   /********************* Code starts here ***********************/
   int n,m;
   ull ans=0;
   cin>>n>>m;
   char a[n][m];
   for(int i=0;i<n;i++)
   {
   	for(int j=0;j<m;j++)
   	{
   		cin>>a[i][j];
   	}
   }
   int hor[n][m],ver[n][m];
   memset(hor,0,sizeof(hor));
   memset(ver,0,sizeof(ver));
   for(int i=0;i<n;i++)
   {
   	for(int j=0;j<m;)
   	{
   		int c=0;
   		char t=a[i][j];
   		int tj=j;
   		while(tj<m&&a[i][tj]==t)
   			tj++,c++;
   		while(j<tj)
   		{
   			hor[i][j]=c;
   			c--;
   			j++;
   		}
   	}
   }
   for(int j=0;j<m;j++)
   {
   	for(int i=0;i<n;)
   	{
   		int c=0;
   		char t=a[i][j];
   		int ti=i;
   		while(ti<n&&a[ti][j]==t)
   			ti++,c++;
   		while(i<ti)
   		{
   			ver[i][j]=c;
   			c--;
   			i++;
   		}
   	}
   }
   // for(int i=0;i<n;i++)
   // {
   // 	for(int j=0;j<m;j++)
   // 	{
   // 		cout<<hor[i][j]<<' ';
   // 	}
   // 	cout<<endl;
   // }
   // for(int i=0;i<n;i++)
   // {
   // 	for(int j=0;j<m;j++)
   // 	{
   // 		cout<<ver[i][j]<<' ';
   // 	}
   // 	cout<<endl;
   // }
   for(int i=0;i<n;i++)
   {
   	for(int j=0;j<m;j++)
   	{
   		int x=i,y=j,Y=hor[i][j];
   		//set<char>t;
   		//t.insert(a[i][j]);
   		if(x+ver[i][j]<n)
   		{
   			x=x+ver[i][j];
   			//t.insert(a[x][y]);
   			Y=min(Y,hor[x][y]);
   			if(ver[i][j]==ver[x][y])
   			{
   				int tx=x;
   				x=x+ver[i][j];
   				//t.insert(a[x][y]);
   				if(x<n&&ver[x][j]>=ver[tx][j]){
   					//t.insert(a[x][y]);
   					Y=min(Y,hor[x][j]);
   					//if(a[i][j]!=a[x][j])
   						ans=ans+Y;
   				}
   			}
   		}
   	}
   }
   cout<<ans<<endl;
}


#define __USE_MINGW_ANSI_STDIO 0
#include <bits/stdc++.h>
#define IOS ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
#define endl '\n'
#define INF (1LL<<59)
#define ff first
#define ss second
#define mod 1000000007
#define pb push_back
#define mp make_pair
#define int long long
#define all(a) a.begin(), a.end()
#define inf (1LL<<61)
#define ull unsigned long long
#define debug1(x) cerr << #x << ": " << x <<'\n'
#define debug2(x, y) cerr << #x << ": " << x << '\t' << #y << ": " << y <<'\n'
#define debug3(x, y, z) cerr << #x << ": " << x << '\t' << #y << ": " << y << '\t' << #z << ": " << z <<'\n'
using namespace std;
int dx[]={1,0,-1,0};int dy[]={0,1,0,-1}; //4 Direction
//int dx[]={1,1,0,-1,-1,-1,0,1};int dy[]={0,1,1,1,0,-1,-1,-1};//8 direction
int gcd(int x,int y)
{
    if(y==0)
        return x;
    else
        return gcd(y,x%y);
}
int expo(int n,int m,int p)   //modULAR EXPONENTIATION
{
    int r=1;
    n=n%p;
    while(m>0)
    {
        if(m%2)
            r=(r*n)%p;
        n=(n*n)%p;
        m=m/2;
    }
    return r%p;
}
bool isPrime(int n)
{
    // Corner cases
    if (n <= 1)  return false;
    if (n <= 3)  return true;

    // This is checked so that we can skip
    // middle five numbers in below loop
    if (n%2 == 0 || n%3 == 0) return false;

    for (int i=5; i*i<=n; i=i+6)
        if (n%i == 0 || n%(i+2) == 0)
           return false;

    return true;
}
bool comp(string x,string y)
{
	if(x.size()!=y.size())
		return x.size()<y.size();
	return x<y;
}
int32_t main()
{
   IOS;
   #ifndef ONLINE_JUDGE
   freopen("input.txt","r",stdin);
   freopen("output.txt","w",stdout);
   #endif
   /********************* Code starts here ***********************/
   int n,m,ans=0;
   cin>>n>>m;
   char a[n][m];
   for(int i=0;i<n;i++)
   {
   	for(int j=0;j<m;j++)
   	{
   		cin>>a[i][j];
   	}
   }
   int hor[n][m],ver[n][m];
   memset(hor,0,sizeof(hor));
   memset(ver,0,sizeof(ver));
   for(int i=0;i<n;i++)
   {
   	for(int j=0;j<m;)
   	{
   		int c=0;
   		char t=a[i][j];
   		int tj=j;
   		while(tj<m&&a[i][tj]==t)
   			tj++,c++;
   		while(j<tj)
   		{
   			hor[i][j]=c;
   			c--;
   			j++;
   		}
   	}
   }
   for(int j=0;j<m;j++)
   {
   	for(int i=0;i<n;)
   	{
   		int c=0;
   		char t=a[i][j];
   		int ti=i;
   		while(ti<n&&a[ti][j]==t)
   			ti++,c++;
   		while(i<ti)
   		{
   			ver[i][j]=c;
   			c--;
   			i++;
   		}
   	}
   }
   // for(int i=0;i<n;i++)
   // {
   // 	for(int j=0;j<m;j++)
   // 	{
   // 		cout<<hor[i][j]<<' ';
   // 	}
   // 	cout<<endl;
   // }
   // for(int i=0;i<n;i++)
   // {
   // 	for(int j=0;j<m;j++)
   // 	{
   // 		cout<<ver[i][j]<<' ';
   // 	}
   // 	cout<<endl;
   // }
   for(int i=0;i<n;i++)
   {
   	for(int j=0;j<m;j++)
   	{
   		int x=i,y=j,Y=hor[i][j];
   		set<char>t;
   		t.insert(a[i][j]);
   		if(x+ver[x][y]<n)
   		{
   			x=x+ver[x][y];
   			t.insert(a[x][y]);
   			Y=min(Y,hor[x][y]);
   			if(ver[i][j]==ver[x][y])
   			{
   				x=x+ver[i][j];
   				t.insert(a[x][y]);
   				if(t.size()==3&&x<n&&ver[x][j]>=ver[i][j]){
   					Y=min(Y,hor[x][j]);
   					ans=ans+Y;
   				}
   			}
   		}
   	}
   }
   cout<<ans<<endl;
}


#define __USE_MINGW_ANSI_STDIO 0
#include <bits/stdc++.h>
#define IOS ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
#define endl '\n'
#define INF (1LL<<59)
#define ff first
#define ss second
#define mod 1000000007
#define pb push_back
#define mp make_pair
#define int long long
#define all(a) a.begin(), a.end()
#define inf (1LL<<61)
#define ull unsigned long long
#define debug1(x) cerr << #x << ": " << x <<'\n'
#define debug2(x, y) cerr << #x << ": " << x << '\t' << #y << ": " << y <<'\n'
#define debug3(x, y, z) cerr << #x << ": " << x << '\t' << #y << ": " << y << '\t' << #z << ": " << z <<'\n'
using namespace std;
int dx[]={1,0,-1,0};int dy[]={0,1,0,-1}; //4 Direction
//int dx[]={1,1,0,-1,-1,-1,0,1};int dy[]={0,1,1,1,0,-1,-1,-1};//8 direction
int gcd(int x,int y)
{
    if(y==0)
        return x;
    else
        return gcd(y,x%y);
}
int expo(int n,int m,int p)   //modULAR EXPONENTIATION
{
    int r=1;
    n=n%p;
    while(m>0)
    {
        if(m%2)
            r=(r*n)%p;
        n=(n*n)%p;
        m=m/2;
    }
    return r%p;
}
bool isPrime(int n)
{
    // Corner cases
    if (n <= 1)  return false;
    if (n <= 3)  return true;

    // This is checked so that we can skip
    // middle five numbers in below loop
    if (n%2 == 0 || n%3 == 0) return false;

    for (int i=5; i*i<=n; i=i+6)
        if (n%i == 0 || n%(i+2) == 0)
           return false;

    return true;
}
bool comp(string x,string y)
{
	if(x.size()!=y.size())
		return x.size()<y.size();
	return x<y;
}
int32_t main()
{
   IOS;
   #ifndef ONLINE_JUDGE
   freopen("input.txt","r",stdin);
   freopen("output.txt","w",stdout);
   #endif
   /********************* Code starts here ***********************/
   int n,m,ans=0;
   cin>>n>>m;
   char a[n][m];
   for(int i=0;i<n;i++)
   {
   	for(int j=0;j<m;j++)
   	{
   		cin>>a[i][j];
   	}
   }
   int hor[n][m],ver[n][m];
   memset(hor,0,sizeof(hor));
   memset(ver,0,sizeof(ver));
   for(int i=0;i<n;i++)
   {
   	for(int j=0;j<m;)
   	{
   		int c=0;
   		char t=a[i][j];
   		int tj=j;
   		while(tj<m&&a[i][tj]==t)
   			tj++,c++;
   		while(j<tj)
   		{
   			hor[i][j]=c;
   			c--;
   			j++;
   		}
   	}
   }
   for(int j=0;j<m;j++)
   {
   	for(int i=0;i<n;)
   	{
   		int c=0;
   		char t=a[i][j];
   		int ti=i;
   		while(ti<n&&a[ti][j]==t)
   			ti++,c++;
   		while(i<ti)
   		{
   			ver[i][j]=c;
   			c--;
   			i++;
   		}
   	}
   }
   // for(int i=0;i<n;i++)
   // {
   // 	for(int j=0;j<m;j++)
   // 	{
   // 		cout<<hor[i][j]<<' ';
   // 	}
   // 	cout<<endl;
   // }
   // for(int i=0;i<n;i++)
   // {
   // 	for(int j=0;j<m;j++)
   // 	{
   // 		cout<<ver[i][j]<<' ';
   // 	}
   // 	cout<<endl;
   // }
   for(int i=0;i<n;i++)
   {
   	for(int j=0;j<m;j++)
   	{
   		int x=i,y=j,Y=hor[i][j];
   		set<char>t;
   		t.insert(a[i][j]);
   		if(x+ver[x][y]<n)
   		{
   			x=x+ver[x][y];
   			t.insert(a[x][y]);
   			Y=min(Y,hor[x][y]);
   			if(ver[i][j]==ver[x][y])
   			{
   				x=x+ver[i][j];
   				t.insert(a[x][y]);
   				if(t.size()==3&&x<n&&ver[x][j]==ver[i][j]){
   					Y=min(Y,hor[x][j]);
   					ans=ans+Y;
   				}
   			}
   		}
   	}
   }
   cout<<ans<<endl;
}


#define __USE_MINGW_ANSI_STDIO 0
#include <bits/stdc++.h>
#define IOS ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
#define endl '\n'
#define INF (1LL<<59)
#define ff first
#define ss second
#define mod 1000000007
#define pb push_back
#define mp make_pair
#define int long long
#define all(a) a.begin(), a.end()
#define inf (1LL<<61)
#define ull unsigned long long
#define debug1(x) cerr << #x << ": " << x <<'\n'
#define debug2(x, y) cerr << #x << ": " << x << '\t' << #y << ": " << y <<'\n'
#define debug3(x, y, z) cerr << #x << ": " << x << '\t' << #y << ": " << y << '\t' << #z << ": " << z <<'\n'
using namespace std;
int dx[]={1,0,-1,0};int dy[]={0,1,0,-1}; //4 Direction
//int dx[]={1,1,0,-1,-1,-1,0,1};int dy[]={0,1,1,1,0,-1,-1,-1};//8 direction
int gcd(int x,int y)
{
    if(y==0)
        return x;
    else
        return gcd(y,x%y);
}
int expo(int n,int m,int p)   //modULAR EXPONENTIATION
{
    int r=1;
    n=n%p;
    while(m>0)
    {
        if(m%2)
            r=(r*n)%p;
        n=(n*n)%p;
        m=m/2;
    }
    return r%p;
}
bool isPrime(int n)
{
    // Corner cases
    if (n <= 1)  return false;
    if (n <= 3)  return true;

    // This is checked so that we can skip
    // middle five numbers in below loop
    if (n%2 == 0 || n%3 == 0) return false;

    for (int i=5; i*i<=n; i=i+6)
        if (n%i == 0 || n%(i+2) == 0)
           return false;

    return true;
}
bool comp(string x,string y)
{
	if(x.size()!=y.size())
		return x.size()<y.size();
	return x<y;
}
int32_t main()
{
   IOS;
   #ifndef ONLINE_JUDGE
   freopen("input.txt","r",stdin);
   freopen("output.txt","w",stdout);
   #endif
   /********************* Code starts here ***********************/
   int n,m,ans=0;
   cin>>n>>m;
   char a[n][m];
   for(int i=0;i<n;i++)
   {
   	for(int j=0;j<m;j++)
   	{
   		cin>>a[i][j];
   	}
   }
   int hor[n][m],ver[n][m];
   memset(hor,0,sizeof(hor));
   memset(ver,0,sizeof(ver));
   for(int i=0;i<n;i++)
   {
   	for(int j=0;j<m;)
   	{
   		int c=0;
   		char t=a[i][j];
   		int tj=j;
   		while(tj<m&&a[i][tj]==t)
   			tj++,c++;
   		while(j<tj)
   		{
   			hor[i][j]=c;
   			c--;
   			j++;
   		}
   	}
   }
   for(int j=0;j<m;j++)
   {
   	for(int i=0;i<n;)
   	{
   		int c=0;
   		char t=a[i][j];
   		int ti=i;
   		while(ti<n&&a[ti][j]==t)
   			ti++,c++;
   		while(i<ti)
   		{
   			ver[i][j]=c;
   			c--;
   			i++;
   		}
   	}
   }
   // for(int i=0;i<n;i++)
   // {
   // 	for(int j=0;j<m;j++)
   // 	{
   // 		cout<<hor[i][j]<<' ';
   // 	}
   // 	cout<<endl;
   // }
   // for(int i=0;i<n;i++)
   // {
   // 	for(int j=0;j<m;j++)
   // 	{
   // 		cout<<ver[i][j]<<' ';
   // 	}
   // 	cout<<endl;
   // }
   for(int i=0;i<n;i++)
   {
   	for(int j=0;j<m;j++)
   	{
   		int x=i,y=j,Y=hor[i][j];
   		//set<char>t;
   		//t.insert(a[i][j]);
   		if(x+ver[i][j]<n)
   		{
   			x=x+ver[i][j];
   			//t.insert(a[x][y]);
   			Y=min(Y,hor[x][y]);
   			if(ver[i][j]==ver[x][y])
   			{
   				int tx=x;
   				x=x+ver[i][j];
   				//t.insert(a[x][y]);
   				if(x<n&&ver[x][j]>=ver[tx][j]){
   					//t.insert(a[x][y]);
   					Y=min(Y,hor[x][j]);
   					//if(a[i][j]!=a[x][j])
   						ans=ans+Y;
   				}
   			}
   		}
   	}
   }
   cout<<ans<<endl;
}


#define __USE_MINGW_ANSI_STDIO 0
#include <bits/stdc++.h>
#define IOS ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
#define endl '\n'
#define INF (1LL<<59)
#define ff first
#define ss second
#define mod 1000000007
#define pb push_back
#define mp make_pair
#define int long long
#define all(a) a.begin(), a.end()
#define inf (1LL<<61)
#define ull unsigned long long
#define debug1(x) cerr << #x << ": " << x <<'\n'
#define debug2(x, y) cerr << #x << ": " << x << '\t' << #y << ": " << y <<'\n'
#define debug3(x, y, z) cerr << #x << ": " << x << '\t' << #y << ": " << y << '\t' << #z << ": " << z <<'\n'
using namespace std;
int dx[]={1,0,-1,0};int dy[]={0,1,0,-1}; //4 Direction
//int dx[]={1,1,0,-1,-1,-1,0,1};int dy[]={0,1,1,1,0,-1,-1,-1};//8 direction
int gcd(int x,int y)
{
    if(y==0)
        return x;
    else
        return gcd(y,x%y);
}
int expo(int n,int m,int p)   //modULAR EXPONENTIATION
{
    int r=1;
    n=n%p;
    while(m>0)
    {
        if(m%2)
            r=(r*n)%p;
        n=(n*n)%p;
        m=m/2;
    }
    return r%p;
}
bool isPrime(int n)
{
    // Corner cases
    if (n <= 1)  return false;
    if (n <= 3)  return true;

    // This is checked so that we can skip
    // middle five numbers in below loop
    if (n%2 == 0 || n%3 == 0) return false;

    for (int i=5; i*i<=n; i=i+6)
        if (n%i == 0 || n%(i+2) == 0)
           return false;

    return true;
}
bool comp(string x,string y)
{
	if(x.size()!=y.size())
		return x.size()<y.size();
	return x<y;
}
int32_t main()
{
   IOS;
   #ifndef ONLINE_JUDGE
   freopen("input.txt","r",stdin);
   freopen("output.txt","w",stdout);
   #endif
   /********************* Code starts here ***********************/
   int n,m,ans=0;
   cin>>n>>m;
   char a[n][m];
   for(int i=0;i<n;i++)
   {
   	for(int j=0;j<m;j++)
   	{
   		cin>>a[i][j];
   	}
   }
   int hor[n][m],ver[n][m];
   memset(hor,0,sizeof(hor));
   memset(ver,0,sizeof(ver));
   for(int i=0;i<n;i++)
   {
   	for(int j=0;j<m;)
   	{
   		int c=0;
   		char t=a[i][j];
   		int tj=j;
   		while(tj<m&&a[i][tj]==t)
   			tj++,c++;
   		while(j<tj)
   		{
   			hor[i][j]=c;
   			c--;
   			j++;
   		}
   	}
   }
   for(int j=0;j<m;j++)
   {
   	for(int i=0;i<n;)
   	{
   		int c=0;
   		char t=a[i][j];
   		int ti=i;
   		while(ti<n&&a[ti][j]==t)
   			ti++,c++;
   		while(i<ti)
   		{
   			ver[i][j]=c;
   			c--;
   			i++;
   		}
   	}
   }
   // for(int i=0;i<n;i++)
   // {
   // 	for(int j=0;j<m;j++)
   // 	{
   // 		cout<<hor[i][j]<<' ';
   // 	}
   // 	cout<<endl;
   // }
   // for(int i=0;i<n;i++)
   // {
   // 	for(int j=0;j<m;j++)
   // 	{
   // 		cout<<ver[i][j]<<' ';
   // 	}
   // 	cout<<endl;
   // }
   for(int i=0;i<n;i++)
   {
   	for(int j=0;j<m;j++)
   	{
   		int x=i,y=j,Y=hor[i][j];
   		//set<char>t;
   		//t.insert(a[i][j]);
   		if(x+ver[x][y]<n)
   		{
   			x=x+ver[x][y];
   			//t.insert(a[x][y]);
   			Y=min(Y,hor[x][y]);
   			if(ver[i][j]==ver[x][y])
   			{
   				x=x+ver[i][j];
   				//t.insert(a[x][y]);
   				if(x<n&&ver[x][j]>=ver[i][j]){
   					//t.insert(a[x][y]);

   					Y=min(Y,hor[x][j]);
   					if(a[i][j]!=a[x][y])
   						ans=ans+Y;
   				}
   			}
   		}
   	}
   }
   cout<<ans<<endl;
}


#define __USE_MINGW_ANSI_STDIO 0
#include <bits/stdc++.h>
#define IOS ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
#define endl '\n'
#define INF (1LL<<59)
#define ff first
#define ss second
#define mod 1000000007
#define pb push_back
#define mp make_pair
#define int long long
#define all(a) a.begin(), a.end()
#define inf (1LL<<61)
#define ull unsigned long long
#define debug1(x) cerr << #x << ": " << x <<'\n'
#define debug2(x, y) cerr << #x << ": " << x << '\t' << #y << ": " << y <<'\n'
#define debug3(x, y, z) cerr << #x << ": " << x << '\t' << #y << ": " << y << '\t' << #z << ": " << z <<'\n'
using namespace std;
int dx[]={1,0,-1,0};int dy[]={0,1,0,-1}; //4 Direction
//int dx[]={1,1,0,-1,-1,-1,0,1};int dy[]={0,1,1,1,0,-1,-1,-1};//8 direction
int gcd(int x,int y)
{
    if(y==0)
        return x;
    else
        return gcd(y,x%y);
}
int expo(int n,int m,int p)   //modULAR EXPONENTIATION
{
    int r=1;
    n=n%p;
    while(m>0)
    {
        if(m%2)
            r=(r*n)%p;
        n=(n*n)%p;
        m=m/2;
    }
    return r%p;
}
bool isPrime(int n)
{
    // Corner cases
    if (n <= 1)  return false;
    if (n <= 3)  return true;

    // This is checked so that we can skip
    // middle five numbers in below loop
    if (n%2 == 0 || n%3 == 0) return false;

    for (int i=5; i*i<=n; i=i+6)
        if (n%i == 0 || n%(i+2) == 0)
           return false;

    return true;
}
bool comp(string x,string y)
{
	if(x.size()!=y.size())
		return x.size()<y.size();
	return x<y;
}
int32_t main()
{
   IOS;
   #ifndef ONLINE_JUDGE
   freopen("input.txt","r",stdin);
   freopen("output.txt","w",stdout);
   #endif
   /********************* Code starts here ***********************/
   int n,m,ans=0;
   cin>>n>>m;
   char a[n][m];
   for(int i=0;i<n;i++)
   {
   	for(int j=0;j<m;j++)
   	{
   		cin>>a[i][j];
   	}
   }
   int hor[n][m],ver[n][m];
   memset(hor,0,sizeof(hor));
   memset(ver,0,sizeof(ver));
   for(int i=0;i<n;i++)
   {
   	for(int j=0;j<m;)
   	{
   		int c=0;
   		char t=a[i][j];
   		int tj=j;
   		while(tj<m&&a[i][tj]==t)
   			tj++,c++;
   		while(j<tj)
   		{
   			hor[i][j]=c;
   			c--;
   			j++;
   		}
   	}
   }
   for(int j=0;j<m;j++)
   {
   	for(int i=0;i<n;)
   	{
   		int c=0;
   		char t=a[i][j];
   		int ti=i;
   		while(ti<n&&a[ti][j]==t)
   			ti++,c++;
   		while(i<ti)
   		{
   			ver[i][j]=c;
   			c--;
   			i++;
   		}
   	}
   }
   // for(int i=0;i<n;i++)
   // {
   // 	for(int j=0;j<m;j++)
   // 	{
   // 		cout<<hor[i][j]<<' ';
   // 	}
   // 	cout<<endl;
   // }
   // for(int i=0;i<n;i++)
   // {
   // 	for(int j=0;j<m;j++)
   // 	{
   // 		cout<<ver[i][j]<<' ';
   // 	}
   // 	cout<<endl;
   // }
   for(int i=0;i<n;i++)
   {
   	for(int j=0;j<m;j++)
   	{
   		int x=i,y=j,Y=hor[i][j];
   		if(x+ver[x][y]<n)
   		{
   			x=x+ver[x][y];
   			Y=min(Y,hor[x][y]);
   			if(ver[i][j]==ver[x][y])
   			{
   				x=x+ver[i][j];
   				if(x<n&&ver[x][j]==ver[i][j]){
   					Y=min(Y,hor[x][j]);
   					ans=ans+Y;
   				}
   			}
   		}
   	}
   }
   cout<<ans<<endl;
}


#define __USE_MINGW_ANSI_STDIO 0
#include <bits/stdc++.h>
#define IOS ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
#define endl '\n'
#define INF (1LL<<59)
#define ff first
#define ss second
#define mod 1000000007
#define pb push_back
#define mp make_pair
#define int long long
#define all(a) a.begin(), a.end()
#define inf (1LL<<61)
#define ull unsigned long long
#define debug1(x) cerr << #x << ": " << x <<'\n'
#define debug2(x, y) cerr << #x << ": " << x << '\t' << #y << ": " << y <<'\n'
#define debug3(x, y, z) cerr << #x << ": " << x << '\t' << #y << ": " << y << '\t' << #z << ": " << z <<'\n'
using namespace std;
int dx[]={1,0,-1,0};int dy[]={0,1,0,-1}; //4 Direction
//int dx[]={1,1,0,-1,-1,-1,0,1};int dy[]={0,1,1,1,0,-1,-1,-1};//8 direction
int gcd(int x,int y)
{
    if(y==0)
        return x;
    else
        return gcd(y,x%y);
}
int expo(int n,int m,int p)   //modULAR EXPONENTIATION
{
    int r=1;
    n=n%p;
    while(m>0)
    {
        if(m%2)
            r=(r*n)%p;
        n=(n*n)%p;
        m=m/2;
    }
    return r%p;
}
bool isPrime(int n)
{
    // Corner cases
    if (n <= 1)  return false;
    if (n <= 3)  return true;

    // This is checked so that we can skip
    // middle five numbers in below loop
    if (n%2 == 0 || n%3 == 0) return false;

    for (int i=5; i*i<=n; i=i+6)
        if (n%i == 0 || n%(i+2) == 0)
           return false;

    return true;
}
int segt[1005][9000];
int hor[1005][1005],ver[1005][1005];
void build(int n,int s,int e,int j)
{
	if(s==e)
	{
		segt[j][n]=hor[s][j];
		return ;
	}
	int m=(s+e)/2;
	build(2*n,s,m,j);
	build(2*n+1,m+1,e,j);
	segt[j][n]=min(segt[j][2*n],segt[j][2*n+1]);
}
int query(int n,int s,int e,int l,int r,int j)
{
	if(s>r||l>e)
		return inf;
	if(l<=s&&e<=r)
		return segt[j][n];
	int m=(s+e)/2;
	return min(query(2*n,s,m,l,r,j),query(2*n+1,m+1,e,l,r,j));
}
int32_t main()
{
   IOS;
   #ifndef ONLINE_JUDGE
   freopen("input.txt","r",stdin);
   freopen("output.txt","w",stdout);
   #endif
   /********************* Code starts here ***********************/
   int n,m;
   ull ans=0;
   cin>>n>>m;
   char a[n][m];
   for(int i=0;i<n;i++)
   {
   	for(int j=0;j<m;j++)
   	{
   		cin>>a[i][j];
   	}
   }
   memset(hor,0,sizeof(hor));
   memset(ver,0,sizeof(ver));
   for(int i=0;i<n;i++)
   {
   	for(int j=0;j<m;)
   	{
   		int c=0;
   		char t=a[i][j];
   		int tj=j;
   		while(tj<m&&a[i][tj]==t)
   			tj++,c++;
   		while(j<tj)
   		{
   			hor[i][j]=c;
   			c--;
   			j++;
   		}
   	}
   }
   for(int j=0;j<m;j++)
   {
   	for(int i=0;i<n;)
   	{
   		int c=0;
   		char t=a[i][j];
   		int ti=i;
   		while(ti<n&&a[ti][j]==t)
   			ti++,c++;
   		while(i<ti)
   		{
   			ver[i][j]=c;
   			c--;
   			i++;
   		}
   	}
   }
   for(int i=0;i<m;i++)
   {
   	build(1,0,n-1,i);
   }
   // for(int i=0;i<n;i++)
   // {
   // 	for(int j=0;j<m;j++)
   // 	{
   // 		cout<<hor[i][j]<<' ';
   // 	}
   // 	cout<<endl;
   // }
   // for(int i=0;i<n;i++)
   // {
   // 	for(int j=0;j<m;j++)
   // 	{
   // 		cout<<ver[i][j]<<' ';
   // 	}
   // 	cout<<endl;
   // }
   for(int i=0;i<n;i++)
   {
   	for(int j=0;j<m;j++)
   	{
   		int x=i,y=j,Y=hor[i][j];
   		//set<char>t;
   		//t.insert(a[i][j]);
   		if(x+ver[i][j]<n)
   		{
   			x=x+ver[i][j];
   			//t.insert(a[x][y]);
   			Y=min(Y,hor[x][y]);
   			if(ver[i][j]==ver[x][y])
   			{
   				int tx=x;
   				x=x+ver[i][j];
   				//t.insert(a[x][y]);
   				if(x<n&&ver[x][j]>=ver[tx][j]){
   					//t.insert(a[x][y]);
   					Y=query(1,0,n-1,i,x+ver[x][j]-1,j);
   					//if(a[i][j]!=a[x][j])
   						ans=ans+Y;
   				}
   			}
   		}
   	}
   }
   cout<<ans<<endl;
}