stablegradients/pie-gem5-pairs huggingface dataset:
// Slower C++ solution:
#include<iostream>

#include<algorithm>

#include<cstring>

#include<string>

#include<cstdio>

using namespace std;

string a[100000];

int main(){

    long long n;

    cin>>n;

    long long ans=0;

    for(long long i=0;i<n;i++){

        cin>>a[i];

        std::sort(a[i].begin(),a[i].end());

    }

    sort(a,a+n);

    long long z[100000]={0},cnt=0;

    for(long long  i=0;i<n;i++){

        if(i==0){

            z[cnt]=1;

            continue;

        }

        if(a[i]==a[i-1]){

            z[cnt]++;

        }

        else{

            cnt++;

            z[cnt]++;

        }

    }



    for(long long  i=0;i<=cnt;i++){

        ans+=((z[i]*(z[i]-1))/2);

    }

    cout<<ans;

}


// Faster C++ solution for the same problem (measured speedup: 5.208964614028072x):
    #include <bits/stdc++.h>



using namespace std;

typedef long long ll;

typedef long double ld;

#define endl "\n"

#define all(v) v.begin(),v.end()

#define sz(v)  v.size()





void fast() {



    cin.tie(0);

    cin.sync_with_stdio(0);

}







int main() {

    fast();

    ll n;cin>>n;

    map<string,ll>ma;

    vector<string>v;

    for (int i = 0; i <n ; ++i) {

        string s;cin>>s;

        sort(all(s));

        if(!ma[s])v.push_back(s);

        ma[s]++;

    }

    ll ans=0;

    for (int j = 0; j <v.size() ; ++j) {

        ll freq=ma[v[j]];

        ans+=(freq*(freq-1))/2;

    }

    cout<<ans;

}
// Slower C++ solution:
#include<iostream>

#include<algorithm>

#include<cstring>

#include<string>

#include<cstdio>

using namespace std;

string a[100000];

int main(){

    long long n;

    cin>>n;

    long long ans=0;

    for(long long i=0;i<n;i++){

        cin>>a[i];

        std::sort(a[i].begin(),a[i].end());

    }

    sort(a,a+n);

    long long z[100000]={0},cnt=0;

    for(long long  i=0;i<n;i++){

        if(i==0){

            z[cnt]=1;

            continue;

        }

        if(a[i]==a[i-1]){

            z[cnt]++;

        }

        else{

            cnt++;

            z[cnt]++;

        }

    }



    for(long long  i=0;i<=cnt;i++){

        ans+=((z[i]*(z[i]-1))/2);

    }

    cout<<ans;

}


// Faster C++ solution for the same problem (measured speedup: 5.2790070084568175x):
#include <bits/stdc++.h>



using namespace std;



const int N = 1e5, M = 1e6 + 6, OO = 0x3f3f3f3f;



long long n, cnt;

map<string, long long> s;

string h;

int main()

{

	cin >> n;

	while(n--)

	{

		cin >> h;

		sort(h.begin(), h.end());

		s[h]++;

	}

	for(auto v : s)

	{

		v.second--;

		cnt += (v.second * (v.second + 1) / 2);

	}

	cout << cnt << endl;

	return 0;

}
// Slower C++ solution:
#include <iostream>

#include <algorithm>

#include <map>



#define Nmax int(1e5 + 5)

using namespace std;



typedef long long ll;

int N;

long long nr;

string s[Nmax];

map <string,ll> m;



int main()

{

    cin >> N;

    for(int i = 1; i <= N; ++i)

    {

        cin >> s[i];

        sort(s[i].begin(),s[i].end());

        m[s[i]]++;

    }

    for(map < string,ll>::iterator it = m.begin(); it != m.end(); ++it)

        nr += (it -> second)  * (it -> second - 1) / 2;

    cout << nr;

    return 0;

}


// Faster C++ solution for the same problem (measured speedup: 4.26504374130621x):
#include <iostream>

