#include <bits/stdc++.h>
using namespace std;
using i64 = long long;

#define SZ(obj) (int)(obj).size()
#define REP(i,n) for(int i=0;i<(int)(n);++i)

const int MOD = 1e9+7;
const int INF = (1<<30)+1;
const i64 INFLL = (1LL<<60)+1;
const int dx[4] = {1, 0, -1, 0};
const int dy[4] = {0, 1, 0, -1};

template<typename T1, typename T2>
ostream &operator<<(ostream &os, const pair<T1, T2> &p) {
    os << p.first << " " << p.second;
    return os;
}

template<typename T1, typename T2>
istream &operator>>(istream &is, pair<T1, T2> &p) {
    is >> p.first >> p.second;
    return is;
}

template<typename T>
ostream &operator<<(ostream &os, const vector<T> &v) {
    REP(i,SZ(v)) os << v[i] << ((i+1) != SZ(v) ? " " : "");
    return os;
}

template<typename T>
istream &operator>>(istream &is, vector<T> &v) {
    for (T &in : v) is >> in;
    return is;
}

template<typename T1, typename T2>
inline bool chmax(T1 &a, T2 b) { return a < b && (a = b, true); }

template<typename T1, typename T2>
inline bool chmin(T1 &a, T2 b) { return a > b && (a = b, true); }

template<typename T = i64>
vector<T> make_v(size_t a) {
    return vector<T>(a);
}

template<typename T, typename... Ts>
auto make_v(size_t a, Ts... ts) {
    return vector<decltype(make_v<T>(ts...))>(a, make_v<T>(ts...));
}

template<typename T, typename V>
typename enable_if<is_class<T>::value==0>::type fill_v(T &t, const V &v) {
    t = v;
}

template<typename T, typename V>
typename enable_if<is_class<T>::value!=0>::type fill_v(T &t, const V &v) {
    for (auto &e : t) fill_v(e, v);
}

int popCount(int data){
    data = (data & 0x55555555)
        + ((data & 0xAAAAAAAA) >> 1);
    data = (data & 0x33333333)
        + ((data & 0xCCCCCCCC) >> 2);
    data = (data & 0x0F0F0F0F)
        + ((data & 0xF0F0F0F0) >> 4);
    data = (data & 0x00FF00FF)
        + ((data & 0xFF00FF00) >> 8);
    data = (data & 0x0000FFFF)
        + ((data & 0xFFFF0000) >> 16);
    return data;
}
// 最大公約数
uint32_t euclidean_gcd(uint32_t a, uint32_t b) {
    while(a^=b^=a^=b%=a);
    return b;
} 
// 最小公倍数
uint32_t euclidean_lcm(uint32_t a, uint32_t b) {
    return a * b / euclidean_gcd(a, b);
}


// 不動点
template<typename F>
struct FixPoint : F {
    FixPoint(F &&f) : F(forward<F> (f)) { }

    template<typename... Args>
    decltype(auto) operator()(Args &&... args) const {
        return F::operator()(*this, forward<Args> (args)...);
    }
};

template<typename F>
inline decltype(auto) MFP(F &&f) {
    return FixPoint<F>{forward<F>(f)};
}

// mod付き四則演算
template<int MOD>
struct ModInt {
    int x;
    ModInt() : x(0) { }
    explicit ModInt(i64 y) : x(y >= 0 ? y % MOD : (MOD - (-y) % MOD) % MOD) { }

    ModInt &operator+=(const ModInt &p) {
        if ((x += p.x) >= MOD) x -= MOD;
        return *this;
    }

    ModInt &operator-=(const ModInt &p) {
        if ((x += MOD - p.x) >= MOD) x -= MOD;
        return *this;
    }

    ModInt &operator*=(const ModInt &p) {
        x = (int) (1LL * x * p.x % MOD);
        return *this;
    }

    ModInt &operator/=(const ModInt &p) {
        *this *= p.inverse();
        return *this;
    }

    ModInt operator-() const { return ModInt(-x); }
    ModInt operator+(const ModInt &p) const { return ModInt(*this) += p; }
    ModInt operator-(const ModInt &p) const { return ModInt(*this) -= p; }
    ModInt operator*(const ModInt &p) const { return ModInt(*this) *= p; }
    ModInt operator/(const ModInt &p) const { return ModInt(*this) /= p; }

