using System;   
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;

class Program{

    const long MOD = (long)1e9 + 7;

    static void Main(string[] args)
    {
        // main ↓
        bool dekiru = true;
       long max = 2;
       long min = 2;
        int n = ScanOneInt();
        long[] k = ScanLongArray(n);
        for (int i = n - 1; i >= 0; i--)
        {
            if (min <= (min + k[i] - 1) / k[i] * k[i ]&& (min + k[i] - 1) / k[i] * k[i] <= max && 
                min <= max / k[i] * k[i] && max / k[i] * k[i] <= max)
            {
                min = (min + k[i] - 1) / k[i] * k[i];
                max = max / k[i] * k[i] + k[i] - 1;
            }
            else
            {
                dekiru = false;
            }
        }


        Console.WriteLine(dekiru ? (min + " " + max) : "-1");


        // main↑
    }

    public class SegmentTree<Monoid>
    {
        private bool debug = false;
        // 0-indexed SegmentTree
        public int size;
        Monoid[] segTree;
        Monoid unit;
        public SegmentTree(int inSize, Monoid unit)
        {
            this.unit = unit;
            size = 2;
            while (size < inSize) size *= 2;
            segTree = new Monoid[2 * size];
            for (int i = 0; i < segTree.Length; i++)
            {
                segTree[i] = unit;
                // 単位元なので全部に代入しておけばよい
            }
        }

        public int BinarySearch(int x)
        {
            int high = size;
            int low = 0;
            int mid = (high + low) / 2;
            while (low < high)
            {
                // Console.WriteLine(low + " " + high);
                Monoid cmp = NonRecursiveQuery(0, mid);
                // Console.WriteLine("[ 0, " + mid + " ] -> " + cmp);
                if ((dynamic)cmp >= x)
                {
                    high = mid;
                }
                else if ((dynamic)cmp < x)
                {
                    low = mid + 1;
                }
                mid = (high + low) / 2;
            }
            return mid;
        }

        public void set(int iter, Monoid val)
        {
            segTree[iter + size - 1] = val;
        }

        public Monoid GetMonoid(int index)
        {
            return segTree[index + size - 1];
        }

        public void add(int iter, Monoid val)
        {
            update(iter, (dynamic)segTree[iter + size - 1] + (dynamic)val);
        }

        public void build()
        {
            // 2段目より上の構築
            for (int k = size - 2; k >= 0; k--)
            {
                segTree[k] = F(segTree[2 * k + 1], segTree[2 * k + 2]);
            }
        }

        public Monoid F(Monoid m1, Monoid m2)
        {
            Monoid res = GCD(m1, m2);
            return res;
        }

        public Monoid Query(int ql, int qr, int index, int nl, int nr)
        {
            // Recursive
            // [ql, qr)について考える
            // index に対応する範囲 nl <= x <= nr
            if(nr <= ql || qr <= nl)
            {
                if (debug) Console.WriteLine("Out: [l , r), [" + nl + " ," + nr + "), " + "index: " + index + " ,unit:" + unit);
                return unit;
            }
            if(ql <= nl && nr <= qr)
            {
                if (debug) Console.WriteLine("All in [l , r): [" + nl + " ," + nr + "), " + "index: " + index + ",rangeAns:" + segTree[index]);
                return segTree[index];
            }
            else
            {
                Monoid vl = Query(ql, qr, index * 2 + 1, nl, (nl + nr) / 2);
                Monoid vr = Query(ql, qr, index * 2 + 2, (nl + nr) / 2, nr);
                if (debug) Console.WriteLine("Recursive: [l , r),+: [" + nl + ", " + nr + "), index->"+ index);
                if (debug) Console.WriteLine("(vl, vr): (" + vl + ", " + vr + ")");
                return F(vl, vr);
            }
        }

        public Monoid NonRecursiveQuery(int l,int r)
        {
            // 区間　-> [ l , r ]
            // 非再帰
            int L = l + size - 1;
            int R = r + size - 1;
            Monoid s = unit;
            while (L <= R)
            {
                if(L % 2 == 0)
                {
                    s = F(s, segTree[L]);
                    L++;
                }
                if(R % 2 == 1)
                {
                    s = F(s, segTree[R]);
                }
                L /= 2;
                R /= 2;
                R--;
            }
            return s;
        }

        public void update(int k, Monoid x)
        {
            k += size-1;
            segTree[k] = x;
            while (true)
            {
                k = (k - 1) / 2;
                segTree[k] = F(segTree[k * 2 + 1], segTree[k * 2 + 2]);
                if(k == 0)
                {
                    break;
                }
            }
        }

