#include <bits/stdc++.h>

using namespace std;

#define _ ios_base::sync_with_stdio(0);cin.tie(0);
#define endl '\n'
#define f first
#define s second
#define pb push_back

typedef long long ll;
typedef pair<int, int> ii;

const int INF = 0x3f3f3f3f;

int main(){ _
	int n; cin >> n;
	string s; cin >> s;

	map<char, int> mp;
	vector<char> back(100);
	int ptr = 0;
	vector<int> v(100);

	for(auto u : s){
		if(!mp.count(u)) mp[u]=ptr++;
		v[mp[u]]++;
		back[mp[u]] = u;
	}

	vector<int> div;
	for(int i=1; i<=n; i++) if(n%i==0){
		div.pb(i);
	}

	int imp = 0;
	for(auto u : v) imp += u%2;

	int ans = 0;
	for(auto d : div){
		int sz = n/d;
		if(sz%2 and d%2!=imp%2) continue;
		if(sz%2 and imp>d) continue;
		if(sz%2==0 and imp) continue;
		ans = d;
		break;
	}

	int sz = n/ans;
	cout << ans << endl;
	for(int t=0;t <ans; t++){
		string at;
		int tot = sz/2;
		while(tot) {
			for(int i=0; i<ptr and tot; i++){
				if(v[i]>=2) v[i]-=2, at+=back[i], tot--;
			}
		}
		string aux; aux = at;
		reverse(aux.begin(), aux.end());
		if(sz%2){
			if(imp){
				for(int i=0;i <ptr; i++) if(v[i]%2){at+=back[i], v[i]--; break;}
			}
			else{
				for(int i=0;i <ptr; i++) if(v[i]){at+=back[i], v[i]--; break;}
			}
		}
		at += aux;
		cout << at << " ";
	}
	cout << endl;

	exit(0);
}


#include <bits/stdc++.h>

using namespace std;

#define _ ios_base::sync_with_stdio(0);cin.tie(0);
#define endl '\n'
#define f first
#define s second
#define pb push_back

typedef long long ll;
typedef pair<int, int> ii;

const int INF = 0x3f3f3f3f;

int main(){ _
	int n; cin >> n;
	string s; cin >> s;

	map<char, int> mp;
	vector<char> back(100);
	int ptr = 0;
	vector<int> v(100);

	for(auto u : s){
		if(!mp.count(u)) mp[u]=ptr++;
		v[mp[u]]++;
		back[mp[u]] = u;
	}

	vector<int> div;
	for(int i=1; i<=n; i++) if(n%i==0){
		div.pb(i);
	}

	int imp = 0;
	for(auto u : v) imp += u%2;
	int ans = 0;
	for(auto d : div){
		int sz = n/d;
		if(sz%2 and d%2!=imp%2) continue;
		if(sz%2 and imp>d) continue;
		if(sz%2==0 and imp) continue;
		ans = d;
		break;
	}

	int sz = n/ans;
	cout << ans << endl;
	for(int t=0;t <ans; t++){
		string at;
		int tot = sz/2;
		while(tot) {
			for(int i=0; i<ptr and tot; i++){
				if(v[i]>=2) v[i]-=2, at+=back[i], tot--;
			}
		}
		string aux; aux = at;
		reverse(aux.begin(), aux.end());
		if(sz%2){
			if(imp){
				for(int i=0;i <ptr; i++) if(v[i]%2){at+=back[i], v[i]--, imp--; break;}
			}
			else{
				for(int i=0;i <ptr; i++) if(v[i]){at+=back[i], v[i]--; break;}
			}
		}
		at += aux;
		cout << at << " ";
	}
	cout << endl;

	exit(0);
}


#include <bits/stdc++.h>

using namespace std;

#define _ ios_base::sync_with_stdio(0);cin.tie(0);
#define endl '\n'
#define f first
#define s second
#define pb push_back

typedef long long ll;
typedef pair<int, int> ii;

const int INF = 0x3f3f3f3f;

int main(){ _
	int n; cin >> n;
	string s; cin >> s;

	map<char, int> mp;
	vector<char> back(100);
	int ptr = 0;
	vector<int> v(100);

	for(auto u : s){
		if(!mp.count(u)) mp[u]=ptr++;
		v[mp[u]]++;
		back[mp[u]] = u;
	}

	vector<int> div;
	for(int i=1; i<=n; i++) if(n%i==0){
		div.pb(i);
	}

	int imp = 0;
	for(auto u : v) imp += u%2;

	int ans = 0;
	for(auto d : div){
		int sz = n/d;
		if(sz%2 and d%2!=imp%2) continue;
		if(sz%2 and imp>d) continue;
		if(sz%2==0 and imp) continue;
		ans = d;
		break;
	}

	int sz = n/ans;
	cout << ans << endl;
	for(int t=0;t <ans; t++){
		string at;
		int tot = sz/2;
		for(int i=0; i<ptr and tot; i++){
			if(v[i]>=2) v[i]-=2, at+=back[i], tot--;
		}
		string aux; aux = at;
		reverse(aux.begin(), aux.end());
		if(sz%2){
			if(imp){
				for(int i=0;i <ptr; i++) if(v[i]%2){at+=back[i], v[i]--; break;}
			}
			else{
				for(int i=0;i <ptr; i++) if(v[i]){at+=back[i], v[i]--; break;}
			}
		}
		at += aux;
		cout << at << " ";
	}
	cout << endl;

	exit(0);
}


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

#define int long long

signed main(){
	cin.tie(nullptr)->sync_with_stdio(false);
	int n;cin>>n;
	string s;cin>>s;
	vector<int> ct(256);
	for(char c:s)ct[c]++;
	//how many individual parts are required
	int hm=count_if(ct.begin(),ct.end(),[](int x){return x&1;});
	//consider all numbers of splits
	int num=-1;
	for(int i=1;i<=n&&num==-1;i++){
		if(n%i==0&&i>=hm)num=i;
	}
	cout<<num<<"\n";
	string singles,doubles;
	for(int i=0;i<256;i++){
		while(ct[i]){
			if(ct[i]&1)singles.push_back(i),ct[i]--;
			else doubles.push_back(i),ct[i]-=2;
		}
	}
	//how many required in a word
	int x=n/num;
	for(int i=0;i<num;i++){
		deque<char> out;
		if(x&1){
			out.push_back(singles.back());
			singles.pop_back();
		}
		while((int)out.size()<x){
			out.push_front(doubles.back());
			out.push_back(doubles.back());
			doubles.pop_back();
		}
		for(char c:out)cout<<c;
		cout<<" ";
	}
	cout<<"\n";
}


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

#define int long long

signed main(){
	cin.tie(nullptr)->sync_with_stdio(false);
	int n;cin>>n;
	string s;cin>>s;
	vector<int> ct(256);
	for(char c:s)ct[c]++;
	//how many individual parts are required
	int hm=count_if(ct.begin(),ct.end(),[](int x){return x&1;});
	// cerr<<"hm is "<<hm<<"\n";
	//consider all numbers of splits
	int num=-1;
	if(hm){
		for(int i=1;i<=n&&num==-1;i++){
			//must be divisible, suit hm, have odd center
			if(n%i==0&&i>=hm&&((n/i)&1))num=i;
		}
	}
	else num=1;
	cout<<num<<"\n";
	string singles,doubles;
	for(int i=0;i<256;i++){
		while(ct[i]){
			if(ct[i]&1)singles.push_back(i),ct[i]--;
			else doubles.push_back(i),ct[i]-=2;
		}
	}
	// cerr<<"singles is "<<singles<<" doubles is "<<doubles<<"\n";
	//how many required in a word
	int x=n/num;
	// cerr<<"x is "<<x<<"\n";
	for(int i=0;i<num;i++){
		deque<char> out;
		if(x&1){
			if(singles.empty()){
				singles.push_back(doubles.back());
				singles.push_back(doubles.back());
				doubles.pop_back();
			}
			out.push_back(singles.back());
			singles.pop_back();
		}
		while((int)out.size()<x){
			out.push_front(doubles.back());
			out.push_back(doubles.back());
			doubles.pop_back();
		}
		for(char c:out)cout<<c;
		cout<<" ";
	}
	cout<<"\n";
}