    bool operator==(const ModInt &p) const { return x == p.x; }
    bool operator!=(const ModInt &p) const { return x != p.x; }

    ModInt inverse() const {
        int a = x, b = MOD, u = 1, v = 0, t;
        while (b > 0) {
            t = a / b;
            swap(a -= t * b, b);
            swap(u -= t * v, v);
        }
        return ModInt(u);
    }

    ModInt pow(i64 n) const {
        ModInt ret(1), mul(x);
        while (n > 0) {
            if (n & 1) ret *= mul;
            mul *= mul;
            n >>= 1;
        }
        return ret;
    }

    friend ostream &operator<<(ostream &os, const ModInt &p) {
        return os << p.x;
    }

    friend istream &operator>>(istream &is, ModInt &p) {
        i64 t;
        is >> t;
        p = ModInt<MOD>(t);
        return (is);
    }

    static int get_mod() { return MOD; }
};

using modint = ModInt<MOD>;

i64 powerMod(i64 x, i64 n, i64 mod) {
    i64 ret = 1;
    while (n > 0) {
        if (n & 1) (ret *= x) %= mod;
        (x *= x) %= mod;
        n >>= 1;
    }
    return ret;
}

// 素因数分解
map<i64, int> prime_factor(i64 n) {
    map<i64, int> ret;
    for(i64 i = 2; i * i <= n; i++) {
        while(n % i == 0) {
            ret[i]++;
            n /= i;
        }
    }
    if(n != 1) ret[n] = 1;
    return ret;
}

// 順列、組み合わせ、重複組み合わせ
template<typename T=modint>
struct Combination {
    vector<T> _fact, _rfact, _inv;

    explicit Combination(int sz) : _fact(sz + 1), _rfact(sz + 1), _inv(sz + 1) {
        _fact[0] = _rfact[sz] = _inv[0] = 1;
        for(int i = 1; i <= sz; i++) _fact[i] = _fact[i-1] * i;
        _rfact[sz] /= _fact[sz];
        for(int i = sz - 1; i >= 0; i--) _rfact[i] = _rfact[i+1] * (i+1);
        for(int i = 1; i <= sz; i++) _inv[i] = _rfact[i] * _fact[i-1];
    }

    inline T inv(int k) const { return _inv[k]; }
    inline T fact(int k) const { return _fact[k]; }
    inline T rfact(int k) const { return _rfact[k]; }

    T P(int n, int r) const {
        if (r < 0 || n < r) return 0;
        return fact(n) * rfact(n - r);
    }
    T C(int p, int q) const {
        if (q < 0 || p < q) return 0;
        return fact(p) * rfact(q) * rfact(p - q);
    }
    T H(int n, int r) const {
        if (n < 0 || r < 0) return 0;
        return r == 0 ? 1 : C(n + r - 1, r);
    }
};

// FFT
namespace FastFourierTransform {
    using real = double;

    struct C {
        real x_, y_;
        C() : x_(0), y_(0) { }
        C(real x, real y) : x_(x), y_(y) { }
        inline C operator+(const C &c) const { return C(x_ + c.x_, y_ + c.y_); }
        inline C operator-(const C &c) const { return C(x_ - c.x_, y_ - c.y_); }
        inline C operator*(const C &c) const { return C(x_ * c.x_ - y_ * c.y_, x_ * c.y_ + y_ * c.x_); }
        inline C conj() const { return C(x_, -y_); }
    };
    const real PI = acosl(-1);
    int base = 1;
    vector<C> rts = { {0, 0}, {1, 0} };
    vector<int> rev = {0, 1};

    void ensure_base(int nbase) {
        if(nbase <= base) return;
        rev.resize(1 << nbase);
        rts.resize(1 << nbase);
        for (int i = 0; i < (1 << nbase); i++) {
            rev[i] = (rev[i >> 1] >> 1) + ((i & 1) << (nbase - 1));
        }
        while (base < nbase) {
            real angle = PI * 2.0 / (1 << (base + 1));
            for (int i = 1 << (base - 1); i < (1 << base); i++) {
                rts[i << 1] = rts[i];
                real angle_i = angle * (2 * i + 1 - (1 << base));
                rts[(i << 1) + 1] = C(cos(angle_i), sin(angle_i));
            }
            ++base;
        }
    }

