stablegradients/pie-gem5-bysrc huggingface dataset:
// Original C++ solution (slower):
#include <cstdio>

#include <cstring>

#include <cstdlib>

#include <iostream>

#include <algorithm>

using namespace std;

int n,m,a[2000];

int main()

{

while (1)

{

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

    if (n==0&&m==0) break;

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

    scanf("%d",&a[i]);

    int max1=-1;

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

    for (int j=1;j<=n;j++)

        if (i!=j)

    {

        if (a[i]+a[j]<=m&&a[i]+a[j]>max1)

            max1=a[i]+a[j];

    }

    if (max1==-1) printf("NONE\n"); else printf("%d\n",max1);



}



    return(0);

}




// Optimized solution to the same problem (faster):
#include<stdio.h>

#include<algorithm>

using namespace std;



int main()

{

    int m, n, a[1005];

    while(1)

    {

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

        if(n==0) return 0;



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

        {

            scanf("%d",a+i);

        }



        int maxsum=0;

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

            for(int j=i+1;j<=n;j++)

        {

            int sum=a[i]+a[j];

            if(sum>maxsum&&sum<=m)

            {

                maxsum=sum;

            }

        }

        if(maxsum==0) printf("NONE\n");

        else printf("%d\n",maxsum);

    }

}




// Fastest known solution for this problem:
// Original C++ solution (slower):
#include<cstdio>

#include<set>

#include<algorithm>

using namespace std;

const int maxn = 1e3 + 5;

int a[maxn];

int n, m;

set<int>s;



int main() {

	while (scanf("%d %d", &n, &m)) {

		s.clear();

		if (n == 0 && m == 0)break;

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

			scanf("%d", &a[i]);

		}

		int max = 0;

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

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

				if(i!=j) s.insert(a[i] + a[j]);

			}

		}

		//set<int>::iterator it = s.upper_bound(m);

		bool flag = false;

		for (set<int>::iterator it = --s.end(); it != s.begin(); it--) {

			if (*it <= m) {

				printf("%d\n", *it);

				flag = true;

				break;

			}

		}

		if (!flag) {

			if (*s.begin() <= m) printf("%d\n", *s.begin());

			else printf("NONE\n");

		}

	}

	return 0;

}


// Optimized solution to the same problem (faster):
#include<cstdio>



int a[1005];



int main()

{

    int n, m;

    while(scanf("%d %d", &n, &m)){

        if(n == 0){

            return 0;

        }

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

            scanf("%d", &a[i]);

        }

        int ans = -1;

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

            for(int j = i + 1; j <= n; j++){

                if((a[i] + a[j]) <= m && (a[i] + a[j]) > ans){

                    ans = (a[i] + a[j]);

                }

            }

        }

        if(ans < 0){

            printf("NONE\n");

        }

        else{

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

        }

    }

}




// Fastest known solution for this problem:
// Original C++ solution (slower):
#include <bits/stdc++.h>

using namespace std;

int n, m;

int nums[1000+10];



int find(int L, int R, int vl)

{

	int l = L, r = R;

	int mid = 0;

	while(l < r)

	{

		mid = (l+r) / 2;

		if(nums[mid] < vl)

			l = mid+1;

		else

			r = mid;

	}

	return l;

}



int main()

{

	while(true)

	{

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

		if(!n && !m)

			break;

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

		{

			scanf("%d", &nums[i]);

		}

		sort(nums, nums+n);

		int ans = 0;

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

		{

			if(nums[i] >= m)

				continue;

//			int pos = lower_bound(nums, nums+n, m-nums[i]) - nums;

			int pos = find(0, n-1, m-nums[i]);

			for(int j = pos; j >= 0; j--)

			{

				if(m-nums[i] >= nums[j] && i != j)

				{

					pos = j;

					break;

				}

			}

			if(i == pos)

				break;

			int tmp = nums[pos];

			if(tmp+nums[i] <= m)

				ans = max(ans, nums[i]+tmp);

		}

		if(ans)

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

		else

			printf("NONE\n");

	}

	return 0;

}


// Optimized solution to the same problem (faster):
#include<cstdio>



int a[1005];



int main()

