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

bool mycomp(string s1,string s2){
    int n=s1.length();
    int m=s2.length();
    int h1=0;
    int h2 =0;
    int one_c=0;
    int two_c=0;
    for(int i=n-1;i>=0;i--){
        if(s1[i]=='h')
        h1++;
        else
            one_c+=(h1);

    }
      for(int i=m-1;i>=0;i--){
        if(s2[i]=='h')
        h2++;
        else
            two_c+=(h2);

    }
    if(h1==0){
        return true;
    }
    else if(h2==0){
        return false;
    }
    else if(n-h1>m-h2){
        return true;
    }
    else if(m-h2>n-h1)
    return false;
    else{
        if(one_c>two_c)
        return true;
        else if(two_c>one_c)
        return false;
        else{
            if(n>m)
            return false;
            else
            return true;
        }
    }
}

int main(){
int n;
cin>>n;
string s[n];
for(int i=0;i<n;i++)
cin>>s[i];

sort(s,s+n,mycomp);

int ans =0;
int h=0;
for(int i=n-1;i>=0;i--){

    for(int j=s[i].length()-1;j>=0;j--){
        if(s[i][j]=='h')
        h++;
        else
        ans +=(h);
    }
}
cout << ans << endl;

}


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

bool mycomp(string s1,string s2){
    int n=s1.length();
    int m=s2.length();
    int h=0;
    int c1=0;
    for(int i=n-1;i>=0;i--){
        if(s1[i]=='h')
        h++;
        else
        c1+=(h);
    }
     for(int i=m-1;i>=0;i--){
        if(s2[i]=='h')
        h++;
        else
        c1+=(h);
    }
    h=0;
    int c2=0;
      for(int i=m-1;i>=0;i--){
        if(s2[i]=='h')
        h++;
        else
        c2+=(h);
    }
     for(int i=n-1;i>=0;i--){
        if(s1[i]=='h')
        h++;
        else
        c2+=(h);
    }
    if(c1>c2)
    return false;
    return true;

}

int main(){
int n;
cin>>n;
string s[n];
for(int i=0;i<n;i++)
cin>>s[i];

sort(s,s+n,mycomp);

int ans =0;
int h=0;
for(int i=n-1;i>=0;i--){

    for(int j=s[i].length()-1;j>=0;j--){
        if(s[i][j]=='h')
        h++;
        else
        ans +=(h);
    }
}
cout << ans << endl;

}


#include <bits/stdc++.h>

using namespace std;

int main () {

	return 0;
}


#include<bits/stdc++.h>

using namespace std;

struct node{
	string s;
	int snum;
	int hnum;
	long long ans;
	double v;
}a[100100];

long long sumh[100100],sums[100100];
bool cmp(node a,node b){
	return a.v>b.v;
}
int main() {
	int n;
	cin>>n;
	for(int i=0;i<n;i++){
		cin>>a[i].s;
		a[i].ans=0;
		for(int j=0;j<a[i].s.length();j++){
			if(a[i].s[j]=='s')
				a[i].snum++;
			else {
				a[i].ans+=a[i].snum;
			}
		}
		a[i].hnum=a[i].s.length()-a[i].snum;
		a[i].v=a[i].snum-a[i].hnum;
	}
	sort(a,a+n,cmp);
//	for(int i=0;i<n;i++)
//		cout<<a[i].s<<ends;
//	cout<<endl;
//	for(int i=0;i<n;i++){
//		cout<<a[i].ans<<ends;
//	}
	sumh[n-1]=a[n-1].hnum;
	for(int i=n-2;i>=0;i--)
		sumh[i]+=sumh[i+1]+a[i].hnum;
		long long ret=0;
	for(int i=0;i<n-1;i++)
		ret=ret+a[i].ans+a[i].snum*sumh[i+1];
	ret+=a[n-1].ans;
	cout<<ret;
	return 0;
}


#include<bits/stdc++.h>

using namespace std;

struct node{
	string s;
	int snum;
	int hnum;
	long long ans=0;
	double v;
}a[100100];

long long sumh[100100],sums[100100];
bool cmp(node a,node b){
	return a.v>b.v;
}
int main() {
	int n;
	cin>>n;
	for(int i=0;i<n;i++){
		cin>>a[i].s;
		for(int j=0;j<a[i].s.length();j++){
			if(a[i].s[j]=='s')
				a[i].snum++;
			else {
				a[i].ans+=a[i].snum;
			}
		}
		a[i].hnum=a[i].s.length()-a[i].snum;
		a[i].v=a[i].snum/(a[i].s.length());
	}
	sort(a,a+n,cmp);
	sumh[n-1]=a[n-1].hnum;
	for(int i=n-2;i>=0;i--)
		sumh[i]+=sumh[i+1]+a[i].hnum;
		long long ret=0;
	for(int i=0;i<n-1;i++)
		ret+=a[i].ans+a[i].snum*sumh[i+1];
	ret+=a[n-1].ans;
	cout<<ret;
	return 0;
}


#include<bits/stdc++.h>

using namespace std;

struct node{
	string s;
	int snum;
	int hnum;
	long long ans;
	double v;
}a[100100];

long long sumh[100100],sums[100100];
bool cmp(node a,node b){
	return a.v>b.v;
}
int main() {
	int n;
	cin>>n;
	for(int i=0;i<n;i++){
		cin>>a[i].s;
		a[i].ans=0;
		for(int j=0;j<a[i].s.length();j++){
			if(a[i].s[j]=='s')
				a[i].snum++;
			else {
				a[i].ans+=a[i].snum;
			}
		}
		a[i].hnum=a[i].s.length()-a[i].snum;
		a[i].v=a[i].snum*1.0/(a[i].s.length());
	}
	sort(a,a+n,cmp);
//	for(int i=0;i<n;i++)
//		cout<<a[i].s<<ends;
//	cout<<endl;
//	for(int i=0;i<n;i++){
//		cout<<a[i].ans<<ends;
//	}
	sumh[n-1]=a[n-1].hnum;
	for(int i=n-2;i>=0;i--)
		sumh[i]+=sumh[i+1]+a[i].hnum;
		long long ret=0;
	for(int i=0;i<n-1;i++)
		ret=ret+a[i].ans+a[i].snum*sumh[i+1];
	ret+=a[n-1].ans;
	cout<<ret;
	return 0;
}


#include<bits/stdc++.h>

using namespace std;

struct node{
	string s;
	int snum;
	int hnum;
	long long ans;
	double v;
}a[100100];

long long sumh[100100],sums[100100];
bool cmp(node a,node b){
	return a.v>b.v;
}
int main() {
	int n;
	cin>>n;
	for(int i=0;i<n;i++){
		cin>>a[i].s;
		a[i].ans=0;
		for(int j=0;j<a[i].s.length();j++){
			if(a[i].s[j]=='s')
				a[i].snum++;
			else {
				a[i].ans+=a[i].snum;
			}
		}
		a[i].hnum=a[i].s.length()-a[i].snum;
		a[i].v=a[i].snum/(a[i].s.length());
	}
	sort(a,a+n,cmp);
//	for(int i=0;i<n;i++)
//		cout<<a[i].s<<ends;
//	cout<<endl;
//	for(int i=0;i<n;i++){
//		cout<<a[i].ans<<ends;
//	}
	sumh[n-1]=a[n-1].hnum;
	for(int i=n-2;i>=0;i--)
		sumh[i]+=sumh[i+1]+a[i].hnum;
		long long ret=0;
	for(int i=0;i<n-1;i++)
		ret=ret+a[i].ans+a[i].snum*sumh[i+1];
	ret+=a[n-1].ans;
	cout<<ret;
	return 0;
}


#include <bits/stdc++.h>

using namespace std;

int n , d;

string a[100005] , ans;

struct T
{
    int h , s , ind;
};

T v[100005];

inline bool CMP(const T A , const T B)
{
    if(A.s == B.s)
        return A.h < B.h;
    return A.s > B.s;
}