    void fft(vector<C> &a, int n) {
        assert((n & (n - 1)) == 0);
        int zeros = __builtin_ctz(n);
        ensure_base(zeros);
        int shift = base - zeros;
        for (int i = 0; i < n; ++i) {
            if (i < (rev[i] >> shift)) {
                swap(a[i], a[rev[i] >> shift]);
            }
        }

        for (int k = 1; k < n; k <<= 1) {
            for (int i = 0; i < n; i += 2 * k) {
                for (int j = 0; j < k; j++) {
                    C z = a[i + j + k] * rts[j + k];
                    a[i + j + k] = a[i + j] - z;
                    a[i + j]  = a[i + j] + z;
                }
            }
        }
    }

    vector<i64> multiply(const vector<int> &a, const vector<int> &b) {
        int need = SZ(a) + SZ(b) - 1;
        int nbase = 1;
        while ((1 << nbase) < need) nbase++;
        ensure_base(nbase);
        int sz = 1 << nbase;
        vector<C> fa(sz);
        for(int i = 0; i < sz; i++) {
            int x = (i < SZ(a) ? a[i] : 0);
            int y = (i < SZ(b) ? b[i] : 0);
            fa[i] = C(x, y);
        }
        fft(fa, sz);

        C r(0, -0.25 / (sz >> 1)), s(0, 1), t(0.5, 0);
        for (int i = 0; i <= (sz >>1); i++) {
            int j = (sz - i) & (sz - 1);
            C z = (fa[j] * fa[j] - (fa[i] * fa[i]).conj()) * r;
            fa[j] = (fa[i] * fa[i] - (fa[j] * fa[j]).conj()) * r;
            fa[i] = z;
        }
        for (int i = 0; i < (sz >> 1); i++) {
            C A0 = (fa[i] + fa[i + (sz >> 1)]) * t;
            C A1 = (fa[i] - fa[i + (sz >> 1)]) * t * rts[(sz >> 1) + i];
            fa[i] = A0 + A1 * s;
        }
        fft(fa, sz >> 1);
        vector<i64> ret(need);
        for (int i = 0; i < need; i++) {
            ret[i] = llround(i & 1 ? fa[i>>1].y_ : fa[i>>1].x_);
        }
        return ret;
    }
}// namespace FastFourierTransform

// NTT
namespace NumberTheoreticTransform{

    constexpr i64 NTT_PRIMES[][2] = {
        {1224736769, 3}, // 2^24 * 73 + 1,
        {1053818881, 7}, // 2^20 * 3 * 5 * 67 + 1
        {1051721729, 6}, // 2^20 * 17 * 59 + 1
        {1045430273, 3}, // 2^20 * 997 + 1
        {1012924417, 5}, // 2^21 * 3 * 7 * 23 + 1
        {1007681537, 3}, // 2^20 * 31^2 + 1
        {1004535809, 3}, // 2^21 * 479 + 1
        {998244353, 3},  // 2^23 * 7 * 17 + 1
        {985661441, 3},  // 2^22 * 5 * 47 + 1
        {976224257, 3},  // 2^20 * 7^2 * 19 + 1
        {975175681, 17}, // 2^21 * 3 * 5 * 31 + 1
        {962592769, 7},  // 2^21 * 3^3 * 17 + 1
        {950009857, 7},  // 2^21 * 4 * 151 + 1
        {943718401, 7},  // 2^22 * 3^2 * 5^2 + 1
        {935329793, 3},  // 2^22 * 223 + 1
        {924844033, 5},  // 2^21 * 3^2 * 7^2 + 1
        {469762049, 3},  // 2^26 * 7 + 1
        {167772161, 3},  // 2^25 * 5 + 1
    };

    i64 extgcd(i64 a, i64 b, i64 &x, i64 &y) {
        i64 d;
        return b == 0 ? (x = 1, y = 0, a) : (d = extgcd(b, a % b, y, x), y -= a / b * x, d);
    }

    i64 modinv(i64 a, i64 mod) {
        i64 x, y;
        extgcd(a, mod, x, y);
        x %= mod;
        return x < 0 ? x + mod : x;
    }