#include <algorithm>

#include <map>



using namespace std;



string s;

map <string,long long> m;

map <string,long long>::iterator it;

int N;

long long sum;



int main() {

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

    cin >> N;

    for(; N; --N) {

        cin >> s;

        sort(s.begin(),s.end());

        m[s]++;

    }

    for(it = m.begin(); it != m.end(); ++it)

        sum += (it -> second) * (it -> second - 1) / 2;

    cout << sum;

    return 0;

}
// Slower C++ solution:
#include <iostream>

#include <string>

#include <algorithm>

#include <vector>

#include <cmath>

#include <map>



using namespace std;

#define rep(i,n) for(int i=0;i<n;i++)





void count(vector<unsigned long long int>&a) {

	rep(i, a.size()) {

		if (i == 0)

			a[i] = 0;

		else

			a[i] = i - 1 + a[i - 1];

	}

}



int main() {



	vector<unsigned long long int>b(100001);

	count(b);



	int n;

	cin >> n;

	vector<string>s(n);



	rep(i, n)

		cin >> s[i];





	map<string, unsigned long long int>dic;

	rep(i, n) {

		sort(s[i].begin(), s[i].end());

		dic[s[i]]++;

	}



	unsigned long long int ans = 0;

	map<string, unsigned long long int>::iterator it;

	for (it = dic.begin(); it != dic.end(); it++)

		ans += b[it->second];



	cout << ans << endl;



	return 0;

}

// Faster C++ solution for the same problem (measured speedup: 1.9136751517429667x):
#include <bits/stdc++.h>

#define rep(i, n) for (int i = 0; i < n; ++i)

using ll = long long;

using namespace std;

const int INF = 1e9;



int main() {

    int N;

    cin >> N;

    vector<string> S(N);

    rep(i, N) cin >> S[i];



    rep(i, N) sort(S[i].begin(), S[i].end());

    ll ans = 0;

    map<string, ll> mp;



    rep(i, N) mp[S[i]]++;



    for (auto p : mp)

        if (p.second != 1) {

            ll a = p.second - 1;

            ans += a * (a + 1) / 2;

        }

    cout << ans << endl;



    return 0;

}
// Slower C++ solution:
#include<bits/stdc++.h>



using namespace std;

typedef long long ll;

typedef pair<ll,ll> P;

#define a first

#define b second

#define sz size()

#define pb(x) push_back(x) 

#define bg begin()

#define ed end()

#define rep(i,n) for(ll i=0;i<n;i++)

#define rep1(i,n) for(ll i=1;i<=n;i++)

#define mp(x,y) make_pair(x,y)

const ll MOD=1000000007;



vector<ll> pw27(11,1);

ll maxx(ll x,ll y,ll z){return max(max(x,y),z);}

ll minn(ll x,ll y,ll z){return min(min(x,y),z);}

ll mid(ll x,ll y,ll z){return x>y?y>=z?y:min(z,x):x>=z?x:min(y,z);}

ll gcd(ll x,ll y){if(x%y==0) return y;else return gcd(y,x%y);}

ll lcm(ll x,ll y){return x*(y/gcd(x,y));}

ll myceil(ll x,ll y){if(x<=y) return 1;else if(x%y==0) return x/y;else return x/y+1;}



//a,b x

int main(){

	rep1(i,10) pw27[i]=27*pw27[i-1];

	ll N; cin>>N;

	vector<ll> S[100000];

	rep(i,N){

		string tmp; cin>>tmp;

		rep(j,10){

			ll TMP=tmp[j]-'a'+1;

			S[i].pb(TMP);

		}

	}

	rep(i,N){

		sort(S[i].bg,S[i].ed);

	}

	//rep(i,N)rep(j,10) cout<<S[i][j];

	vector<ll> NN(N,0);

	rep(i,N)rep(j,10){

		NN[i]+=S[i][j]*pw27[9-j];

	}

	sort(NN.bg,NN.ed);

	//rep(i,N) cout<<NN[i]<<endl;;

	ll mem=NN[0],cnt=1,ans=0;

	rep1(i,N-1){

		if(NN[i]==mem) cnt++;

		else{

			ans+=cnt*(cnt-1)/2;

			mem=NN[i];

			cnt=1;

		}

	}

	ans+=cnt*(cnt-1)/2;;

	cout<<ans;

}	