{

    int n, m;

    while(scanf("%d %d", &n, &m)){

        if(n == 0){

            return 0;

        }

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

            scanf("%d", &a[i]);

        }

        int ans = -1;

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

            for(int j = i + 1; j <= n; j++){

                if((a[i] + a[j]) <= m && (a[i] + a[j]) > ans){

                    ans = (a[i] + a[j]);

                }

            }

        }

        if(ans < 0){

            printf("NONE\n");

        }

        else{

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

        }

    }

}




// Fastest known solution for this problem:
// Original C++ solution (slower):
#include<stdio.h>

#include<iostream>

#include<algorithm>

#include<string>

#include<vector>

using namespace std;

typedef long long ll;

ll b[1000005];

int main()

{

	while(1)

    {

        ll a[1005];

        ll n,m;

        cin >> n>>m;

        if(n==0)break;

        for(ll i=0; i<n; i++)

        {

            cin>>a[i];

        }

        ll k=0;

        for(ll i=0; i<n; i++)

            for(ll j=0; j<n; j++)

            {

                if(i==j)b[k]=0;

                else if(a[i]+a[j]<=m)

                b[k]=a[i]+a[j];

                else b[k]=0;

                k++;

            }

        ll sum=0;

        for(ll i=0; i<k; i++)

        {

            sum=max(b[i],sum);

        }

        if(sum==0)cout<<"NONE"<<endl;

        else cout<<sum<<endl;

    }

	return 0;

}








// Optimized solution to the same problem (faster):
#include<cstdio>



int a[1005];



int main()

{

    int n, m;

    while(scanf("%d %d", &n, &m)){

        if(n == 0){

            return 0;

        }

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

            scanf("%d", &a[i]);

        }

        int ans = -1;

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

            for(int j = i + 1; j <= n; j++){

                if((a[i] + a[j]) <= m && (a[i] + a[j]) > ans){

                    ans = (a[i] + a[j]);

                }

            }

        }

        if(ans < 0){

            printf("NONE\n");

        }

        else{

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

        }

    }

}




// Fastest known solution for this problem:
// Original C++ solution (slower):
#include <iostream>

#include <cstdio>

#include <cmath>

#include <algorithm>

#include <queue>



#define MAX_N 5000



using namespace std;



int N;

int E;

vector<int > in[MAX_N + 1];

vector<int > out[MAX_N + 1];

queue<int > S;

queue<int > L;



bool multi_flag;



bool in_exist(int v){

	bool flag = false;

	if(in[v].empty()) return false;

	for(int i = 0;i < in[v].size();i++){

		if(in[v][i] != -1) return true;

	}

	return false;

}



void solve(){

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

		if(in_exist(i) == false) S.push(i);

	}



	while(!S.empty()){

		int u = S.front();S.pop();

		L.push(u);

		int entered = 0;

		for(int i = 0;i < out[u].size();i++){

			int to = out[u][i];

			for(int i = 0;i < in[to].size();i++){

				if(in[to][i] == u) in[to][i] = -1;

			}

			

			if(in_exist(to) == false){

				S.push(to);

				entered++;

			}

		}

		if(entered >= 2) multi_flag = true;

	}



	return ;

}



int main(){



	scanf("%d",&N);

	scanf("%d",&E);

	//for(int i = 0;i <= MAX_N;i++){

	//	for(int j = 0;j <= MAX_N;j++){

	//		edge[i][j] = false;

	//	}

	//}

	int _u,_v;

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

		scanf("%d%d",&_u,&_v);

		in[_v].push_back(_u);

		out[_u].push_back(_v);

	}



	solve();



	while(!L.empty()){

		int team = L.front();L.pop();

		printf("%d\n",team);

	}

	if(multi_flag) puts("1");

	else puts("0");



	return 0;

}

// Optimized solution to the same problem (faster):
#include <iostream>

#include <cstdio>

#include <algorithm>

#include <stack>

#include <vector>



#define MAX_V 5000



using namespace std;



vector<int > G[MAX_V + 1];

bool visited[MAX_V + 1];



stack<int > L;

int ans[MAX_V];

int num;



int V,E;

bool single;



void init(){

	for(int i = 0;i <= MAX_V;i++) visited[i] = false;

	return ;

}