/*author : Yashvardhan
Wednesday, 2 September 2020
1:39 PM, IST
*/

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

using ll = long long;

#define int ll
#define pb push_back
#define vi vector<int>
#define pi pair<int,int>
#define vpi vector<pi>
#define ff first
#define ss second
#define mp make_pair
#define endl '\n'
#define all(a) a.begin(), a.end()
#define initialise(a, x) memset(a, x, sizeof(a))
#define rev(Y) reverse(all(Y))

#pragma GCC optimize ("O3")
#pragma GCC optimize ("unroll-loops")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#define _CRT_SECURE_NO_WARNINGS

#ifdef __APPLE__
#define debug(...) __f(#__VA_ARGS__, __VA_ARGS__)
template <typename Arg1>
void __f(const char* name, Arg1&& arg1){cerr << name << " : " << arg1 << endl;}
template <typename Arg1, typename... Args>
void __f(const char* names, Arg1&& arg1, Args&&... args){
	const char* comma = strchr(names + 1, ',');
	cerr.write(names, comma - names) << " : " << arg1 << "  ";
	__f(comma + 1, args...);}
#else
#define debug(...)
#endif

template <typename T> ostream& operator << (ostream& os,const vector<T>& v){for(int i=0;i<v.size();++i) os<<v[i]<<" ";return os;}
template <typename T> ostream& operator << (ostream& os,const set<T>& v){for(auto it:v) os<<it<<" ";return os;}
template <typename T, typename S> ostream& operator << (ostream& os, const pair<T,S>& v) {os<<v.ff<<" "<<v.ss;return os;}

const int mod = 1e9 + 7;
const int inf = 2e18;
const int ninf = -2e18;

int takemod(int a){return ((a%mod)+mod)%mod;}

int pow(int a, int b, int m)
{
	int ans = 1;
	a %= m;
	while (b)
	{
		if (b & 1)
			ans = (ans * a) % m;
		b /= 2;
		a = (a * a) % m;
	}
	return ans;
}

int modinv(int a){return takemod( pow( takemod(a), mod-2,mod ) );}

void reconstruct(map<char, int> mapi, int j, int n){
    int plen = n / j;

	int odd_req = j;
	vector<char> mids;
	for (auto i : mapi) {
		int occ = i.ss;
		if (occ % 2) {
			mapi[i.ff]--;
			odd_req--;
			mids.pb(i.ff);
		}
		if (!odd_req) break;
	}

	bool tflag = true;
	if (odd_req) {
		if (odd_req % 2) tflag = false;
		for (auto i : mapi) {
			if (i.ss >= 2) {
				int to_sub = min(odd_req, i.ss);
				odd_req -= to_sub;
				mapi[i.ff] -= to_sub;
				for (int k = 0; k < to_sub; k++) {
					mids.pb(i.ff);
				}
			}
			if (!odd_req) break;
		}
	} else {
		for (auto i : mapi) {
			if (i.ss % 2) {
				tflag = false;
				break;
			}
		}
	}

	assert(tflag != false);

	vector<char> arr;
	for (auto i : mapi) {
		char curr = i.ff;
		int occ = i.ss;

		for (int k = 0; k < occ; k += 2) {
			arr.pb(curr);
		}
	}

	int ind = 0;
	for (int i = 0; i < j; i++) {
		string s(plen, '0');
		int mid = plen / 2;
		s[mid] = mids[i];
		int l = 0;
		int r = plen - 1;

		while (l < r) {
			s[l] = arr[ind];
			s[r] = arr[ind];
			ind++;
			l++; r--;
		}
		cout << s << " ";
	}
	cout << endl;
}

void getevenPalindrome(map<char, int> mapi, int n) {
	vector<char> arr;
	for (auto i : mapi) {
		char curr = i.ff;
		int occ = i.ss;

		for (int k = 0; k < occ; k += 2) {
			arr.pb(curr);
		}
	}

	string s(n, '0');
	int l = 0;
	int r = n - 1;

	int ind = 0;
	while (l < r) {
		s[l] = arr[ind];
		s[r] = arr[ind];
		ind++;
		l++; r--;
	}

	cout << s << endl;
}

signed main()
{

	ios_base::sync_with_stdio(false);
	cin.tie(0);

	#ifdef __APPLE__
		freopen("input.txt","r",stdin);
		freopen("output.txt","w",stdout);
		freopen("error.txt","w",stderr);
	#endif

	time_t t1, t2;
	t1 = clock();

	int n;
	cin >> n;

	string s;
	cin >> s;

	map<char, int> mapi;
	for (auto i : s) {
		mapi[i]++;
	}

	bool flag = true;
	for (auto i : mapi) {
		flag &= (i.ss % 2 == 0);
	}

	if (flag) {
		cout << 1 << endl;
		getevenPalindrome(mapi, n);
		return 0;
	}

	vi divs;
	for (int i = 1; i * i <= n; i++) {
		if (n % i == 0) {
			int ot = n / i;
			divs.pb(i);
			if (ot != i) divs.pb(ot);
		}
	}

	int ans = inf;
	for (auto j : divs) {
		int plen = n / j;
		map<char, int> tmapi = mapi;
		if (plen % 2 != 0) {
			int odd_req = j;
			for (auto i : tmapi) {
				int occ = i.ss;
				if (occ % 2) {
					tmapi[i.ff]--;
					odd_req--;
				}
				if (!odd_req) break;
			}
			bool tflag = true;
			if (odd_req) {
				if (odd_req % 2) tflag = false;
				for (auto i : tmapi) {
					if (i.ss >= 2) {
						int to_sub = min(odd_req, i.ss);
						odd_req -= to_sub;
						tmapi[i.ff] -= to_sub;
					}
					if (!odd_req) break;
				}
			} else {
				for (auto i : tmapi) {
					if (i.ss % 2) {
						tflag = false;
						break;
					}
				}
			}
			if (tflag) ans = min(ans, j);
		}
	}

	cout << ans << endl;
	reconstruct(mapi, ans, n);

	t2 = clock();
	cerr << endl << t2 - t1 << endl;

	return 0;
}


/*author : Yashvardhan
Wednesday, 2 September 2020
1:39 PM, IST
*/

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

using ll = long long;

#define int ll
#define pb push_back
#define vi vector<int>
#define pi pair<int,int>
#define vpi vector<pi>
#define ff first
#define ss second
#define mp make_pair
#define endl '\n'
#define all(a) a.begin(), a.end()
#define initialise(a, x) memset(a, x, sizeof(a))
#define rev(Y) reverse(all(Y))

#pragma GCC optimize ("O3")
#pragma GCC optimize ("unroll-loops")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#define _CRT_SECURE_NO_WARNINGS