    i64 modpow(i64 a, i64 b, i64 mod) {
        i64 r = 1;
        a %= mod;
        while(b) {
            if (b & 1) r = r * a % mod;
            a = a * a % mod;
            b >>= 1;
        }
        return r;
    }

    template <i64 mod, i64 primitive>
    struct Core {
        Core() { }
        using uint = uint_fast32_t;
        int MAX_H;
        vector<i64> zetaList, zetaInvList;
        explicit Core(int MAX_H) : MAX_H(MAX_H), zetaList(MAX_H), zetaInvList(MAX_H) {
            assert((mod & ((1 << MAX_H) - 1)) == 1);

            zetaList.back() = modpow(primitive, (mod - 1) / (1 << MAX_H), mod);
            zetaInvList.back() = modinv(zetaList.back(), mod);
            for (int ih = MAX_H - 2; ih >= 0; --ih) {
                zetaList[ih] = zetaList[ih + 1] * zetaList[ih + 1] % mod;
                zetaInvList[ih] = zetaInvList[ih + 1] * zetaInvList[ih + 1] % mod;
            }
        }
        void fft(vector<i64> &a, uint n, uint h, bool inv) const {
            static vector<i64> tmp;
            tmp.resize(n);
            uint mask = n - 1;
            for (uint i = n >> 1, ih = h - 1; i >= 1; i >>= 1, --ih) {
                i64 zeta = inv ? zetaInvList[h - 1 - ih] : zetaList[h - 1 - ih];
                i64 powZeta = 1;
                for (uint j = 0; j < n; j += i) {
                    for (uint k = 0; k < i; ++k) {
                        tmp[j + k] = (a[((j << 1) & mask) + k] + powZeta * a[(((j << 1) + i) & mask) + k]) % mod;
                    }
                    powZeta = powZeta * zeta % mod;
                }
                swap(a, tmp);
            }
            if (inv) {
                i64 invN = modinv(n, mod);
                for (uint i = 0; i < n; ++i) a[i] = a[i] * invN % mod;
            }
        }
        vector<i64> conv(const vector<i64> &a, const vector<i64> &b) const {
            assert(a.size() + b.size() - 1 <= (1 << MAX_H));

            if (a.size() == 0) return {};
            if (b.size() == 0) return {};
            return _conv(a, b);
        }
        vector<i64> _conv(vector<i64> a, vector<i64> b) const {
            uint deg = a.size() + b.size() - 1;
            uint h = 0, n = 1;
            while(n < deg) n <<= 1, ++h;
            a.resize(n), b.resize(n);
            return _convStrict(a, b, n, h);
        }
        vector<i64> _convStrict(vector<i64> a, vector<i64> b, uint n, uint h) const {
            fft(a, n, h, 0), fft(b, n, h, 0);
            for(uint i = 0; i < n; ++i) a[i] = a[i] * b[i] % mod;
            fft(a, n, h, 1);
            return a;
        }
    };
    template<int I>
    void conv_for(int MAX_H, int n, int h,
                const vector<i64> &a,
                const vector<i64> &b,
                vector<i64> &mods,
                vector<i64> &coeffs,
                vector<vector<i64>> &constants) {
        static const Core<NTT_PRIMES[I][0], NTT_PRIMES[I][1]> ntt(MAX_H);
        auto c = ntt._convStrict(a, b, n, h);
        mods[I] = NTT_PRIMES[I][0];
        if(I >= 1) {
            conv_for<I - 1>(MAX_H, n, h, a, b, mods, coeffs, constants);
        }

        for(size_t i = 0; i < c.size(); ++i) {
            i64 v = (c[i] - constants[I][i]) * modinv(coeffs[I], mods[I]) % mods[I];
            if(v < 0) v += mods[i];
            for(size_t j = I + 1; j < mods.size(); ++j) {
                constants[j][i] = (constants[j][i] + coeffs[j] * v) % mods[j];
            }
        }
        for(size_t j = I + 1; j < mods.size(); ++j) {
            coeffs[j] = (coeffs[j] * mods[I]) % mods[j];
        }
    }

    template <>
    void conv_for< -1 >(int, int, int, const vector< i64 > &, const vector< i64 > &,
                        vector< i64 > &, vector< i64 > &,
                        vector< vector< i64 > > &) { }