// Faster C++ solution for the same problem (measured speedup: 3.534065076939927x):
#include<bits/stdc++.h>



using namespace std;

typedef long long ll;

typedef pair<ll,ll> P;

#define a first

#define b second

#define sz size()

#define pb(x) push_back(x) 

#define bg begin()

#define ed end()

#define rep(i,n) for(ll i=0;i<n;i++)

#define rep1(i,n) for(ll i=1;i<=n;i++)

#define mp(x,y) make_pair(x,y)

const ll MOD=1000000007;



vector<ll> pw27(10,1);

ll maxx(ll x,ll y,ll z){return max(max(x,y),z);}

ll minn(ll x,ll y,ll z){return min(min(x,y),z);}

ll mid(ll x,ll y,ll z){return x>y?y>=z?y:min(z,x):x>=z?x:min(y,z);}

ll gcd(ll x,ll y){if(x%y==0) return y;else return gcd(y,x%y);}

ll lcm(ll x,ll y){return x*(y/gcd(x,y));}

ll myceil(ll x,ll y){if(x<=y) return 1;else if(x%y==0) return x/y;else return x/y+1;}



//a,b x

int main(){

	rep1(i,9) pw27[i]=27*pw27[i-1];

	ll N; cin>>N;

	vector<ll> NN(N,0);

	rep(i,N){

		string t; cin>>t;

		vector<ll> tmp(10);

		rep(j,10){

			tmp[j]=t[j]-'a'+1;

		}

		sort(tmp.bg,tmp.ed);

		rep(j,10) NN[i]+=pw27[j]*tmp[j];

	}

	sort(NN.bg,NN.ed);

	ll mem=0,cnt=0,ans=0;

	rep(i,N){

		if(mem!=NN[i]){

			mem=NN[i];

			ans+=cnt*(cnt-1)/2;

			cnt=1;

		}

		else cnt++;



		if(i==N-1) ans+=cnt*(cnt-1)/2;

	}

	cout<<ans;

}
// Slower C++ solution:
#include<bits/stdc++.h>



using namespace std;

typedef long long ll;

typedef pair<ll,ll> P;

#define a first

#define b second

#define sz size()

#define pb(x) push_back(x) 

#define bg begin()

#define ed end()

#define rep(i,n) for(ll i=0;i<n;i++)

#define rep1(i,n) for(ll i=1;i<=n;i++)

#define mp(x,y) make_pair(x,y)

const ll MOD=1000000007;



vector<ll> pw27(11,1);

ll maxx(ll x,ll y,ll z){return max(max(x,y),z);}

ll minn(ll x,ll y,ll z){return min(min(x,y),z);}

ll mid(ll x,ll y,ll z){return x>y?y>=z?y:min(z,x):x>=z?x:min(y,z);}

ll gcd(ll x,ll y){if(x%y==0) return y;else return gcd(y,x%y);}

ll lcm(ll x,ll y){return x*(y/gcd(x,y));}

ll myceil(ll x,ll y){if(x<=y) return 1;else if(x%y==0) return x/y;else return x/y+1;}



//a,b x