void count(int to,int cnt){

	//printf("###to = %d:cnt = %d\n",to,cnt);

	if(cnt == V - 1) single = true;

	for(int i = 0;i < G[to].size();i++){

		if(G[to][i] == ans[cnt + 1]) count(G[to][i],cnt + 1);

	}

	return ;

}



void visit(int to){

	//printf("###visited %d\n",to);

	if(!visited[to]){

		visited[to] = true;

		for(int i = 0;i < G[to].size();i++){

			int _to = G[to][i];

			visit(_to);

		}

		L.push(to);

		num++;

	}

	return ;

}



void solve(){

	init();

	for(int i = 1;i <= V;i++){

		visit(i);

	}

	single = false;

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

		ans[i] = L.top();L.pop();

	}

	count(ans[0],0);

	return ;

}



int main(){



	scanf("%d%d",&V,&E);

	int _u,_v;

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

		scanf("%d%d",&_u,&_v);

		G[_u].push_back(_v);

	}



	solve();

	

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

		printf("%d\n",ans[i]);

	}

	if(single)puts("0");

	else puts("1");



	return 0;

}

// Fastest known solution for this problem:
// Original C++ solution (slower):
#include<iostream>

#include<string>

#include<algorithm>

#include<string.h>

using namespace std;

#define ll long long

string a[100001];

int main()

{

	int n;

	cin>>n;

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

	{

		char b[11];

		cin>>b;

		sort(b,b+strlen(b));

		a[i]=b;

	}

	sort(a,a+n);

	ll count=0;

	ll sum=0;

	for(int i=0;i<n-1;i++)

	{

		if(a[i]==a[i+1])

		{

			count++;

		}

		else

		{

			if(count)

			{

				sum+=count*(count+1)/2;

			}

			count=0;

		}

	}

	if(count)

	{

		sum+=count*(count+1)/2;

	}

	cout<<sum<<endl;

	return 0;

} 

// Optimized solution to the same problem (faster):
#include <bits/stdc++.h>

using namespace std;

int main()

{

    long long int n, sum = 0;

    cin >> n;

    string s;

    map<string, long long int> mp;



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

    {

        cin >> s;

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

        mp[s]++;

    }



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

    {

        long long int s = it->second;

        sum += ((s) * (s - 1)) / 2;

    }

    cout << sum;

}

// Fastest known solution for this problem:
// Original C++ solution (slower):
#include<bits/stdc++.h>

using namespace std;

#define ll long long int

ll ar[500009],br[500009];

map<string,ll>mp;

int main()

{

    ll a,b,c,i,j,k=0,x=0;

    string s;

    cin>>a;

    getchar();

    for(i=1;i<=a;i++)

    {

        cin>>s;

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

        if(mp.find(s)==mp.end())

        {

            k++;

            mp[s]=k;

        }

        ar[mp[s]]++;

    }

    for(i=1;i<=100009;i++)

    {

        x=x+((ar[i]*(ar[i]-1))/2);

    }

    cout<<x;

}


// Optimized solution to the same problem (faster):
#include <bits/stdc++.h>



using namespace std;

char str[13];



int main() {

    //  freopen("in.txt", "rt", stdin);

    int n;

    scanf("%d", &n);

    map<string, int> mp;

    long long ans = 0;

    while (n--) {

        scanf("%s", str);

        sort(str, str + 10);

        ans += mp[string(str)]++;

    }

    printf("%lld", ans);

}

// Fastest known solution for this problem:
// Original C++ solution (slower):
#include <bits/stdc++.h>

using namespace std;



const int N = 1e5+5;

long long n, cntr = 0, ans = 0;

string s[N], temp;

vector<long long> v;



int main() {

	

	cin >> n;

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

		cin >> s[i];

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

	}

	

	sort(s, s+n);

	temp = s[0];

	cntr = 0;

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

		if(s[i] != temp){

			v.push_back(cntr);

			cntr = 0;

			temp = s[i];

		}

		cntr++;

	}

	v.push_back(cntr);

	

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

		

		if(v[i] == 2)	ans += 1;

		else if(v[i] == 3)	ans += 3;

		else if(v[i] > 3){ ans += v[i]*(v[i]-1)/2;}

		

		// cout << v[i] << " " << ans << endl;

	}

	cout << ans << endl;

	// for(int i = 0 ; i < n ; ++i)	cout << s[i] << " ";

	// puts("");

	// for(int i = 0 ; i < v.size() ; ++i)	cout << v[i] <<  " ";

	

	return 0;

}