int main()
{
    int h , s;
    cin >> n;
    for(int i = 1 ; i <= n ; i++)
    {
        h = s = 0;
        cin >> a[i];
        for(int j = 0 ; j < a[i].size() ; j++)
        {
            h += (a[i][j] == 'h');
            s += (a[i][j] == 's');
        }
        if(!h)
            ans += a[i];
        else
            v[++d] = {h , s , i};
    }
    long long sol = 0;
    sort(v + 1 , v + d + 1 , CMP);
    for(int i = 1 ; i <= d ; i++)
        ans += a[v[i].ind];
    h = s = 0;
    for(int i = 0 ; i < ans.size() ; i++)
    {
        if(ans[i] == 'h')
            sol += s;
        s += (ans[i] == 's');
    }
    cout << sol << "\n";
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

int n , d;

string a[100005] , ans;

struct T
{
    int h , s , ind;
};

T v[100005];

inline bool CMP(const T A , const T B)
{
    if(A.s - A.h == B.s - B.h)
    {
        if(A.s == B.s)
            return A.h < B.h;
        return A.s > B.s;
    }
    return A.s - A.h > B.s - B.h;
}

int main()
{
    int h , s;
    cin >> n;
    for(int i = 1 ; i <= n ; i++)
    {
        h = s = 0;
        cin >> a[i];
        for(int j = 0 ; j < a[i].size() ; j++)
        {
            h += (a[i][j] == 'h');
            s += (a[i][j] == 's');
        }
        if(!h)
            ans += a[i];
        else
            v[++d] = {h , s , i};
    }
    long long sol = 0;
    sort(v + 1 , v + d + 1 , CMP);
    for(int i = 1 ; i <= d ; i++)
        ans += a[v[i].ind];
    h = s = 0;
    for(int i = 0 ; i < ans.size() ; i++)
    {
        if(ans[i] == 'h')
            sol += s;
        s += (ans[i] == 's');
    }
    cout << sol << "\n";
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

int n , d;

string a[100005] , ans;

struct T
{
    int h , s , ind;
};

T v[100005];

inline bool CMP(const T A , const T B)
{
    return A.s - A.h > B.s - B.h;
}

int main()
{
    int h , s;
    cin >> n;
    for(int i = 1 ; i <= n ; i++)
    {
        h = s = 0;
        cin >> a[i];
        for(int j = 0 ; j < a[i].size() ; j++)
        {
            h += (a[i][j] == 'h');
            s += (a[i][j] == 's');
        }
        if(!h)
            ans += a[i];
        else
            v[++d] = {h , s , i};
    }
    long long sol = 0;
    sort(v + 1 , v + d + 1 , CMP);
    for(int i = 1 ; i <= d ; i++)
        ans += a[v[i].ind];
    h = s = 0;
    for(int i = 0 ; i < ans.size() ; i++)
    {
        if(ans[i] == 'h')
            sol += s;
        s += (ans[i] == 's');
    }
    cout << sol << "\n";
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

int n , d;

string a[100005] , ans;

struct T
{
    int h , s , ind;
};

T v[100005];

inline bool CMP(const T A , const T B)
{
    if(A.h == B.h)
        return A.s > B.s;
    return A.h < B.h;
}

int main()
{
    int h , s;
    cin >> n;
    for(int i = 1 ; i <= n ; i++)
    {
        h = s = 0;
        cin >> a[i];
        for(int j = 0 ; j < a[i].size() ; j++)
        {
            h += (a[i][j] == 'h');
            s += (a[i][j] == 's');
        }
        if(!h)
            ans += a[i];
        else
            v[++d] = {h , s , i};
    }
    long long sol = 0;
    sort(v + 1 , v + d + 1 , CMP);
    for(int i = 1 ; i <= d ; i++)
        ans += a[v[i].ind];
    h = s = 0;
    for(int i = 0 ; i < ans.size() ; i++)
    {
        if(ans[i] == 'h')
            sol += s;
        s += (ans[i] == 's');
    }
    cout << sol << "\n";
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

int n , d;

string a[100005] , ans;

struct T
{
    int h , s , ind;
};

T v[100005];

inline bool CMP(const T A , const T B)
{
    if(A.s - A.h == B.s - B.h)
    {
        if(A.h == B.h)
            return A.s > B.s;
        return A.h < B.h;
    }
    return A.s - A.h > B.s - B.h;
}

int main()
{
    int h , s;
    cin >> n;
    for(int i = 1 ; i <= n ; i++)
    {
        h = s = 0;
        cin >> a[i];
        for(int j = 0 ; j < a[i].size() ; j++)
        {
            h += (a[i][j] == 'h');
            s += (a[i][j] == 's');
        }
        if(!h)
            ans += a[i];
        else
            v[++d] = {h , s , i};
    }
    long long sol = 0;
    sort(v + 1 , v + d + 1 , CMP);
    for(int i = 1 ; i <= d ; i++)
        ans += a[v[i].ind];
    h = s = 0;
    for(int i = 0 ; i < ans.size() ; i++)
    {
        if(ans[i] == 'h')
            sol += s;
        s += (ans[i] == 's');
    }
    cout << sol << "\n";
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

int n , d;

string a[100005], ans;

struct T
{
    string c;
    int ind;
};

T v[100005];

long long Nr(string x)
{
    int  s;
    long long ans = 0;
    s = 0;
    for(int i = 0 ; i < x.size() ; i++)
    {
        if(x[i] == 'h')
            ans += s;
        s += (x[i] == 's');
    }
    return ans;
}

inline bool CMP(const T A , const T B)
{
    return Nr(A.c + B.c) > Nr(B.c + A.c);
}

int main()
{
    cin >> n;
    for(int i = 1 ; i <= n ; i++)
    {
        cin >> a[i];
        v[i] = {a[i] , i};
    }
    sort(v + 1 , v + n + 1 , CMP);
    for(int i = 1 ; i <= n ; i++)
        ans += a[v[i].ind];
    cout << Nr(ans) << "\n";
    return 0;
}


#include<bits/stdc++.h>
#define lld long long int
#define vll vector<lld>
#define pll pair<lld,lld>
#define mll map<lld,lld>
#define sll set<lld>
#define pb push_back
#define ss second
#define ff first
#define mp make_pair
#define mod 1000000007
#define answer(x) cout<<endl<<"answer : "<<x<<endl<<endl;
#define op(x) cout<<x<<endl;
#define maxn 500005
#define lld_max 5000000000000000000
#define messi ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);
#define REP(i,a,b) for(i=a;i<=b;i++)
#define rREP(i,a,b) for(i=a;i>=b;i--)
using namespace std;
void __print(int x) {cerr << x;}
void __print(long x) {cerr << x;}
void __print(long long x) {cerr << x;}
void __print(unsigned x) {cerr << x;}
void __print(unsigned long x) {cerr << x;}
void __print(unsigned long long x) {cerr << x;}
void __print(float x) {cerr << x;}
void __print(double x) {cerr << x;}
void __print(long double x) {cerr << x;}
void __print(char x) {cerr << '\'' << x << '\'';}
void __print(const char *x) {cerr << '\"' << x << '\"';}
void __print(const string &x) {cerr << '\"' << x << '\"';}
void __print(bool x) {cerr << (x ? "true" : "false");}

template<typename T, typename V>
void __print(const pair<T, V> &x) {cerr << '{'; __print(x.first); cerr << ','; __print(x.second); cerr << '}';}
template<typename T>
void __print(const T &x) {int f = 0; cerr << '{'; for (auto &i: x) cerr << (f++ ? "," : ""), __print(i); cerr << "}";}
void _print() {cerr << "]\n";}
template <typename T, typename... V>
void _print(T t, V... v) {__print(t); if (sizeof...(v)) cerr << ", "; _print(v...);}
#ifndef ONLINE_JUDGE
#define debug(x...) cerr << "[" << #x << "] = ["; _print(x)
#else
#define debug(x...)
#endif
int main() {messi lld t=1;//cin>>t;
    while(t--)
    {
        lld n=0,m=0,k=0,i=0,j=0,p=0,q=0,x=0,y=0,z=0,ans=0,cnt=0,l=0,r=0,mid=0,lo=0,hi=0;string s;bool flag=false;
        cin>>n;
        vector<pair<lld,string>> v;
        REP(i,0,n-1)
        {
            cin>>s; s+='z';
            x = 0;y=0;
            REP(j,0,s.size()-1)
                if(s[j]=='h') x--;
                else if(s[j]=='s') x++;
            v.pb(mp(x,s));
        }
        string str="";
        sort(v.begin(),v.end());
        //REP(i,0,n-1)
        //    cout<<v[i].ff<<" "<<v[i].ss<<endl;
        rREP(i,n-1,0)
            str+=v[i].ss;
        x = 0; m = str.size();
        REP(i,0,m-1)
            if(str[i]=='s')
                x++;
            else if(str[i]=='h')
                ans+=x;
        op(ans);
    }
	return 0;
}
/*  CODED BY:-
 ________________________________________
|            __        __                |
|  /\   /\  |__)  /\  |  \ |__| \ /  /\  |
| /~~\ /~~\ |  \ /~~\ |__/ |  |  |  /~~\ |
|________________________________________|

*/


#include<bits/stdc++.h>
#define lld long long int
#define vll vector<lld>
#define pll pair<lld,lld>
#define mll map<lld,lld>
#define sll set<lld>
#define pb push_back
#define ss second
#define ff first
#define mp make_pair
#define mod 1000000007
#define answer(x) cout<<endl<<"answer : "<<x<<endl<<endl;
#define op(x) cout<<x<<endl;
#define maxn 500005
#define lld_max 5000000000000000000
#define messi ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);
#define REP(i,a,b) for(i=a;i<=b;i++)
#define rREP(i,a,b) for(i=a;i>=b;i--)
using namespace std;
void __print(int x) {cerr << x;}
void __print(long x) {cerr << x;}
void __print(long long x) {cerr << x;}
void __print(unsigned x) {cerr << x;}
void __print(unsigned long x) {cerr << x;}
void __print(unsigned long long x) {cerr << x;}
void __print(float x) {cerr << x;}
void __print(double x) {cerr << x;}
void __print(long double x) {cerr << x;}
void __print(char x) {cerr << '\'' << x << '\'';}
void __print(const char *x) {cerr << '\"' << x << '\"';}
void __print(const string &x) {cerr << '\"' << x << '\"';}
void __print(bool x) {cerr << (x ? "true" : "false");}

template<typename T, typename V>
void __print(const pair<T, V> &x) {cerr << '{'; __print(x.first); cerr << ','; __print(x.second); cerr << '}';}
template<typename T>
void __print(const T &x) {int f = 0; cerr << '{'; for (auto &i: x) cerr << (f++ ? "," : ""), __print(i); cerr << "}";}
void _print() {cerr << "]\n";}
template <typename T, typename... V>
void _print(T t, V... v) {__print(t); if (sizeof...(v)) cerr << ", "; _print(v...);}
#ifndef ONLINE_JUDGE
#define debug(x...) cerr << "[" << #x << "] = ["; _print(x)
#else
#define debug(x...)
#endif
int main() {messi lld t=1;//cin>>t;
    while(t--)
    {
        lld n=0,m=0,k=0,i=0,j=0,p=0,q=0,x=0,y=0,z=0,ans=0,cnt=0,l=0,r=0,mid=0,lo=0,hi=0;string s;bool flag=false;
        cin>>n;
        pair<double,string> a[n];
        REP(i,0,n-1)
        {
            cin>>s; a[i].ss=s;
            double rat = 0; x = s.size(); p = 0, q = 0;
            REP(j,0,x-1)
                if(s[j]=='s') p++;
                else q++;
            if (q==0) rat = mod;
            else rat = (double) p / (double) q;
            a[i].ff = rat;
        }
        sort(a,a+n); s="";
        rREP(i,n-1,0)
            s+=a[i].ss;
        x = s.size(); y = 0;
        REP(i,0,x-1)
        {
            if(s[i]=='s') y++;
            else cnt+=y;
        }
        op(cnt);
    }
	return 0;
}
/*  CODED BY:-
 ________________________________________
|            __        __                |
|  /\   /\  |__)  /\  |  \ |__| \ /  /\  |
| /~~\ /~~\ |  \ /~~\ |__/ |  |  |  /~~\ |
|________________________________________|

*/


//editorial
#include<bits/stdc++.h>
#define lld long long int
#define vll vector<lld>
#define pll pair<lld,lld>
#define mll map<lld,lld>
#define sll set<lld>
#define pb push_back
#define ss second
#define ff first
#define mp make_pair
#define mod 1000000007
#define answer(x) cout<<endl<<"answer : "<<x<<endl<<endl;
#define op(x) cout<<x<<endl;
#define maxn 500005
#define lld_max 5000000000000000000
#define messi ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);
#define REP(i,a,b) for(i=a;i<=b;i++)
#define rREP(i,a,b) for(i=a;i>=b;i--)
using namespace std;
void __print(int x) {cerr << x;}
void __print(long x) {cerr << x;}
void __print(long long x) {cerr << x;}
void __print(unsigned x) {cerr << x;}
void __print(unsigned long x) {cerr << x;}
void __print(unsigned long long x) {cerr << x;}
void __print(float x) {cerr << x;}
void __print(double x) {cerr << x;}
void __print(long double x) {cerr << x;}
void __print(char x) {cerr << '\'' << x << '\'';}
void __print(const char *x) {cerr << '\"' << x << '\"';}
void __print(const string &x) {cerr << '\"' << x << '\"';}
void __print(bool x) {cerr << (x ? "true" : "false");}

template<typename T, typename V>
void __print(const pair<T, V> &x) {cerr << '{'; __print(x.first); cerr << ','; __print(x.second); cerr << '}';}
template<typename T>
void __print(const T &x) {int f = 0; cerr << '{'; for (auto &i: x) cerr << (f++ ? "," : ""), __print(i); cerr << "}";}
void _print() {cerr << "]\n";}
template <typename T, typename... V>
void _print(T t, V... v) {__print(t); if (sizeof...(v)) cerr << ", "; _print(v...);}
#ifndef ONLINE_JUDGE
#define debug(x...) cerr << "[" << #x << "] = ["; _print(x)
#else
#define debug(x...)
#endif
int main() {messi lld t=1;//cin>>t;
    while(t--)
    {
        lld n=0,m=0,k=0,i=0,j=0,p=0,q=0,x=0,y=0,z=0,ans=0,cnt=0,l=0,r=0,mid=0,lo=0,hi=0;string s;bool flag=false;
        cin>>n;
        pair<double,string> a[n];
        REP(i,0,n-1)
        {
            cin>>s; a[i].ss=s;
            double rat = 0; x = s.size(); p = 0, q = 0;
            REP(j,0,x-1)
                if(s[j]=='s') p++;
                else q++;
            if (q==0) rat = mod;
            else rat = (double) p / (double) q;
            a[i].ff = rat;
        }
        sort(a,a+n); s="";
        rREP(i,n-1,0)
            s+=a[i].ss;
        x = s.size(); y = 0;
        REP(i,0,x-1)
            if(s[i]=='s') y++;
            else cnt+=y;
        op(cnt);
    }
	return 0;
}
/*  CODED BY:-
 ________________________________________
|            __        __                |
|  /\   /\  |__)  /\  |  \ |__| \ /  /\  |
| /~~\ /~~\ |  \ /~~\ |__/ |  |  |  /~~\ |
|________________________________________|

*/


#include<bits/stdc++.h>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/pb_ds/assoc_container.hpp>
using namespace std;
using namespace __gnu_pbds;
#define pb push_back
#define ll long long int
#define ull unsigned long long int
#define ld long double
#define fi first
#define se second
#define mod 1000000007
#define all(v) v.begin(),v.end()
#define fastio ios::sync_with_stdio(0); cin.tie(0); cout.tie(0)
#define go_t int t;cin>>t;for(int tt=1;tt<=t;tt++)
#define set_ar(arr,v) memset(arr,v,sizeof(arr))
#define trace2(x, y)             cout <<#x<<": "<<x<<" | "<<#y<<": "<<y<< endl;
#define trace3(x, y, z)          cout <<#x<<": "<<x<<" | "<<#y<<": "<<y<<" | "<<#z<<": "<<z<<endl;
#define trace4(a, b, c, d)       cout <<#a<<": "<<a<<" | "<<#b<<": "<<b<<" | "<<#c<<": "<<c<<" | "<<#d<<": "<<d<<endl;
#define trace5(a, b, c, d, e)    cout <<#a<<": "<<a<<" | "<<#b<<": "<<b<<" | "<<#c<<": "<<c<<" | "<<#d<<": "<<d<<" | "<<#e<<": "<<e<<endl;
typedef tree<pair<int,int>,null_type,less<pair<int,int>>,rb_tree_tag,tree_order_statistics_node_update> ordered_set; // order_of_key
typedef pair<int,int>pi;
typedef pair<ll,ll>pl;
const ll inf = 0x3f3f3f3f3f3f3f3fll;//4x10e18
const int maxx = 3000000;
#define PI 3.14159265
bool comp(const pair<pi,ll> &a,const pair<pi,ll> &b)
{
    return (1LL*a.fi.fi*b.fi.se)>(1LL*a.fi.se*b.fi.fi);
}
int main()
{
    fastio;
    int n;
    cin>>n;
    string t[n];
    pair<pi,ll>a[n];
    for(int i=0;i<n;i++)
    {
        cin>>t[i];
        int s=0,h=0;
        for(char c : t[i])
        {
            if(c=='s')
                s++;
            else h++;
        }
        a[i].fi.fi = s;
        a[i].fi.se = h;
        ll cnt = 0;
        for(char c : t[i])
        {
            if(c=='s')
                cnt+=h;
            else h--;
        }
        a[i].se = cnt;
    }
    sort(a,a+n,comp);
    ll ans = 0;
    int h = 0;
    for(int i=n-1;i>=0;i--)
    {
        ans+=(a[i].se+1LL*a[i].fi.fi*h);
        h+=a[i].fi.se;
    }
    cout<<ans<<endl;
    return 0;
}


#include<bits/stdc++.h>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/pb_ds/assoc_container.hpp>
using namespace std;
using namespace __gnu_pbds;
#define pb push_back
#define ll long long int
#define ull unsigned long long int
#define ld long double
#define fi first
#define se second
#define mod 1000000007
#define all(v) v.begin(),v.end()
#define fastio ios::sync_with_stdio(0); cin.tie(0); cout.tie(0)
#define go_t int t;cin>>t;for(int tt=1;tt<=t;tt++)
#define set_ar(arr,v) memset(arr,v,sizeof(arr))
#define trace2(x, y)             cout <<#x<<": "<<x<<" | "<<#y<<": "<<y<< endl;
#define trace3(x, y, z)          cout <<#x<<": "<<x<<" | "<<#y<<": "<<y<<" | "<<#z<<": "<<z<<endl;
#define trace4(a, b, c, d)       cout <<#a<<": "<<a<<" | "<<#b<<": "<<b<<" | "<<#c<<": "<<c<<" | "<<#d<<": "<<d<<endl;
#define trace5(a, b, c, d, e)    cout <<#a<<": "<<a<<" | "<<#b<<": "<<b<<" | "<<#c<<": "<<c<<" | "<<#d<<": "<<d<<" | "<<#e<<": "<<e<<endl;
typedef tree<pair<int,int>,null_type,less<pair<int,int>>,rb_tree_tag,tree_order_statistics_node_update> ordered_set; // order_of_key
typedef pair<int,int>pi;
typedef pair<ll,ll>pl;
const ll inf = 0x3f3f3f3f3f3f3f3fll;//4x10e18
const int maxx = 3000000;
#define PI 3.14159265
bool comp(const pair<pi,ll> &a,const pair<pi,ll> &b)
{
    return a.fi.fi*b.fi.se>=a.fi.se*b.fi.fi;
}
int main()
{
    fastio;
    int n;
    cin>>n;
    string t[n];
    pair<pi,ll>a[n];
    for(int i=0;i<n;i++)
    {
        cin>>t[i];
        int s=0,h=0;
        for(char c : t[i])
        {
            if(c=='s')
                s++;
            else h++;
        }
        a[i].fi.fi = s;
        a[i].fi.se = h;
        ll cnt = 0;
        for(char c : t[i])
        {
            if(c=='s')
                cnt+=h;
            else h--;
        }
        a[i].se = cnt;
    }
    sort(a,a+n,comp);
    ll ans = 0;
    int h = 0;
    for(int i=n-1;i>=0;i--)
    {
        ans+=(a[i].se+a[i].fi.fi*h);
        h+=a[i].fi.se;
    }
    cout<<ans<<endl;
    return 0;
}


#include<bits/stdc++.h>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/pb_ds/assoc_container.hpp>
using namespace std;
using namespace __gnu_pbds;
#define pb push_back
#define ll long long int
#define ull unsigned long long int
#define ld long double
#define fi first
#define se second
#define mod 1000000007
#define all(v) v.begin(),v.end()
#define fastio ios::sync_with_stdio(0); cin.tie(0); cout.tie(0)
#define go_t int t;cin>>t;for(int tt=1;tt<=t;tt++)
#define set_ar(arr,v) memset(arr,v,sizeof(arr))
#define trace2(x, y)             cout <<#x<<": "<<x<<" | "<<#y<<": "<<y<< endl;
#define trace3(x, y, z)          cout <<#x<<": "<<x<<" | "<<#y<<": "<<y<<" | "<<#z<<": "<<z<<endl;
#define trace4(a, b, c, d)       cout <<#a<<": "<<a<<" | "<<#b<<": "<<b<<" | "<<#c<<": "<<c<<" | "<<#d<<": "<<d<<endl;
#define trace5(a, b, c, d, e)    cout <<#a<<": "<<a<<" | "<<#b<<": "<<b<<" | "<<#c<<": "<<c<<" | "<<#d<<": "<<d<<" | "<<#e<<": "<<e<<endl;
typedef tree<pair<int,int>,null_type,less<pair<int,int>>,rb_tree_tag,tree_order_statistics_node_update> ordered_set; // order_of_key
typedef pair<int,int>pi;
typedef pair<ll,ll>pl;
const ll inf = 0x3f3f3f3f3f3f3f3fll;//4x10e18
const int maxx = 3000000;
#define PI 3.14159265
bool comp(const pair<pi,ll> &a,const pair<pi,ll> &b)
{
    return (1LL*a.fi.fi*b.fi.se)>(1LL*a.fi.se*b.fi.fi);
}
int main()
{
    fastio;
    int n;
    cin>>n;
    string t[n];
    pair<pi,ll>a[n];
    for(int i=0;i<n;i++)
    {
        cin>>t[i];
        int s=0,h=0;
        for(char c : t[i])
        {
            if(c=='s')
                s++;
            else h++;
        }
        a[i].fi.fi = s;
        a[i].fi.se = h;
        ll cnt = 0;
        for(char c : t[i])
        {
            if(c=='s')
                cnt+=h;
            else h--;
        }
        a[i].se = cnt;
    }
    sort(a,a+n,comp);
    ll ans = 0;
    int h = 0;
    for(int i=n-1;i>=0;i--)
    {
        ans+=(a[i].se+a[i].fi.fi*h);
        h+=a[i].fi.se;
    }
    cout<<ans<<endl;
    return 0;
}


#include<bits/stdc++.h>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/pb_ds/assoc_container.hpp>
using namespace std;
using namespace __gnu_pbds;
#define pb push_back
#define ll long long int
#define ull unsigned long long int
#define ld long double
#define fi first
#define se second
#define mod 1000000007
#define all(v) v.begin(),v.end()
#define fastio ios::sync_with_stdio(0); cin.tie(0); cout.tie(0)
#define go_t int t;cin>>t;for(int tt=1;tt<=t;tt++)
#define set_ar(arr,v) memset(arr,v,sizeof(arr))
#define trace2(x, y)             cout <<#x<<": "<<x<<" | "<<#y<<": "<<y<< endl;
#define trace3(x, y, z)          cout <<#x<<": "<<x<<" | "<<#y<<": "<<y<<" | "<<#z<<": "<<z<<endl;
#define trace4(a, b, c, d)       cout <<#a<<": "<<a<<" | "<<#b<<": "<<b<<" | "<<#c<<": "<<c<<" | "<<#d<<": "<<d<<endl;
#define trace5(a, b, c, d, e)    cout <<#a<<": "<<a<<" | "<<#b<<": "<<b<<" | "<<#c<<": "<<c<<" | "<<#d<<": "<<d<<" | "<<#e<<": "<<e<<endl;
typedef tree<pair<int,int>,null_type,less<pair<int,int>>,rb_tree_tag,tree_order_statistics_node_update> ordered_set; // order_of_key
typedef pair<int,int>pi;
typedef pair<ll,ll>pl;
const ll inf = 0x3f3f3f3f3f3f3f3fll;//4x10e18
const int maxx = 3000000;
#define PI 3.14159265
bool comp(const pair<pi,ll> &a,const pair<pi,ll> &b)
{
    return (1LL*a.fi.fi*b.fi.se)>=(1LL*a.fi.se*b.fi.fi);
}
int main()
{
    fastio;
    int n;
    cin>>n;
    string t[n];
    pair<pi,ll>a[n];
    for(int i=0;i<n;i++)
    {
        cin>>t[i];
        int s=0,h=0;
        for(char c : t[i])
        {
            if(c=='s')
                s++;
            else h++;
        }
        a[i].fi.fi = s;
        a[i].fi.se = h;
        ll cnt = 0;
        for(char c : t[i])
        {
            if(c=='s')
                cnt+=h;
            else h--;
        }
        a[i].se = cnt;
    }
    sort(a,a+n,comp);
    ll ans = 0;
    int h = 0;
    for(int i=n-1;i>=0;i--)
    {
        ans+=(a[i].se+a[i].fi.fi*h);
        h+=a[i].fi.se;
    }
    cout<<ans<<endl;
    return 0;
}


#include <bits/stdc++.h>
#include <sys/time.h>
using namespace std;
typedef long long int ll;
typedef vector<ll> V;
#define F first
#define S second
#define mod 1000000007
const ll INF = 3000000000000000000;
#define MAXN 100005
#define PI 3.1415926535897932384626433832795
#pragma GCC optimize("Ofast")
#pragma GCC optimize ("unroll-loops")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
static auto _ = [] { std::ios::sync_with_stdio(0); std::cin.tie(0); std::cout.tie(0); std::cerr.tie(0); return 0; }();

ll power(ll x, ll y, ll p)
{
    ll res = 1;
    while (y > 0)
    {
        if (y & 1)
            res = (res * x) % p;
        y = y >> 1;
        x = (x * x) % p;
    }
    return res;
}
int getMaxSubsequence(vector<string> str)
{
    int n=str.size();
    vector<pair<int,int>> weight(n);
    for(int i=0;i<n;i++)
    {
        int m = str[i].size();
        int cnt = count(str[i].begin(),str[i].end(),'s');
        int thisWeight = cnt -  (m-cnt);
        weight[i] = {thisWeight ,i};
    }

    sort(weight.begin(),weight.end());
    long long int ans = 0;
    int sTillNow= 0;
    for(int i=n-1;i>=0;i--)
    {
        for(auto x:str[weight[i].second])
        {
            if(x=='s')
                sTillNow++;
            else
                ans+=sTillNow;
        }
    }
    return ans;
}

int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    ll T = 1, xp = 1;
    //cin>>T;
    while (T--)
    {
        struct timeval start, end;
        ll i = 0, j = 0, n, x = 0, y = 0, m, l = 0, k = 0, r = 0, o = 0, cnt1 = INT_MAX, cnt2 = 0, cnt3 = INT_MIN, cnt4 = 0, min1 = INT_MIN;
        gettimeofday(&start, NULL);
        cin>>n;
        vector<string> v;
        for(i=0;i<n;i++){
            string s;
            cin>>s;
            v.push_back(s);
        }
        cout<<getMaxSubsequence(v)<<endl;

        /*gettimeofday(&end, NULL);
        double time_taken;

        time_taken = (end.tv_sec - start.tv_sec) * 1e6;
        time_taken = (time_taken + (end.tv_usec -
                                  start.tv_usec)) * 1e-6;

        cout << "Time taken by program is : " << fixed
             << time_taken << setprecision(6);
        cout << " sec" << endl; */

        xp++;

    }
    return EXIT_SUCCESS;
}


#include <bits/stdc++.h>
#include <sys/time.h>
using namespace std;
typedef long long int ll;
typedef vector<ll> V;
#define F first
#define S second
#define mod 1000000007
const ll INF = 3000000000000000000;
#define MAXN 100005
#define PI 3.1415926535897932384626433832795
#pragma GCC optimize("Ofast")
static auto _ = [] { std::ios::sync_with_stdio(0); std::cin.tie(0); std::cout.tie(0); std::cerr.tie(0); return 0; }();

ll power(ll x, ll y, ll p)
{
    ll res = 1;
    while (y > 0)
    {
        if (y & 1)
            res = (res * x) % p;
        y = y >> 1;
        x = (x * x) % p;
    }
    return res;
}
map<string,pair<ll,ll>> mp;
bool comp(string s1,string s2){
    if((mp[s1].F-mp[s1].S)>(mp[s2].F-mp[s2].S)){
        return true;
    }
    else if((mp[s1].F-mp[s1].S)<(mp[s2].F-mp[s2].S)){
        return false;
    }
    else{
        if(mp[s1].S<mp[s2].S){
            return true;
        }
        else
            return false;
    }
}
int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    ll T = 1, xp = 1;
    //cin>>T;
    while (T--)
    {
        struct timeval start, end;
        ll i = 0, j = 0, n, x = 0, y = 0, m, l = 0, k = 0, r = 0, o = 0, cnt1 = INT_MAX, cnt2 = 0, cnt3 = INT_MIN, cnt4 = 0, min1 = INT_MIN;
        gettimeofday(&start, NULL);
        cin>>n;
        vector<string> s(n);
        for(i=0;i<n;i++){
            cin>>s[i];
            x = count(s[i].begin(),s[i].end(),'s');
            mp[s[i]] = {x,s[i].size() - x};
            m += s[i].size();
        }
        sort(s.begin(),s.end(),comp);
        ll ans = 0,cnt = 0;
        for(i=n-1;i>=0;i--){
            for(j=s[i].size()-1;j>=0;j--){
                if(s[i][j]=='s'){
                    ans += cnt;
                }
                else{
                    cnt++;
                }
            }
        }
        cout<<ans<<endl;

       /* gettimeofday(&end, NULL);
        double time_taken;

        time_taken = (end.tv_sec - start.tv_sec) * 1e6;
        time_taken = (time_taken + (end.tv_usec -
                                  start.tv_usec)) * 1e-6;

        cout << "Time taken by program is : " << fixed
             << time_taken << setprecision(6);
        cout << " sec" << endl; */
        xp++;

    }
    return EXIT_SUCCESS;
}


#include <bits/stdc++.h>
#include <sys/time.h>
using namespace std;
typedef long long int ll;
typedef vector<ll> V;
#define F first
#define S second
#define mod 1000000007
const ll INF = 3000000000000000000;
#define MAXN 100005
#define PI 3.1415926535897932384626433832795
#pragma GCC optimize("Ofast")
static auto _ = [] { std::ios::sync_with_stdio(0); std::cin.tie(0); std::cout.tie(0); std::cerr.tie(0); return 0; }();

ll power(ll x, ll y, ll p)
{
    ll res = 1;
    while (y > 0)
    {
        if (y & 1)
            res = (res * x) % p;
        y = y >> 1;
        x = (x * x) % p;
    }
    return res;
}
map<string,pair<ll,ll>> mp;
bool comp(string s1,string s2){
    if(mp[s1].F*mp[s2].S>mp[s1].S*mp[s2].F)
        return true;
    else
        return false;
}
bool comp1(string s1,string s2){
    if(mp[s1].F>mp[s2].F)
        return true;
    else if(mp[s1].F == mp[s2].F){
        if(mp[s1].S<mp[s2].S){
            return true;
        }
        else{
            return false;
        }
    }
    else{
        return false;
    }
}
bool comp2(string s1,string s2){
    if(mp[s1].S<mp[s2].S)
        return true;
    else if(mp[s1].S == mp[s2].S){
        if(mp[s1].F>mp[s2].F){
            return true;
        }
        else{
            return false;
        }
    }
    else{
        return false;
    }
}
int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    ll T = 1, xp = 1;
    //cin>>T;
    while (T--)
    {
        struct timeval start, end;
        ll i = 0, j = 0, n, x = 0, y = 0, m, l = 0, k = 0, r = 0, o = 0, cnt1 = INT_MAX, cnt2 = 0, cnt3 = INT_MIN, cnt4 = 0, min1 = INT_MIN;
        gettimeofday(&start, NULL);
        cin>>n;
        vector<string> s(n);
        for(i=0;i<n;i++){
            cin>>s[i];
            x = count(s[i].begin(),s[i].end(),'s');
            mp[s[i]] = {x,s[i].size() - x};
            m += s[i].size();
        }
        sort(s.begin(),s.end(),comp1);
        ll ans = 0,cnt = 0;
        for(i=n-1;i>=0;i--){
            for(j=s[i].size()-1;j>=0;j--){
                if(s[i][j]=='s'){
                    ans += cnt;
                }
                else{
                    cnt++;
                }
            }
        }
        ll ans2 = 0;
        cnt = 0;
        sort(s.begin(),s.end(),comp2);
        for(i=n-1;i>=0;i--){
            for(j=s[i].size()-1;j>=0;j--){
                if(s[i][j]=='s'){
                    ans2 += cnt;
                }
                else{
                    cnt++;
                }
            }
        }
        cout<<max(ans,ans2)<<endl;

       /* gettimeofday(&end, NULL);
        double time_taken;

        time_taken = (end.tv_sec - start.tv_sec) * 1e6;
        time_taken = (time_taken + (end.tv_usec -
                                  start.tv_usec)) * 1e-6;

        cout << "Time taken by program is : " << fixed
             << time_taken << setprecision(6);
        cout << " sec" << endl; */
        xp++;

    }
    return EXIT_SUCCESS;
}


#include <bits/stdc++.h>
#include <sys/time.h>
using namespace std;
typedef long long int ll;
typedef vector<ll> V;
#define F first
#define S second
#define mod 1000000007
const ll INF = 3000000000000000000;
#define MAXN 100005
#define PI 3.1415926535897932384626433832795
#pragma GCC optimize("Ofast")
static auto _ = [] { std::ios::sync_with_stdio(0); std::cin.tie(0); std::cout.tie(0); std::cerr.tie(0); return 0; }();

ll power(ll x, ll y, ll p)
{
    ll res = 1;
    while (y > 0)
    {
        if (y & 1)
            res = (res * x) % p;
        y = y >> 1;
        x = (x * x) % p;
    }
    return res;
}
map<string,pair<ll,ll>> mp;
bool comp(string s1,string s2){
    if(mp[s1].S<mp[s2].S){
        return true;
    }
    else if(mp[s1].S>mp[s2].S){
        return false;
    }
    else{
        if(mp[s1].F>mp[s2].F){
            return true;
        }
        else
            return false;
    }
}
int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    ll T = 1, xp = 1;
    //cin>>T;
    while (T--)
    {
        struct timeval start, end;
        ll i = 0, j = 0, n, x = 0, y = 0, m, l = 0, k = 0, r = 0, o = 0, cnt1 = INT_MAX, cnt2 = 0, cnt3 = INT_MIN, cnt4 = 0, min1 = INT_MIN;
        gettimeofday(&start, NULL);
        cin>>n;
        vector<string> s(n);
        for(i=0;i<n;i++){
            cin>>s[i];
            x = count(s[i].begin(),s[i].end(),'s');
            mp[s[i]] = {x,s[i].size() - x};
            m += s[i].size();
        }
        sort(s.begin(),s.end(),comp);
        ll ans = 0,cnt = 0;
        for(i=n-1;i>=0;i--){
            for(j=s[i].size()-1;j>=0;j--){
                if(s[i][j]=='s'){
                    ans += cnt;
                }
                else{
                    cnt++;
                }
            }
        }
        cout<<ans<<endl;

       /* gettimeofday(&end, NULL);
        double time_taken;

        time_taken = (end.tv_sec - start.tv_sec) * 1e6;
        time_taken = (time_taken + (end.tv_usec -
                                  start.tv_usec)) * 1e-6;

        cout << "Time taken by program is : " << fixed
             << time_taken << setprecision(6);
        cout << " sec" << endl; */
        xp++;

    }
    return EXIT_SUCCESS;
}


#include <bits/stdc++.h>
#include <sys/time.h>
using namespace std;
typedef long long int ll;
typedef vector<ll> V;
#define F first
#define S second
#define mod 1000000007
const ll INF = 3000000000000000000;
#define MAXN 100005
#define PI 3.1415926535897932384626433832795
#pragma GCC optimize("Ofast")
static auto _ = [] { std::ios::sync_with_stdio(0); std::cin.tie(0); std::cout.tie(0); std::cerr.tie(0); return 0; }();

ll power(ll x, ll y, ll p)
{
    ll res = 1;
    while (y > 0)
    {
        if (y & 1)
            res = (res * x) % p;
        y = y >> 1;
        x = (x * x) % p;
    }
    return res;
}
map<string,pair<ll,ll>> mp;
bool comp(string s1,string s2){
    if(mp[s1].F*mp[s2].S>mp[s1].S*mp[s2].F)
        return true;
    else
        return false;
}
int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    ll T = 1, xp = 1;
    //cin>>T;
    while (T--)
    {
        struct timeval start, end;
        ll i = 0, j = 0, n, x = 0, y = 0, m, l = 0, k = 0, r = 0, o = 0, cnt1 = INT_MAX, cnt2 = 0, cnt3 = INT_MIN, cnt4 = 0, min1 = INT_MIN;
        gettimeofday(&start, NULL);
        cin>>n;
        vector<string> s(n);
        for(i=0;i<n;i++){
            cin>>s[i];
            x = count(s[i].begin(),s[i].end(),'s');
            mp[s[i]] = {x,s[i].size() - x};
            m += s[i].size();
        }
        sort(s.begin(),s.end(),comp);
        ll ans = 0,cnt = 0;
        for(i=n-1;i>=0;i--){
            for(j=s[i].size()-1;j>=0;j--){
                if(s[i][j]=='s'){
                    ans += cnt;
                }
                else{
                    cnt++;
                }
            }
        }
        cout<<ans<<endl;

       /* gettimeofday(&end, NULL);
        double time_taken;

        time_taken = (end.tv_sec - start.tv_sec) * 1e6;
        time_taken = (time_taken + (end.tv_usec -
                                  start.tv_usec)) * 1e-6;

        cout << "Time taken by program is : " << fixed
             << time_taken << setprecision(6);
        cout << " sec" << endl; */
        xp++;

    }
    return EXIT_SUCCESS;
}