int main(){

	rep1(i,10) pw27[i]=27*pw27[i-1];

	ll N; cin>>N;

	vector<ll> S[100000];

	rep(i,N){

		string tmp; cin>>tmp;

		rep(j,10){

			ll TMP=tmp[j]-'a'+1;

			S[i].pb(TMP);

		}

	}

	rep(i,N){

		sort(S[i].bg,S[i].ed);

	}

	//rep(i,N)rep(j,10) cout<<S[i][j];

	vector<ll> NN(N,0);

	rep(i,N)rep(j,10){

		NN[i]+=S[i][j]*pw27[9-j];

	}

	sort(NN.bg,NN.ed);

	//rep(i,N) cout<<NN[i]<<endl;;

	ll mem=NN[0],cnt=1,ans=0;

	rep1(i,N-1){

		if(NN[i]==mem) cnt++;

		else{

			ans+=cnt*(cnt-1)/2;

			mem=NN[i];

			cnt=1;

		}

	}

	ans+=cnt*(cnt-1)/2;;

	cout<<ans;

}	

// Faster C++ solution for the same problem (measured speedup: 3.528781594376348x):
#include<bits/stdc++.h>



using namespace std;

typedef long long ll;

typedef pair<ll,ll> P;

#define a first

#define b second

#define sz(x) (ll)((x).size())

#define pb push_back

#define mp make_pair 

#define bg begin()

#define ed end()

#define all(x) (x).bg,(x).ed

#define rep(i,n) for(ll i=0;i<n;i++)

#define rep1(i,n) for(ll i=1;i<=n;i++)

#define rrep(i,n) for(ll i=n-1;i>=0;i--)

#define rrep1(i,n) for(ll i=n;i>=1;i--)

#define FOR(i,a,b) for(ll i=a;i<b;i++)



int main(){

	ll N; cin>>N;

    map<string,ll> m;

    ll ans=0;

    rep(i,N){

        string tmp; cin>>tmp;

        sort(all(tmp));

        m[tmp]++;

    }

    for(auto it=m.bg;it!=m.ed;it++){

        ll x=it->b;

        ans+=x*(x-1)/2;

    }

    cout<<ans;

}
// Slower C++ solution:
#include<bits/stdc++.h>



using namespace std;

typedef long long ll;

typedef pair<ll,ll> P;

#define a first

#define b second

#define sz size()

#define pb(x) push_back(x) 

#define bg begin()

#define ed end()

#define rep(i,n) for(ll i=0;i<n;i++)

#define rep1(i,n) for(ll i=1;i<=n;i++)

#define mp(x,y) make_pair(x,y)

const ll MOD=1000000007;



vector<ll> pw27(11,1);

ll maxx(ll x,ll y,ll z){return max(max(x,y),z);}

ll minn(ll x,ll y,ll z){return min(min(x,y),z);}

ll mid(ll x,ll y,ll z){return x>y?y>=z?y:min(z,x):x>=z?x:min(y,z);}

ll gcd(ll x,ll y){if(x%y==0) return y;else return gcd(y,x%y);}

ll lcm(ll x,ll y){return x*(y/gcd(x,y));}

ll myceil(ll x,ll y){if(x<=y) return 1;else if(x%y==0) return x/y;else return x/y+1;}



//a,b x

int main(){

	rep1(i,10) pw27[i]=27*pw27[i-1];

	ll N; cin>>N;

	vector<ll> S[100000];

	rep(i,N){

		string tmp; cin>>tmp;

		rep(j,10){

			ll TMP=tmp[j]-'a'+1;

			S[i].pb(TMP);

		}

	}

	rep(i,N){

		sort(S[i].bg,S[i].ed);

	}

	//rep(i,N)rep(j,10) cout<<S[i][j];

	vector<ll> NN(N,0);

	rep(i,N)rep(j,10){

		NN[i]+=S[i][j]*pw27[9-j];

	}

	sort(NN.bg,NN.ed);

	//rep(i,N) cout<<NN[i]<<endl;;

	ll mem=NN[0],cnt=1,ans=0;

	rep1(i,N-1){

		if(NN[i]==mem) cnt++;

		else{

			ans+=cnt*(cnt-1)/2;

			mem=NN[i];

			cnt=1;

		}

	}

	ans+=cnt*(cnt-1)/2;;

	cout<<ans;

}	

