#include<bits/stdc++.h>
//#include <boost/multiprecision/cpp_int.hpp>
//using namespace boost::multiprecision;
#include <ext/pb_ds/assoc_container.hpp> // Common file
#include <ext/pb_ds/tree_policy.hpp> // Including tree_order_statistics_node_update
using namespace std;
using namespace __gnu_pbds;
#define PI                      3.1415926535897932384626
#define int                   long long int
//#define ll                      long long int
#define fi                      first
#define se                      second
#define pq                      priority_queue
#define pb                      push_back
#define pf                      pop_front
#define endl                    '\n'
#define all(x)                  x.begin(),x.end()
#define pii                     pair<int,int>
#define fill(x,y)               memset(x,y,sizeof(x));
#define fast                    ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
#define hash                    _H
#define lg                      long double         
#define vi                      std::vector<int>
#define vc                      std::vector<char> v;
#define mii                     map<int,int> 
#define SZ(x)                   ((int)x.size())
#define REP(i,a,b)               for(int i = a; i <= b; ++i)
#define fr(i,a,b)              for(int i = a; i < b; ++i)
#define trav(it,v)              for(auto it = v.begin(); it != v.end(); ++it)
#define ordered_set             tree <int, null_type,less<int>, rb_tree_tag,tree_order_statistics_node_update>
// find_by_order(x) ==> xth element in the set counting from 0
// order_of_key(x) ==> number of element strictly less than x

template<typename T> void println(T &x)                             {cout << x << endl;}
template<typename T> void prints(T &x)                              {cout << x << " ";}
template<typename T> void print(T &x)                               {cout << x;}    

template<typename T> void pv(std::vector<T> &v)                     {for(auto i:v) cout << i << " "; cout << endl;}
template<typename T> void pv1(std::vector<T> &v)                    {for(int i = 1; i < SZ(v); ++i) cout << v[i] << " "; cout << endl;}
template<typename T> void pvln(std::vector<T> &v)                   {for(auto i:v) cout << i << endl;}
template<typename T> void pvln1(std::vector<T> &v)                  {for(int i = 1; i < SZ(v); ++i) cout << v[i] << endl;}

template<typename T> void p_set(set<T> s)                           {for(auto i:s) cout << i << " "; cout << endl;}

template<typename T> void debug(std::vector<T> &v)                  {for(auto i:v) cerr << i <<" "; cerr << endl;}
template<typename T> void d2(T &v)                                  {cerr << v << endl;}


template<typename T> void in(std::vector<T> &v,int n)               {for(int i = 0; i < n; ++i) cin >> v[i];}
template<typename T> void in1(std::vector<T> &v,int n)              {for(int i = 1; i <= n; ++i) cin >> v[i];}

template<typename T> T pow(T a,T b, int m){T ans=1; while(b>0){ if(b%2==1) ans=(ans*a)%m; b/=2; a=(a*a)%m; } return ans%m; }
template<typename T> T InverseMod(T a,T m){return pow(a,m-2,m);}
template<typename T>int SquareDist(T a,T b){int x = abs(a.fi - b.fi),y = abs(a.se - b.se); return x*x + y*y;}


struct custom_hash {
    static uint64_t splitmix64(uint64_t x) {
        // http://xorshift.di.unimi.it/splitmix64.c
        x += 0x9e3779b97f4a7c15;
        x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9;
        x = (x ^ (x >> 27)) * 0x94d049bb133111eb;
        return x ^ (x >> 31);
    }

    size_t operator()(uint64_t x) const {
        static const uint64_t FIXED_RANDOM = chrono::steady_clock::now().time_since_epoch().count();
        return splitmix64(x + FIXED_RANDOM);
    }
};


void solve() {
    int n;
    cin >> n;
    int f[n][26];
    fill(f,0);
    map<string ,int > mp;
    fr(i,0,n) {
        string s;
        cin >> s;
        fr(j,0,s.length()) {
            f[i][s[j]-'a']++;
        }
        s = "";
        fr(j,0,26) {
            if(f[i][j] == 10)
                s += "10";
            else
                s += (char)('0' + f[i][j]);
        }
        mp[s]++;
    }
    int ans = 0;
    for(auto i:mp) {
        ans += (i.se*(i.se-1) / 2);
    }
    cout << ans << endl;
}  

int32_t main()
{
    //freopen("input.txt", "r", stdin);
    //freopen("output.txt", "w", stdout);
    fast;
    int t = 1;
    //cin >> t;
    while(t--)
        solve();
}

Measured memory_bytes: 34688