#include<cstdio>
#include<cstring>
#include<algorithm>
#define int long long
using namespace std;
int s[100010],h[100010];
int so[100010];
char c[100010];
long long p[100010];
bool cmp(const int &a, const int &b) {
		return s[a]*h[b]>=h[a]*s[b];
}
signed main() {
	int i,j,n,m;
	long long ans=0,toth=0;
//	freopen("data0.txt","r",stdin);
//	freopen("out.txt","w",stdout);
	scanf("%lld",&n);
	for(i=0;i<n;i++){
		scanf("%s",c);
		for(j=strlen(c)-1;j>=0;j--) {
			if(c[j]=='s'){
				s[i]++;
				p[i]+=h[i];
			}
			else h[i]++;
		}
		so[i]=i;
	}
	sort(so,so+n,cmp);
//	printf("finish sorting\n");
	for(i=n-1;i>=0;i--) {
		ans+=p[so[i]];
		ans+=s[so[i]]*toth;
		toth+=h[so[i]];
	}
	printf("%lld\n",ans);
	return 0;
}
/*
*/


#include<cstdio>
#include<cstring>
#include<algorithm>
//#define int long long
using namespace std;
int s[100010],h[100010];
int so[100010];
char c[100010];
long long p[100010];
bool cmp(const int &a, const int &b) {
		return s[a]*h[b]>=h[a]*s[b];
}
signed main() {
	int i,j,n,m;
	long long ans=0,toth=0;
//	freopen("data0.txt","r",stdin);
//	freopen("out.txt","w",stdout);
	scanf("%d",&n);
	for(i=0;i<n;i++){
		scanf("%s",c);
		for(j=strlen(c)-1;j>=0;j--) {
			if(c[j]=='s'){
				s[i]++;
				p[i]+=h[i];
			}
			else h[i]++;
		}
		so[i]=i;
	}
	sort(so,so+n,cmp);
//	printf("finish sorting\n");
	for(i=n-1;i>=0;i--) {
		ans+=p[so[i]];
		ans+=s[so[i]]*toth;
		toth+=h[so[i]];
	}
	printf("%lld\n",ans);
	return 0;
}
/*
*/