// Optimized solution to the same problem (faster):
#include <bits/stdc++.h>

#define MAX 11000

#define ll long int

using namespace std;

 

 

int main() {

 

	map<string,int> mp;

	string s ;

	ll i,j,n,count=0,sum=0;

	

	cin >> n;

	

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

	{

		cin >> s;

		sort(s.rbegin(), s.rend(), greater<char>());

		count += mp[s]++;

	

	}

	

	cout << count;





	

 

}

// Fastest known solution for this problem:
// Original C++ solution (slower):
#include <bits/stdc++.h>

using namespace std;

const int N=2e5+5;

string A[N];

int n;

long long sum,mem[N];

long long fact(int i){

    if(!i) return 1;

    if(mem[i]!=-1) return mem[i];

    return mem[i]=fact(i-1)*i*1ll;

}

long long ans(int i){

if(i<=1) return 0;

if(i==2) return 1;

return fact(i)/(fact(i-2)*2);

}

long long spdAns(int i){

    if(i<=1) return 0;

    if(i==2) return 1;

    long long ret=1;

    ret=1ll*i*(i-1) / 2;

    return ret;

}

map<string,int> mp;

int main(){

    ios_base::sync_with_stdio(false);

    cin.tie(NULL);

    memset(mem,-1,sizeof mem);

    cin>>n;

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

        cin>>A[i];

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

        mp[A[i]]++;

    }

    long long ze=0;

    map<string,int>::iterator it = mp.begin();

    while(it!=mp.end()){

        

        ze+=spdAns(it->second);

        it++;

    }

    /*sort(A,A+n);

    int re=1;

    string cur=A[0];

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

       if(cur!=A[i]){

        sum+=ans(re);

      //  cout<<re<<endl;

        re=0;

        cur=A[i];

       }

       re++;

    }*/



    cout<<ze<<endl;

    return 0;

}


// Optimized solution to the same problem (faster):
#include <bits/stdc++.h>

#define MAX 11000

#define ll long int

using namespace std;

 

 

int main() {

 

	map<string,int> mp;

	string s ;

	ll i,j,n,count=0,sum=0;

	

	cin >> n;

	

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

	{

		cin >> s;

		sort(s.rbegin(), s.rend(), greater<char>());

		count += mp[s]++;

	

	}

	

	cout << count;





	

 

}

// Fastest known solution for this problem:
// Original C++ solution (slower):
#include <bits/stdc++.h>

using namespace std;



int main() {

  int n;

  cin >> n;

  

  string s;

  map<string, int> a;

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

    cin >> s;

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

    a[s]++;

  }

  

  int64_t ans = 0;

  vector<int64_t> memo(100001, -1);

  for(pair<string, int64_t> p : a) {

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

  }

  

  cout << ans << endl;

  return 0;

}

// Optimized solution to the same problem (faster):
#include <bits/stdc++.h>

using namespace std;



int main() {

  int n;

  cin >> n;

  

  string s;

  map<string, int> a;

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

    cin >> s;

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

    a[s]++;

  }

  

  int64_t ans = 0;

  for(pair<string, int64_t> p : a) {

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

  }

  

  cout << ans << endl;

  return 0;

}

// Fastest known solution for this problem:
// Original C++ solution (slower):
#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;

}


// Optimized solution to the same problem (faster):
#include<iostream>

#include<algorithm>

#include<map>



using namespace std;



typedef long long ll;



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];

	}

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

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

	}

	cout << ans << '\n';

	return 0;

}


// Fastest known solution for this problem:
// Original C++ solution (slower):
#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;

}


// Optimized solution to the same problem (faster):
#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;

}


// Fastest known solution for this problem:
// Original C++ solution (slower):
#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;

}

// Optimized solution to the same problem (faster):
#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;

}

// Fastest known solution for this problem:
// Original C++ solution (slower):
#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;

}	

// Optimized solution to the same problem (faster):
#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;

}

// Fastest known solution for this problem:
// Original C++ solution (slower):
#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;

}


// Optimized solution to the same problem (faster):
//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;

}


// Fastest known solution for this problem: