Problem:
Score : 200 points

Problem Statement

We have sticks numbered 1, \cdots, N. The length of Stick i (1 \leq i \leq N) is L_i.

In how many ways can we choose three of the sticks with different lengths that can form a triangle?

That is, find the number of triples of integers (i, j, k) (1 \leq i < j < k \leq N) that satisfy both of the following conditions:

L_i, L_j, and L_k are all different.

There exists a triangle whose sides have lengths L_i, L_j, and L_k.

Constraints

1 \leq N \leq 100

1 \leq L_i \leq 10^9

All values in input are integers.

Input

Input is given from Standard Input in the following format:

N
L_1 L_2 \cdots L_N

Output

Print the number of ways to choose three of the sticks with different lengths that can form a triangle.

Sample Input 1

5
4 4 9 7 5

Sample Output 1

5

The following five triples (i, j, k) satisfy the conditions: (1, 3, 4), (1, 4, 5), (2, 3, 4), (2, 4, 5), and (3, 4, 5).

Sample Input 2

6
4 5 4 3 3 5

Sample Output 2

8

We have two sticks for each of the lengths 3, 4, and 5. To satisfy the first condition, we have to choose one from each length.

There is a triangle whose sides have lengths 3, 4, and 5, so we have 2 ^ 3 = 8 triples (i, j, k) that satisfy the conditions.

Sample Input 3

10
9 4 6 1 9 6 10 6 6 8

Sample Output 3

39

Sample Input 4

2
1 1

Sample Output 4

0

No triple (i, j, k) satisfies 1 \leq i < j < k \leq N, so we should print 0.

Solution in C# (Mono-csc 3.5.0) (judge verdict: Accepted)

namespace AtCoder
{
    using System;
    using System.Linq;
    using System.Collections.Generic;
    using System.IO;
    using System.Text;
    using System.Text.RegularExpressions;

    class Program
    {
        static void Main()
        {
            var n = int.Parse(System.Console.ReadLine());
            var input = System.Console.ReadLine().Split(' ').Select((x) => long.Parse(x)).ToArray();
            var ans = 0;
            if (n < 3)
            {
                Output(ans.ToString());
                return;
            }
            for (int i = 0; i < n; i++)
            {
                for (int j = i + 1; j < n; j++)
                {
                    for (int k = j + 1; k < n; k++)
                    {
                        var a = input[i];
                        var b = input[j];
                        var c = input[k];
                        if (a == b || b == c || c == a)
                        {
                            continue;
                        }
                        if (a + b <= c || a + c <= b || b + c <= a)
                        {
                            continue;
                        }
                        ans++;
                    }
                }
            }
            Output(ans.ToString());
        }
        private static void Output(string str)
        {
            var sw = new StreamWriter(Console.OpenStandardOutput()) { AutoFlush = false };
            Console.SetOut(sw);

            Console.WriteLine(str);

            Console.Out.Flush();
        }
    }
    static class Extentions
    {
        #region 拡張メソッド（string）

        public static string LeftB(this string stTarget, int iByteSize)
        {
            return MidB(stTarget, 1, iByteSize);
        }

        public static string MidB(this string stTarget, int iStart)
        {
            System.Text.Encoding hEncoding = System.Text.Encoding.GetEncoding("utf-8");
            byte[] bBytes = hEncoding.GetBytes(stTarget);

            return hEncoding.GetString(bBytes, iStart - 1, bBytes.Length - iStart + 1);
        }

        public static string MidB(this string stTarget, int iStart, int iByteSize)
        {
            System.Text.Encoding hEncoding = System.Text.Encoding.GetEncoding("utf-8");
            byte[] bBytes = hEncoding.GetBytes(stTarget);

            return hEncoding.GetString(bBytes, iStart - 1, iByteSize);
        }

        public static string RightB(this string stTarget, int iByteSize)
        {
            System.Text.Encoding hEncoding = System.Text.Encoding.GetEncoding("utf-8");
            byte[] bBytes = hEncoding.GetBytes(stTarget);

            return hEncoding.GetString(bBytes, bBytes.Length - iByteSize, iByteSize);
        }

        public static bool IsNullOrEmpty(this string str)
        {
            return string.IsNullOrEmpty(str);
        }

        /// <summary>
        /// カルチャに依存した比較、または大文字と小文字を区別しない比較などの序数による比較を指定できる Contains。
        /// </summary>
        /// <param name="value">対象文字列</param>
        /// <param name="partialValue">部分文字列</param>
        /// <param name="comparison">カルチャ、大文字と小文字の区別、および並べ替え規則を指定する StringComparison</param>
        /// <returns>一致する場合に true を返します。</returns>
        public static bool Contains(this string value, string partialValue, StringComparison comparison = 0)
        {
            return value.IndexOf(partialValue, comparison) >= 0;
        }

        public static bool IsNumeric(this string value)
        {
            return decimal.TryParse(value, out decimal d);
        }
        public static int ToInt32(this String number, int retValue = 0)
        {
            if (!number.IsNumeric()) return retValue;
            return int.Parse(number);
        }

        #endregion
    }
}
/*
 
        static void Main()
        {
            var input = System.Console.ReadLine().ToArray();
            var a = input[0];
            var b = input[1];
            var c = input[2];
            var rain = 0;
            if (a == 'R') rain++;
            if (b == 'R') rain++;
            if (c == 'R') rain++;
            if (rain > 0 && b != 'R') rain--;

            Output(rain.ToString());
        }
*/
/*
    using System;
    using System.Collections.Generic;
    using System.Linq;

    // 整数の入力========================================
    string[] input = Console.ReadLine().Split(' ');
    int a = int.Parse(input[0]);
    int b = int.Parse(input[1]);
    int c = int.Parse(Console.ReadLine());
    
    //配列操作========================================
    var a = System.Console.ReadLine().Split(' ').Select((x) => long.Parse(x)).ToArray();

    int[] a = new int[n];
    for (int i = 0; i < n; i++)
    {
        a[i] = int.Parse(input2[i]);
    }
    
    Array.Sort(a);
    Array.Reverse(a);
    
    // 最小公倍数========================================
    public static decimal Lcm(decimal a, decimal b)
    {
        return a * b / Gcd(a, b);
    }

    // ユークリッドの互除法 ========================================
    public static decimal Gcd(decimal a, decimal b)
    {
        if (a < b)
        {
            // 引数を入替えて自分を呼び出す
            return Gcd(b, a);
        }
        while (b != 0)
        {
            var remainder = a % b;
            a = b;
            b = remainder;
        }
        return a;
    }

    //出力========================================
    Console.WriteLine("");


    var sb = new StringBuilder();
    for (int j = 0; j<n; j++)
    {
        sb.AppendLine(a[j].ToString());
    }
    var sw = new StreamWriter(Console.OpenStandardOutput()) { AutoFlush = false };
    Console.SetOut(sw);
    Console.WriteLine(sb.ToString());
    Console.Out.Flush();
*/