#include <iostream>
#include <vector>
#include <iomanip>
#include <cstring>
#include <string.h>
#include <iterator>
#include <math.h>
#include <set>
#include <queue>
#include <stack>
#include <algorithm>
#include <tuple>
#include <limits.h>
#include <string>
#include <bitset>
#include <map>
#include <numeric>
#include<unordered_map>
#include<unordered_set>
//#include <ext/pb_ds/assoc_container.hpp>
//#include <ext/pb_ds/tree_policy.hpp>

#define endl cout<<"\n"
#define lli long long int
#define ld long double
#define M_PI (3.14159265358979323846264338327950288)
#define MOD (1000000007)
#define MOD2 (998244353)
#define pii pair<lli,lli>
#define ordered_set tree<int, null_type,less<int>, rb_tree_tag,tree_order_statistics_node_update>
#define inf 1e17
#define all(a) a.begin(), a.end()
#define rev_all(a) a.rbegin(), a.rend()

using namespace std;
//using namespace __gnu_pbds;

//fast-exponentiation-lli
unsigned lli expo_fast(lli a, lli b) {
	a = a;
	lli result = 1;
	while (b) {
		//multiplyint(tos(result), a);
		if (b & 1)result = (result * a);
		b >>= 1;
		a = (a*a);
	}
	return (result);
}

void take_in(vector<lli> *arr) {
	for (int i = 0; i < arr->size(); i++)cin >> (*(arr))[i];
}

lli gcd(lli a, lli b)
{
	if (b == 0)
		return a;
	return gcd(b, a % b);

}

/* Iterative Function to calculate (x^y)%p in O(log y) */
unsigned lli power(lli x, unsigned lli y, lli p)
{
	lli res = 1;      // Initialize result
	x = x % p;  // Update x if it is more than or equal to p
	while (y > 0) {
		// If y is odd, multiply x with result
		if (y & 1)res = (res*x) % p;
		// y must be even now
		y = y >> 1;
		x = (x*x) % p;
	}
	return res;
}

lli calc(string s) {
	int n = s.length();
	vector<int>b(n);
	for (int i = n - 1; i > -1; i--) {
		if (i == n - 1)b[i] = (s[i] == 'h') ? 1 : 0;
		else b[i] = b[i + 1] + ((s[i] == 'h') ? 1 : 0);
	}
	lli ret = 0;
	for (int i = 0; i < n; i++) {
		if (s[i] == 's')ret += (b[i]);
	}
	return ret;
}

int main()
{
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);
	cout.tie(NULL);
	//freopen("input.txt", "r", stdin);
	//freopen("output.txt", "w", stdout);
	int n; cin >> n; vector<string>a(n); vector<pii>to_sort; lli ans = 0,hc=0;
	for (int i = 0; i < n; i++) {
		cin >> a[i];
		ans += calc(a[i]);
		int cnt = 0; for (auto x : a[i])if (x == 's')cnt++;
		to_sort.push_back({ cnt,a[i].length() - cnt });
	}
	auto cmp = [](const pii &a, const pii &b)->bool {
		return a.first*b.second > b.first*a.second;
	};
	sort(all(to_sort), cmp);
	for (int i = n - 1; i > -1; i--) {
		ans += (to_sort[i].first*hc);
		hc += to_sort[i].second;
	}
	cout << ans;
	//system("PAUSE");
}


#include <iostream>
#include <vector>
#include <algorithm>
#include <string>

using namespace std;

struct sh_node{
    int s;
    int h;
    int num;

    sh_node(int s1, int h1, int num1):
    s(s1), h(h1), num(num1){};
};

bool cmp(sh_node node1, sh_node node2)
{
    if(node1.s * node2.h > node1.h * node2.s)
    {
        return true;
    }
    else{
        return false;
    }
}

int main() {
    int n;
    cin >> n;
    // vector<string> vs(n, "");
    vector<sh_node> vsh(n, sh_node(0,0,0));

    for(int i=0; i<n; i++)
    {
        string tmp("");
        cin >> tmp;
        for(int j=0; j<tmp.size(); j++)
        {
            if(tmp[j] == 's')
            {
                vsh[i].s += 1;
            }
            else{
                vsh[i].h += 1;
                vsh[i].num += vsh[i].s;
            }
        }
    }

    sort(vsh.begin(), vsh.end(), cmp);

    // for(auto sh:vsh)
    // {
    //     cout << sh.s << " " << sh.h << " " << sh.num << endl;
    // }
    long long result = 0;
    int s_num = 0;
    for(int i=0; i<n; i++)
    {
        result += s_num * vsh[i].h + vsh[i].num;
        s_num += vsh[i].s;
    }
    cout << result << endl;

}


#include <iostream>
#include <vector>
#include <algorithm>
#include <string>

using namespace std;

struct sh_node{
    int s;
    int h;
    long long num;

    sh_node(int s1, int h1, int num1):
    s(s1), h(h1), num(num1){};
};

bool cmp(sh_node node1, sh_node node2)
{
    if(node1.s * node2.h > node1.h * node2.s)
    {
        return true;
    }
    else{
        return false;
    }
}

int main() {
    int n;
    cin >> n;
    // vector<string> vs(n, "");
    vector<sh_node> vsh(n, sh_node(0,0,0));

    for(int i=0; i<n; i++)
    {
        string tmp("");
        cin >> tmp;
        for(int j=0; j<tmp.size(); j++)
        {
            if(tmp[j] == 's')
            {
                vsh[i].s += 1;
            }
            else{
                vsh[i].h += 1;
                vsh[i].num += vsh[i].s;
            }
        }
    }

    sort(vsh.begin(), vsh.end(), cmp);

    // for(auto sh:vsh)
    // {
    //     cout << sh.s << " " << sh.h << " " << sh.num << endl;
    // }
    long long result = 0;
    long long s_num = 0;
    for(int i=0; i<n; i++)
    {
        result += s_num * vsh[i].h + vsh[i].num;
        s_num += vsh[i].s;
    }
    cout << result << endl;

}


#include <iostream>
#include <vector>
#include <algorithm>
#include <string>

using namespace std;

struct sh_node{
    long long s;
    long long h;
    long long num;

    sh_node(long long s1, long long h1, long long num1):
    s(s1), h(h1), num(num1){};
};

bool cmp(sh_node node1, sh_node node2)
{
    if(node1.s * node2.h > node1.h * node2.s)
    {
        return true;
    }
    else{
        return false;
    }
}

int main() {
    int n;
    cin >> n;
    // vector<string> vs(n, "");
    vector<sh_node> vsh(n, sh_node(0,0,0));

    for(int i=0; i<n; i++)
    {
        string tmp("");
        cin >> tmp;
        for(int j=0; j<tmp.size(); j++)
        {
            if(tmp[j] == 's')
            {
                vsh[i].s += 1;
            }
            else{
                vsh[i].h += 1;
                vsh[i].num += vsh[i].s;
            }
        }
    }

    sort(vsh.begin(), vsh.end(), cmp);

    // for(auto sh:vsh)
    // {
    //     cout << sh.s << " " << sh.h << " " << sh.num << endl;
    // }
    long long result = 0;
    long long s_num = 0;
    for(int i=0; i<n; i++)
    {
        result += s_num * vsh[i].h + vsh[i].num;
        s_num += vsh[i].s;
    }
    cout << result << endl;

}


#include <iostream>
#include <vector>
#include <algorithm>
#include <string>

using namespace std;

struct sh_node{
    int s;
    int h;
    int num;

    sh_node(int s1, int h1, int num1):
    s(s1), h(h1), num(num1){};
};

bool cmp(sh_node node1, sh_node node2)
{
    if(node1.s * node2.h > node1.h * node2.s)
    {
        return true;
    }
    else{
        return false;
    }
}

int main() {
    int n;
    cin >> n;
    // vector<string> vs(n, "");
    vector<sh_node> vsh(n, sh_node(0,0,0));

    for(int i=0; i<n; i++)
    {
        string tmp("");
        cin >> tmp;
        for(int j=0; j<tmp.size(); j++)
        {
            if(tmp[j] == 's')
            {
                vsh[i].s += 1;
            }
            else{
                vsh[i].h += 1;
                vsh[i].num += vsh[i].s;
            }
        }
    }

    sort(vsh.begin(), vsh.end(), cmp);

    // for(auto sh:vsh)
    // {
    //     cout << sh.s << " " << sh.h << " " << sh.num << endl;
    // }
    long long result = 0;
    long long s_num = 0;
    for(int i=0; i<n; i++)
    {
        result += s_num * vsh[i].h + vsh[i].num;
        s_num += vsh[i].s;
    }
    cout << result << endl;

}


#include <iostream>
#include <fstream>
#include <algorithm>
#include <string>
#include <cmath>
#include <vector>
#include <iomanip>
#include <set>
#include <map>
#include <utility>
#include <queue>
#include <string.h>
#include <climits>

#define SZ size()
#define VEC vector
#define PB push_back
#define MP make_pair
#define SS second
#define FF first
#define PII pair <int,int>
#define LL long long

#define IN_NAME input.txt
#define OUT_NAME output.txt

using namespace std;

int n;
LL ans;
VEC <string> v;
map <string, int> s, h;

bool comp (string& s1, string& s2)
{
    if (h[s1] == 0)
        return true;
    if (h[s2] == 0)
        return false;
    if (s[s1] != s[s2])
        return s[s1] > s[s2];
    return h[s1] < h[s2];
}

void in()
{
    //ifstream cin("input.txt");
    ios_base:: sync_with_stdio(false);
    cin.tie(0);
    cin >> n;
    v.resize(n);
    for (int i = 0; i < n; ++i) {
        cin >> v[i];
    }
}

void solution()
{
    for (int i = 0; i < n; ++i) {
        int ss = 0, hh = 0;
        for (int j = 0; j < v[i].SZ; ++j) {
            if (v[i][j] == 's')
                ++ss;
            else ++hh;
        }
        s[v[i]] = ss;
        h[v[i]] = hh;
    }
    sort(v.begin(), v.end(), comp);
    int ss = 0, hh = 0;
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < v[i].SZ; ++j) {
            if (v[i][j] == 's')
                ++ss;
            else
                ans += ss;
        }
    }
}

void out()
{
    //ofstream cout("output.txt");
    cout << ans << "\n";
}

int main()
{
    in();
    solution();
    out();
    return 0;
}


#include <iostream>
#include <fstream>
#include <algorithm>
#include <string>
#include <cmath>
#include <vector>
#include <iomanip>
#include <set>
#include <map>
#include <utility>
#include <queue>
#include <string.h>
#include <climits>

#define SZ size()
#define VEC vector
#define PB push_back
#define MP make_pair
#define SS second
#define FF first
#define PII pair <int,int>
#define LL long long

#define OUT_NAME output.txt
#define IN_NAME input.txt

using namespace std;

LL n;
LL ans;
VEC <string> v;

LL get (string s)
{
    LL ss = 0, res = 0;
    for (LL j = 0; j < s.SZ; ++j) {
        if (s[j] == 's')
            ++ss;
        else res += ss;
    }
    return res;
}

bool comp (string& s1, string& s2)
{
    return get(s1+s2) > get(s2+s1);
}