        public void print()
        {
            Console.Write("Print:");
            for (int i = 0; i < segTree.Length; i++)
            {
                Console.Write(segTree[i] + " ");
            }
            Console.WriteLine("");
        }

    }

    static int Nibutan(long[] array, long k)
    {
        int low = 0 ;
        int high = array.Length-1;
        int mid = high;

        while (low < high)
        {
            mid = (low + high) / 2;
            if(array[mid] >= k) // k以上の最小index.ココを変えるだけ
            {
                high = mid;
            }
            else
            {
                low = mid + 1;
            }
            mid = (low + high) / 2;
        }
        return mid;
    }   

    static int ScanOneInt()
    {
        return int.Parse(Console.ReadLine());
    }

    static long ScanOneLong()
    {
        return long.Parse(Console.ReadLine());
    }

    static string[] ScanStringArray(int lines)
    {
        string[] str = new string[lines];
        for (int i = 0; i < lines; i++)
        {
            str[i] = Console.ReadLine();
        }
        return str;
    }

    static int[] ScanIntArray(int t)
    {
        string[] str = Console.ReadLine().Split(' ');
        int[] ar = new int[t];
        for (int i = 0; i < t; i++)
        {
            ar[i] = int.Parse(str[i]);
        }
        return ar;
    }

    static string[] ScanStringArrayInOneLine(int t)
    {
        string[] str = Console.ReadLine().Split(' ');
        return str;
    }

    static Tuple<int,int> ScanTuple()
    {
        int[] tmp = ScanIntArray(2);
        return new Tuple<int, int>(tmp[0], tmp[1] * -1);
    }

    static long[] ScanLongArray(int t)
    {
        string[] str = Console.ReadLine().Split(' ');
        long[] ar = new long[t];
        for (int i = 0; i < t; i++)
        {
            ar[i] = long.Parse(str[i]);
        }
        return ar;
    }

    static double[] ScanDoubleArray(int t)
    {
        string[] str = Console.ReadLine().Split(' ');
        double[] ar = new double[t];
        for (int i = 0; i < t; i++)
        {
            ar[i] = double.Parse(str[i]);
        }
        return ar;
    }

    static int[,] ScanIntSquareArray(int h, int w)
    {
        int[,] resAr = new int[h, w];
        for (int i = 0; i < h; i++)
        {
            int[] ar = ScanIntArray(w);
            for (int j = 0; j < w; j++)
            {
                resAr[i, j] = ar[j];
            }
        }
        return resAr;
    }

    static int[,] CombModMake()
    {
        int[,] res = new int[2005, 2005];
        for (int i = 0; i < 2005; i++)
        {
            for (int j = 0; j < 2005; j++)
            {
                if (i == 0 || i < j)
                {
                    res[i, j] = 0;
                }
                else if (j == 0 || i == j)
                {
                    res[i, j] = 1;
                }
                else
                {
                    res[i, j] = (res[i - 1, j] + res[i - 1, j - 1]) % (int)MOD;
                }
            }
        }
        return res;
    }

    // int, long両方で出来るGCDを作った
    static T GCD<T>(T a, T b)
    {
        if((dynamic)b == 0)
        {
            return a;
        }
        else
        {
            return GCD((dynamic)b, (dynamic)a % (dynamic)b);
        }
    }

    static bool isPrime(int a) //O(sqrt N)
    {
        int max = (int)Math.Sqrt(a);
        if (a == 1) return false;
        for (int i = 2; i <= max; i++)
        {
            if(a % i == 0)
            {
                return false;
            }
        }
        return true;
    }
}

public class Pair<T,U>: IComparable where T : IComparable<T> where U: IComparable<U>
{
    public T Item1;
    public U Item2;

    public int  CompareTo(object obj)
    {
        Pair<T,U> pair = (Pair<T, U>)obj;
        return Item1.CompareTo(pair.Item1);
    }
    public Pair(T t, U u)
    {
        Item1 = t;
        Item2 = u;
    }

}

// 計算量: Push -> O(logN), Peek -> O(1)。Clear() -> O(logN)
// ToArray()で配列化
public class PriorityQueue<T> where T : IComparable
{
    private IComparer<T> _comparer = null;
    private int _type = 0;
    private T[] _heap;
    private int _sz = 0;
    private int _count = 0;

    /// <summary>
    /// Priority Queue with custom comparer
    /// </summary>
    public PriorityQueue(int maxSize, IComparer<T> comparer)
    {
        _heap = new T[maxSize];
        _comparer = comparer;
    }