    template<int USE>
    vector<i64> conv(   int MAX_H,
                        vector<i64> a, 
                        vector<i64> b,
                        i64 mod) {
        static_assert(USE >= 1, "USE must be positive");
        static_assert(USE <= sizeof(NTT_PRIMES) / sizeof(*NTT_PRIMES), "USE is too big");
        int deg = a.size() + b.size() - 1;
        int n = 1, h = 0;
        while(n < deg) n <<= 1, ++h;
        a.resize(n), b.resize(n);
        vector<i64> coeffs(USE + 1, 1);
        vector<vector<i64>> constants(USE + 1, vector<i64>(n, 0));
        vector<i64> mods(USE + 1, mod);
        conv_for<USE-1>(MAX_H, n, h, a, b, mods, coeffs, constants);
        return constants.back();
    }
}//namespace NumberTheoreticTransform

const int MAX_H = 18;
NumberTheoreticTransform::Core<NumberTheoreticTransform::NTT_PRIMES[0][0], NumberTheoreticTransform::NTT_PRIMES[0][1]> ntt(MAX_H);

// BIT
template<typename T>
struct BinaryIndexedTree {
    vector<T> data;

    BinaryIndexedTree(int sz) {
        data.assign(++sz, 0);
    }

    T sum(int k) {
        T ret = 0;
        for(++k; k > 0; k -= k & -k) ret += data[k];
        return (ret);
    }

    void add(int k, T x) {
        for(++k; k < data.size(); k += k & -k) data[k] += x;
    }
};

// セグ木
template<typename Monoid>
struct SegmentTree {
    using F = function<Monoid(Monoid, Monoid)>;

    int sz;
    vector<Monoid> seg;
    const F f;
    const Monoid M1;

    SegmentTree(int n, const F f, const Monoid &M1) : f(f), M1(M1) {
        sz = 1;
        while(sz < n) sz <<= 1;
        seg.assign(2 * sz, M1);
    }

    void set(int k, const Monoid &x) {
        seg[k+sz] = x;
    }

    void build() {
        for (int k = sz - 1; k > 0; k--) {
            seg[k] = f(seg[2 * k + 0], seg[2 * k + 1]);
        }
    }

    void update(int k, const Monoid &x) {
        k += sz;
        seg[k] = x;
        while(k >>= 1) {
            seg[k] = f(seg[2 * k + 0], seg[2 * k + 1]);
        }
    }

    Monoid query(int a, int b) {
        Monoid L = M1, R = M1;
        for(a += sz, b += sz; a < b; a >>= 1, b >>= 1) {
            if(a & 1) L = f(L, seg[a++]);
            if(b & 1) R = f(seg[--b], R);
        }
        return f(L, R);
    }

    Monoid operator[](const int &k) const {
        return seg[k + sz];
    }
};

// 遅延セグ木
template<typename Monoid, typename OperatorMonoid = Monoid>
struct LazySegmentTree {
    using F = function<Monoid(Monoid, Monoid)>;
    using G = function<Monoid(Monoid, OperatorMonoid, int)>;
    using H = function<OperatorMonoid(OperatorMonoid, OperatorMonoid)>;

    int sz;
    vector<Monoid> data;
    vector<OperatorMonoid> lazy;
    const F f;
    const G g;
    const H h;

    const Monoid M1;
    const OperatorMonoid OM0;
    LazySegmentTree(int n, const F f, const G g, const H h,
                    const Monoid &M1, const OperatorMonoid OM0)
                        : f(f), g(g), h(h), M1(M1), OM0(OM0) {
        sz = 1;
        while(sz < n) sz <<= 1;
        data.assign(2 * sz, M1);
        lazy.assign(2 * sz, OM0);
    }

    void set(int k, const Monoid &x) {
        data[k + sz] = x;
    }

    void build() {
        for(int k = sz - 1; k > 0; k--) {
            data[k] = f(data[2 * k + 0], data[2 * k + 1]);
        }
    }

    void propagate(int k, int len) {
        if(lazy[k] != OM0) {
            if(k < sz) {
                lazy[2 * k + 0] = h(lazy[2 * k + 0], lazy[k]);
                lazy[2 * k + 1] = h(lazy[2 * k + 1], lazy[k]);
            }
            data[k] = g(data[k], lazy[k], len);
            lazy[k] = OM0;
        }
    }