void in()
{
    //ifstream cin("input.txt");
    ios_base:: sync_with_stdio(false);
    cin.tie(0);
    cin >> n;
    v.resize(n);
    for (LL i = 0; i < n; ++i) {
        cin >> v[i];
    }
}

void solution()
{
    sort(v.begin(), v.end(), comp);
    string s = "";
    for (LL i = 0; i < n; ++i) {
        s += v[i];
    }
    ans = get(s);
}

void out()
{
    //ofstream cout("output.txt");
    cout << ans << "\n";
}

int main()
{
    in();
    solution();
    out();
    return 0;
}


#include <iostream>
#include <fstream>
#include <algorithm>
#include <string>
#include <cmath>
#include <vector>
#include <iomanip>
#include <set>
#include <map>
#include <utility>
#include <queue>
#include <string.h>
#include <climits>

#define SZ size()
#define VEC vector
#define PB push_back
#define MP make_pair
#define SS second
#define FF first
#define PII pair <int,int>
#define LL long long

#define IN_NAME input.txt
#define OUT_NAME output.txt

using namespace std;

int n;
LL ans;
VEC <string> v;

int get (string s)
{
    int ss = 0, hh = 0, res = 0;
    for (int j = 0; j < s.SZ; ++j) {
        if (s[j] == 's')
            ++ss;
        else res += ss;
    }
    return res;
}

bool comp (string& s1, string& s2)
{
    return get(s1+s2) > get(s2+s1);
}

void in()
{
    //ifstream cin("input.txt");
    ios_base:: sync_with_stdio(false);
    cin.tie(0);
    cin >> n;
    v.resize(n);
    for (int i = 0; i < n; ++i) {
        cin >> v[i];
    }
}

void solution()
{
    sort(v.begin(), v.end(), comp);
    string s = "";
    for (int i = 0; i < n; ++i) {
        s += v[i];
    }
    ans = get(s);
}

void out()
{
    //ofstream cout("output.txt");
    cout << ans << "\n";
}

int main()
{
    in();
    solution();
    out();
    return 0;
}


#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <vector>
#include <cmath>
#include <algorithm>
#include <set>
#include <map>
#include <queue>
#include <ctime>
#include <cassert>

#define pb push_back
#define ll long long
#define mp make_pair
#define f first
#define s second
#define pii pair < int, int >
#define ull unsigned long long
#define pll pair < ll, ll >
#define forit(it, s) for(__typeof(s.begin()) it = s.begin(); it != s.end(); it ++)
#define all(s) s.begin(), s.end()
#define sz(a) (int)a.size()

const int inf = (1ll << 30) - 1;
const int maxn = (int) 1e5 + 10;

using namespace std;
char c[100200];
string t;

bool cmp(pii a, pii b) {
	if (a.first * 1ll * b.second != b.first * 1ll * a.second) return a.first * 1ll * b.second > b.first * 1ll * a.second;
	return a.first > b.first;
}
void solve() {
	int n;
	cin >> n;
	ll ans = 0;
	vector<pii> li;
	for (int i = 0; i < n; i++) {
		cin >> c;
		int len = strlen(c);
		int cur = 0;
		for (int j = 0; j < len; j++) {
			if (c[j] == 's') cur++;
			else ans += cur;
		}
		li.pb(mp(cur, len - cur));
	}
	sort(all(li), cmp);
	ll cur = 0;
	for (int i = 0; i < li.size(); i++) {
		ans += cur * li[i].second;
		cur += li[i].first;
	}
	cout << ans << endl;

}

int main() {
#ifdef LOCAL
	freopen("a.in", "r", stdin);
	freopen("a.out", "w", stdout);
#endif
	int t = 1;

	for (int i = 1; i <= t; i++) {
		//printf("Case #%d\n", i);
		solve();
	}
	char c;
	//cin >> c;
	return 0;

}


#include <iostream>
#include <cmath>
#include <algorithm>
#include <utility>
#include <string>
#include <vector>
#include <set>
#include <math.h>
#include <map>
#include <iomanip>
#include <functional>
#include <list>
#include <random>
#include <queue>
#include <stdio.h>
#include <regex>
#include <bitset>
#include <numeric>
#include <bitset>
#include <assert.h>
#include <conio.h>
#include <sstream>
#include <fstream>
#include <cstring>
#include <array>
#include <unordered_map>
#include <unordered_set>
#include <stack>

using namespace std;

#define all(cd) (cd).begin(), (cd).end()
#define sqr(cd) ((cd) * (cd))

#define y0 sdkfaslhagaklsldk
#define y1 aasdfasdfasdf
#define yn askfhwqriuperikldjk
#define j1 assdgsdgasghsf
#define tm sdfjahlfasfh
#define lr asgasgash
#define norm asdfasdgasdgsd
#define have adsgagshdshfhds
#define ends asdgahhfdsfshdshfd

template <typename T> void alert(const T& t) { cout << t << endl; exit(0); }

typedef long long int64;
typedef unsigned long long uint64;
typedef array<int64, 2> hv;

int LSON(int r) { return r * 2; }
int RSON(int r) { return r * 2 + 1; }
int MID(int l, int r) { return l + r >> 1; }

struct ST
{
	ST(int n) : vec(4 * n) {};

	void Set(int sl, int sr, int pos, int v, int val)
	{
		if (sl == sr)
		{
			vec[v] = val;
			return;
		}

		int mid = MID(sl, sr);
		if (pos <= mid) Set(sl, mid, pos, LSON(v), val);
		else Set(mid + 1, sr, pos, RSON(v), val);

		vec[v] = vec[LSON(v)] + vec[RSON(v)];
	}

	int64 Get(int sl, int sr, int l, int r, int v)
	{
		if (sl == l && sr == r)
		{
			return vec[v];
		}

		int mid = MID(sl, sr);

		if (r <= mid) return Get(sl, mid, l, r, LSON(v));
		else if (l > mid) return Get(mid + 1, sr, l, r, RSON(v));
		else
		{
			int64 left = Get(sl, mid, l, mid, LSON(v));
			int64 right = Get(mid + 1, sr, mid + 1, r, RSON(v));
			return left + right;
		}
	}

	vector<int64> vec;
};

vector<int64> calcZ(string s)
{
    int64 n=s.size();
    vector<int64> z(n);
    int64 l=0, r=0;
    for(int64 i=1;i<n;i++)
    {
        if(i>=l && i<r)
        {
            z[i]=min(z[i-l], r-i);
        }

        while(i+z[i]<n && s[i+z[i]]==s[z[i]])
        {
            z[i]++;
        }

        if(i+z[i]>r)
        {
            r=i+z[i];
            l=i;
        }
    }

    return z;
}

int64 Sh(string &s)
{
	int64 a=0, ans=0;;
	for(int64 i=0; i<s.size();i++)
	{
		if(s[i]=='s')a++;
		else ans+=a;
	}

	return ans;
}
bool comp(string & a, string &b)
{
	return Sh(a+b)>Sh(b+a);
}
int main()
{
#ifdef _DEBUG
	freopen("in.h", "r", stdin);
	//freopen("123.txt", "w", stdout);
	//test();
#else
	{

	//	freopen("codecoder.in", "r", stdin);
		//freopen("codecoder.out", "w", stdout);
	}
#endif
	//srand(time(NULL));
	ios_base::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);

	int64 n;
	cin >> n;

	vector<string> vec;
	for(int64 i=0; i<n;i++)
	{
		string s;
		cin >> s;
		vec.push_back(s);

	}

	sort(vec.begin(), vec.end(), comp);

	int64 s=0;int64 ans=0;

	for(int64 i=0; i<n;i++)
	{
		for(int64 j=0;j<vec[i].size();j++)
		{
			if(vec[i][j]=='s')s++;
				else ans+=s;
		}
	}
	cout <<ans;

	return 0;
}


#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;

struct sh
{
	int s, h, sum;
	sh() { s = 0; h = 0; sum = 0; }
};

bool comp(sh sh1, sh sh2)
{
	return sh1.s * sh2.h > sh2.s * sh1.h;
}

int main()
{
	int n;
	cin >> n;
	cin.get();
	vector<sh> shum(n);
	string str;
	for (int i = 0; i < n; i++)
	{
		getline(cin, str);
		int s = 0;
		for (int j = 0; j < str.length(); j++)
		{
			if (str[j] == 's')
			{
				shum[i].s++;
				s++;
			}
			else
			{
				shum[i].h++;
				shum[i].sum += s;
			}
		}
	}
	sort(shum.begin(), shum.end(), comp);
	long long count = 0;
	int h = 0;
	for (int i = n - 1; i >= 0; i--)
	{
		count += shum[i].sum + shum[i].s * h;
		h += shum[i].h;
	}
	cout << count;
	return 0;
}


#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;

struct sh
{
	long long s, h, sum;
	sh() { s = 0; h = 0; sum = 0; }
};

bool comp(sh sh1, sh sh2)
{
	return sh1.s * sh2.h > sh2.s * sh1.h;
}

int main()
{
	int n;
	cin >> n;
	cin.get();
	vector<sh> shum(n);
	string str;
	for (int i = 0; i < n; i++)
	{
		getline(cin, str);
		int s = 0;
		for (int j = 0; j < str.length(); j++)
		{
			if (str[j] == 's')
			{
				shum[i].s++;
				s++;
			}
			else
			{
				shum[i].h++;
				shum[i].sum += s;
			}
		}
	}
	sort(shum.begin(), shum.end(), comp);
	long long count = 0;
	int h = 0;
	for (int i = n - 1; i >= 0; i--)
	{
		count += shum[i].sum + shum[i].s * h;
		h += shum[i].h;
	}
	cout << count;
	return 0;
}


#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;

struct sh
{
	int s = 0, h = 0, sum = 0;
};

bool comp(sh sh1, sh sh2)
{
	return sh1.s * sh2.h > sh2.s * sh1.h;
}

int main()
{
	int n;
	cin >> n;
	cin.get();
	vector<sh> shum(n);
	string str;
	for (int i = 0; i < n; i++)
	{
		getline(cin, str);
		int s = 0;
		for (int j = 0; j < str.length(); j++)
		{
			if (str[j] == 's')
			{
				shum[i].s++;
				s++;
			}
			else
			{
				shum[i].h++;
				shum[i].sum += s;
			}
		}
	}
	sort(shum.begin(), shum.end(), comp);
	long long count = 0;
	int h = 0;
	for (int i = n - 1; i >= 0; i--)
	{
		count += shum[i].sum + shum[i].s * h;
		h += shum[i].h;
	}
	cout << count;
	return 0;
}


#include <iostream>
#include <fstream>
#include <vector>
#include <unordered_map>
#include <string>
#include <algorithm>

using namespace std;

int main () {
	long long n;
	cin >> n;

	string s;
	long long ans = 0;
	vector<pair<long long, long long> > kolsh(n);
	vector<pair<double, long long> > kol(n);
	for (long long i = 0; i < n; i++) {
		cin >> s;
		long long kols = 0;
		long long res = 0;
		for (long long j = 0; j < s.size(); j++) {
			if (s[j] == 's') {
				kols++;
			}
			else {
				res += kols;
			}
		}
		ans += res;
		kol[i] = make_pair((double)kols / (double)(s.size() - kols), i);
		kolsh[i] = make_pair(kols, s.size() - kols);
	}

	sort(kol.begin(), kol.end());
	long long kols = 0;
	for (long long i = n - 1; i >= 0; i--) {
		ans += kolsh[kol[i].second].second * kols;
		kols += kolsh[kol[i].second].first;
	}
	cout << ans;
}


