Problem:
Score : 500 points

Problem Statement

Given are N positive integers A_1,...,A_N.

Consider positive integers B_1, ..., B_N that satisfy the following condition.

Condition: For any i, j such that 1 \leq i < j \leq N, A_i B_i = A_j B_j holds.

Find the minimum possible value of B_1 + ... + B_N for such B_1,...,B_N.

Since the answer can be enormous, print the sum modulo (10^9 +7).

Constraints

1 \leq N \leq 10^4

1 \leq A_i \leq 10^6

All values in input are integers.

Input

Input is given from Standard Input in the following format:

N
A_1 ... A_N

Output

Print the minimum possible value of B_1 + ... + B_N for B_1,...,B_N that satisfy the condition, modulo (10^9 +7).

Sample Input 1

3
2 3 4

Sample Output 1

13

Let B_1=6, B_2=4, and B_3=3, and the condition will be satisfied.

Sample Input 2

5
12 12 12 12 12

Sample Output 2

5

We can let all B_i be 1.

Sample Input 3

3
1000000 999999 999998

Sample Output 3

996989508

Print the sum modulo (10^9+7).

Solution in C# (Mono 4.6.2.0) (judge verdict: Time Limit Exceeded)

using System;
using System.Collections.Generic;
using System.Linq;
using static Input;
using static Prog;
using NX = System.Int64;

public class Solver
{
    public void Solve()
    {
        int N = NextInt();
        NX[] A = LineLong();
        NX[] X = A.ToArray();

        HashSet<NX> prime = new HashSet<NX>();
        Dictionary<NX, NX>[] d = Enumerable.Range(0, N).Select(v => new Dictionary<NX, NX>()).ToArray();
        for (int i = 0; i < N; i++)
        {
            for (NX x = 2; x * x <= A[i]; x++)
            {
                if (A[i] % x == 0) d[i][x] = 0;
                else continue;
                while (A[i] % x == 0) { A[i] /= x; d[i][x]++; }
                if (!prime.Contains(x)) prime.Add(x);
            }
            if (A[i] != 1) { d[i][A[i]] = 1; if (!prime.Contains(A[i])) prime.Add(A[i]); }
        }

        NX LCM = 1;
        foreach (var p in prime)
        {
            NX x = 0;
            for (int i = 0; i < N; i++)
            {
                if (!d[i].ContainsKey(p)) continue;
                x = Math.Max(x, d[i][p]);
            }
            LCM *= RepPow(p, x);
            LCM %= MOD;
        }
        //Console.WriteLine(LCM);

        NX ans = 0;
        for (int i = 0; i < N; i++)
        {
            ans += LCM * RepPow(X[i], MOD - 2);
            ans %= MOD;
        }
        Console.WriteLine(ans);


        //for (int i = 0; i < N; i++)
        //{
        //    Console.Write(i + " :  ");
        //    foreach (var e in prime)
        //    {
        //        if (d[i].ContainsKey(e)) Console.Write("[" + e + "] " + d[i][e] + "  ");
        //    }
        //    Console.WriteLine();
        //}

    }
}

public class Prog
{
    public const long MOD = 1000000007;
    public const int INF = 1000000007;
    public struct Pair { public int x, y; public Pair(int a, int b) { x = a; y = b; } }
    public static long RepPow(long x, long p, long m = 1000000007)
    {
        if (p == 1) return x % m;
        long b = RepPow(x, p / 2, m) % m;
        if (p % 2 == 0) { return (b * b) % m; }
        else { return (x * ((b * b) % m)) % m; }
    }

    static void Main()
    {
        var sw = new System.IO.StreamWriter(Console.OpenStandardOutput()) { AutoFlush = false };
        Console.SetOut(sw);
        new Solver().Solve();
        Console.Out.Flush();
        return;
    }
}

public class Input
{
    private static Queue<string> q = new Queue<string>();
    private static void Confirm() { if (q.Count == 0) foreach (var s in Console.ReadLine().Split(' ')) q.Enqueue(s); }
    public static int NextInt() { Confirm(); return int.Parse(q.Dequeue()); }
    public static long NextLong() { Confirm(); return long.Parse(q.Dequeue()); }
    public static string NextString() { Confirm(); return q.Dequeue(); }
    public static double NextDouble() { Confirm(); return double.Parse(q.Dequeue()); }
    public static int[] LineInt() { return Console.ReadLine().Split(' ').Select(int.Parse).ToArray(); }
    public static long[] LineLong() { return Console.ReadLine().Split(' ').Select(long.Parse).ToArray(); }
    public static string[] LineString() { return Console.ReadLine().Split(' ').ToArray(); }
    public static double[] LineDouble() { return Console.ReadLine().Split(' ').Select(double.Parse).ToArray(); }
    public long Abs(long a, long b) => Math.Abs(a - b);
}