// Faster C++ solution for the same problem (measured speedup: 3.522239157028075x):
#include<iostream>

#include<vector>

#include<string>

#include<algorithm>

#include<cmath>

#include<bitset>

#include<deque>

#include<functional>

#include<iterator>

#include<map>

#include<set>

#include<stack>

#include<queue>

#include<utility>

using namespace std;

typedef long long ll;

typedef pair<ll,ll> P;

#define a first

#define b second

#define sz(x) (ll)((x).size())

#define pb push_back

#define mp make_pair

#define bg begin()

#define ed end()

#define all(x) (x).bg,(x).ed

#define rep(i,n) for(ll i=0;i<(n);i++)

#define rep1(i,n) for(ll i=1;i<=(n);i++)

#define rrep(i,n) for(ll i=(n)-1;i>=0;i--)

#define rrep1(i,n) for(ll i=(n);i>=1;i--)

#define FOR(i,a,b) for(ll i=(a);i<(b);i++)

const ll MOD=1000000007;

const ll INF=1000000000000000;

template<class T> inline bool chmin(T& a, T b){if(a>b){a=b;return true;}return false;}

template<class T> inline bool chmax(T& a, T b){if(a<b){a=b;return true;}return false;}

ll maxx(ll x,ll y,ll z){return max(max(x,y),z);}

ll minn(ll x,ll y,ll z){return min(min(x,y),z);}

ll gcd(ll x,ll y){if(x%y==0) return y;else return gcd(y,x%y);}

ll lcm(ll x,ll y){return x*(y/gcd(x,y));}

ll digsz(ll x){if(x==0) return 1;else{ll ans=0;while(x){x/=10;ans++;}return ans;}}

ll digsum(ll x){ll sum=0;while(x){sum+=x%10;x/=10;}return sum;}

vector<ll> pw2(62,1);vector<ll> pw10(19,1);





int main(){

    {rep1(i,61) pw2[i]=2*pw2[i-1];}

    {rep1(i,18) pw10[i]=10*pw10[i-1];}

    ll N; cin>>N;

    ll ans=0;

    vector<string> S(N);

    rep(i,N) cin>>S[i];

    rep(i,N){

        sort(all(S[i]));

    }

    map<string,ll> m;

    rep(i,N){

        m[S[i]]++;

    }

    

    for(auto x:m){

        ans+=(x.b)*(x.b-1)/2;

    }

    cout<<ans<<endl;

}
// Slower C++ solution:
#include<bits/stdc++.h>

using namespace std;

#define int long long

#define rep(i,n) for(int i=0;i<(n);++i)

template<class T> inline bool chmin(T& a, T b) { if (a > b) { a = b; return true; } return false; }

int N,ans=0,tmp=1;

string s[100000+10];



signed main(){

  cin >> N;

  rep(i,N){

    string S;

    cin >> S;

    sort(S.begin(),S.end());

    s[i]=S;

    //cout << s[i] << endl;

  }

  sort(s,s+N);

  //rep(i,N) cout << s[i] << endl;

  rep(i,N-1){

    if(s[i]==s[i+1]){

      tmp++;

    }

    else{

      for(int j=tmp-1;j>=1;j--) ans+=j;

      tmp=1;

    }

  }

  //cout << tmp << endl;

  for(int j=tmp-1;j>=1;j--) ans+=j;

  tmp=1;

  cout << ans << endl;

  return 0;

}


// Faster C++ solution for the same problem (measured speedup: 4.319086609143878x):
//default

#include<bits/stdc++.h>

using namespace std;

#define int long long

#define double long double

typedef pair<int, int> P_i;

typedef pair<double,double> P_d;

#define rep(i,n) for(int i=0;i<(n);++i)

#define alrep(i,j,n) for(int i=0;i<(n);++i)for(int j=i+1;j<(n);++j)

#define Yes cout << "Yes" << endl;

#define No cout << "No" << endl;

int ans=0;