#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<algorithm>
#include<vector>
#include<set>
#include<queue>
#include<map>
#include<math.h>
#include<string>
#include<fstream>
#include<stdio.h>
#include<string>
using namespace std;
bool cmp(pair<int, int> a, pair<int, int> b)
{
	if (a.second == 0 && b.second == 0)
		return a.first > b.first;
	if (a.second == 0)
		return true;
	if (b.second == 0)
		return false;
	double x = a.first*1.0 / a.second;
	double y = b.first*1.0 / b.second;
	return x > y;
}
int main()
{
#ifdef _DEBUG
	freopen("input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);
#endif
	int n;
	string s;
	vector<pair<int, int>> v;
	long long int cnt = 0;
	scanf("%d",&n);
	for (int i = 0; i < n; i++)
	{
		cin >> s;
		pair<int, int> p;
		p.first = 0;
		p.second = 0;
		for (int j = 0; j < s.size(); j++)
		{
			if (s[j] == 's')
				p.first++;
			else
			{
				p.second++;
				cnt += p.first;
			}
		}
		v.push_back(p);
	}
	sort(v.begin(), v.end(), cmp);
	long long int cnt1 = 0;
	for (int i = 0; i < n; i++)
	{
		cnt += cnt1*v[i].second;
		cnt1 += v[i].first;
	}
	printf("%I64",cnt);
	return 0;
}


#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<algorithm>
#include<vector>
#include<set>
#include<queue>
#include<map>
#include<math.h>
#include<string>
#include<fstream>
#include<stdio.h>
#include<string>
using namespace std;
bool cmp(pair<int, int> a, pair<int, int> b)
{
	if (a.second == 0 && b.second == 0)
		return a.first > b.first;
	if (a.second == 0)
		return true;
	if (b.second == 0)
		return false;
	double x = a.first*1.0 / a.second;
	double y = b.first*1.0 / b.second;
	return x > y;
}
int main()
{
#ifdef _DEBUG
	freopen("input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);
#endif
	int n;
	string s;
	vector<pair<int, int>> v;
	long long int cnt = 0;
	scanf("%d",&n);
	for (int i = 0; i < n; i++)
	{
		cin >> s;
		pair<int, int> p;
		p.first = 0;
		p.second = 0;
		for (int j = 0; j < s.size(); j++)
		{
			if (s[j] == 's')
				p.first++;
			else
			{
				p.second++;
				cnt += p.first;
			}
		}
		v.push_back(p);
	}
	sort(v.begin(), v.end(), cmp);
	long long int cnt1 = 0;
	for (int i = 0; i < n; i++)
	{
		cnt += cnt1*v[i].second;
		cnt1 += v[i].first;
	}
	printf("%d",cnt);
	return 0;
}


#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<algorithm>
#include<vector>
#include<set>
#include<queue>
#include<map>
#include<math.h>
#include<string>
#include<fstream>
#include<stdio.h>
#include<string>
using namespace std;
bool cmp(pair<int, int> a, pair<int, int> b)
{
	if (a.second == 0 && b.second == 0)
		return a.first > b.first;
	if (a.second == 0)
		return true;
	if (b.second == 0)
		return false;
	double x = a.first*1.0 / a.second;
	double y = b.first*1.0 / b.second;
	return x > y;
}
int main()
{
#ifdef _DEBUG
	freopen("input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);
#endif
	int n;
	string s;
	vector<pair<int, int>> v;
	long long int cnt = 0;
	scanf("%d",&n);
	for (int i = 0; i < n; i++)
	{
		cin >> s;
		pair<int, int> p;
		p.first = 0;
		p.second = 0;
		for (int j = 0; j < s.size(); j++)
		{
			if (s[j] == 's')
				p.first++;
			else
			{
				p.second++;
				cnt += p.first;
			}
		}
		v.push_back(p);
	}
	sort(v.begin(), v.end(), cmp);
	long long int cnt1 = 0;
	for (int i = 0; i < n; i++)
	{
		cnt += cnt1*v[i].second;
		cnt1 += v[i].first;
	}
	printf("%I64d",cnt);
	return 0;
}


#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<algorithm>
#include<vector>
#include<set>
#include<queue>
#include<map>
#include<math.h>
#include<string>
#include<fstream>
#include<stdio.h>
#include<string>
using namespace std;
bool cmp(pair<int, int> a, pair<int, int> b)
{
	if (a.second == 0 && b.second == 0)
		return a.first > b.first;
	if (a.second == 0)
		return true;
	if (b.second == 0)
		return false;
	double x = a.first*1.0 / a.second;
	double y = b.first*1.0 / b.second;
	return x > y;
}
int main()
{
#ifdef _DEBUG
	freopen("input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);
#endif
	int n;
	string s;
	vector<pair<int, int>> v;
	int cnt = 0;
	scanf("%d",&n);
	for (int i = 0; i < n; i++)
	{
		cin >> s;
		pair<int, int> p;
		p.first = 0;
		p.second = 0;
		for (int j = 0; j < s.size(); j++)
		{
			if (s[j] == 's')
				p.first++;
			else
			{
				p.second++;
				cnt += p.first;
			}
		}
		v.push_back(p);
	}
	sort(v.begin(), v.end(), cmp);
	int cnt1 = 0;
	for (int i = 0; i < n; i++)
	{
		cnt += cnt1*v[i].second;
		cnt1 += v[i].first;
	}
	printf("%d",cnt);
	return 0;
}


#include <iostream>
#include <set>
#include <string>
#include <vector>
#include <algorithm>
	using namespace std;

	int sh(string s)
	{
		int i, j, k = 0, kp = 0;
		for (i = 0; i < s.length(); i++)
		{
			if (s[i] == 'h')
				k++;
		}

		for (i = 0; i < s.size() && k > 0; i++)
		{
			if (s[i] == 's')
				kp+=k;
			else
				k--;
		}

		return kp;
	}

	bool cmp(string a, string b)
	{
		string s1 = a + b;
		string s2 = b + a;
		if (sh(s1) > sh(s2))
			return true;
		else
			return false;

	}

	int main()
	{
		int i, n;
		string *s, f;
		cin >> n;
		s = new string[n];
		getline(cin, f);
		for (i = 0; i < n; i++)
			getline(cin, s[i]);

		sort(s, s + n, cmp);
		f = "";
		for (i = 0; i < n; i++)
		{
			f += s[i];
		}
		cout << sh(f);
		getchar();
		getchar();
		return 0;
	}


# -*- coding: utf-8 -*-
from __future__ import division
import sys
import math
import numpy as np

def get_symb(x): # Превращаем буквы в 0, цифры в 1, спецсимволы в 2
	if x.isalpha():
		return 0
	if x.isdigit():
		return 1
	return 2

data = sys.stdin.readlines()
# data = [
# 	'3 4',
# 	'1**2',
# 	'a3*0',
# 	'c4**'
# ]
# data = [
# 	'5 1',
# 	'#',
# 	'*',
# 	'a',
# 	'#',
# 	'3'
# ]
n_lines, length = [int(x) for x in data[0].split()]
values = np.zeros((n_lines, length), dtype=np.int) # Тип символа в i-й строке на j-м месте
rasst = np.zeros((n_lines, 3), dtype=np.int) # Расстояния в i-й строке до первого символа типа j
rasst.fill(3 * length) # Точно больше оптимального расстояния
for i in range(n_lines):
	values[i, 0] = get_symb(data[i + 1][0])
	rasst[i, values[i, 0]] = 0
	for j in range(1, length):
		values[i, j] = get_symb(data[i + 1][j])
		if values[i, j] != values[i, 0]:
			diff = int(min(j, length - j))
			old_val = rasst[i, values[i, j]]
			if old_val > diff:
				rasst[i, values[i, j]] = diff

# print rasst

from_where = [0, 1, 2] # Из каких строк берем, соотв., символы длины 1,2,3?
price = rasst[0, 0] + rasst[1, 1] + rasst[2, 2]
for i,j,k in [(0,2,1), (1,0,2), (1,2,0), (2,1,0), (2,0,1)]: # Сначала перебираем перестановки первых трёх строк
	new_price = rasst[i, 0] + rasst[j, 1] + rasst[k, 2]
	if new_price < price:
		from_where = [i,j,k]
		price = new_price
for i in range(3, n_lines):
	new_prices = [
		rasst[i, 0] + rasst[from_where[1], 1] + rasst[from_where[2], 2],
		rasst[from_where[0], 0] + rasst[i, 1] + rasst[from_where[2], 2],
		rasst[from_where[0], 0] + rasst[from_where[1], 1] + rasst[i, 2]
	]
	new_price = int(min(new_prices))
	if new_price < price:
		price = new_price
		if new_prices[0] == new_price:
			from_where[0] = i
		elif new_prices[1] == new_price:
			from_where[1] = i
		else:
			from_where[2] = i
print price


from __future__ import division
import sys
import math
import numpy as np

def get_symb(x):
	if x.isalpha():
		return 0
	if x.isdigit():
		return 1
	return 2

# data = sys.stdin.readlines()
data = [
	'5 5',
	'#*&#*',
	'*a1c&',
	'&q2w*',
	'#a3c#',
	'*&#*&'
]
n_lines, length = [int(x) for x in data[0].split()]
values = np.zeros((n_lines, length), dtype=np.int)
rasst = np.zeros((n_lines, 3), dtype=np.int)
rasst.fill(3 * length)
lines = [''] * n_lines
for i in range(n_lines):
	values[i, 0] = get_symb(data[i + 1][0])
	rasst[i, values[i, 0]] = 0
	for j in range(length):
		values[i, j] = get_symb(data[i + 1][j])
		if values[i, j] != values[i, 0]:
			diff = min(j, length - j)
			old_val = rasst[i, values[i, j]]
			if old_val > diff:
				rasst[i, values[i, j]] = diff

print rasst

from_where = [0, 1, 2]
price = rasst[0, 0] + rasst[1, 1] + rasst[2, 2]
for i,j,k in [(0,2,1), (1,0,2), (1,2,0), (2,1,0), (2,0,1)]:
	new_price = rasst[i, 0] + rasst[j, 1] + rasst[k, 2]
	if new_price < price:
		from_where = [i,j,k]
		price = new_price
for i in range(3, n_lines):
	new_prices = [
		rasst[i, 0] + rasst[from_where[1], 1] + rasst[from_where[2], 2],
		rasst[from_where[0], 0] + rasst[i, 1] + rasst[from_where[2], 2],
		rasst[from_where[0], 0] + rasst[from_where[1], 1] + rasst[i, 2]
	]
	new_price = min(new_prices)
	if new_price < price:
		price = new_price
		if new_prices[0] == new_price:
			from_where[0] = i
		elif new_prices[1] == new_price:
			from_where[1] = i
		else:
			from_where[2] = i

print price


import sys

def get_symb(x):
	if x.isalpha():
		return 0
	if x.isdigit():
		return 1
	return 2

data = []
data.append(sys.stdin.readline())
n_lines, length = [int(x) for x in data[0].split()]
for i in range(n_lines):
	data.append(sys.stdin.readline())

print 0


from __future__ import division
import sys
import math
import numpy as np

def get_symb(x):
	if x.isalpha():
		return 0
	if x.isdigit():
		return 1
	return 2

data = sys.stdin.readlines()
# data = [
# 	'5 5',
# 	'#*&#*',
# 	'*a1c&',
# 	'&q2w*',
# 	'#a3c#',
# 	'*&#*&'
# ]
# data = [
# 	'5 1',
# 	'#',
# 	'*',
# 	'a',
# 	'#',
# 	'3'
# ]
n_lines, length = [int(x) for x in data[0].split()]
values = np.zeros((n_lines, length), dtype=np.int)
rasst = np.zeros((n_lines, 3), dtype=np.int)
rasst.fill(3 * length)
for i in range(n_lines):
	values[i, 0] = get_symb(data[i + 1][0])
	rasst[i, values[i, 0]] = 0
	for j in range(1, length):
		values[i, j] = get_symb(data[i + 1][j])
		if values[i, j] != values[i, 0]:
			diff = int(min(j, length - j))
			old_val = rasst[i, values[i, j]]
			if old_val > diff:
				rasst[i, values[i, j]] = diff

# print rasst

from_where = [0, 1, 2]
price = rasst[0, 0] + rasst[1, 1] + rasst[2, 2]
for i,j,k in [(0,2,1), (1,0,2), (1,2,0), (2,1,0), (2,0,1)]:
	new_price = rasst[i, 0] + rasst[j, 1] + rasst[k, 2]
	if new_price < price:
		from_where = [i,j,k]
		price = new_price
for i in range(3, n_lines):
	new_prices = [
		rasst[i, 0] + rasst[from_where[1], 1] + rasst[from_where[2], 2],
		rasst[from_where[0], 0] + rasst[i, 1] + rasst[from_where[2], 2],
		rasst[from_where[0], 0] + rasst[from_where[1], 1] + rasst[i, 2]
	]
	new_price = int(min(new_prices))
	if new_price < price:
		price = new_price
		if new_prices[0] == new_price:
			from_where[0] = i
		elif new_prices[1] == new_price:
			from_where[1] = i
		else:
			from_where[2] = i
print price


# -*- coding: utf-8 -*-
from __future__ import division
import sys
import numpy as np

def get_symb(x): # Превращаем буквы в 0, цифры в 1, спецсимволы в 2
	if x.isalpha():
		return 0
	if x.isdigit():
		return 1
	return 2

data = []
data.append(sys.stdin.readline())
n_lines, length = [int(x) for x in data[0].split()]
for i in range(n_lines):
	data.append(sys.stdin.readline())

# values = np.zeros((n_lines, length), dtype=np.int) # Тип символа в i-й строке на j-м месте
# rasst = np.zeros((n_lines, 3), dtype=np.int) # Расстояния в i-й строке до первого символа типа j
# rasst.fill(3 * length) # Точно больше оптимального расстояния
# for i in range(n_lines):
# 	values[i, 0] = get_symb(data[i + 1][0])
# 	rasst[i, values[i, 0]] = 0
# 	for j in range(1, length):
# 		values[i, j] = get_symb(data[i + 1][j])
# 		if values[i, j] != values[i, 0]:
# 			diff = int(min(j, length - j))
# 			old_val = rasst[i, values[i, j]]
# 			if old_val > diff:
# 				rasst[i, values[i, j]] = diff

# print rasst

from_where = [0, 1, 2] # Из каких строк берем, соотв., символы длины 1,2,3?
price = rasst[0, 0] + rasst[1, 1] + rasst[2, 2]
# for i,j,k in [(0,2,1), (1,0,2), (1,2,0), (2,1,0), (2,0,1)]: # Сначала перебираем перестановки первых трёх строк
# 	new_price = rasst[i, 0] + rasst[j, 1] + rasst[k, 2]
# 	if new_price < price:
# 		from_where = [i,j,k]
# 		price = new_price
# for i in range(3, n_lines):
# 	new_prices = [
# 		rasst[i, 0] + rasst[from_where[1], 1] + rasst[from_where[2], 2],
# 		rasst[from_where[0], 0] + rasst[i, 1] + rasst[from_where[2], 2],
# 		rasst[from_where[0], 0] + rasst[from_where[1], 1] + rasst[i, 2]
# 	]
# 	new_price = int(min(new_prices))
# 	if new_price < price:
# 		price = new_price
# 		if new_prices[0] == new_price:
# 			from_where[0] = i
# 		elif new_prices[1] == new_price:
# 			from_where[1] = i
# 		else:
# 			from_where[2] = i
print price


# -*- coding: utf-8 -*-
from __future__ import division
import sys
import numpy as np

def get_symb(x): # Превращаем буквы в 0, цифры в 1, спецсимволы в 2
	if x.isalpha():
		return 0
	if x.isdigit():
		return 1
	return 2

data = []
data.append(sys.stdin.readline())
n_lines, length = [int(x) for x in data[0].split()]
for i in range(n_lines):
	data.append(sys.stdin.readline())

values = np.zeros((n_lines, length), dtype=np.int) # Тип символа в i-й строке на j-м месте
rasst = np.zeros((n_lines, 3), dtype=np.int) # Расстояния в i-й строке до первого символа типа j
rasst.fill(3 * length) # Точно больше оптимального расстояния
for i in range(n_lines):
	values[i, 0] = get_symb(data[i + 1][0])
	rasst[i, values[i, 0]] = 0
	for j in range(1, length):
		values[i, j] = get_symb(data[i + 1][j])
		if values[i, j] != values[i, 0]:
			diff = int(min(j, length - j))
			old_val = rasst[i, values[i, j]]
			if old_val > diff:
				rasst[i, values[i, j]] = diff

# print rasst

from_where = [0, 1, 2] # Из каких строк берем, соотв., символы длины 1,2,3?
price = rasst[0, 0] + rasst[1, 1] + rasst[2, 2]
for i,j,k in [(0,2,1), (1,0,2), (1,2,0), (2,1,0), (2,0,1)]: # Сначала перебираем перестановки первых трёх строк
	new_price = rasst[i, 0] + rasst[j, 1] + rasst[k, 2]
	if new_price < price:
		from_where = [i,j,k]
		price = new_price
for i in range(3, n_lines):
	new_prices = [
		rasst[i, 0] + rasst[from_where[1], 1] + rasst[from_where[2], 2],
		rasst[from_where[0], 0] + rasst[i, 1] + rasst[from_where[2], 2],
		rasst[from_where[0], 0] + rasst[from_where[1], 1] + rasst[i, 2]
	]
	new_price = int(min(new_prices))
	if new_price < price:
		price = new_price
		if new_prices[0] == new_price:
			from_where[0] = i
		elif new_prices[1] == new_price:
			from_where[1] = i
		else:
			from_where[2] = i
print price


# -*- coding: utf-8 -*-
# from __future__ import division
import sys

def get_symb(x): # Превращаем буквы в 0, цифры в 1, спецсимволы в 2
	if x.isalpha():
		return 0
	if x.isdigit():
		return 1
	return 2

data = []
data.append(sys.stdin.readline())
n_lines, length = [int(x) for x in data[0].split()]
for i in range(n_lines):
	data.append(sys.stdin.readline())

values = [[0] * length for i in range(n_lines)] # Тип символа в i-й строке на j-м месте
rasst = [[3 * length] * 3 for i in range(n_lines)] # Расстояния в i-й строке до первого символа типа j
for i in range(n_lines):
	values[i][0] = get_symb(data[i + 1][0])
	rasst[i][values[i][0]] = 0
	for j in range(1, length):
		values[i][j] = get_symb(data[i + 1][j])
		if values[i][j] != values[i][0]:
			diff = int(min(j, length - j))
			old_val = rasst[i][values[i][j]]
			if old_val > diff:
				rasst[i][values[i][j]] = diff

# print rasst

from_where = [0, 1, 2] # Из каких строк берем, соотв., символы длины 1,2,3?
price = rasst[0][0] + rasst[1][1] + rasst[2][2]
for i,j,k in [(0,2,1), (1,0,2), (1,2,0), (2,1,0), (2,0,1)]: # Сначала перебираем перестановки первых трёх строк
	new_price = rasst[i][0] + rasst[j][1] + rasst[k][2]
	if new_price < price:
		from_where = [i,j,k]
		price = new_price
for i in range(3, n_lines):
	new_prices = [
		rasst[i][0] + rasst[from_where[1]][1] + rasst[from_where[2]][2],
		rasst[from_where[0]][0] + rasst[i][1] + rasst[from_where[2]][2],
		rasst[from_where[0]][0] + rasst[from_where[1]][1] + rasst[i][2]
	]
	new_price = int(min(new_prices))
	if new_price < price:
		price = new_price
		if new_prices[0] == new_price:
			from_where[0] = i
		elif new_prices[1] == new_price:
			from_where[1] = i
		else:
			from_where[2] = i
print price


import sys
import numpy as np

data = []
data.append(sys.stdin.readline())
n_lines, length = [int(x) for x in data[0].split()]
for i in range(n_lines):
	data.append(sys.stdin.readline())

print 0


# -*- coding: utf-8 -*-
# from __future__ import division
import sys
# import numpy as np

# def get_symb(x): # Превращаем буквы в 0, цифры в 1, спецсимволы в 2
# 	if x.isalpha():
# 		return 0
# 	if x.isdigit():
# 		return 1
# 	return 2

data = []
data.append(sys.stdin.readline())
n_lines, length = [int(x) for x in data[0].split()]
for i in range(n_lines):
	data.append(sys.stdin.readline())

# values = np.zeros((n_lines, length), dtype=np.int) # Тип символа в i-й строке на j-м месте
# rasst = np.zeros((n_lines, 3), dtype=np.int) # Расстояния в i-й строке до первого символа типа j
# rasst.fill(3 * length) # Точно больше оптимального расстояния
# for i in range(n_lines):
# 	values[i, 0] = get_symb(data[i + 1][0])
# 	rasst[i, values[i, 0]] = 0
# 	for j in range(1, length):
# 		values[i, j] = get_symb(data[i + 1][j])
# 		if values[i, j] != values[i, 0]:
# 			diff = int(min(j, length - j))
# 			old_val = rasst[i, values[i, j]]
# 			if old_val > diff:
# 				rasst[i, values[i, j]] = diff

# print rasst

from_where = [0, 1, 2] # Из каких строк берем, соотв., символы длины 1,2,3?
price = rasst[0, 0] + rasst[1, 1] + rasst[2, 2]
# for i,j,k in [(0,2,1), (1,0,2), (1,2,0), (2,1,0), (2,0,1)]: # Сначала перебираем перестановки первых трёх строк
# 	new_price = rasst[i, 0] + rasst[j, 1] + rasst[k, 2]
# 	if new_price < price:
# 		from_where = [i,j,k]
# 		price = new_price
# for i in range(3, n_lines):
# 	new_prices = [
# 		rasst[i, 0] + rasst[from_where[1], 1] + rasst[from_where[2], 2],
# 		rasst[from_where[0], 0] + rasst[i, 1] + rasst[from_where[2], 2],
# 		rasst[from_where[0], 0] + rasst[from_where[1], 1] + rasst[i, 2]
# 	]
# 	new_price = int(min(new_prices))
# 	if new_price < price:
# 		price = new_price
# 		if new_prices[0] == new_price:
# 			from_where[0] = i
# 		elif new_prices[1] == new_price:
# 			from_where[1] = i
# 		else:
# 			from_where[2] = i
print price


# -*- coding: utf-8 -*-
from __future__ import division
import sys
import numpy as np

def get_symb(x): # Превращаем буквы в 0, цифры в 1, спецсимволы в 2
	if x.isalpha():
		return 0
	if x.isdigit():
		return 1
	return 2

data = []
data.append(sys.stdin.readline())
n_lines, length = [int(x) for x in data[0].split()]
for i in range(n_lines):
	data.append(sys.stdin.readline())

values = np.zeros((n_lines, length), dtype=np.int) # Тип символа в i-й строке на j-м месте
rasst = np.zeros((n_lines, 3), dtype=np.int) # Расстояния в i-й строке до первого символа типа j
rasst.fill(3 * length) # Точно больше оптимального расстояния
for i in range(n_lines):
	values[i, 0] = get_symb(data[i + 1][0])
	rasst[i, values[i, 0]] = 0
	for j in range(1, length):
		values[i, j] = get_symb(data[i + 1][j])
		if values[i, j] != values[i, 0]:
			diff = int(min(j, length - j))
			old_val = rasst[i, values[i, j]]
			if old_val > diff:
				rasst[i, values[i, j]] = diff

# print rasst

from_where = [0, 1, 2] # Из каких строк берем, соотв., символы длины 1,2,3?
price = rasst[0, 0] + rasst[1, 1] + rasst[2, 2]
# for i,j,k in [(0,2,1), (1,0,2), (1,2,0), (2,1,0), (2,0,1)]: # Сначала перебираем перестановки первых трёх строк
# 	new_price = rasst[i, 0] + rasst[j, 1] + rasst[k, 2]
# 	if new_price < price:
# 		from_where = [i,j,k]
# 		price = new_price
# for i in range(3, n_lines):
# 	new_prices = [
# 		rasst[i, 0] + rasst[from_where[1], 1] + rasst[from_where[2], 2],
# 		rasst[from_where[0], 0] + rasst[i, 1] + rasst[from_where[2], 2],
# 		rasst[from_where[0], 0] + rasst[from_where[1], 1] + rasst[i, 2]
# 	]
# 	new_price = int(min(new_prices))
# 	if new_price < price:
# 		price = new_price
# 		if new_prices[0] == new_price:
# 			from_where[0] = i
# 		elif new_prices[1] == new_price:
# 			from_where[1] = i
# 		else:
# 			from_where[2] = i
print price


import sys

data = []
data.append(sys.stdin.readline())
n_lines, length = [int(x) for x in data[0].split()]
for i in range(n_lines):
	data.append(sys.stdin.readline())

print 0


from __future__ import division
import sys
import math
import numpy as np

def get_symb(x):
	if x.isalpha():
		return 0
	if x.isdigit():
		return 1
	return 2

data = sys.stdin.readlines()
# data = [
# 	'5 5',
# 	'#*&#*',
# 	'*a1c&',
# 	'&q2w*',
# 	'#a3c#',
# 	'*&#*&'
# ]
n_lines, length = [int(x) for x in data[0].split()]
values = np.zeros((n_lines, length), dtype=np.int)
rasst = np.zeros((n_lines, 3), dtype=np.int)
rasst.fill(3 * length)
for i in range(n_lines):
	values[i, 0] = get_symb(data[i + 1][0])
	rasst[i, values[i, 0]] = 0
	for j in range(length):
		values[i, j] = get_symb(data[i + 1][j])
		if values[i, j] != values[i, 0]:
			diff = min(j, length - j)
			old_val = rasst[i, values[i, j]]
			if old_val > diff:
				rasst[i, values[i, j]] = diff

print rasst

from_where = [0, 1, 2]
price = rasst[0, 0] + rasst[1, 1] + rasst[2, 2]
for i,j,k in [(0,2,1), (1,0,2), (1,2,0), (2,1,0), (2,0,1)]:
	new_price = rasst[i, 0] + rasst[j, 1] + rasst[k, 2]
	if new_price < price:
		from_where = [i,j,k]
		price = new_price
for i in range(3, n_lines):
	new_prices = [
		rasst[i, 0] + rasst[from_where[1], 1] + rasst[from_where[2], 2],
		rasst[from_where[0], 0] + rasst[i, 1] + rasst[from_where[2], 2],
		rasst[from_where[0], 0] + rasst[from_where[1], 1] + rasst[i, 2]
	]
	new_price = min(new_prices)
	if new_price < price:
		price = new_price
		if new_prices[0] == new_price:
			from_where[0] = i
		elif new_prices[1] == new_price:
			from_where[1] = i
		else:
			from_where[2] = i

print price


import sys
import numpy as np

def get_symb(x):
	if x.isalpha():
		return 0
	if x.isdigit():
		return 1
	return 2

data = []
data.append(sys.stdin.readline())
n_lines, length = [int(x) for x in data[0].split()]
for i in range(n_lines):
	data.append(sys.stdin.readline())

print 0


import sys
from itertools import permutations
from itertools import combinations

n, m = map(lambda x: int(x.strip()), sys.stdin.readline().split())

tuples = [[1000000, 1000000, 1000000] for i in range(n)]
for i in range(n):
    line = sys.stdin.readline().strip()

    for j in range(len(line)):
        tmp = min(j, m - j)
        if line[j].isdigit():
            tuples[i][0] = min(tuples[i][0], tmp)
        elif line[j].islower():
            tuples[i][1] = min(tuples[i][1], tmp)
        elif line[j] in ('#', '*', '&'):
            tuples[i][2] = min(tuples[i][2], tmp)

def chooseMin(t1, t2, t3):
    res = 100000000
    for i, j, k in permutations(range(3)):
        if t1[i] < 10000 and t2[j] < 10000 and t3[k] < 10000:
            res = min(res, t1[i] + t2[j] + t3[k])
    return res

res = 10000000
for c in combinations(tuples, 3):
    res = min(res, chooseMin(*c))

print res


n, m = map(int, raw_input().split())

di = [m] * n
da = [m] * n
dc = [m] * n

for i in range(n):
    s = raw_input()
    for p, c in enumerate(s):
        if c.isdigit():
            di[i] = min(di[i], p, m - p)
        elif c.isalpha():
            da[i] = min(da[i], p, m - p)
        else:
            dc[i] = min(dc[i], p, m - p)

ans = n * m

for ii in range(n):
    for ia in range(n):
        for ic in range(n):
            if ii != ia and ii != ic and ia != ic and di[ii] != m and da[ia] != m and dc[ic] != m:
                ans = min(ans, di[ii] + da[ia] + dc[ic])

print ans


n, m = map(int, raw_input().split())
ch = [10 ** 10] * n
let = [10 ** 10] * n
dig = [10 ** 10] * n

for i in xrange(n) :
    s = raw_input()

    for j, c in enumerate(s) :
        if c in "*&#" :
            ch[i] = min(ch[i], j, m-j)
        elif ord('a') <= ord(c) <= ord('a') + 26 :
            let[i] = min(let[i], j, m-j)
        else :
            dig[i] = min(dig[i],j, m-j)

p = 10 ** 10

for i in xrange(n):
    for j in xrange(n) :
        for k in xrange(n) :
            if (i ^ j and i ^ k and k ^ j) :
                p = min(p, ch[i] + let[j] + dig[k])
print p


n, m = map(int, raw_input().split())
S = []
for i in range(n):
    S.append(raw_input().rstrip())

alphas = ['1234567890', 'abcdefghijklmnopqrstuvwxyz', '#*&']
leasts = []
for s in S:
    t = s[:1] + ''.join(list(reversed(s[1:])))
    least = [float('inf')] * 3
    for i, alpha in enumerate(alphas):
        for j in range(m):
            if s[j] in alpha or t[j] in alpha:
                least[i] = j
                break
    # print least
    leasts.append(least)

def f(lsts, now, tot, three):
    if now == n:
        if three == 2**3 - 1:
            return tot
        else:
            return float('inf')

    tmp = []
    for i in range(3):
        tmp.append(f(lsts, now+1, tot + lsts[now][i], three | 2**i))

    return min(tmp)

print f(leasts, 0, 0, 0)

# print 'YES' if a*b > 0 and abs(a - b) <= 1 else 'NO'


import itertools

INF = float('inf')
n, m = map(int, raw_input().split())
S = []
for i in range(n):
    S.append(raw_input().rstrip())

alphas = ['1234567890', 'abcdefghijklmnopqrstuvwxyz', '#*&']
leasts = []
for s in S:
    t = s[:1] + ''.join(list(reversed(s[1:])))
    least = [INF] * 3
    for i, alpha in enumerate(alphas):
        for j in range(m):
            if s[j] in alpha or t[j] in alpha:
                least[i] = j
                break
    # print least
    leasts.append(least)

# def f(lsts, now, tot, three):
#     if now == n:
#         if three == 2**3 - 1:
#             return tot
#         else:
#             return float('inf')
#
#     tmp = []
#     for i in range(3):
#         tmp.append(f(lsts, now+1, tot + lsts[now][i], three | 2**i))
#
#     return min(tmp)

# print f(leasts, 0, 0, 0)

sum_min = sum(map(min, leasts))
# print sum_min

min_ = INF
for perm in itertools.permutations(range(n), 3):
    new = 0
    for i in range(3):
        new += leasts[perm[i]][i]
    min_ = min(min_, new)

print min_ + sum_min


n, m = map(int, raw_input().split())
S = []
for i in range(n):
    S.append(raw_input().rstrip())

alphas = ['1234567890', 'abcdefghijklmnopqrstuvwxyz', '#*&']
leasts = []
for s in S:
    t = s[:1] + ''.join(list(reversed(s[1:])))
    least = [float('inf')] * 3
    for i, alpha in enumerate(alphas):
        for j in range(m):
            if s[j] in alpha or t[j] in alpha:
                least[i] = j
                break
    print least
    leasts.append(least)

def f(lsts, now, tot, three):
    if now == n:
        if three == 2**3 - 1:
            return tot
        else:
            return float('inf')

    tmp = []
    for i in range(3):
        tmp.append(f(lsts, now+1, tot + lsts[now][i], three | 2**i))

    return min(tmp)

print f(leasts, 0, 0, 0)

# print 'YES' if a*b > 0 and abs(a - b) <= 1 else 'NO'


# -*- coding: utf-8 -*-
# @Author: HaonanWu
# @Date:   2017-02-26 15:31:28
# @Last Modified by:   HaonanWu
# @Last Modified time: 2017-02-26 15:47:32

R = lambda:map(int,raw_input().split())
def T(c):
    if c >= '0' and c <= '9':
        return 0
    if c == '#' or c == '*' or c == '&':
        return 1
    return 2

n,m = R()
dp = [[55 for i in range(3)] for i in range(n)]
s = []

for i in range(n):
    st = list(raw_input())
    s.append(st)

for i in range(n):
    for j in range(m):
        ty = T(s[i][j])
        dp[i][ty] = min(dp[i][ty], min(j,m-j))

ans = 55*3

for i in range(n):
    for j in range(n):
        if i == j:
            continue
        for k in range(n):
            if j==k or k==i:
                continue
            ans = min(ans,dp[i][0]+dp[j][1]+dp[k][2])

print ans


import string
def howfar(pw):
    lc= 'abcdefghijklmnopqrstuvwxyz'
    digit = '0123456789'
    sign = '#*&'
    slc = 99999
    sd = 99999
    ss = 99999
    for i in range(len(pw)):
        ch = pw[i]
        if ch in lc:
            slc = min(len(pw)-i, i, slc)
        if ch in digit:
            sd = min(len(pw)-i, i, sd)
        if ch in sign:
            ss = min(len(pw)-i, i, ss)
    return [slc, sd, ss]

n, m = map(int, raw_input().split())

countdi = 0
countchar = 0
countsym = 0
effort = [0] * n

pwd = [0] * n
for i in range(n):
    pwd[i] = raw_input()
    effort[i] = howfar(pwd[i])

ans = 999
for i in range(n):
    for j in range(n):
        for k in range(n):
            if not (i == j or i == k or j == k):
                ans = min(ans, effort[i][0] + effort[j][1] + effort[k][2])

print ans


n, m = map(int, raw_input().split())
s = [raw_input() for _ in xrange(n)]

lower, digit, symbol = [], [], []

for i in xrange(n):

    lower_cost, digit_cost, symbol_cost = 1000000000, 1000000000, 1000000000

    if s[i][0] in 'abcdefghijklmnopqrstuvwxyz':
        lower_cost = 0
    if s[i][0] in '0123456789':
        digit_cost = 0
    if s[i][0] in '#*&':
        symbol_cost = 0

    for j in xrange(1,m):
        if s[i][j] in 'abcdefghijklmnopqrstuvwxyz':
            lower_cost = min(lower_cost, j)
        if s[i][j] in '0123456789':
            digit_cost = min(digit_cost, j)
        if s[i][j] in '#*&':
            symbol_cost = min(symbol_cost, j)

        if s[i][m-j] in 'abcdefghijklmnopqrstuvwxyz':
            lower_cost = min(lower_cost, j)
        if s[i][m-j] in '0123456789':
            digit_cost = min(digit_cost, j)
        if s[i][m-j] in '#*&':
            symbol_cost = min(symbol_cost, j)

    lower.append(lower_cost)
    digit.append(digit_cost)
    symbol.append(symbol_cost)

dp = [[1000000000 for j in xrange(8)] for i in xrange(n+1)]
dp[0][0] = 0
for i in xrange(n):
    for j in xrange(8):
        dp[i+1][j|1] = min(dp[i+1][j|1], dp[i][j] + lower[i])
        dp[i+1][j|2] = min(dp[i+1][j|2], dp[i][j] + digit[i])
        dp[i+1][j|4] = min(dp[i+1][j|4], dp[i][j] + symbol[i])
print dp[n][7]


import math

n, m = map(int, raw_input().split())

def s2digit(s):
    s2 = s+s
    l = len(s)
    n2 = [abs(i-l) for i,v in enumerate(s2) if v.isdigit()]
    if len(n2)==0:
        return l*2
    return min(n2)

def s2char(s):
    s2 = s+s
    l = len(s)
    n2 = [abs(i-l) for i,v in enumerate(s2) if v.islower()]
    if len(n2)==0:
        return l*2
    return min(n2)

def s2spec(s):
    s2 = s+s
    l = len(s)
    spec = {'#','*','&'}
    n2 = [abs(i-l) for i,v in enumerate(s2) if v in spec]
    if len(n2)==0:
        return l*2
    return min(n2)

def s2a(s):
    return [s2digit(s), s2char(s), s2spec(s)]

inf = n*m*2
state1 = [inf for i in range(n)]  #a,b,c
state2 = [inf for i in range(n)]  #ab, bc, ca
state3 = inf  # abc

for i in range(n):
    op = s2a(raw_input())
    print op
    ## need to update from state3, then state2, finally state1
    state3= min (state3, state2[0]+op[2], state2[1]+op[0], state2[2]+op[1]) # orig, ab+c, bc+a, ca+b
    state2[0] = min (state2[0], state1[1] +op[0], state1[0] +op[1]) # orig, or a+b, or b+a
    state2[1] = min (state2[1], state1[2] +op[1], state1[1] +op[2])
    state2[2] = min (state2[2], state1[0] +op[2], state1[2] +op[0])
    state1 = min (state1, op)
    print state1, state2, state3

print state3

"""
#print n,l
#print a1
#print a2

def f(a):
    global n, l
    a2 = []
    for i, v in enumerate(a):
        if i < n - 1:
            a2.append(a[i+1] - a[i])
        else:
            a2.append(a[0]+l - a[i])

    return a2

#print f(a1)
#print f(a2)

def cmp_c(a1,a2):
    return int(' '.join(map(str, a2)) in ' '.join(map(str, a1*2)))

ans = ['NO', 'YES']

print ans[cmp_c(f(a1),f(a2))]

 """


import math

n, m = map(int, raw_input().split())

def s2digit(s):
    s2 = s+s
    l = len(s)
    n2 = [abs(i-l) for i,v in enumerate(s2) if v.isdigit()]
    if len(n2)==0:
        return l*2
    return min(n2)

def s2char(s):
    s2 = s+s
    l = len(s)
    n2 = [abs(i-l) for i,v in enumerate(s2) if v.islower()]
    if len(n2)==0:
        return l*2
    return min(n2)

def s2spec(s):
    s2 = s+s
    l = len(s)
    spec = {'#','*','&'}
    n2 = [abs(i-l) for i,v in enumerate(s2) if v in spec]
    if len(n2)==0:
        return l*2
    return min(n2)

def s2a(s):
    return [s2digit(s), s2char(s), s2spec(s)]

inf = n*m*2
state1 = [inf for i in range(n)]  #a,b,c
state2 = [inf for i in range(n)]  #ab, bc, ca
state3 = inf  # abc

for i in range(n):
    op = s2a(raw_input())
    #print op
    ## need to update from state3, then state2, finally state1
    state3= min (state3, state2[0]+op[2], state2[1]+op[0], state2[2]+op[1]) # orig, ab+c, bc+a, ca+b
    state2[0] = min (state2[0], state1[1] +op[0], state1[0] +op[1]) # orig, or a+b, or b+a
    state2[1] = min (state2[1], state1[2] +op[1], state1[1] +op[2])
    state2[2] = min (state2[2], state1[0] +op[2], state1[2] +op[0])
    state1 = min (state1, op)
    #5print state1, state2, state3

print state3

"""
#print n,l
#print a1
#print a2

def f(a):
    global n, l
    a2 = []
    for i, v in enumerate(a):
        if i < n - 1:
            a2.append(a[i+1] - a[i])
        else:
            a2.append(a[0]+l - a[i])

    return a2

#print f(a1)
#print f(a2)

def cmp_c(a1,a2):
    return int(' '.join(map(str, a2)) in ' '.join(map(str, a1*2)))

ans = ['NO', 'YES']

print ans[cmp_c(f(a1),f(a2))]

 """


import string

n, m = map(int, raw_input().split())

l = []
for _ in xrange(n):
    l.append(raw_input())
lower = string.ascii_lowercase
digits = string.digits
shorts = [[2*m]*3 for x in xrange(n)]
p = '#*&'
for i in xrange(n):
    for index, c in enumerate(l[i]):
        index = min(index, m - index)
        if c in lower:
            shorts[i][0] = min(shorts[i][0] , index)
        elif c in digits:
            shorts[i][1] = min(shorts[i][1] , index)
        elif c in p:
            shorts[i][2] = min(shorts[i][2] , index)

ans = 1000000000

for i in xrange(n):
    for j in xrange(i,n):
        for k in xrange(j,n):
            total = 100000000
            for x in range(3):
                for y in range(3):
                    if y == x:
                        continue
                    for z in range(3):
                        if z == x or z == y:
                            continue
                        total = min(total, shorts[i][x] + shorts[j][y] + shorts[k][z])
            ans = min(ans, total)

print ans


import string

n, m = map(int, raw_input().split())

l = []
for _ in xrange(n):
    l.append(raw_input())
lower = string.ascii_lowercase
digits = string.digits
shorts = [[2*m]*3 for x in xrange(n)]
p = '#*&'
for i in xrange(n):
    for index, c in enumerate(l[i]):
        index = min(index, m - index)
        if c in lower:
            shorts[i][0] = min(shorts[i][0] , index)
        elif c in digits:
            shorts[i][1] = min(shorts[i][1] , index)
        elif c in p:
            shorts[i][2] = min(shorts[i][2] , index)

ans = 1000000000

for i in xrange(n):
    for j in xrange(i+1,n):
        for k in xrange(j+1,n):
            total = 100000000
            for x in range(3):
                for y in range(3):
                    if y == x:
                        continue
                    for z in range(3):
                        if z == x or z == y:
                            continue
                        total = min(total, shorts[i][x] + shorts[j][y] + shorts[k][z])
            ans = min(ans, total)

print ans


vals=[int(x) for x in raw_input().split()]
n=vals[0]
m=vals[1]
minalph=m
minnum=m
minsym=m
for i in range(n):
    v=list(raw_input())
    for j in range(m):
        if j<minalph and v[j].islower():
            minalph=j
        if j<minnum and v[j].isdigit():
            minnum=j
        if j<minsym and (v[j]=='*' or v[j]=='&' or v[j]=='#'):
            minsym=j

print(minalph+minnum+minsym)


def issym(c):
    if c=='*' or c=='#' or c=='&': return True
    return False

vals=[int(x) for x in raw_input().split()]
n=vals[0]
m=vals[1]
minarr=[[m for i in range(n)] for j in range(3)]
for i in range(n):
    v=list(raw_input())
    for j in range(m):
        if minarr[0][i]==m and (v[j].islower() or v[-j].islower()):
            minarr[0][i]=j
        if minarr[1][i]==m and (v[j].isdigit() or v[-j].isdigit()):
            minarr[1][i]=j
        if minarr[2][i]==m and (issym(v[j]) or issym(v[-j])):
            minarr[2][i]=j
        if not (minarr[0][i]==m or minarr[1][i]==m or minarr[2][i]==m):break
mins=[min(arr) for arr in minarr]
inds=[arr.index(mins[i])for arr,i in zip(minarr,range(3))]

for i in range(3):
    if inds[i-1]==inds[i]:
        temp1=minarr[i-1][:]
        temp1[inds[i-1]]=m
        newmin1=mins[:]
        newmin1[i-1]=min(temp1)
        temp2=minarr[i][:]
        temp2[inds[i]]=m
        newmin2=mins[:]
        newmin2[i]=min(temp2)
        if sum(newmin1)<sum(newmin2):
            minarr[i-1]=temp1
            mins=newmin1
            inds[i-1]=minarr[i-1].index(mins[i-1])
        else:
            minarr[i]=temp2
            mins=newmin2
            inds[i]=minarr[i].index(mins[i])

if m in mins: print(-1)
else: print(sum(mins))


n, m = map(int, raw_input().split())

di = [m] * m
da = [m] * m
dc = [m] * m

for i in range(n):
    s = raw_input()
    for p, c in enumerate(s):
        if c.isdigit():
            di[i] = min(di[i], p, m - p)
        elif c.isalpha():
            da[i] = min(da[i], p, m - p)
        else:
            dc[i] = min(dc[i], p, m - p)

ans = n * m

for ii in range(n):
    for ia in range(n):
        for ic in range(n):
            if ii != ia and ii != ic and ia != ic and di[ii] != m and da[ia] != m and dc[ic] != m:
                ans = min(ans, di[ii] + da[ia] + dc[ic])

print ans


n,m = map(int,raw_input().split())
t = []
ts = []
tsign = []
smin = 51
dmin = 51
lmin = 51
for x in range(0,n,+1):
    tsign.append([51,51,51])
for z in range(0,n,+1):
    s = str(raw_input())
    for x in range(0,m,+1):
        #print s[x],ord(s[x])
        if s[x].isdigit() == True:
            if tsign[z][0]==51:
                tsign[z][0] = x
        elif ord(s[x])-97 >= 0 and ord(s[x])-97<= 25 and tsign[z][1] == 51:
            tsign[z][1] = x
        elif (s[x] == '#' or s[x] == '*' or s[x]== '&') and tsign[z][2] == 51:
            tsign[z][2] = x
    ts.append(s[0])
    t.append(s)
for x in tsign:
    if x[0]<dmin:
        dmin = x[0]
    if x[1]<lmin:
        lmin = x[1]
    if x[2]<smin:
        smin = x[2]
print dmin+lmin+smin


n,m = map(int,raw_input().split())
t = []
ts = []
tsign = []
smin = 51
dmin = 51
lmin = 51
for x in range(0,n,+1):
    tsign.append([51,51,51,False])
for z in range(0,n,+1):
    smin = 51
    dmin = 51
    lmin = 51
    s = str(raw_input())
    for x in range(0,m,+1):
        if s[x].isdigit() == True:
            if x<dmin:
                dmin = x
            if m-x<dmin:
                dmin = m-x
            tsign[z][0] = dmin
        elif ord(s[x])-97 >= 0 and ord(s[x])-97<= 25:
            if x<lmin:
                lmin = x
            if m-x<lmin:
                lmin = m-x
            tsign[z][1] = lmin
        elif (s[x] == '#' or s[x] == '*' or s[x]== '&'):
            if x<smin:
                smin = x
            if m-x < smin:
                smin = m-x
            tsign[z][2] = smin
    ts.append(s[0])
    t.append(s)
smin = 51
dmin = 51
lmin = 51
poz_lmin = poz_smin = poz_dmin = -1
xx=0
for x in tsign:
    if x[0]<dmin and x[3] == False:
        dmin = x[0]
        x[3] = True
        if poz_dmin != -1:
            x[poz_dmin][3] = False
        poz_dmin = xx
    xx += 1
xx=0
for x in tsign:
    if x[1]<lmin and x[3] == False:
        lmin = x[1]
        x[3] = True
        if poz_lmin != -1:
            x[poz_lmin][3] = False
        poz_lmin = xx
    xx += 1
xx=0
for x in tsign:
    if x[2]<smin and x[3] == False:
        smin = x[2]
        x[3] = True
        if poz_smin != -1:
            x[poz_smin][3] = False
        poz_smin = xx
    xx += 1
print lmin+dmin+smin


n,m = map(int,raw_input().split())
t = []
ts = []
tsign = []
smin = 51
dmin = 51
lmin = 51
for x in range(0,n,+1):
    tsign.append([51,51,51])
for z in range(0,n,+1):
    s = str(raw_input())
    for x in range(0,m,+1):
        #print s[x],ord(s[x])
        if s[x].isdigit() == True:
            if x<dmin:
                dmin = x
            if m-x<dmin:
                dmin = m-x
            #if tsign[z][0]==51:
                #tsign[z][0] = x
        elif ord(s[x])-97 >= 0 and ord(s[x])-97<= 25:
            #tsign[z][1] = x
            if x<lmin:
                lmin = x
            if m-x<lmin:
                lmin = m-x
        elif s[x] == '#' or s[x] == '*' or s[x]== '&':
            if x<smin:
                smin = x
            if m-x < smin:
                smin = m-x
    ts.append(s[0])
    t.append(s)
'''
for x in tsign:
    if x[0]<dmin:
        dmin = x[0]
    if x[1]<lmin:
        lmin = x[1]
    if x[2]<smin:
        smin = x[2]
'''
print dmin+lmin+smin