Dima got into number sequences. Now he's got sequence a1, a2, ..., an, consisting of n positive integers. Also, Dima has got a function f(x), which can be defined with the following recurrence:

  * f(0) = 0; 
  * f(2·x) = f(x); 
  * f(2·x + 1) = f(x) + 1. 



Dima wonders, how many pairs of indexes (i, j) (1 ≤ i < j ≤ n) are there, such that f(ai) = f(aj). Help him, count the number of such pairs. 

Input

The first line contains integer n (1 ≤ n ≤ 105). The second line contains n positive integers a1, a2, ..., an (1 ≤ ai ≤ 109).

The numbers in the lines are separated by single spaces.

Output

In a single line print the answer to the problem.

Please, don't use the %lld specifier to read or write 64-bit integers in C++. It is preferred to use the cin, cout streams or the %I64d specifier.

Examples

Input

3
1 2 4


Output

3


Input

3
5 3 1


Output

1

Note

In the first sample any pair (i, j) will do, so the answer is 3.

In the second sample only pair (1, 2) will do.
import java.io.*;
import java.util.*;


public class Main {

    public static void main(String[] args) throws IOException {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        InputReader in = new InputReader(inputStream);
        InputReader.OutputWriter out = new InputReader.OutputWriter(outputStream);


        TaskC taskB = new TaskC();
        taskB.solve(in,out);

        out.flush();
    }
}

class InputReader extends BufferedReader {
    StringTokenizer tokenizer;

    public InputReader(InputStream inputStream) {
        super(new InputStreamReader(inputStream), 32768);
    }

    public InputReader(String filename) {
        super(new InputStreamReader(Thread.currentThread().getContextClassLoader().getResourceAsStream(filename)));
    }

    public String next() {
        while (tokenizer == null || !tokenizer.hasMoreTokens()) {
            try {
                tokenizer = new StringTokenizer(readLine());
            } catch (IOException e) {
                throw new RuntimeException();
            }
        }
        return tokenizer.nextToken();
    }

    public Integer nextInt() {
        return Integer.valueOf(next());
    }
    public Long nextLong() {return  Long.valueOf(next());}

    static class OutputWriter extends PrintWriter {
        public OutputWriter(OutputStream outputStream) {
            super(outputStream);
        }

        public OutputWriter(Writer writer) {
            super(writer);
        }

        public OutputWriter(String filename) throws FileNotFoundException {
            super(filename);
        }

        public void close() {
            super.close();
        }
    }
}

class TaskA {
    public void solve(InputReader in, InputReader.OutputWriter out) {
        int n = in.nextInt();
        String s = in.next();
        int x = 0;
        int y = 0;
        HashMap<Point,Integer> map = new HashMap<>();
        Point[] points = new Point[n + 1];
        Point first = new Point(0,0);
        points[0] = first;
        for (int i = 0; i < s.length(); i++) {
            char current = s.charAt(i);
            if(current == 'R') {
                x++;
            }
            else if(current == 'L') {
                x--;
            }
            else if(current == 'U') {
                y++;
            }
            else {
                y--;
            }
            points[i + 1] = new Point(x,y);
        }
        int r = 0;
        int max = 0;
        int l = 0;
        out.println(Arrays.toString(points));
        HashSet<Point> sub = new HashSet<>();
        while (r < points.length) {
            while (sub.contains(points[r])) {
                sub.remove(points[l]);
                l++;
            }
            out.println(points[r] + " " + l);
            max = Math.max(max,r-l);
            sub.add(points[r]);
            r++;
        }
        out.println(max);
    }
}
class Point {
    private int x;
    private int y;

    public int getX() {
        return x;
    }

    public int getY() {
        return y;
    }
    public Point(int x,int y) {
        this.x = x;
        this.y = y;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Point point = (Point) o;
        return x == point.x &&
                y == point.y;
    }

    @Override
    public int hashCode() {
        return Objects.hash(x, y);
    }

    @Override
    public String toString() {
        return  x + " " + y;
    }
}
class TaskB {
    public void solve(InputReader in, InputReader.OutputWriter out) {
        int n = in.nextInt();
        int [] a = new int[n];
        for (int i = 0; i < a.length; i++) {
            a[i] = Math.abs(in.nextInt());
        }
        Arrays.sort(a);
        long count = 0;
        for (int i = 0; i < a.length; i++) {
            int index = binarySearch(a,i+1,a[i]);
            if(index<n) {
                count+=(long)(index - i);
            }
        }
        out.println(count);
    }
    private int binarySearch(int [] a, int index,int target) {
        int lo = index;
        int hi = a.length - 1;
        while (lo<=hi) {
            int med = lo + (hi-lo)/2;
            if(a[med] - target <= target) {
                lo = med + 1;
            }
            else hi = med  - 1;
        }
        return hi;
    }
}
class TaskC {
    public void solve(InputReader in, InputReader.OutputWriter out) {

        int n = in.nextInt();
        int [] a = new int[n];
        for (int i = 0; i < n; i++) {
            a[i] = in.nextInt();
        }
        HashMap<Integer,Integer> map = new HashMap<>();
        for (int i = 0; i < a.length; i++) {
            int count = f(a[i]);
            map.put(count,map.getOrDefault(count,0) + 1);
        }
        long answer = 0;
        for (Map.Entry<Integer,Integer> m : map.entrySet()) {
            long value = m.getValue();
            answer+=(value*(value-1))/2;
        }
        out.println(answer);


    }
    static int f(int n) {
        return Integer.bitCount(n);
    }
    static int lowerBound(long [] a, long target) {
        int lo = 0;
        int hi = a.length - 1;
        while (lo<=hi) {
            int med = lo + (hi-lo)/2;
            if(target == a[med]) return med;
            if(target > a[med]) lo = med + 1;
            else hi = med - 1;
        }
        return lo;
    }
    static boolean isPrime(int n) {
        if(n<2) return false;
        for(int i = 2;i*i<=n;i++) {
            if(n%i==0) return false;
        }
        return true;
    }

    static int binarySearch(int [] a, int target) {
        int lo = 0;
        int hi = a.length - 1;
        while (lo<=hi) {
            int med = lo + (hi-lo)/2;
            if(target>=a[med]) {
                lo = med + 1;
            }
            else {
                hi = med - 1;
            }
        }
        return hi;
    }
}
class Pair {
    int x;
    int y;

    public int getX() {
        return x;
    }

    public int getY() {
        return y;
    }
    public Pair(int x,int y) {
        this.x = x;
        this.y = y;
    }
}