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# (.NET Core 3.1.201) (judge verdict: Wrong Answer)

using System;
using System.Text;
using System.Collections.Generic;
using System.Collections;
using static System.Math;
using System.Linq;
using static System.Array;

namespace ConsoleApp2
{
    public static class StringExtensions
    {
        public static string ToTitleCase(this string self)
        {
            return System.Globalization.CultureInfo.CurrentCulture.TextInfo.ToTitleCase(self);
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            //var N = long.Parse(Console.ReadLine());
            Solve();
            
        }
        static long N;
        static long[] A;
        static void Solve()
        {
            N = long.Parse(Console.ReadLine());
            A = Console.ReadLine().Split(' ').Select(x => long.Parse(x)).ToArray();
            var ans = true;
            var low = 0L;
            var high = A.Max() * N;
            var mid = 0L;
            while(low + 1 < high)
            {
                mid = (low + high) / 2;
                if (Check(mid) > 2)
                {
                    high = mid;
                }
                else
                {
                    low = mid;
                }
            }

            var max = mid;
            low = 0L;
            high = A.Max() * N;

            while (low+1 < high)
            {
                mid = (low + high) / 2;
                if (Check(mid) >= 2)
                {
                    high = mid;
                }
                else
                {
                    low = mid;
                }
            }
            var min = mid;
            if (min <= max)
            {
                Console.WriteLine(min +" "+max);
            }
            else
            {
                Console.WriteLine(-1);
            }
            

        }

        static long Check(long inp)
        {
            for (int i = 0; i < N; i++)
            {
                inp = inp - inp % A[i];
            }

            return inp;
        }

        class Treap<T> : IEnumerable<T> where T : IComparable
        {
            public int Length
            {
                get { return this.Root == null ? 0 : this.NodeCount(this.Root); }
            }
            public T this[int i]
            {
                get
                {
                    if (this.Root.Count < i - 1) throw new IndexOutOfRangeException();
                    return this.Root.Get(i);
                }
            }
            public Node Root;
            private IComparer<T> Cmp = Comparer<T>.Default;
            public Treap(IComparer<T> cmp = null)
            {
                if (cmp != null) this.Cmp = cmp;
            }
            public Node Merge(Node l, Node r)
            {
                if (l == null || r == null) return l == null ? r : l;

                if (l.Priority > r.Priority)
                {
                    l.R = this.Merge(l.R, r);
                    return this.Update(l);
                }
                else
                {
                    r.L = this.Merge(l, r.L);
                    return this.Update(r);
                }
            }
            // 左にk個、右に残り(n-k)個に分割する
            public (Node, Node) Split(int k) { return this.Split(this.Root, k); }
            public (Node, Node) Split(Node t, int k)
            {
                if (t == null) return (null, null);
                if (k <= this.NodeCount(t.L))
                {
                    var s = this.Split(t.L, k);
                    t.L = s.Item2;
                    return (s.Item1, this.Update(t));
                }
                else
                {
                    var s = this.Split(t.R, k - this.NodeCount(t.L) - 1);
                    t.R = s.Item1;
                    return (this.Update(t), s.Item2);
                }
            }
            public int NodeCount(Node node)
            {
                return node == null ? 0 : node.Count;
            }
            public int LowerBouond(T value) { return this.LowerBouond(this.Root, value); }
            public int LowerBouond(Node node, T value)
            {
                if (node == null) return 0;
                if (this.Cmp.Compare(value, node.Value) <= 0)
                    return this.LowerBouond(node.L, value);
                else
                    return this.NodeCount(node.L) + 1 + this.LowerBouond(node.R, value);
            }
            public int UpperBound(T value) { return this.UpperBound(this.Root, value); }
            public int UpperBound(Node node, T value)
            {
                if (node == null) return 0;
                if (this.Cmp.Compare(value, node.Value) >= 0)
                    return this.NodeCount(node.L) + 1 + this.UpperBound(node.R, value);
                else
                    return this.UpperBound(node.L, value);
            }
            public int ValueCount(T value)
            {
                return this.UpperBound(value) - this.LowerBouond(value);
            }
            public void Insert(T value)
            {
                var sub = this.Split(this.Root, this.LowerBouond(value));
                var newNode = new Node(value);
                var merged = this.Merge(sub.Item1, newNode);
                this.Root = this.Merge(merged, sub.Item2);
            }
            public void Erase(T value)
            {
                if (this.ValueCount(value) == 0) return;
                var sub = this.Split(this.Root, this.LowerBouond(value));
                this.Root = this.Merge(sub.Item1, this.Split(sub.Item2, 1).Item2);
            }
            public void InsertAt(Node node, int k)
            {
                var sub = this.Split(this.Root, k);
                var merged = this.Merge(sub.Item1, node);
                this.Root = this.Merge(merged, sub.Item2);
            }
            public void InsertAt(T value, int k)
            {
                var node = new Node(value);
                var sub = this.Split(this.Root, k);
                var merged = this.Merge(sub.Item1, node);
                this.Root = this.Merge(merged, sub.Item2);
            }
            public Node EraseAt(int k)
            {
                var sub = this.Split(this.Root, k);
                var sub2 = this.Split(sub.Item2, 1);
                var res = sub2.Item1;
                this.Root = this.Merge(sub.Item1, sub2.Item2);
                return res;
            }
            public Node Update(Node node)
            {
                node.Count = this.NodeCount(node.L) + this.NodeCount(node.R) + 1;
                return node;
            }
            public class Node
            {
                private static Random Rand = new Random();
                public T Value;
                public Node L = null;
                public Node R = null;
                public int Count;
                public double Priority;
                public Node(T value, double priority)
                {
                    this.Value = value;
                    this.Priority = priority;
                    this.Count = 1;
                }
                public Node(T value) : this(value, Rand.NextDouble()) { }
                public T Get(int i) { return this.GetNode(i).Value; }
                public Node GetNode(int i)
                {
                    var lcount = 0;
                    if (this.L != null) lcount = this.L.Count;
                    if (lcount == i) return this;
                    else if (lcount < i) return this.R.GetNode(i - lcount - 1);
                    else return this.L.GetNode(i);
                }
            }
            public IEnumerator<T> GetEnumerator()
            {
                for (int i = 0; i < this.Length; i++) yield return this.Root.Get(i);
            }
            IEnumerator IEnumerable.GetEnumerator() { return this.GetEnumerator(); }
        }

    }

}