Problem:
Score : 500 points

Problem Statement

An adult game master and N children are playing a game on an ice rink.
The game consists of K rounds.
In the i-th round, the game master announces:

Form groups consisting of A_i children each!

Then the children who are still in the game form as many groups of A_i children as possible.
One child may belong to at most one group.
Those who are left without a group leave the game. The others proceed to the next round.
Note that it's possible that nobody leaves the game in some round.

In the end, after the K-th round, there are exactly two children left, and they are declared the winners.

You have heard the values of A_1, A_2, ..., A_K. You don't know N, but you want to estimate it.

Find the smallest and the largest possible number of children in the game before the start, or determine that no valid values of N exist.

Constraints

1 \leq K \leq 10^5

2 \leq A_i \leq 10^9

All input values are integers.

Input

Input is given from Standard Input in the following format:

K
A_1 A_2 ... A_K

Output

Print two integers representing the smallest and the largest possible value of N, respectively,
or a single integer -1 if the described situation is impossible.

Sample Input 1

4
3 4 3 2

Sample Output 1

6 8

For example, if the game starts with 6 children, then it proceeds as follows:

In the first round, 6 children form 2 groups of 3 children, and nobody leaves the game.

In the second round, 6 children form 1 group of 4 children, and 2 children leave the game.

In the third round, 4 children form 1 group of 3 children, and 1 child leaves the game.

In the fourth round, 3 children form 1 group of 2 children, and 1 child leaves the game.

The last 2 children are declared the winners.

Sample Input 2

5
3 4 100 3 2

Sample Output 2

-1

This situation is impossible.
In particular, if the game starts with less than 100 children, everyone leaves after the third round.

Sample Input 3

10
2 2 2 2 2 2 2 2 2 2

Sample Output 3

2 3

Solution in C# (Mono 4.6.2.0) (judge verdict: Wrong Answer)

using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;

namespace AGC020B
{
    class Program
    {
        public static void Solve(Input input)
        {
            var k = input.NextInt();
            var a = input.NextLong(k);

            long min = 2;
            long max = 2;
            foreach (var r in a.Reverse().Skip(1))
            {
                if (max < r * 2 - 1)
                {
                    max = r * 2 - 1;
                }
                else
                {
                    max = (max + r - 1) / r * r - 1;
                }

                var m = min * 2 - 1;
                if (r > m)
                {
                    Console.WriteLine(-1);
                    return;
                }

                // min以上で、rの倍数
                min = (min + r - 1) / r * r;
            }

            Console.WriteLine($"{min} {max}");
        }

        #region Main
        public static void Main(string[] args)
        {
            // 出力が少ないときはこれをセットする方が時間かかるけれど
            // そのときにTLEするのはアルゴリズムが悪いせいだし、まあ良しとする
            var needsFlushOutput = true;
            if (needsFlushOutput)
            {
                // 細かく出力しないようにする
                var sw = new StreamWriter(Console.OpenStandardOutput()) { AutoFlush = false };
                Console.SetOut(sw);
            }

            // 通常は引数無しで、ファイルから読み出したい場合はpath指定する
            var input = new Input();

            // 仮想的に標準入力をセットする
            // テスト入力したまま提出することがままあるので……
#if DEBUG
            input.SetText("6");
            input.SetText("3 3 9 5 3 2");
#endif

            Solve(input);

            Console.Out.Flush();
        }
        #endregion

        #region Competitive Template
#pragma warning disable CS0414
        static readonly int MOD = (int)1e9 + 7;
        static readonly int[] dx = { 1, 0, -1, 0 };
        static readonly int[] dy = { 0, 1, 0, -1 };
        /// <summary> 左上が原点 </summary>
        static readonly char[] dir = { 'R', 'U', 'L', 'D' };
#pragma warning restore CS0414

        public class Input
        {
            // 変な改行コードがたまに混じっているので、一応セパレート指定する
            // スペース単独指定の方がもちろん早い
            static readonly char[] separator = { ' ', '\r', '\n' };
            readonly StreamReader sr;
            readonly Queue<string> queue;

            /// <summary>
            /// 特定のファイルから読み出したい場合はpath指定する
            /// </summary>
            public Input(string path = "")
            {
                queue = new Queue<string>();

                if (string.IsNullOrEmpty(path)) { sr = new StreamReader(Console.OpenStandardInput()); }
                else { sr = new StreamReader(path); }
            }

            /// <summary>
            /// 入力予約
            /// </summary>
            public void SetText(IEnumerable<string> items)
            {
                foreach (var item in items)
                    SetText(item);
            }

            /// <summary>
            /// 入力予約
            /// </summary>
            public bool SetText(string s)
            {
                if (string.IsNullOrEmpty(s)) return false;

                foreach (var elem in s.Trim().Split(separator, StringSplitOptions.RemoveEmptyEntries))
                    queue.Enqueue(elem);

                return true;
            }

            /// <summary>
            /// 要素が存在するか
            /// </summary>
            public bool Any() => queue.Any() || Read();

            /// <summary>
            /// 内部queueに入力からの値をsplitして格納する
            /// </summary>
            bool Read()
            {
                if (!SetText(sr.ReadLine())) return false;

                if (!queue.Any()) return Read();

                return queue.Any();
            }

            /// <summary>
            /// 次のstringを一つ読み込む
            /// </summary>
            public string Next()
            {
                if (!queue.Any() && !Read()) return "";

                return queue.Dequeue();
            }

            /// <summary>
            /// 指定個数queueにたまるまでenqueueし続ける
            /// </summary>
            bool Accumulate(int n)
            {
                while (queue.Count() < n)
                    if (!Read()) return false;

                return true;
            }

            public int NextInt() => int.Parse(Next());
            public long NextLong() => long.Parse(Next());
            public double NextDouble() => double.Parse(Next());

            /// <summary>
            /// n個の要素をparseして、それぞれにoffsetをaddした配列を返す
            /// </summary>
            T[] NextT<T>(int n, T offset, Func<string, T> parse, Func<T, T, T> add)
            {
                if (!Accumulate(n)) return null;

                var a = new T[n];

                for (int i = 0; i < n; i++)
                    a[i] = add(parse(queue.Dequeue()), offset);

                return a;
            }

            public string[] Next(int n) => NextT(n, "", x => x, (x, y) => x);
            public int[] NextInt(int n, int offset = 0) => NextT(n, offset, int.Parse, (x, y) => x + y);
            public long[] NextLong(int n, long offset = 0) => NextT(n, offset, long.Parse, (x, y) => x + y);
            public double[] NextDouble(int n, double offset = 0.0) => NextT(n, offset, double.Parse, (x, y) => x + y);
        }

        static class Utils
        {
            public static T Max<T>(params T[] objs) => objs.Max();
            public static T Min<T>(params T[] objs) => objs.Min();

            /// <summary>
            /// vでfillされたT[d1][d2]配列を作成する
            /// </summary>
            public static T[][] Create2DArray<T>(int d1, int d2, T v)
            {
                return
                    Enumerable.Repeat(0, d1).Select(_ =>
                    Enumerable.Repeat(v, d2).ToArray()).ToArray();
            }

            /// <summary>
            /// vでfillされたT[d1][d2][d3]配列を作成する
            /// </summary>
            public static T[][][] Create3DArray<T>(int d1, int d2, int d3, T v)
            {
                return
                    Enumerable.Repeat(0, d1).Select(_ =>
                    Enumerable.Repeat(0, d2).Select(__ =>
                    Enumerable.Repeat(v, d3).ToArray()).ToArray()).ToArray();
            }
        }
        #endregion
    }
}