    Monoid update(int a, int b, const OperatorMonoid &x, int k, int l, int r) {
        propagate(k, r - l);
        if(r <= a || b <= l) {
            return data[k];
        } else if(a <= l && r <= b) {
            lazy[k] = h(lazy[k], x);
            propagate(k, r - l);
            return data[k];
        } else {
            return data[k] = f(update(a, b, x, 2 * k + 0, l, (l + r) >> 1),
                               update(a, b, x, 2 * k + 1, (l + r) >> 1, r));
        }
    }

    Monoid update(int a, int b, const OperatorMonoid &x) {
        return update(a, b, x, 1, 0, sz);
    }


    Monoid query(int a, int b, int k, int l, int r) {
        propagate(k, r - l);
        if(r <= a || b <= l) {
            return M1;
        } else if(a <= l && r <= b) {
            return data[k];
        } else {
            return f(   query(a, b, 2 * k + 0, l, (l + r) >> 1),
                        query(a, b, 2 * k + 1, (l + r) >> 1, r));
        }
    }

    Monoid query(int a, int b) {
        return query(a, b, 1, 0, sz);
    }

    Monoid operator[](const int &k) {
        return query(k, k + 1);
    }
};

// 永続セグ木
template<typename Monoid>
struct PersistentSegmentTree {
    using F = function<Monoid(Monoid, Monoid)>;

    struct Node {
        Monoid data;
        Node *l, *r;

        Node(const Monoid &data) : data(data), l(nullptr), r(nullptr) { }
    };

    int sz;
    const F f;
    const Monoid M1;

    PersistentSegmentTree(const F f, const Monoid &M1) : f(f), M1(M1) { }

    Node *build(vector<Monoid> &v) {
        sz = SZ(v);
        return build(0, sz, v);
    }
    Node *merge(Node *l, Node *r) {
        auto t = new Node(f(l->data, r->data));
        t->l = l;
        t->r = r;
        return t;
    }

    Node *build(int l, int r, vector< Monoid > &v) {
        if(l + 1 >= r) return new Node(v[l]);
        return merge(build(l, (l + r) >> 1, v), build((l + r) >> 1, r, v));
    }

    Node *update(int a, const Monoid &x, Node *k, int l, int r) {
        if(r <= a || a + 1 <= l) {
            return k;
        } else if(a <= l && r <= a + 1) {
            return new Node(x);
        } else {
            return merge(update(a, x, k->l, l, (l + r) >> 1), update(a, x, k->r, (l + r) >> 1, r));
        }
    }

    Node *update(Node *t, int k, const Monoid &x) {
        return update(k, x, t, 0, sz);
    }

    Monoid query(int a, int b, Node *k, int l, int r) {
        if(r <= a || b <= l) {
            return M1;
        } else if(a <= l && r <= b) {
            return k->data;
        } else {
            return f(   query(a, b, k->l, l, (l + r) >> 1),
                        query(a, b, k->r, (l + r) >> 1, r));
        }
    }

    Monoid query(Node *t, int a, int b) {
        return query(a, b, t, 0, sz);
    }
};

// Union-Find
struct UnionFind {
    vector<int> data;
    explicit UnionFind(int sz) {
        data.assign(sz, -1);
    }
    bool unite(int x, int y) {
        x = find(x), y = find(y);
        if (x == y) return false;
        if (data[x] > data[y]) swap(x, y);
        data[x] += data[y];
        data[y] = x;
        return true;
    }
    int find(int k) {
        if (data[k] < 0) return k;
        return (data[k] = find(data[k]));
    }

    int size(int k) {
        return (-data[find(k)]);
    }
};

void Main();
int main() {
    cin.tie(nullptr);
    ios::sync_with_stdio(false);
    cout << fixed << setprecision(10);
    cerr << fixed << setprecision(10);
    Main();
    return 0;
}

void Main() {
    //--here
    int N; cin >> N;
    uint32_t a[N];
    uint32_t ans = 1;
    REP(i,N) cin >> a[i], ans = euclidean_lcm(ans, a[i]);
    cout << ans << endl;
}


Measured memory_bytes: 3172