#define answer cout << ans << endl;

template<class T> inline bool chmin(T& a, T b) { if (a > b) { a = b; return true; } return false; }

template<class T> inline bool chmax(T& a, T b) { if (a < b) { a = b; return true; } return false; }

const int MOD=1e9+7;

const long long INF = 1LL << 60;



map<string,int> mp;



signed main(){

  int N;

  cin >> N;

  rep(i,N){

    string s;

    cin >> s;

    sort(s.begin(),s.end());

    mp[s]++;

  }

  for(auto p:mp){

    ans+=p.second*(p.second-1)/2;

  }

  answer

  return 0;

}
// Slower C++ solution:
#include<bits/stdc++.h>



using namespace std;

#define REPP(i,a,b,c) for(int i=a; i<=b; i+=c)

#define REP(i,a,b) REPP(i,a,b,1)

#define REVV(i,a,b,c) for(int i=a; i>=b; i-=c)

#define REV(i,a,b) REVV(i,a,b,1)

#define FOR(i,a) REP(i,0,(int)a-1)

#define FORD(i,a) REV(i,(int)a-1,0)

#define PB push_back

#define POB pop_back

#define MP make_pair

#define FI first

#define SE second

typedef long long ll;

typedef unsigned long long ull;

typedef pair < int , int > pii;

typedef vector < int > vi;

typedef vector < pii > vii;

typedef vector < ll > vl;



const double EPS = 1e-9;

const double PI = acos(-1);

const int INF = 1e9;

const ll MOD = 1e9 + 7;



ll addMod(ll a, ll b){

	return (a+b) % MOD;

}



ll mulMod(ll a, ll b){

	return (a*b) % MOD;

}



ll fast(ll a, ll b){

	if(b == 0) return 1;

	ll tmp = fast(a,b/2);

	tmp = mulMod(tmp, tmp);

	if(b & 1) tmp = mulMod(tmp, a);

	return tmp;

}



/////////////////////////////////////////////////////////



const int N = 1e5;



int n;

string str[N+5];





ll solve(){

	ll ret = 0, sz = 0;

	int bef = 0;

	FOR(i,n){

		if(str[i] != str[bef]){

			ret += sz * (sz - 1) / 2;

			bef = i;

			sz = 0;

		}

		sz++;

	}

	ret += sz * (sz - 1) / 2;

	return ret;

}



int main(){

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

	cin >> n;

	FOR(i,n){

		cin >> str[i];

		sort(str[i].begin(), str[i].end());

	}

	sort(str,str+n);

	cout << solve() << endl;

	return 0;

}

// Faster C++ solution for the same problem (measured speedup: 4.293893810571066x):
#include        <map>

#include      <cmath>

#include      <queue>

#include     <string>

#include     <cstdio>

#include     <vector>

#include    <cstring>

#include   <iostream>

#include  <algorithm>

using namespace std;

#define ll long long

const ll inf = 0x3f3f3f3f;

const int maxn = 1e5+5;

const ll mod = 1e9+7;



int main(){

    int n;

    string s;

    map<string,int>M;

    std::ios::sync_with_stdio(false);

    cin>>n;



    for(int i=0;i<n;i++){



        cin>>s;

        sort(s.begin(),s.end());

        M[s]++;

    }

    ll ans = 0;

    for(map<string,int>::iterator its=M.begin();its!=M.end();its++){

        ll t = (*its).second;

        ans += (t-1)*t/2;

    }

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

    return 0;

}
// Slower C++ solution:
#include<bits/stdc++.h>



using namespace std;

#define REPP(i,a,b,c) for(int i=a; i<=b; i+=c)

#define REP(i,a,b) REPP(i,a,b,1)

#define REVV(i,a,b,c) for(int i=a; i>=b; i-=c)

#define REV(i,a,b) REVV(i,a,b,1)

#define FOR(i,a) REP(i,0,(int)a-1)

#define FORD(i,a) REV(i,(int)a-1,0)