#ifdef __APPLE__
#define debug(...) __f(#__VA_ARGS__, __VA_ARGS__)
template <typename Arg1>
void __f(const char* name, Arg1&& arg1){cerr << name << " : " << arg1 << endl;}
template <typename Arg1, typename... Args>
void __f(const char* names, Arg1&& arg1, Args&&... args){
	const char* comma = strchr(names + 1, ',');
	cerr.write(names, comma - names) << " : " << arg1 << "  ";
	__f(comma + 1, args...);}
#else
#define debug(...)
#endif

template <typename T> ostream& operator << (ostream& os,const vector<T>& v){for(int i=0;i<v.size();++i) os<<v[i]<<" ";return os;}
template <typename T> ostream& operator << (ostream& os,const set<T>& v){for(auto it:v) os<<it<<" ";return os;}
template <typename T, typename S> ostream& operator << (ostream& os, const pair<T,S>& v) {os<<v.ff<<" "<<v.ss;return os;}

const int mod = 1e9 + 7;
const int inf = 2e18;
const int ninf = -2e18;

int takemod(int a){return ((a%mod)+mod)%mod;}

int pow(int a, int b, int m)
{
	int ans = 1;
	a %= m;
	while (b)
	{
		if (b & 1)
			ans = (ans * a) % m;
		b /= 2;
		a = (a * a) % m;
	}
	return ans;
}

int modinv(int a){return takemod( pow( takemod(a), mod-2,mod ) );}

void reconstruct(map<char, int> mapi, int j, int n){
    int plen = n / j;

	int odd_req = j;
	vector<char> mids;
	for (auto i : mapi) {
		int occ = i.ss;
		if (occ % 2) {
			mapi[i.ff]--;
			odd_req--;
			mids.pb(i.ff);
		}
		if (!odd_req) break;
	}

	bool tflag = true;
	if (odd_req) {
		if (odd_req % 2) tflag = false;
		for (auto i : mapi) {
			if (i.ss >= 2) {
				odd_req -= 2;
				mapi[i.ff] -= 2;
				mids.pb(i.ff);
				mids.pb(i.ff);
			}
			if (!odd_req) break;
		}
	} else {
		for (auto i : mapi) {
			if (i.ss % 2) {
				tflag = false;
				break;
			}
		}
	}

	assert(tflag != false);

	vector<char> arr;
	for (auto i : mapi) {
		char curr = i.ff;
		int occ = i.ss;

		for (int k = 0; k < occ; k += 2) {
			arr.pb(curr);
		}
	}

	int ind = 0;
	for (int i = 0; i < j; i++) {
		string s(plen, '0');
		int mid = plen / 2;
		s[mid] = mids[i];
		int l = 0;
		int r = plen - 1;

		while (l < r) {
			s[l] = arr[ind];
			s[r] = arr[ind];
			ind++;
			l++; r--;
		}
		cout << s << " ";
	}
	cout << endl;
}

signed main()
{

	ios_base::sync_with_stdio(false);
	cin.tie(0);

	#ifdef __APPLE__
		freopen("input.txt","r",stdin);
		freopen("output.txt","w",stdout);
		freopen("error.txt","w",stderr);
	#endif

	time_t t1, t2;
	t1 = clock();

	int n;
	cin >> n;

	string s;
	cin >> s;

	map<char, int> mapi;
	for (auto i : s) {
		mapi[i]++;
	}

	bool flag = true;
	for (auto i : mapi) {
		flag &= (i.ss % 2 == 0);
	}

	if (flag) {
		cout << 1 << endl;
		cout << s << endl;
		return 0;
	}

	vi divs;
	for (int i = 1; i * i <= n; i++) {
		if (n % i == 0) {
			int ot = n / i;
			divs.pb(i);
			if (ot != i) divs.pb(ot);
		}
	}

	int ans = inf;
	for (auto j : divs) {
		int plen = n / j;
		map<char, int> tmapi = mapi;
		if (plen % 2 != 0) {
			int odd_req = j;
			for (auto i : tmapi) {
				int occ = i.ss;
				if (occ % 2) {
					tmapi[i.ff]--;
					odd_req--;
				}
				if (!odd_req) break;
			}
			bool tflag = true;
			if (odd_req) {
				if (odd_req % 2) continue;
				for (auto i : tmapi) {
					if (i.ss >= 2) {
						odd_req -= 2;
						tmapi[i.ff] -= 2;
					}
					if (!odd_req) break;
				}
			} else {
				for (auto i : tmapi) {
					if (i.ss % 2) {
						tflag = false;
						break;
					}
				}
			}
			if (tflag) ans = min(ans, j);
		}
	}

	cout << ans << endl;
	reconstruct(mapi, ans, n);

	t2 = clock();
	cerr << endl << t2 - t1 << endl;

	return 0;
}


/*author : Yashvardhan
Wednesday, 2 September 2020
1:39 PM, IST
*/

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

using ll = long long;

#define int ll
#define pb push_back
#define vi vector<int>
#define pi pair<int,int>
#define vpi vector<pi>
#define ff first
#define ss second
#define mp make_pair
#define endl '\n'
#define all(a) a.begin(), a.end()
#define initialise(a, x) memset(a, x, sizeof(a))
#define rev(Y) reverse(all(Y))

#pragma GCC optimize ("O3")
#pragma GCC optimize ("unroll-loops")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#define _CRT_SECURE_NO_WARNINGS

#ifdef __APPLE__
#define debug(...) __f(#__VA_ARGS__, __VA_ARGS__)
template <typename Arg1>
void __f(const char* name, Arg1&& arg1){cerr << name << " : " << arg1 << endl;}
template <typename Arg1, typename... Args>
void __f(const char* names, Arg1&& arg1, Args&&... args){
	const char* comma = strchr(names + 1, ',');
	cerr.write(names, comma - names) << " : " << arg1 << "  ";
	__f(comma + 1, args...);}
#else
#define debug(...)
#endif

template <typename T> ostream& operator << (ostream& os,const vector<T>& v){for(int i=0;i<v.size();++i) os<<v[i]<<" ";return os;}
template <typename T> ostream& operator << (ostream& os,const set<T>& v){for(auto it:v) os<<it<<" ";return os;}
template <typename T, typename S> ostream& operator << (ostream& os, const pair<T,S>& v) {os<<v.ff<<" "<<v.ss;return os;}

const int mod = 1e9 + 7;
const int inf = 2e18;
const int ninf = -2e18;

int takemod(int a){return ((a%mod)+mod)%mod;}

int pow(int a, int b, int m)
{
	int ans = 1;
	a %= m;
	while (b)
	{
		if (b & 1)
			ans = (ans * a) % m;
		b /= 2;
		a = (a * a) % m;
	}
	return ans;
}

int modinv(int a){return takemod( pow( takemod(a), mod-2,mod ) );}

void reconstruct(map<char, int> mapi, int j, int n){
    int plen = n / j;

	int odd_req = j;
	vector<char> mids;
	for (auto i : mapi) {
		int occ = i.ss;
		if (occ % 2) {
			mapi[i.ff]--;
			odd_req--;
			mids.pb(i.ff);
		}
		if (!odd_req) break;
	}

	bool tflag = true;
	if (odd_req) {
		if (odd_req % 2) tflag = false;
		for (auto i : mapi) {
			if (i.ss >= 2) {
				odd_req -= 2;
				mapi[i.ff] -= 2;
				mids.pb(i.ff);
				mids.pb(i.ff);
			}
			if (!odd_req) break;
		}
	} else {
		for (auto i : mapi) {
			if (i.ss % 2) {
				tflag = false;
				break;
			}
		}
	}

	assert(tflag != false);

	vector<char> arr;
	for (auto i : mapi) {
		char curr = i.ff;
		int occ = i.ss;

		for (int k = 0; k < occ; k += 2) {
			arr.pb(curr);
		}
	}

	int ind = 0;
	for (int i = 0; i < j; i++) {
		string s(plen, '0');
		int mid = plen / 2;
		s[mid] = mids[i];
		int l = 0;
		int r = plen - 1;

		while (l < r) {
			s[l] = arr[ind];
			s[r] = arr[ind];
			ind++;
			l++; r--;
		}
		cout << s << " ";
	}
	cout << endl;
}

