Parmida is a clever girl and she wants to participate in Olympiads this year. Of course she wants her partner to be clever too (although he's not)! Parmida has prepared the following test problem for Pashmak.

There is a sequence a that consists of n integers a1, a2, ..., an. Let's denote f(l, r, x) the number of indices k such that: l ≤ k ≤ r and ak = x. His task is to calculate the number of pairs of indicies i, j (1 ≤ i < j ≤ n) such that f(1, i, ai) > f(j, n, aj).

Help Pashmak with the test.

Input

The first line of the input contains an integer n (1 ≤ n ≤ 106). The second line contains n space-separated integers a1, a2, ..., an (1 ≤ ai ≤ 109).

Output

Print a single integer — the answer to the problem.

Examples

Input

7
1 2 1 1 2 2 1


Output

8


Input

3
1 1 1


Output

1


Input

5
1 2 3 4 5


Output

0

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.StringTokenizer;

/**
 *
 *
 * 3 2 3 5
 * -2 -1 4 -1 2 7 3
 *
 *
 * @author pttrung
 */
public class D {

    public static long MOD = 1000000007;
    public static int[][] dp;
    public static boolean second = false;

    public static void main(String[] args) throws FileNotFoundException {
        PrintWriter out;
        Scanner in = new Scanner();
        //out = new PrintWriter(new FileOutputStream(new File("output.txt")));
        out = new PrintWriter(System.out);
        int n = in.nextInt();
        int []data = new int[n];
        int []re = new int[n];
        int []other = new int[n];
        HashMap<Integer, Integer> map = new HashMap();
        for(int i = 0; i < n; i++){
            int v = in.nextInt();
            data[i] = v;
            if(map.containsKey(v)){
                re[i] = re[map.get(v)] + 1;                
            }else{
                re[i] = 1;
            }
            map.put(v, i);
        }
        map = new HashMap();
        for(int i = n - 1; i >= 0; i --){
            if(map.containsKey(data[i])){
                other[i] = other[map.get(data[i])] + 1;
            }else{
                other[i] = 1;
            }
            map.put(data[i], i);
        }
        long result = 0;
        FT tree = new FT(n + 1);
        for(int i = 0; i < n; i++){
            tree.update(other[i], 1);
        }
        for(int i = 0; i < n; i++){
            tree.update(other[i], -1);
            int val = tree.get(re[i] - 1);
            result += val;
        }
        out.println(result);
        
        
        out.close();
    }

    public static int cal(int index, Node cur) {
        if (cur == null) {
            return 1 - index;
        }
        int result = 1 - index;
        for (int i = 0; i < 26; i++) {
            if (cur.nxt[i] != null) {
                int val = cal(1 - index, cur.nxt[i]);
                if (val == index) {
                    result = index;
                }
                if (val == 1) {
                    second = true;
                }
            }
        }
        return result;
    }

    public static void insert(String val, int index, Node pa) {
        char c = val.charAt(index);
        int pos = c - 'a';
        if (pa.nxt[pos] == null) {
            pa.nxt[pos] = new Node(c);
        }
        if (index + 1 != val.length()) {
            insert(val, index + 1, pa.nxt[pos]);
        } else {
            pa.nxt[pos].end = true;
        }
    }

    public static class Node {

        char c;
        boolean end = false;
        Node[] nxt = new Node[26];

        public Node(char c) {
            this.c = c;
        }
    }

    public static boolean nextPer(int[] data) {
        int i = data.length - 1;
        while (i > 0 && data[i] < data[i - 1]) {
            i--;
        }
        if (i == 0) {
            return false;
        }
        int j = data.length - 1;
        while (data[j] < data[i - 1]) {
            j--;
        }
        int temp = data[i - 1];
        data[i - 1] = data[j];
        data[j] = temp;
        Arrays.sort(data, i, data.length);
        return true;
    }

    public static int digit(long n) {
        int result = 0;
        while (n > 0) {
            n /= 10;
            result++;
        }
        return result;
    }

    public static double dist(long a, long b, long x, long y) {
        double val = (b - a) * (b - a) + (x - y) * (x - y);
        val = Math.sqrt(val);
        double other = x * x + a * a;
        other = Math.sqrt(other);
        return val + other;








    }

    public static class Point implements Comparable<Point> {

        int x, y;

        public Point(int start, int end) {
            this.x = start;
            this.y = end;
        }

        @Override
        public int hashCode() {
            int hash = 5;
            hash = 47 * hash + this.x;
            hash = 47 * hash + this.y;
            return hash;
        }

        @Override
        public boolean equals(Object obj) {
            if (obj == null) {
                return false;
            }
            if (getClass() != obj.getClass()) {
                return false;
            }
            final Point other = (Point) obj;
            if (this.x != other.x) {
                return false;
            }
            if (this.y != other.y) {
                return false;
            }
            return true;
        }

        @Override
        public int compareTo(Point o) {
            return x - o.x;
        }
    }

    public static class FT {

        int[] data;

        FT(int n) {
            data = new int[n];
        }

        public void update(int index, int value) {
            while (index < data.length) {
                data[index] += value;
                index += (index & (-index));
            }
        }

        public int get(int index) {
            int result = 0;
            while (index > 0) {
                result += data[index];
                index -= (index & (-index));
            }
            return result;

        }
    }

    public static long gcd(long a, long b) {
        if (b == 0) {
            return a;
        }
        return gcd(b, a % b);
    }

    public static long pow(long a, long b) {
        if (b == 0) {
            return 1;
        }
        if (b == 1) {
            return a;
        }
        long val = pow(a, b / 2);
        if (b % 2 == 0) {
            return val * val % MOD;
        } else {
            return val * (val * a % MOD) % MOD;








        }
    }

    static class Scanner {

        BufferedReader br;
        StringTokenizer st;

        public Scanner() throws FileNotFoundException {
            // System.setOut(new PrintStream(new BufferedOutputStream(System.out), true));
            br = new BufferedReader(new InputStreamReader(System.in));
            //br = new BufferedReader(new InputStreamReader(new FileInputStream(new File("input.txt"))));
        }

        public String next() {

            while (st == null || !st.hasMoreTokens()) {
                try {
                    st = new StringTokenizer(br.readLine());
                } catch (Exception e) {
                    throw new RuntimeException();
                }
            }
            return st.nextToken();
        }

        public long nextLong() {
            return Long.parseLong(next());
        }

        public int nextInt() {
            return Integer.parseInt(next());
        }

        public double nextDouble() {
            return Double.parseDouble(next());
        }

        public String nextLine() {
            st = null;
            try {
                return br.readLine();
            } catch (Exception e) {
                throw new RuntimeException();
            }
        }

        public boolean endLine() {
            try {
                String next = br.readLine();
                while (next != null && next.trim().isEmpty()) {
                    next = br.readLine();
                }
                if (next == null) {
                    return true;
                }
                st = new StringTokenizer(next);
                return st.hasMoreTokens();
            } catch (Exception e) {
                throw new RuntimeException();
            }
        }
    }
}