#define PB push_back

#define POB pop_back

#define MP make_pair

#define FI first

#define SE second

typedef long long ll;

typedef unsigned long long ull;

typedef pair < int , int > pii;

typedef vector < int > vi;

typedef vector < pii > vii;

typedef vector < ll > vl;



const double EPS = 1e-9;

const double PI = acos(-1);

const int INF = 1e9;

const ll MOD = 1e9 + 7;



ll addMod(ll a, ll b){

	return (a+b) % MOD;

}



ll mulMod(ll a, ll b){

	return (a*b) % MOD;

}



ll fast(ll a, ll b){

	if(b == 0) return 1;

	ll tmp = fast(a,b/2);

	tmp = mulMod(tmp, tmp);

	if(b & 1) tmp = mulMod(tmp, a);

	return tmp;

}



/////////////////////////////////////////////////////////



const int N = 1e5;



int n;

string str[N+5];





ll solve(){

	ll ret = 0, sz = 0;

	int bef = 0;

	FOR(i,n){

		if(str[i] != str[bef]){

			ret += sz * (sz - 1) / 2;

			bef = i;

			sz = 0;

		}

		sz++;

	}

	ret += sz * (sz - 1) / 2;

	return ret;

}



int main(){

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

	cin >> n;

	FOR(i,n){

		cin >> str[i];

		sort(str[i].begin(), str[i].end());

	}

	sort(str,str+n);

	cout << solve() << endl;

	return 0;

}

// Faster C++ solution for the same problem (measured speedup: 4.285157250220137x):
/*g++ main.cpp -o main.out*/

/*./main.out*/



#include<bits/stdc++.h>

using namespace std;



#define LL long long

#define LD long double

#define Mod 1000000007

#define L_Mod 17100000013



const double eps = 1e-9;

const int INF = 0x3f3f3f3f;

const double PI = 3.1415926535;



#define NO_TLE std::ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);



#define ree(a,n) memset(a,n,sizeof(a));



#define rep(i,n) for(int (i)=0;(i)<(int)(n);++(i))

#define rer(i,l,u) for(int (i)=(int)(l);(i)<=(int)(u);++(i))

#define red(i,l,u) for(int (i)=(int)(l);(i)>=(int)(u);--(i))



map<string,LL>m;

string t;







int main()

{

    NO_TLE

    int n;

    cin>>n;

    LL ans=0;

    rep(i,n)

    {

        cin>>t;

        sort(t.begin(),t.end());

        m[t]++;

    }

    for(map<string,LL>::iterator i=m.begin();i!=m.end();++i)

    {

        LL tmp=i->second;

        //int f=1;

        if(tmp%2==0)ans+=(tmp/2)*(tmp-1);

        else ans+=((tmp-1)/2)*tmp;

    }

        cout<<ans<<endl;

    return 0;

}
// Slower C++ solution:
#include<bits/stdc++.h>



using namespace std;

#define REPP(i,a,b,c) for(int i=a; i<=b; i+=c)

#define REP(i,a,b) REPP(i,a,b,1)

#define REVV(i,a,b,c) for(int i=a; i>=b; i-=c)

#define REV(i,a,b) REVV(i,a,b,1)

#define FOR(i,a) REP(i,0,(int)a-1)

#define FORD(i,a) REV(i,(int)a-1,0)

#define PB push_back

#define POB pop_back

#define MP make_pair

#define FI first

#define SE second

typedef long long ll;

typedef unsigned long long ull;

typedef pair < int , int > pii;

typedef vector < int > vi;

typedef vector < pii > vii;

typedef vector < ll > vl;



const double EPS = 1e-9;

const double PI = acos(-1);

const int INF = 1e9;

const ll MOD = 1e9 + 7;



ll addMod(ll a, ll b){

	return (a+b) % MOD;

}



ll mulMod(ll a, ll b){

	return (a*b) % MOD;

}