    /*
     -> Item: _heap(ヒープを持つ.sizeはmaxSize)
     -> Item: _type -> 0:asc(昇順), 1:desc(降順)
     */
    public PriorityQueue(int maxSize, int type = 0)
    {
        _heap = new T[maxSize];
        _type = type;
    }

    private int Compare(T x, T y)
    {
        if (_comparer != null) return _comparer.Compare(x, y);
        return _type == 0 ? x.CompareTo(y) : y.CompareTo(x);
        // typeが0なら昇順, 1なら降順にソートするCompare
    }

    public void Push(T x)
    {
        _count++;

        //node number
        var i = _sz++;

        while (i > 0)
        {
            //parent node number
            var p = (i - 1) / 2;
            if (Compare(_heap[p], x) <= 0) break;
            _heap[i] = _heap[p];
            i = p;
        }

        _heap[i] = x;
    }

    public T Pop()
    {
        _count--;

        T ret = _heap[0];
        T x = _heap[--_sz];

        int i = 0;
        while (i * 2 + 1 < _sz)
        {
            //children
            int a = i * 2 + 1;
            int b = i * 2 + 2;

            if (b < _sz && Compare(_heap[b], _heap[a]) < 0) a = b;

            if (Compare(_heap[a], x) >= 0) break;

            _heap[i] = _heap[a];
            i = a;
        }

        _heap[i] = x;

        return ret;
    }

    public int Count()  // O(1)
    {
        return _count;
    }

    public T Peek() // O(1)
    {
        return _heap[0];
    }

    public bool Contains(T x)   // O(N)なので注意
    {
        for (int i = 0; i < _sz; i++) if (x.Equals(_heap[i])) return true;
        return false;
    }

    public void Clear()
    {
        while (Count() > 0) Pop();
    }

    public IEnumerator<T> GetEnumerator() // なにこれ
    {
        var ret = new List<T>();

        while (Count() > 0)
        {
            ret.Add(Pop());
        }

        foreach (var r in ret)
        {
            Push(r);
            yield return r;
        }
    }

    public T[] ToArray()
    {
        T[] array = new T[_sz];
        int i = 0;

        foreach (var r in this)
        {
            array[i++] = r;
        }

        return array;
    }
}

public class GenericOperation<T>
{
    public GenericOperation()
    {
        var availableT = new Type[]
        {
            typeof(int), typeof(uint), typeof(short), typeof(ushort), typeof(long), typeof(ulong), typeof(byte),
            typeof(decimal), typeof(double)
        };
        if (!availableT.Contains(typeof(T)))
        {
            throw new NotSupportedException();
        }
        var p1 = Expression.Parameter(typeof(T));
        var p2 = Expression.Parameter(typeof(T));
        Add = Expression.Lambda<Func<T, T, T>>(Expression.Add(p1, p2), p1, p2).Compile();
        Subtract = Expression.Lambda<Func<T, T, T>>(Expression.Subtract(p1, p2), p1, p2).Compile();
        Multiply = Expression.Lambda<Func<T, T, T>>(Expression.Multiply(p1, p2), p1, p2).Compile();
        Divide = Expression.Lambda<Func<T, T, T>>(Expression.Divide(p1, p2), p1, p2).Compile();
        Modulo = Expression.Lambda<Func<T, T, T>>(Expression.Modulo(p1, p2), p1, p2).Compile();
        Equal = Expression.Lambda<Func<T, T, bool>>(Expression.Equal(p1, p2), p1, p2).Compile();
        GreaterThan = Expression.Lambda<Func<T, T, bool>>(Expression.GreaterThan(p1, p2), p1, p2).Compile();
        GreaterThanOrEqual = Expression.Lambda<Func<T, T, bool>>(Expression.GreaterThanOrEqual(p1, p2), p1, p2).Compile();
        LessThan = Expression.Lambda<Func<T, T, bool>>(Expression.LessThan(p1, p2), p1, p2).Compile();
        LessThanOrEqual = Expression.Lambda<Func<T, T, bool>>(Expression.LessThanOrEqual(p1, p2), p1, p2).Compile();
    }

    public Func<T, T, T> Add { get; private set; }
    public Func<T, T, T> Subtract { get; private set; }
    public Func<T, T, T> Multiply { get; private set; }
    public Func<T, T, T> Divide { get; private set; }
    public Func<T, T, T> Modulo { get; private set; }
    public Func<T, T, bool> Equal { get; private set; }
    public Func<T, T, bool> GreaterThan { get; private set; }
    public Func<T, T, bool> GreaterThanOrEqual { get; private set; }
    public Func<T, T, bool> LessThan { get; private set; }
    public Func<T, T, bool> LessThanOrEqual { get; private set; }
}



Measured memory_bytes: 27484