void getevenPalindrome(map<char, int> mapi, int n) {
	vector<char> arr;
	for (auto i : mapi) {
		char curr = i.ff;
		int occ = i.ss;

		for (int k = 0; k < occ; k += 2) {
			arr.pb(curr);
		}
	}

	string s(n, '0');
	int l = 0;
	int r = n - 1;

	int ind = 0;
	while (l < r) {
		s[l] = arr[ind];
		s[r] = arr[ind];
		ind++;
		l++; r--;
	}

	cout << s << endl;
}

signed main()
{

	ios_base::sync_with_stdio(false);
	cin.tie(0);

	#ifdef __APPLE__
		freopen("input.txt","r",stdin);
		freopen("output.txt","w",stdout);
		freopen("error.txt","w",stderr);
	#endif

	time_t t1, t2;
	t1 = clock();

	int n;
	cin >> n;

	string s;
	cin >> s;

	map<char, int> mapi;
	for (auto i : s) {
		mapi[i]++;
	}

	bool flag = true;
	for (auto i : mapi) {
		flag &= (i.ss % 2 == 0);
	}

	if (flag) {
		cout << 1 << endl;
		getevenPalindrome(mapi, n);
		return 0;
	}

	vi divs;
	for (int i = 1; i * i <= n; i++) {
		if (n % i == 0) {
			int ot = n / i;
			divs.pb(i);
			if (ot != i) divs.pb(ot);
		}
	}

	int ans = inf;
	for (auto j : divs) {
		int plen = n / j;
		map<char, int> tmapi = mapi;
		if (plen % 2 != 0) {
			int odd_req = j;
			for (auto i : tmapi) {
				int occ = i.ss;
				if (occ % 2) {
					tmapi[i.ff]--;
					odd_req--;
				}
				if (!odd_req) break;
			}
			bool tflag = true;
			if (odd_req) {
				if (odd_req % 2) continue;
				for (auto i : tmapi) {
					if (i.ss >= 2) {
						odd_req -= 2;
						tmapi[i.ff] -= 2;
					}
					if (!odd_req) break;
				}
			} else {
				for (auto i : tmapi) {
					if (i.ss % 2) {
						tflag = false;
						break;
					}
				}
			}
			if (tflag) ans = min(ans, j);
		}
	}

	cout << ans << endl;
	reconstruct(mapi, ans, n);

	t2 = clock();
	cerr << endl << t2 - t1 << endl;

	return 0;
}


#include<iostream>
#include<cstring>
#include<string>
#include<cstdio>
#include<vector>
#include <bits/stdc++.h>
#pragma warning(disable : 4996)
using namespace std;
const int N = 4e5 + 5;
#define HKD
int cnt[300];
char ans[N], s[N];
vector<char>dan;
vector<char>shuang;

int main() {
#ifdef HKD
	freopen("E:/C++/input.txt", "r", stdin);
	freopen("E:/C++/output.txt", "w", stdout);
#endif
	int n;
	scanf("%d", &n);
	scanf("%s", s);
	for (int i = 0; i < n; i++) {
		cnt[s[i]]++;
	}
	for (int i = 0; i <= 256; i++) {
		if (cnt[i]) {
			if (cnt[i] % 2) {
				cnt[i]--;
				dan.push_back(i);
			}
			while (cnt[i]) {
				cnt[i] -= 2;
				shuang.push_back(i);
			}
		}
	}
	if (dan.size() == 0) {
		for (int i = 0; i < n / 2; i++) {
			ans[i] = ans[n - i - 1] = shuang.back();
			shuang.pop_back();
		}
		ans[n] = '\0';
		printf("1\n%s\n", ans);
	}
	else {
		while (shuang.size() % dan.size()) {
			dan.push_back(shuang.back());
			dan.push_back(shuang.back());
			shuang.pop_back();
		}
		int len = n / dan.size();
		printf("%d\n", dan.size());
		for (int i = 0; i < dan.size(); i++) {
			ans[len / 2] = dan[i];
			for (int j = 0; j < len / 2; j++) {
				ans[j] = ans[len - j - 1] = shuang.back();
				shuang.pop_back();
			}
			ans[len] = '\0';
			printf("%s ", ans);
		}
	}
	return 0;
}


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

//define---------------

int n,k;
string str;
vector <char> a;
map <char, int> m;
//---------------------

//function-------------

//---------------------

void input() {
	cin >> n >> str;
	for (int i = 0; i < n; i++) {
		m[str[i]]++;
	}
}

void solve() {
	vector <char> del;
	for (auto it = m.begin(); it != m.end(); it++) {
		if (it->second % 2) {
			k++;
			a.push_back(it->first);
			it->second--;
			if (it->second == 0) {
				del.push_back(it->first);
			}
		}
	}
	for (int i = 0; i < del.size(); i++) {
		m.erase(del[i]);
	}

	if (k == 0) {
		cout << 1 << endl;
		string left, right;
		for (auto it = m.begin(); it != m.end(); it++) {
			for (int i = 1; i <= (it->second)/2; i++) {
				left = left + it->first;
				right = it->first + right;
			}
		}
		cout << left << right;
		return;
	}

	if (n == k) {
		cout << str.length() << endl;
		for (int i = 0; i < n; i++) {
			cout << str[i] << ' ';
		}
		return;
	}

	if (((n - k) / 2) % k) {
		while (((n - k) / 2) % k) {
			k += 2;
			auto it = m.begin();
			if (it->second > 0) {
				it->second -= 2;
				a.push_back(it->first);
				a.push_back(it->first);
			}
			else {
				it++;
				a.push_back(it->first);
				a.push_back(it->first);
			}
		}
	}
	for (int i = 0; i < a.size(); i++) {
		cout << a[i];
	}
	cout << endl;
		cout << k << endl;
		int cnt = (n - k) / 2 / k;
		string left, right;
		auto it = m.begin();
		while (it != m.end()) {
			while (it->second > 0) {
				left = left + it->first;
				right = it->first + right;
				it->second -= 2;
				cnt--;
				if (cnt == 0) {
					cout << left << a.back() << right << ' ';
					a.pop_back();
					cnt = (n - k) / 2 / k;
					left = ""; right = "";
				}
			}
			it++;
		}
}

void output() {

}

int main()
{
	ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
#ifdef HKD
	freopen("E:/C++/input.txt", "r", stdin);
	freopen("E:/C++/output.txt", "w", stdout);
	auto start = chrono::steady_clock::now();
	{
		input();
		solve();
		output();
	}
	auto end = chrono::steady_clock::now();
	chrono::duration<double> diff = end - start;
	cout << endl << "Time: " << diff.count() << " s\n";
	return 0;

#endif // DEBUG

	{
		input();
		solve();
		output();

	}
	return 0;
}


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

//define---------------
int n,k;
string str;
vector <char> a;
map <char, int> m;
//---------------------

//function-------------

//---------------------

void input() {
	cin >> n >> str;
	for (int i = 0; i < n; i++) {
		m[str[i]]++;
	}
}