ll fast(ll a, ll b){

	if(b == 0) return 1;

	ll tmp = fast(a,b/2);

	tmp = mulMod(tmp, tmp);

	if(b & 1) tmp = mulMod(tmp, a);

	return tmp;

}



/////////////////////////////////////////////////////////



const int N = 1e5;



int n;

string str[N+5];





ll solve(){

	ll ret = 0, sz = 0;

	int bef = 0;

	FOR(i,n){

		if(str[i] != str[bef]){

			ret += sz * (sz - 1) / 2;

			bef = i;

			sz = 0;

		}

		sz++;

	}

	ret += sz * (sz - 1) / 2;

	return ret;

}



int main(){

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

	cin >> n;

	FOR(i,n){

		cin >> str[i];

		sort(str[i].begin(), str[i].end());

	}

	sort(str,str+n);

	cout << solve() << endl;

	return 0;

}

// Faster C++ solution for the same problem (measured speedup: 4.350148398127069x):
#include<bits/stdc++.h>

#include<algorithm>

using namespace std;

int main(){

 long long int i,j,n,m,ans=0;

 map<string,int> p;

 string s;

 cin>>n;

 while(n--){

    cin>>s;

    sort(s.begin(),s.end());

    ans+=p[s]++;

 }

 cout<<ans;

}
// Slower C++ solution:
#include<bits/stdc++.h>



using namespace std;

#define REPP(i,a,b,c) for(int i=a; i<=b; i+=c)

#define REP(i,a,b) REPP(i,a,b,1)

#define REVV(i,a,b,c) for(int i=a; i>=b; i-=c)

#define REV(i,a,b) REVV(i,a,b,1)

#define FOR(i,a) REP(i,0,(int)a-1)

#define FORD(i,a) REV(i,(int)a-1,0)

#define PB push_back

#define POB pop_back

#define MP make_pair

#define FI first

#define SE second

typedef long long ll;

typedef unsigned long long ull;

typedef pair < int , int > pii;

typedef vector < int > vi;

typedef vector < pii > vii;

typedef vector < ll > vl;



const double EPS = 1e-9;

const double PI = acos(-1);

const int INF = 1e9;

const ll MOD = 1e9 + 7;



ll addMod(ll a, ll b){

	return (a+b) % MOD;

}



ll mulMod(ll a, ll b){

	return (a*b) % MOD;

}



ll fast(ll a, ll b){

	if(b == 0) return 1;

	ll tmp = fast(a,b/2);

	tmp = mulMod(tmp, tmp);

	if(b & 1) tmp = mulMod(tmp, a);

	return tmp;

}



/////////////////////////////////////////////////////////



const int N = 1e5;



int n;

string str[N+5];





ll solve(){

	ll ret = 0, sz = 0;

	int bef = 0;

	FOR(i,n){

		if(str[i] != str[bef]){

			ret += sz * (sz - 1) / 2;

			bef = i;

			sz = 0;

		}

		sz++;

	}

	ret += sz * (sz - 1) / 2;

	return ret;

}



int main(){

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

	cin >> n;

	FOR(i,n){

		cin >> str[i];

		sort(str[i].begin(), str[i].end());

	}

	sort(str,str+n);

	cout << solve() << endl;

	return 0;

}

// Faster C++ solution for the same problem (measured speedup: 4.344412597587648x):
#include<iostream>

#include<stdio.h>

#include<cstring>

#include<cmath>

#include<algorithm>

#include<map>

#define ll long long

using namespace std;

int main(){

	ll n, ans = 0;

	cin >> n;

	string s;

	map<string, ll> mp;

	for(int i = 0 ; i < n ; i++){

		cin >> s;

		sort(s.begin(), s.end());

		++mp[s];

	}

	map<string, ll>::iterator it;  

	for(it=mp.begin(); it!=mp.end(); it++){

		ans += (it->second) * (it->second - 1) / 2;

	}

	cout << ans << '\n';

	return 0;

}