// 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.28742936674393x):
/*	MASTER HAS FAILED MORE TIMES

	THAN BEGINNER HAS EVER TRIED

*/



#include <bits/stdc++.h>



using namespace std;



#define endl             '\n'

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

#define mem(a, n)        memset(a, n, sizeof(a))

#define Unique(n)        (n).erase(unique(all(n)), (n).end())

#define NumofDigits(n)   ((long long)log10(n)+1)

#define repeat(i, a, n)  for(int i=a; i<n; i++)

#define isPowerOfTwo(n)  (n && !(n & (n - 1)))



typedef long long ll;

typedef long double ld;



int sieve(int n);

unsigned long long pow(long long base, long long power);

long long gcd(long long a, long long b){ return a%b ? gcd(b, a%b) : b; }

long long lcm(long long a, long long b){ return a*b/gcd(a, b); }



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

void file(){

    #ifdef ONLINE_JUDGE

    freopen("input.txt", "r", stdin);

    freopen("output.txt", "w", stdout);

    #endif /*ONLINE_JUDGE*/

}



int main(){

    quicken();



    ll n, num=0; cin >> n;

    string arr[n];



    map<string, int> mp;

    repeat(i, 0, n){

        cin >> arr[i];

        sort(all(arr[i]));

        mp[arr[i]]++;

    }





    for(auto it:mp){

        pair<string, ll> p = it;

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

    }

    cout << num;



    return 0;

}



unsigned long long pow(long long base, long long power){ /// mod?

    if(power==0) return 1;

    if(power==1) return base;



    unsigned long long ans = pow(base, power/2); /// mod?

    ans *= ans; /// ((ans%mod)*(ans%mod))%mod;



    if(power&1) return ans*base; /// ((ans%mod)*(base%mod))%mod;

    return ans;

}



int sieve(int n){

    int c = 0;

    vector<bool> isPrime(n+1, true);

    isPrime[0] = isPrime[1] = 0;



    for(long long i=2; i*i<=n; i++)

        if(isPrime[i])

            for(long long j=i*2; j<=n; j+=i)

                isPrime[j] = 0;

    repeat(i, 0, n+1)

        if(isPrime[i]) c++;

    return c; /// primeCount [1:n]

}