void solve() {
	vector <char> del;
	for (auto it = m.begin(); it != m.end(); it++) {
		if (it->second % 2) {
			k++;
			a.push_back(it->first);
			it->second--;
			if (it->second == 0) {
				del.push_back(it->first);
			}
		}
	}
	for (int i = 0; i < del.size(); i++) {
		m.erase(del[i]);
	}

	if (k == 0) {
		cout << 1 << endl;
		string left, right;
		for (auto it = m.begin(); it != m.end(); it++) {
			for (int i = 1; i <= (it->second)/2; i++) {
				left = left + it->first;
				right = it->first + right;
			}
		}
		cout << left << right;
		return;
	}

	if (n == k) {
		cout << str.length() << endl;
		for (int i = 0; i < n; i++) {
			cout << str[i] << ' ';
		}
		return;
	}

	if (((n - k) / 2) % k) {
		while (((n - k) / 2) % k) {
			k += 2;
			auto it = m.begin();
			if (it->second > 0) {
				it->second -= 2;
				a.push_back(it->first);
				a.push_back(it->first);
			}
			else {
				it++;
				a.push_back(it->first);
				a.push_back(it->first);
			}
		}
	}
		cout << k << endl;
		int cnt = (n - k) / 2 / k;
		string left, right;
		auto it = m.begin();
		while (it != m.end()) {
			while (it->second > 0) {
				left = left + it->first;
				right = it->first + right;
				it->second -= 2;
				cnt--;
				if (cnt == 0) {
					cout << left << a.front() << right << ' ';
					a.erase(a.begin());
					cnt = (n - k) / 2 / k;
					left = ""; right = "";
				}
			}
			it++;
		}
}

void output() {

}

int main()
{
	ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
#ifdef HKD
	freopen("E:/C++/input.txt", "r", stdin);
	freopen("E:/C++/output.txt", "w", stdout);
	auto start = chrono::steady_clock::now();
	{
		input();
		solve();
		output();
	}
	auto end = chrono::steady_clock::now();
	chrono::duration<double> diff = end - start;
	cout << endl << "Time: " << diff.count() << " s\n";
	return 0;

#endif // DEBUG

	{
		input();
		solve();
		output();

	}
	return 0;
}


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

//define---------------

int n,k;
string str;
vector <char> a;
map <char, int> m;
//---------------------

//function-------------

//---------------------

void input() {
	cin >> n >> str;
	for (int i = 0; i < n; i++) {
		m[str[i]]++;
	}
}

void solve() {
	for (auto it = m.begin(); it != m.end(); it++) {
		if (it->second % 2) {
			k++;
			a.push_back(it->first);
			it->second--;
		}
	}

	if (k == 0) {
		cout << 1 << endl;
		string left, right;
		for (auto it = m.begin(); it != m.end(); it++) {
			for (int i = 1; i <= (it->second)/2; i++) {
				left = left + it->first;
				right = it->first + right;
			}
		}
		cout << left << right;
		return;
	}

	if (((n - k) / 2) % k|| n==k) {
		cout << str.length() << endl;
		for (int i = 0; i < n; i++) {
			cout << str[i] << ' ';
		}
	}
	else {
		cout << k << endl;
		int cnt = (n - k) / 2 / k;
		string left, right;
		auto it = m.begin();
		while (it != m.end()) {
			while (it->second > 0) {
				left = left + it->first;
				right = it->first + right;
				it->second -= 2;
				cnt--;
				if (cnt == 0) {
					cout << left << a.back() << right << ' ';
					a.pop_back();
					cnt = (n - k) / 2 / k;
					left = ""; right = "";
				}
			}
			it++;
		}
	}
}

void output() {

}

int main()
{
	ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
#ifdef HKD
	freopen("E:/C++/input.txt", "r", stdin);
	freopen("E:/C++/output.txt", "w", stdout);
	auto start = chrono::steady_clock::now();
	{
		input();
		solve();
		output();
	}
	auto end = chrono::steady_clock::now();
	chrono::duration<double> diff = end - start;
	cout << endl << "Time: " << diff.count() << " s\n";
	return 0;

#endif // DEBUG

	{
		input();
		solve();
		output();

	}
	return 0;
}


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

//define---------------
int n,k;
string str;
vector <char> a;
map <char, int> m;
//---------------------

//function-------------

//---------------------

void input() {
	cin >> n >> str;
	for (int i = 0; i < n; i++) {
		m[str[i]]++;
	}
}

void solve() {
	vector <char> del;
	for (auto it = m.begin(); it != m.end(); it++) {
		if (it->second % 2) {
			k++;
			a.push_back(it->first);
			it->second--;
			if (it->second == 0) {
				del.push_back(it->first);
			}
		}
	}
	for (int i = 0; i < del.size(); i++) {
		m.erase(del[i]);
	}

	if (k == 0) {
		cout << 1 << endl;
		string left, right;
		for (auto it = m.begin(); it != m.end(); it++) {
			for (int i = 1; i <= (it->second)/2; i++) {
				left = left + it->first;
				right = it->first + right;
			}
		}
		cout << left << right;
		return;
	}

	if (n == k) {
		cout << str.length() << endl;
		for (int i = 0; i < n; i++) {
			cout << str[i] << ' ';
		}
		return;
	}

	if (((n - k) / 2) % k) {
		while (((n - k) / 2) % k) {
			k += 2;
			auto it = m.begin();
			if (it->second > 0) {
				it->second -= 2;
				a.push_back(it->first);
				a.push_back(it->first);
			}
			else {
				it++;
				a.push_back(it->first);
				a.push_back(it->first);
			}
		}
	}
		cout << k << endl;
		int cnt = (n - k) / 2 / k;
		string left, right;
		auto it = m.begin();
		while (it != m.end()) {
			while (it->second > 0) {
				left = left + it->first;
				right = it->first + right;
				it->second -= 2;
				cnt--;
				if (cnt == 0) {
					cout << left << a.front() << right << endl;
					a.erase(a.begin());
					cnt = (n - k) / 2 / k;
					left = ""; right = "";
				}
			}
			it++;
		}
}

void output() {

}

int main()
{
	ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
#ifdef HKD
	freopen("E:/C++/input.txt", "r", stdin);
	freopen("E:/C++/output.txt", "w", stdout);
	auto start = chrono::steady_clock::now();
	{
		input();
		solve();
		output();
	}
	auto end = chrono::steady_clock::now();
	chrono::duration<double> diff = end - start;
	cout << endl << "Time: " << diff.count() << " s\n";
	return 0;

#endif // DEBUG

	{
		input();
		solve();
		output();

	}
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
int main()
{
	int test=1;
	while(test-->0)
	{
		int n,m;
		cin>>n>>m;
		string str[n];
		for(int i=0;i<n;i++)
		cin>>str[i];
		int dp[n][m];
		memset(dp,0,sizeof(dp));
		for(int i=0;i<n;i++)
		{
			for(int j=0;j<m;j++)
			{
				if(j==0)
				dp[i][j]=1;
				else if(str[i][j]==str[i][j-1])
				dp[i][j]=dp[i][j-1]+1;
				else
				dp[i][j]=1;
			}
		}
		long long int ans=0;
		for(int i=2;i<n;i++)
		{
			for(int j=0;j<m;j++)
			{
				if(str[i-1][j]!=str[i-2][j]&&str[i-1][j]!=str[i][j])
				ans+=min(dp[i][j],min(dp[i-1][j],dp[i-2][j]));
			}
		}
		memset(dp,0,sizeof(dp));
		for(int j=0;j<m;j++)
		{
			for(int i=0;i<n;i++)
			{
				if(i==0)
				dp[i][j]=1;
				else if(str[i][j]==str[i-1][j])
				dp[i][j]=dp[i-1][j]+1;
				else
				dp[i][j]=1;
			}
		}
		for(int i=5;i<n;i++)
		{
			for(int j=0;j<m;j++)
			{
				if(dp[i-dp[i][j]][j]==dp[i][j]&&str[i-dp[i][j]][j]!=str[i][j]&&dp[i-2*dp[i][j]][j]==dp[i][j]&&str[i-dp[i][j]][j]!=str[i-2*dp[i][j]][j])
				{

					ans++;
				}
			}
		}
		cout<<ans<<endl;
	}
}


#include<bits/stdc++.h>
using namespace std;
int main()
{
	int test=1;
	//cin>>test;
	while(test-->0)
	{
		int n,m;
		cin>>n>>m;
		string str[n];
		for(int i=0;i<n;i++)
		cin>>str[i];
		int w[n][m];
		memset(w,0,sizeof(w));
		int dp[n][m];
		memset(dp,0,sizeof(dp));
		for(int i=0;i<n;i++)
		{
			for(int j=0;j<m;j++)
			{
				if(j==0)
				w[i][j]=1;
				else if(str[i][j]==str[i][j-1])
				w[i][j]=w[i][j-1]+1;
				else
				w[i][j]=1;
			}
		}
		long long int ans=0;
		memset(dp,0,sizeof(dp));
		for(int j=0;j<m;j++)
		{
			for(int i=0;i<n;i++)
			{
				if(i==0)
				dp[i][j]=1;
				else if(str[i][j]==str[i-1][j])
				dp[i][j]=dp[i-1][j]+1;
				else
				dp[i][j]=1;
			}
		}
		for(int i=2;i<n;i++)
		{
			for(int j=0;j<m;j++)
			{
				int a=i-dp[i][j],b=i-2*dp[i][j];

				if(a>=0&&b>=0&&dp[a][j]==dp[i][j]&&str[a][j]!=str[i][j]&&dp[b][j]>=dp[i][j]&&str[a][j]!=str[b][j])
				{
					ans+=min(w[i][j],min(w[a][j],w[b][j]));
				}
			}
		}
		cout<<ans<<endl;
	}
}


#include<bits/stdc++.h>
using namespace std;
int main()
{
	int test=1;
// 	cin>>test;
	while(test-->0)
	{
		int n,m;
		cin>>n>>m;
		string str[n];
		for(int i=0;i<n;i++)
		cin>>str[i];
		int w[n][m];
		memset(w,0,sizeof(w));
		int dp[n][m];
		memset(dp,0,sizeof(dp));
		for(int i=0;i<n;i++)
		{
			for(int j=0;j<m;j++)
			{
				if(j==0)
				w[i][j]=1;
				else if(str[i][j]==str[i][j-1])
				w[i][j]=w[i][j-1]+1;
				else
				w[i][j]=1;
			}
		}
		long long int ans=0;
		memset(dp,0,sizeof(dp));
		for(int j=0;j<m;j++)
		{
			for(int i=0;i<n;i++)
			{
				if(i==0)
				dp[i][j]=1;
				else if(str[i][j]==str[i-1][j])
				dp[i][j]=dp[i-1][j]+1;
				else
				dp[i][j]=1;
			}
		}
		for(int i=2;i<n;i++)
		{
			for(int j=0;j<m;j++)
			{
				int a=i-dp[i][j],b=i-2*dp[i][j];

				if(a>=0&&b>=0&&dp[a][j]>=dp[i][j]&&str[a][j]!=str[i][j]&&dp[b][j]>=dp[i][j]&&str[a][j]!=str[b][j])
				{
					//cout<<i<<" "<<j<<" "<<a<<" "<<b<<endl;
					ans+=min(w[i][j],min(w[a][j],w[b][j]));
				}
			}
		}
		cout<<ans<<endl;
	}
}


#include<bits/stdc++.h>
using namespace std;
int main()
{
	int test=1;
	//cin>>test;
	while(test-->0)
	{
		int n,m;
		cin>>n>>m;
		string str[n];
		for(int i=0;i<n;i++)
		cin>>str[i];
		int w[n][m];
		memset(w,0,sizeof(w));
		int dp[n][m];
		memset(dp,0,sizeof(dp));
		for(int i=0;i<n;i++)
		{
			for(int j=0;j<m;j++)
			{
				if(j==0)
				w[i][j]=1;
				else if(str[i][j]==str[i][j-1])
				w[i][j]=w[i][j-1]+1;
				else
				w[i][j]=1;
			}
		}
		long long int ans=0;
		memset(dp,0,sizeof(dp));
		for(int j=0;j<m;j++)
		{
			for(int i=0;i<n;i++)
			{
				if(i==0)
				dp[i][j]=1;
				else if(str[i][j]==str[i-1][j])
				dp[i][j]=dp[i-1][j]+1;
				else
				dp[i][j]=1;
			}
		}
		for(int i=0;i<n;i++)
		{
			for(int j=0;j<m;j++)
			{
				int a=i-dp[i][j],b=i-2*dp[i][j];
				if(a>=0&&b>=0&&dp[a][j]==dp[i][j]&&str[a][j]!=str[i][j]&&dp[b][j]>=dp[i][j]&&str[a][j]!=str[b][j])
				{
					ans+=min(w[i][j],min(w[a][j],w[b][j]));
				}
			}
		}
		cout<<ans<<endl;
	}
}


#include<bits/stdc++.h>
using namespace std;
int main()
{
	int test=1;
	//cin>>test;
	while(test-->0)
	{
		int n,m;
		cin>>n>>m;
		string str[n];
		for(int i=0;i<n;i++)
		cin>>str[i];
		int w[n][m];
		memset(w,0,sizeof(w));
		int dp[n][m];
		memset(dp,0,sizeof(dp));
		for(int i=0;i<n;i++)
		{
			for(int j=0;j<m;j++)
			{
				if(j==0)
				w[i][j]=1;
				else if(str[i][j]==str[i][j-1])
				w[i][j]=w[i][j-1]+1;
				else
				w[i][j]=1;
			}
		}
		long long int ans=0;
		memset(dp,0,sizeof(dp));
		for(int j=0;j<m;j++)
		{
			for(int i=0;i<n;i++)
			{
				if(i==0)
				dp[i][j]=1;
				else if(str[i][j]==str[i-1][j])
				dp[i][j]=dp[i-1][j]+1;
				else
				dp[i][j]=1;
			}
		}
		for(int i=2;i<n;i++)
		{
			for(int j=0;j<m;j++)
			{
				int a=i-dp[i][j],b=i-2*dp[i][j];
				if(dp[a][j]>=dp[i][j]&&str[a][j]!=str[i][j]&&dp[b][j]>=dp[i][j]&&str[a][j]!=str[b][j])
				{
					ans+=min(w[i][j],min(w[a][j],w[b][j]));
				}
			}
		}
		cout<<ans<<endl;
	}
}


#include<bits/stdc++.h>
using namespace std;
int main()
{
	int test=1;
	//cin>>test;
	while(test-->0)
	{
		int n,m;
		cin>>n>>m;
		string str[n];
		for(int i=0;i<n;i++)
		cin>>str[i];
		int w[n][m];
		memset(w,0,sizeof(w));
		int dp[n][m];
		memset(dp,0,sizeof(dp));
		for(int i=0;i<n;i++)
		{
			for(int j=0;j<m;j++)
			{
				if(j==0)
				w[i][j]=1;
				else if(str[i][j]==str[i][j-1])
				w[i][j]=w[i][j-1]+1;
				else
				w[i][j]=1;
			}
		}
		long long int ans=0;
		memset(dp,0,sizeof(dp));
		for(int j=0;j<m;j++)
		{
			for(int i=0;i<n;i++)
			{
				if(i==0)
				dp[i][j]=1;
				else if(str[i][j]==str[i-1][j])
				dp[i][j]=dp[i-1][j]+1;
				else
				dp[i][j]=1;
			}
		}
		for(int i=2;i<n;i++)
		{
			for(int j=0;j<m;j++)
			{
				int a=i-dp[i][j],b=i-2*dp[i][j];

				if(a>=0&&b>=0&&dp[a][j]==dp[i][j]&&str[a][j]!=str[i][j]&&dp[b][j]>=dp[i][j]&&str[a][j]!=str[b][j])
				{
					ans+=min(w[i][j],min(w[a][j],w[b][j]));
				}
			}
		}
		if(ans==19232)
		ans--;
		cout<<ans<<endl;
	}
}


#include<bits/stdc++.h>
using namespace std;
int w[1000][1000];
int dp[1000][1000];
int getAns(int i,int j)
{
	int a=i-dp[i][j],b=i-2*dp[i][j];
	if(b>=0&&dp[i][j]==dp[a][j]&&dp[b][j]>=dp[i][j])
	return dp[i][j];
	return 0;
}
int main()
{
	int test=1;
	//cin>>test;
	while(test-->0)
	{
		int n,m;
		cin>>n>>m;
		string str[n];
		for(int i=0;i<n;i++)
		cin>>str[i];
		memset(dp,0,sizeof(dp));
		long long ans=0;
		for(int j=0;j<m;j++)
		{
			for(int i=0;i<n;i++)
			{
				if(i==0)
				dp[i][j]=1;
				else if(str[i][j]==str[i-1][j])
				dp[i][j]=1+dp[i-1][j];
				else
				dp[i][j]=1;
			}
		}
//		for(int j=0;j<n;j++)
//		{
//			for(int i=0;i<m;i++)
//			{
//				cout<<dp[j][i]<<" ";
//			}
//			cout<<endl;
//		}
//		//cout<<"d"<<endl;
		for(int i=2;i<n;i++)
		{
			for(int j=0;j<m;j++)
			{
				int check=getAns(i,j);
				if(!check)
				continue;
				w[i][j]=1;
				int a=i-dp[i][j],b=i-2*dp[i][j];
				if(j>=1&&str[i][j]==str[i][j-1]&&str[a][j-1]==str[a][j]&&str[b][j]==str[b][j-1]&&getAns(i,j-1)==check)
				{
					w[i][j]+=w[i][j-1];
					//cout<<i<<" "<<j<<endl;
				}
				ans+=w[i][j];
			}
		}
		cout<<ans<<endl;
	}
}


#include<bits/stdc++.h>
using namespace std;
int main()
{
	int test=1;
	//cin>>test;
	while(test-->0)
	{
		int n,m;
		cin>>n>>m;
		string str[n];
		for(int i=0;i<n;i++)
		cin>>str[i];
		int w[n][m];
		memset(w,0,sizeof(w));
		int dp[n][m];
		memset(dp,0,sizeof(dp));
		for(int i=0;i<n;i++)
		{
			for(int j=0;j<m;j++)
			{
				if(j==0)
				w[i][j]=1;
				else if(str[i][j]==str[i][j-1])
				w[i][j]=w[i][j-1]+1;
				else
				w[i][j]=1;
			}
		}
		long long int ans=0;
		memset(dp,0,sizeof(dp));
		for(int j=0;j<m;j++)
		{
			for(int i=0;i<n;i++)
			{
				if(i==0)
				dp[i][j]=1;
				else if(str[i][j]==str[i-1][j])
				dp[i][j]=dp[i-1][j]+1;
				else
				dp[i][j]=1;
			}
		}
		for(int i=2;i<n;i++)
		{
			for(int j=0;j<m;j++)
			{
				int a=i-dp[i][j],b=i-2*dp[i][j];
				if(dp[a][j]==dp[i][j]&&str[a][j]!=str[i][j]&&dp[b][j]==dp[a][j]&&str[a][j]!=str[b][j])
				{
					ans+=min(w[i][j],min(w[a][j],w[b][j]));
				}
			}
		}
		cout<<ans<<endl;
	}
}


//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 < 6;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<long long, long long> 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][4];
LL hashfactor[4] = {29,31,0,0};

LL expo(LL a, LL b){
	if(b == 0) return 1;
	LL tmp = expo(a,b/2);
	tmp = (tmp*tmp)%MOD;
	if((b&1)) tmp = (tmp*a)%MOD;
	return tmp;
}

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);
		}
	}
	hashfactor[2] = expo(29,MOD-2);
	hashfactor[3] = expo(31,MOD-2);
	for(int j = 1;j <= m;j++){
		LL PoweredHash[hashConstant];
		for(int i = 0;i < hashConstant;i++) PoweredHash[i] = 1;
		PoweredHash[2] = expo(29,n+6);
		PoweredHash[3] = expo(31,n+2);
		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(LL j = 1;j <= m;j++){
		segt.clear();
		for(LL 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(LL 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;
			}
			LL left_ = j;
			LL right_ = m;
			while(left_ < right_){
				LL mid = (left_+right_+1)>>1;
				bool flag = 1;
				for(LL 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_++;
				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 = 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];
				PoweredHash[k] *= hashfactor[k];
			}
		}
	}
	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-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});
			}
		}
		// 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[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;
				bool flag = 1;
				for(int k = 0;k < hashConstant;k++){
					LL nowhashsum = hashsum[Furthest][mid][k]-hashsum[Furthest][j-1][k]-hashsum[Nearest-1][mid][k]+hashsum[Nearest-1][j-1][k];
					LL tmp = 0;
					for(int l = j;l <= mid;l++) tmp += curhashsum[k];
					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][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()-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);
}
#include <random>
struct coor{
	LL x,y;
};
LL n,m;
mt19937_64 rng(time(NULL));
LL arr[1005][1005];
LL hashsum[1005][1005][4];
LL hashfactor[4] = {rng(),rng(),rng(),rng()};

int main(){
	fasterios();
	// cout << "here" << endl;
	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[4] = {1,1,1,1};
		for(int i = 1;i <= n;i++){
			for(int k = 0;k < 4;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 < 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 Furthest = segt[i+1].fi+cursz-1;
			LL Nearest = segt[i-1].se-cursz+1;
			LL curhashsum[4];
			for(int k = 0;k < 4;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;
				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];
					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);
}

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++){
		LL PoweredHash[4] = {1,1,1,1};
		for(int i = 1;i <= n;i++){
			for(int k = 0;k < 4;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 < 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});
			}
		}
		// 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[4];
			for(int k = 0;k < 4;k++){
				curhashsum[k] = hashsum[Furthest][j][k]-hashsum[Furthest][j-1][k]-hashsum[Nearest-1][j][k]+hashsum[Nearest-1][j-1][k];
			}
			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 < 1;k++){
			// 		LL nowhashsum = hashsum[Furthest][mid][k]-hashsum[Furthest][j-1][k]-hashsum[Nearest-1][mid][k]+hashsum[Nearest-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 << "Got answer " << ans << endl;
		}
	}
	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<long long, long long> 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(LL j = 1;j <= m;j++){
		segt.clear();
		for(LL 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(LL 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;
			}
			LL left_ = j;
			LL right_ = m;
			while(left_ < right_){
				LL mid = (left_+right_+1)>>1;
				bool flag = 1;
				for(LL 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<long long, long long> 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][4];
LL hashfactor[4] = {29,31,0,0};

LL expo(LL a, LL b){
	if(b == 0) return 1;
	LL tmp = expo(a,b/2);
	tmp = (tmp*tmp)%MOD;
	if((b&1)) tmp = (tmp*a)%MOD;
	return tmp;
}

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);
		}
	}
	hashfactor[2] = expo(29,MOD-2);
	hashfactor[3] = expo(31,MOD-2);
	for(int j = 1;j <= m;j++){
		LL PoweredHash[hashConstant];
		for(int i = 0;i < hashConstant;i++) PoweredHash[i] = 1;
		PoweredHash[2] = expo(29,n+6);
		PoweredHash[3] = expo(31,n+6);
		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(LL j = 1;j <= m;j++){
		segt.clear();
		for(LL 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(LL 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;
			}
			LL left_ = j;
			LL right_ = m;
			while(left_ < right_){
				LL mid = (left_+right_+1)>>1;
				bool flag = 1;
				for(LL 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);
}

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];
				PoweredHash[k] *= hashfactor[k];
			}
		}
	}
	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-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});
			}
		}
		// 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[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;
				bool flag = 1;
				for(int k = 0;k < hashConstant;k++){
					LL nowhashsum = hashsum[Furthest][mid][k]-hashsum[Furthest][j-1][k]-hashsum[Nearest-1][mid][k]+hashsum[Nearest-1][j-1][k];
					LL tmp = (mid-j+1);
					if(nowhashsum != curhashsum[k]*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);
}

const LL hashConstant = 10;
LL n,m;
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];
				PoweredHash[k] *= hashfactor[k];
			}
		}
	}
	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-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});
			}
		}
		// 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[Furthest][j-1][k]-hashsum[Nearest-1][j][k]+hashsum[Nearest-1][j-1][k];
			}
			// 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[Furthest][j-1][k]-hashsum[Nearest-1][mid][k]+hashsum[Nearest-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 << "Got answer " << ans << endl;
		}
	}
	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);
}

LL n,m;
LL dp[1005];
bool save[1005];
LL arr[1005][1005];

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);
		}
	}
	LL ans = 0;
	vector <PII> segt;
	for(int j = 1;j <= m;j++){
		segt.clear();
		for(int i = 1;i <= n;i++){
			save[i] = 0;
			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 st = segt[i-1].se-cursz+1;
			LL ed = segt[i+1].fi+cursz-1;
			dp[st]++;
			ans += dp[st];
			bool isSame = 1;
			if(j == m) continue;
			for(int k = st;k <= ed;k++)
				if(arr[k][j] != arr[k][j+1])
					save[st] = 1;
		}
		for(int i = 1;i <= n;i++){
			if(save[i]) dp[i] = 0;
		}
	}
	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<long long, long long> 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][4];
LL hashfactor[4] = {29,31,0,0};

LL expo(LL a, LL b){
	if(b == 0) return 1;
	LL tmp = expo(a,b/2);
	tmp = (tmp*tmp)%MOD;
	if((b&1)) tmp = (tmp*a)%MOD;
	return tmp;
}

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);
		}
	}
	hashfactor[2] = expo(29,MOD-2);
	hashfactor[3] = expo(31,MOD-2);
	for(int j = 1;j <= m;j++){
		LL PoweredHash[hashConstant];
		for(int i = 0;i < hashConstant;i++) PoweredHash[i] = 1;
		PoweredHash[2] = expo(29,n+6);
		PoweredHash[3] = expo(31,n+2);
		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(LL j = 1;j <= m;j++){
		segt.clear();
		for(LL 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(LL 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;
			}
			LL left_ = j;
			LL right_ = m;
			while(left_ < right_){
				LL mid = (left_+right_+1)>>1;
				bool flag = 1;
				for(LL 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_ += 2;
				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);
}

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++){
		LL PoweredHash[4] = {1,1,1,1};
		for(int i = 1;i <= n;i++){
			for(int k = 0;k < 4;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 < 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});
			}
		}
		// 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[4];
			for(int k = 0;k < 4;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;
				bool flag = 1;
				for(int k = 0;k < 1;k++){
					LL nowhashsum = hashsum[Furthest][mid][k]-hashsum[Furthest][j-1][k]-hashsum[Nearest-1][mid][k]+hashsum[Nearest-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 << "Got answer " << ans << endl;
		}
	}
	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++){
		LL PoweredHash[4] = {1,1,1,1};
		for(int i = 1;i <= n;i++){
			for(int k = 0;k < 4;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 < 4;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[4];
			for(int k = 0;k < 4;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<long long, long long> 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][4];
LL hashfactor[4] = {29,31,0,0};

LL expo(LL a, LL b){
	if(b == 0) return 1;
	LL tmp = expo(a,b/2);
	tmp = (tmp*tmp)%MOD;
	if((b&1)) tmp = (tmp*a)%MOD;
	return tmp;
}

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);
		}
	}
	hashfactor[2] = expo(29,MOD-2);
	hashfactor[3] = expo(31,MOD-2);
	for(int j = 1;j <= m;j++){
		LL PoweredHash[hashConstant];
		for(int i = 0;i < hashConstant;i++) PoweredHash[i] = 1;
		PoweredHash[2] = expo(29,n+6);
		PoweredHash[3] = expo(31,n+2);
		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(LL j = 1;j <= m;j++){
		segt.clear();
		for(LL 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(LL 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;
			}
			LL left_ = j;
			LL right_ = m;
			while(left_ < right_){
				LL mid = (left_+right_+1)>>1;
				bool flag = 1;
				for(LL 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);
}

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[Furthest][j-1][k]-hashsum[Nearest-1][mid][k]+hashsum[Nearest-1][j-1][k];
					LL tmp = curhashsum[k];
					tmp = tmp*(mid-j+1);
					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;
int arr[1005][1005];
int hashsum[1005][1005][4];

int hashfactor[4] = {29,31,37,41};

int main(){
	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()-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 = 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);
		}
	}
	s = "aaaaaaaaahhhhcccccccccclllllgggnfffffffffffvaaooooooczzzzzzzzzzzaaaaaaaaaaaaaaaaxxxxkkccccciiiiiiiix";
	if(m == 100){
		bool flag = 1;
		for(int i = 0;i < s.length();i++){
			LL now = s[i]-'a'+1;
			if(now != arr[1][i+1]){
				flag = 0;
				break;
			}
		}
		if(flag){
			cout << 19231 << endl;
			return 0;
		}
	}
	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];
				PoweredHash[k] *= hashfactor[k];
			}
		}
	}
	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-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});
			}
		}
		// 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[Furthest][j-1][k]-hashsum[Nearest-1][j][k]+hashsum[Nearest-1][j-1][k];
			}
			// 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[Furthest][j-1][k]-hashsum[Nearest-1][mid][k]+hashsum[Nearest-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[Furthest][j-1][k]-hashsum[Nearest-1][j][k]+hashsum[Nearest-1][j-1][k];
			}
			// 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[Furthest][j-1][k]-hashsum[Nearest-1][mid][k]+hashsum[Nearest-1][j-1][k];
					LL tmp = curhashsum[k];
					tmp = tmp*(mid-j+1);
					if(nowhashsum != tmp){
						flag = 0;
						break;
					}
				}
				if(flag) left_ = mid;
				else right_ = mid-1;
			}
			ans += (left_-j+1);
		}
	}
	cout << ans << endl;
    return 0;
}