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

typedef long long ll;
const int INF = 1e9;
const ll LINF = 1e18;
const int mod = 1e9+7;

#define pi pair<int,int>
#define pl pair<lld,lld>

#define dump(x) cout << #x << " = " << (x) << endl
#define YES(n) cout << ((n) ? "YES" : "NO"  ) << endl
#define Yes(n) cout << ((n) ? "Yes" : "No"  ) << endl
#define SANKOU(n,a,b) cout << ((n) ? (#a) : (#b) ) << endl

#define mem0(x) memset(x,0,sizeof(x))
#define fillnum(x,n) fill(begin(x),end(x),n)
#define asort(x) sort(x.begin(),x.end())
#define dsort(x,t) sort(x.begin(),x.end(),greater<t>())
#define vuniq(x) x.erase(unique(x.begin(), x.end()), x.end())

#define pb(a) push_back(a)
#define mp(a,b) make_pair(a,b)

int main() {
    ll N[4];
    ll C[4] = {1,9,7,4};
    for (int i = 0; i < 4; i++) {
        cin >> N[i];
    }
    for (int i = 0; i < 4; i++) {
        if(N[i] != C[i]){
            cout << "NO" << endl;
            exit(0);
        }
    }
    cout << "YES" << endl;
}


#include <stdio.h>

int main(){
 int test,b,i,n,c,d,sum=0;
char a[10];
gets(a);

if(a[0]=='1'|| a[2]=='1' || a[4]=='1' || a[6]=='1')
{
    sum++;
}
if(a[0]=='7'|| a[2]=='7' || a[4]=='7' || a[6]=='7')
{
    sum++;
}
if(a[0]=='9'|| a[2]=='9' || a[4]=='9' || a[6]=='9')
{
    sum++;
}
if(a[0]=='4'|| a[2]=='4' || a[4]=='4' || a[6]=='4')
{
    sum++;
}
if(sum==4)
{
    printf("YES");
}else{
    printf("NO");
}
      return 0;
}


#include<stdio.h>
#include<stdlib.h>
int cmp(const void *a,const void *b){return *(int*)a-*(int*)b;}
int main(){
    int n[4];
    for(int i = 0; i < 4; i++)
        scanf("%d",&n[i]);
    qsort(n,4,4,cmp);
    if(n[0] == 1 && n[1] == 4 && n[2] == 7 && n[3] == 9)
        puts("YES");
    else puts("NO");
    return 0;
}


#include <stdio.h>

int main()
{
	int check(int,int,int,int) ,c, n[4];
	scanf("%d %d %d %d",&n[0], &n[1], &n[2], &n[3]);

	if(n[0]!=1 && n[0]!=7 && n[0]!=9 && n[0]!= 4){
		c = 0;
	}else if((n[1]!=1 && n[1]!=7 && n[1]!=9 && n[1]!= 4)||(n[0]==n[1])){
		c = 0;
	}else if((n[2]!=1 && n[2]!=7 && n[2]!=9 && n[2]!= 4)||(n[2]==n[1])||(n[2]==n[0])){
		c = 0;
	}else if((n[3]!=1 && n[3]!=7 && n[3]!=9 && n[3]!= 4)||(n[3]==n[1])||(n[3]==n[0])||(n[3]==n[2])){
		c = 0;
	}else c = 1;

	if(c==1) printf("YES");
	else printf("NO");
}


#include<stdio.h>
int main()
{
    int N1,N2,N3,N4;
    scanf("%d",&N1);
    scanf("%d",&N2);
    scanf("%d",&N3);
    scanf("%d",&N4);
    if(N1==1&&N2==9||N2==7&&N3==7||N3==9&&N4==4){
        printf("YES\n");
    }
    else{
    printf("NO\n");
    }
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define IOS ios::sync_with_stdio(false); cin.tie(0);
#define FOR(i,s,n) for(int i = (s); i < (n); i++)
#define REP(i,n) FOR(i,0,n)
#define RREP(i,n) for(int i = (n); i >= 0; i--)
#define ALL(n) (n).begin(), (n).end()
#define RALL(n) (n).rbegin(), (n).rend()
#define ATYN(n) cout << ( (n) ? "Yes":"No") << '\n';
#define CFYN(n) cout << ( (n) ? "YES":"NO") << '\n';
#define OUT(n) cout << (n) << '\n';
using ll = long long;
using ull = unsigned long long;
using pii = pair<int,int>;
using pll = pair<ll,ll>;

int main(void)
{
    IOS
    vector<int> x{1,9,7,4};
    int count = 0;
    REP(i,4) {
        int n; cin >> n;
        REP(j,4) {
            if (x[j] == n) {
                count++;
                x[j] = 0;
                break;
            }
        }
    }

    CFYN(count == 4)

    return 0;
}


#include<stdio.h>
int main(void)
{
  int n[4];
  int sum=0;

  for(int i=0;i<4;i++){
    scanf("%d",&n[i]);
    sum+=n[i];
  }

  if(sum!=21){
    puts("NO");
  }else{
    puts("YES");
  }
  return 0;
}


function Main(input) {
    input = input.split(" ");
    one = false;
    nana = false;
    nine = false;
    four = false;
    for(i = 0; i < 4; i++){
        if(Number(input[i]) === 1) one=true;
        if(parseInt(input[i]) == 7) nana = true;
        if(parseInt(input[i]) == 4) four = true;
        if(Number(input[i]) == 9) nine = true;
    }
  if(one && nana && nine && four){
    console.log('YES')
  }else{
    console.log('NO')
  }

}

Main(require("fs").readFileSync("/dev/stdin", "utf8"));


function Main(input) {
	input = input.split(" ").sort().join("");
	console.log(input=="1479" ? "YES" : "NO");
}Main(require("fs").readFileSync("/dev/stdin", "utf8").trim());


"use strict";

const main = arg => {
    arg = arg.trim().split("\n");
    const N = arg[0].split(" ").map(n=>~~n);

    console.log(~~N.sort((a,b)=>a-b).join("") === 1479 ? "YES" : "NO");
}
main(require('fs').readFileSync('/dev/stdin', 'utf8'));


// inputに入力データ全体が入る
function Main(input) {
    input = input.split(" ").map(e => Number(e));
    console.log(input.indexOf(1)>=0&&input.indexOf(9)>=0&&input.indexOf(7)>=0&&input.indexOf(4) ? 'YES' : 'NO');
}
//*この行以降は編集しないでください（標準入出力から一度に読み込み、Mainを呼び出します）
Main(require("fs").readFileSync("/dev/stdin", "utf8"));


// inputに入力データ全体が入る
function Main(input) {
    input = input.split(" ");
    if (input.indexOf('1')>=0&&input.indexOf('9')>=0&&input.indexOf('7')>=0&&input.indexOf('4')){
        console.log('YES');
    }else {
        console.log('NO');
    }
}
//*この行以降は編集しないでください（標準入出力から一度に読み込み、Mainを呼び出します）
Main(require("fs").readFileSync("/dev/stdin", "utf8"));


// inputに入力データ全体が入る
function Main(input) {
    input = input.split(" ");
    console.log(input.indexOf(1)>=0&&input.indexOf(9)>=0&&input.indexOf(7)>=0&&input.indexOf(4)>=0?'YES':'NO');
}
//*この行以降は編集しないでください（標準入出力から一度に読み込み、Mainを呼び出します）
Main(require("fs").readFileSync("/dev/stdin", "utf8"));


package main

import "fmt"

func main() {
	xm := make(map[int]bool)
	for i := 0; i < 4; i++ {
		var n int
		fmt.Scan(&n)
		xm[n] = true
	}

	if xm[1] && xm[9] && xm[7] && xm[4] {
		fmt.Println("YES")
	} else {
		fmt.Println("NO")
	}
}


package main

import (
	"bufio"
	"fmt"
	"math"
	"os"
	"reflect"
	"sort"
	"strconv"
	"strings"
	// "regexp"
)

/* sort */
type pair struct {
	index  int64
	p1, p2 interface{}
}
type pairs []pair

func (slice pairs) Len() int {
	return len(slice)
}

func (slice pairs) Less(i, j int) bool {
	return slice[i].index < slice[j].index
}

func (slice pairs) Swap(i, j int) {
	slice[i], slice[j] = slice[j], slice[i]
}

/* sort */
type Int64Slice []int64

func (slice Int64Slice) Len() int {
	return len(slice)
}

func (slice Int64Slice) Less(i, j int) bool {
	return slice[i] < slice[j]
}

func (slice Int64Slice) Swap(i, j int) {
	slice[i], slice[j] = slice[j], slice[i]
}
func Int64s(a []int64)                    { sort.Sort(Int64Slice(a)) }
func Int64sSliceAreSorted(a []int64) bool { return sort.IsSorted(Int64Slice(a)) }

const (
	initialBufSize = 1e4
	maxBufSize     = 1e8
	INF            = 1e8
)

var (
	scanner = bufio.NewScanner(os.Stdin)
	writer  = bufio.NewWriter(os.Stdout)
	di      = []int64{-1, 0, 1, 0}
	dj      = []int64{0, -1, 0, 1}
	di8     = []int64{-1, -1, 0, 1, 1, 1, 0, -1}
	dj8     = []int64{0, -1, -1, -1, 0, 1, 1, 1}
)

func main() {
	buf := make([]byte, initialBufSize)
	scanner.Buffer(buf, maxBufSize)
	scanner.Split(bufio.ScanWords)
	correct := []int64{1, 4, 7, 9}
	N1, N2, N3, N4 := readInt(), readInt(), readInt(), readInt()
	a := []int64{N1, N2, N3, N4}
	Int64s(correct)
	Int64s(a)
	if aryEq(correct, a) {
		fmt.Println("YES")
	} else {
		fmt.Println("NO")
	}
}

/*==========================================
 *             Library
 *==========================================*/
func NextPermutation(x sort.Interface) bool {
	n := x.Len() - 1
	if n < 1 {
		return false
	}
	j := n - 1
	for ; !x.Less(j, j+1); j-- {
		if j == 0 {
			return false
		}
	}
	l := n
	for !x.Less(j, l) {
		l--
	}
	x.Swap(j, l)
	for k, l := j+1, n; k < l; {
		x.Swap(k, l)
		k++
		l--
	}
	return true
}
func doubleAry(h int64, w int64, init int64) (res [][]int64) {
	res = make([][]int64, h)
	for i := int64(0); i < h; i++ {
		res[i] = make([]int64, w)
		for j := int64(0); j < w; j++ {
			res[i][j] = init
		}
	}
	return
}

func aryEq(a []int64, b []int64) bool {
	return reflect.DeepEqual(a, b)
}

func clone(n []int64) (r []int64) {
	r = make([]int64, len(n))
	for i := 0; i < len(n); i++ {
		r[i] = n[i]
	}
	return
}
func write(s string) {
	writer.WriteString(s)
}

func print() {
	writer.Flush()
}

// scanner.Split(bufio.ScanWords) をコメントアウトしないと使用不可
func readLine() (s string) {
	if scanner.Scan() {
		s = scanner.Text()
	}
	return s
}

func readInt() (read int64) {
	scanner.Scan()
	read, err := strconv.ParseInt(scanner.Text(), 10, 64)
	if err != nil {
		panic(err)
	}
	return
}

func readFloat() (read float64) {
	scanner.Scan()
	read, err := strconv.ParseFloat(scanner.Text(), 64)
	if err != nil {
		panic(err)
	}
	return
}

func readRunes() (read []rune) {
	scanner.Scan()
	for _, v := range scanner.Text() {
		read = append(read, v)
	}
	return
}

func readString() (read string) {
	scanner.Scan()
	read = scanner.Text()
	return
}

func readStrings() (read []string) {
	scanner.Scan()
	for _, v := range scanner.Text() {
		read = append(read, string(v))
	}
	return
}

func s2i(s string) int64 {
	var intVal, e = strconv.ParseInt(s, 10, 64)
	if e != nil {
		panic(e)
	}
	return intVal
}

func i2s(i int64) string {
	var strVal = strconv.FormatInt(i, 10)
	return strVal
}

func s2f(s string) float64 {
	var floatVal, e = strconv.ParseFloat(s, 64)
	if e != nil {
		panic(e)
	}
	return floatVal
}

func abs(i int64) int64 {
	return int64(math.Abs(float64(i)))
}

func max(a ...int64) int64 {
	ans := int64(0)
	for i, v := range a {
		if i == 0 {
			ans = v
		}
		if ans < v {
			ans = v
		}
	}
	return ans
}
func min(a ...int64) int64 {
	ans := int64(0)
	for i, v := range a {
		if i == 0 {
			ans = v
		}
		if ans > v {
			ans = v
		}
	}
	return ans
}

func sum(i []int64) int64 {
	sum := int64(0)
	for _, val := range i {
		sum += val
	}
	return sum
}

func split(s string) []string {
	return strings.Fields(s)
}

func strAry2intAry(strs []string) []int64 {
	var ret = make([]int64, 0, len(strs))
	for _, str := range strs {
		var intVal = s2i(str)
		ret = append(ret, intVal)
	}
	return ret
}

func intAry2strAry(nums []int64) []string {
	var ret = make([]string, 0, len(nums))
	for _, num := range nums {
		var strVal = i2s(num)
		ret = append(ret, strVal)
	}
	return ret
}

func ary2str(strs []string) string {
	return strings.Join(strs, " ")
}

func reverse(res []int64) []int64 {
	for i, j := 0, len(res)-1; i < j; i, j = i+1, j-1 {
		res[i], res[j] = res[j], res[i]
	}
	return res
}
func reverseStr(res []string) []string {
	for i, j := 0, len(res)-1; i < j; i, j = i+1, j-1 {
		res[i], res[j] = res[j], res[i]
	}
	return res
}

func ini(res []int, init int) {
	if len(res) == 0 {
		return
	}
	res[0] = init
	for i := 0; i < len(res); i++ {
		copy(res[i:], res[:i])
	}
}

//
// func regexpExample() {
//     // Your code here!
//     var str = "13:20"
//     r := regexp.MustCompile(`(\d+):(\d+)`)
//     fmt.Println(r.FindStringSubmatch(str))
// }

// type Country struct {
//     gold int
//     silver int
//     blonze int
// }

// // 複数ソートのサンプル
// func stableSortExample() []Country{
//     var country = []Country {
//         {gold:1, silver:2, blonze:3},
//         {gold:1, silver:2, blonze:3},
//         {gold:1, silver:3, blonze:2},
//         {gold:1, silver:3, blonze:3},
//     }
//     sort.SliceStable(country, func(i, j int) bool { return country[i].blonze > country[j].blonze })
//     sort.SliceStable(country, func(i, j int) bool { return country[i].silver > country[j].silver })
//     sort.SliceStable(country, func(i, j int) bool { return country[i].gold > country[j].gold })
//     return country
// }


package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
)

const (
	initialBufSize = 1e4
	maxBufSize     = 1e6 + 7
)

var buf []byte = make([]byte, maxBufSize)
var sc = bufio.NewScanner(os.Stdin)

func init() {
	sc.Split(bufio.ScanWords)
	sc.Buffer(buf, maxBufSize)
}

func main() {
	ans := "YES"
	list := map[int]bool{}
	for i := 0; i < 10; i++ {
		list[i] = false
	}
	check := []int{1, 9, 7, 4}
	for i := 0; i < 4; i++ {
		list[nextInt()] = true
	}
	for _, c := range check {
		if !list[c] {
			ans = "NO"
		}
	}
	fmt.Println(ans)
}

func nextLine() string {
	sc.Scan()
	return sc.Text()
}

func nextInt() int {
	sc.Scan()
	i, e := strconv.Atoi(sc.Text())
	if e != nil {
		panic(e)
	}
	return i
}


package main

import "fmt"

func main() {
	var num1, num2, num3, num4 int
	var ans string
	fmt.Scanf("%d %d %d %d\n", &num1, &num2, &num3, &num4)

	if num1 == 1 || num2 == 1 || num3 == 1 || num4 == 1 {
		if num1 == 9 || num2 == 9 || num3 == 9 || num4 == 9 {
			if num1 == 7 || num2 == 7 || num3 == 7 || num4 == 7 {
				if num1 == 4 || num2 == 4 || num3 == 4 || num4 == 4 {
					ans = "YES"
				} else {
					ans = "NO"
				}
			} else {
				ans = "NO"
			}
		} else {
			ans = "NO"
		}
	}
	fmt.Println(ans)

}


def main(argv)
  ns = gets.chomp.split(' ').map(&:to_i).sort

  puts (ns == [1, 4, 7, 9] ? 'YES' : 'NO')
end

if self.to_s == 'main' then
  main(ARGV)
end


puts (gets.chomp.split.map(&:to_i).sort! == [1, 4, 7, 9])? "YES" : "NO"


puts (gets.split.map(&:to_i).sort == [1,4,7,9] ? "YES" : "NO")


s=gets.to_i.split("").map(&:to_i)
puts ([1,9,7,4].repeated_permutation.include?(s)?"YES":"NO")


a=gets.chomp
b=gets.chomp
puts (a.reverse==b ? "YES" : "NO")


puts (gets.split.sort == [?1,?4?,?7,?9] ? "YES" : "NO")


#![allow(unused_imports)]

use std::cmp;
use std::cmp::{max, min, Ordering};
use std::collections::{BTreeMap, BTreeSet, BinaryHeap, HashMap, HashSet, VecDeque};
use std::io::stdin;
use std::ops::*;
use std::process::exit;
use std::str::FromStr;

#[macro_export]
macro_rules! minimum {
    ($($e:expr),+) => {
        {
            let mut res = Vec::new();
            $(
                res.push($e);
            )+
            res.into_iter().min().unwrap()
        }
    };
}

pub const MOD: usize = 1000000007;

fn main() {
    let mut a: Vec<u32> = input_vec();
    a.sort();
    if a == vec![1, 4, 7, 9] {
        println!("YES");
    } else {
        println!("NO");
    }
}

pub fn input<T: FromStr>() -> T {
    let mut buf = String::new();
    stdin().read_line(&mut buf).unwrap();
    buf.trim().parse().ok().unwrap()
}

pub fn input_vec<T: FromStr>() -> Vec<T> {
    let mut buf = String::new();
    stdin().read_line(&mut buf).unwrap();
    buf.trim()
        .split_whitespace()
        .map(|x| x.parse().ok().unwrap())
        .collect::<Vec<_>>()
}

pub fn input_chars() -> Vec<char> {
    let s: String = input();
    s.chars().collect()
}

pub fn input_lines<T: FromStr>(l: usize) -> Vec<T> {
    let mut res = Vec::new();
    for _i in 0..l {
        res.push(input());
    }
    res
}

pub fn input_lines_two<T: FromStr, U: FromStr>(l: usize) -> Vec<(T, U)> {
    let mut res = Vec::new();
    for _i in 0..l {
        res.push(input_two());
    }
    res
}

pub fn input_lines_three<T: FromStr, U: FromStr, V: FromStr>(l: usize) -> Vec<(T, U, V)> {
    let mut res = Vec::new();
    for _i in 0..l {
        res.push(input_three());
    }
    res
}

pub fn input_two<T: FromStr, U: FromStr>() -> (T, U) {
    let mut buf = String::new();
    stdin().read_line(&mut buf).unwrap();
    let s: Vec<&str> = buf.split_whitespace().collect();
    (
        s[0].parse::<T>().ok().unwrap(),
        s[1].parse::<U>().ok().unwrap(),
    )
}

pub fn input_three<T: FromStr, U: FromStr, V: FromStr>() -> (T, U, V) {
    let mut buf = String::new();
    stdin().read_line(&mut buf).unwrap();
    let s: Vec<&str> = buf.split_whitespace().collect();
    (
        s[0].parse::<T>().ok().unwrap(),
        s[1].parse::<U>().ok().unwrap(),
        s[2].parse::<V>().ok().unwrap(),
    )
}

pub fn input_four<T: FromStr, U: FromStr, V: FromStr, W: FromStr>() -> (T, U, V, W) {
    let mut buf = String::new();
    stdin().read_line(&mut buf).unwrap();
    let s: Vec<&str> = buf.split_whitespace().collect();
    (
        s[0].parse().ok().unwrap(),
        s[1].parse().ok().unwrap(),
        s[2].parse().ok().unwrap(),
        s[3].parse().ok().unwrap(),
    )
}

pub fn input_matrix<T: FromStr + Clone>(h: usize) -> Vec<Vec<T>> {
    let mut res = vec![Vec::new(); h];
    for i in 0..h {
        res[i] = input_vec();
    }
    res
}


#![allow(unused, non_snake_case, dead_code, non_upper_case_globals)]
use std::cmp::*;
use std::collections::*;
use std::mem::*;

fn main() {
    let (r, w, e) = (std::io::stdin(), std::io::stdout(), std::io::stderr());
    let mut io = IO::new(r.lock(), w.lock(), e.lock());
    let mut ns = io.readn::<usize>(4);

    ns.sort();

    if ns[0] == 1 && ns[1] == 4 && ns[2] == 7 && ns[3] == 9 {
        io.writeln("YES")
    } else {
        io.writeln("NO")
    }
}

static MOD: i64 = 1000000007;
static INF: i64 = std::i64::MAX >> 1;
// IO
use std::io::*;
struct IO<R: Read, W: Write, E: Write> {
    Read: R,
    Write: BufWriter<W>,
    Error: BufWriter<E>,
}
impl<R: Read, W: Write, E: Write> IO<R, W, E> {
    fn new(r: R, w: W, e: E) -> IO<R, W, E> {
        IO {
            Read: r,
            Write: BufWriter::new(w),
            Error: BufWriter::new(e),
        }
    }
    fn read<T>(&mut self) -> T
    where
        T: std::str::FromStr,
    {
        let next: String = self
            .Read
            .by_ref()
            .bytes()
            .map(|c| c.unwrap() as char)
            .skip_while(|c| c.is_whitespace())
            .take_while(|c| !c.is_whitespace())
            .collect();
        next.parse().ok().unwrap()
    }
    fn chars(&mut self) -> Vec<char> {
        self.read::<String>().chars().collect()
    }
    fn readn<T: std::str::FromStr>(&mut self, n: usize) -> Vec<T> {
        (0..n).map(|_| self.read::<T>()).collect::<Vec<_>>()
    }
    fn readmat<T: std::str::FromStr>(&mut self, n: usize, m: usize) -> Vec<Vec<T>> {
        (0..n).map(|_| self.readn(m)).collect()
    }
    fn write<S: ToString>(&mut self, val: S) {
        self.Write.write(val.to_string().as_bytes());
    }
    fn writeln<S: ToString>(&mut self, val: S) {
        self.Write.write(val.to_string().as_bytes());
        self.Write.write(b"\n");
    }
    fn debug<S: std::fmt::Debug>(&mut self, val: S) {
        writeln!(self.Error, "(debug) {:?}", &val);
    }
    fn debug2<S: std::fmt::Debug, T: std::fmt::Debug>(&mut self, val1: S, val2: T) {
        writeln!(self.Error, "(debug2) {:?} -> {:?}", val1, val2);
    }
    fn debug3<S: std::fmt::Debug, T: std::fmt::Debug, U: std::fmt::Debug>(
        &mut self,
        val1: S,
        val2: T,
        val3: U,
    ) {
        writeln!(
            self.Error,
            "(debug3) {:?} -> {:?} -> {:?}",
            val1, val2, val3
        );
    }
}


#![allow(non_snake_case)]
#![allow(unused_variables)]
#![allow(dead_code)]

fn main() {
    let (N1, N2, N3, N4): (i64, i64, i64, i64) = {
        let mut line: String = String::new();
        std::io::stdin().read_line(&mut line).unwrap();
        let mut iter = line.split_whitespace();
        (
            iter.next().unwrap().parse().unwrap(),
            iter.next().unwrap().parse().unwrap(),
            iter.next().unwrap().parse().unwrap(),
            iter.next().unwrap().parse().unwrap()
        )
    };

    let mut N = vec![N1, N2, N3, N4];
    N.sort();
    let ans = if N == vec![1, 4, 7, 9] { "YES" } else { "NO" };

    println!("{}", ans);
}


#![allow(unused, non_snake_case, dead_code, non_upper_case_globals)]
use std::cmp::*;
use std::collections::*;
use std::mem::*;

fn main() {
    let (r, w, e) = (std::io::stdin(), std::io::stdout(), std::io::stderr());
    let mut io = IO::new(r.lock(), w.lock(), e.lock());
    let mut ns = io.readn::<usize>(4);

    ns.sort();

    if ns[0] == 1 && ns[1] == 9 && ns[2] == 7 && ns[3] == 4 {
        io.writeln("YES")
    } else {
        io.writeln("NO")
    }
}

static MOD: i64 = 1000000007;
static INF: i64 = std::i64::MAX >> 1;
// IO
use std::io::*;
struct IO<R: Read, W: Write, E: Write> {
    Read: R,
    Write: BufWriter<W>,
    Error: BufWriter<E>,
}
impl<R: Read, W: Write, E: Write> IO<R, W, E> {
    fn new(r: R, w: W, e: E) -> IO<R, W, E> {
        IO {
            Read: r,
            Write: BufWriter::new(w),
            Error: BufWriter::new(e),
        }
    }
    fn read<T>(&mut self) -> T
    where
        T: std::str::FromStr,
    {
        let next: String = self
            .Read
            .by_ref()
            .bytes()
            .map(|c| c.unwrap() as char)
            .skip_while(|c| c.is_whitespace())
            .take_while(|c| !c.is_whitespace())
            .collect();
        next.parse().ok().unwrap()
    }
    fn chars(&mut self) -> Vec<char> {
        self.read::<String>().chars().collect()
    }
    fn readn<T: std::str::FromStr>(&mut self, n: usize) -> Vec<T> {
        (0..n).map(|_| self.read::<T>()).collect::<Vec<_>>()
    }
    fn readmat<T: std::str::FromStr>(&mut self, n: usize, m: usize) -> Vec<Vec<T>> {
        (0..n).map(|_| self.readn(m)).collect()
    }
    fn write<S: ToString>(&mut self, val: S) {
        self.Write.write(val.to_string().as_bytes());
    }
    fn writeln<S: ToString>(&mut self, val: S) {
        self.Write.write(val.to_string().as_bytes());
        self.Write.write(b"\n");
    }
    fn debug<S: std::fmt::Debug>(&mut self, val: S) {
        writeln!(self.Error, "(debug) {:?}", &val);
    }
    fn debug2<S: std::fmt::Debug, T: std::fmt::Debug>(&mut self, val1: S, val2: T) {
        writeln!(self.Error, "(debug2) {:?} -> {:?}", val1, val2);
    }
    fn debug3<S: std::fmt::Debug, T: std::fmt::Debug, U: std::fmt::Debug>(
        &mut self,
        val1: S,
        val2: T,
        val3: U,
    ) {
        writeln!(
            self.Error,
            "(debug3) {:?} -> {:?} -> {:?}",
            val1, val2, val3
        );
    }
}


#![allow(unused_imports)]
#![allow(unused_macros)]
#![allow(non_snake_case)]
#![allow(dead_code)]
#![allow(unused_variables)]
#![allow(unused_mut)]
use std::collections::{BTreeMap, BTreeSet, BinaryHeap, HashMap, HashSet, VecDeque};
use std::cmp::{max, min, Ordering};

macro_rules! get {
    ($t:ty) => {
        {
            let mut line: String = String::new();
            std::io::stdin().read_line(&mut line).unwrap();
            line.trim().parse::<$t>().unwrap()
        }
    };
    ($($t:ty),*) => {
        {
            let mut line: String = String::new();
            std::io::stdin().read_line(&mut line).unwrap();
            let mut iter = line.split_whitespace();
            (
                $(iter.next().unwrap().parse::<$t>().unwrap(),)*
            )
        }
    };
    ($t:ty; $n:expr) => {
        (0..$n).map(|_|
            get!($t)
        ).collect::<Vec<_>>()
    };
    ($($t:ty),*; $n:expr) => {
        (0..$n).map(|_|
            get!($($t),*)
        ).collect::<Vec<_>>()
    };
    ($t:ty ;;) => {
        {
            let mut line: String = String::new();
            std::io::stdin().read_line(&mut line).unwrap();
            line.split_whitespace()
                .map(|t| t.parse::<$t>().unwrap())
                .collect::<Vec<_>>()
        }
    };
    ($t:ty ;; $n:expr) => {
        (0..$n).map(|_| get!($t ;;)).collect::<Vec<_>>()
    };
}

// N M => let (N, M) = get!(usize, usize)
// A1 B1
// ...
// AQ BQ => let A = get!(usize, usize; Q)

const MOD: u64 = 1000000007;

fn main() {
    let (N1, N2, N3, N4) = get!(usize, usize, usize, usize);
    let mut A = [N1, N2, N3, N4];
    A.sort();

    if A == [1, 4, 7, 9] {
        println!("Yes");
    } else {
        println!("No");
    }
}


#![allow(unused_imports)]
#![allow(unused_macros)]
use std::cmp::{ min, max };

macro_rules! ewriteln {
    ($($args:expr),*) => { let _ = writeln!(&mut std::io::stderr(), $($args),*); };
}
macro_rules! trace {
    ($x:expr) => { ewriteln!(">>> {} = {:?}", stringify!($x), $x) };
    ($($xs:expr),*) => { trace!(($($xs),*)) }
}
macro_rules! put {
    ($x:expr) => { println!("{}", $x) };
    ($x:expr, $($xs:expr),*) => { print!("{} ", $x); put!($($xs),*) }
}

const M: i64 = 1_000_000_007;

fn main() {
    let mut sc = Scanner::new();

    use std::collections::HashSet;
    let mut a = HashSet::new();
    a.insert('1');
    a.insert('9');
    a.insert('7');
    a.insert('4');
    let mut b = HashSet::new();
    for _ in 0..4 {
        b.insert(sc.cin::<char>());
    }
    put!(if a==b { "YES" } else { "NO" });
}

use std::io::{self, Write};
use std::str::FromStr;
use std::collections::VecDeque;

struct Scanner { stdin: io::Stdin, buffer: VecDeque<String>, }
impl Scanner {
    fn new() -> Scanner { Scanner { stdin: io::stdin(), buffer: VecDeque::new() } }
    fn cin<T: FromStr>(&mut self) -> T {
        while self.buffer.len() == 0 {
            let mut line = String::new();
            let _ = self.stdin.read_line(&mut line);
            for w in line.split_whitespace() {
                self.buffer.push_back(String::from(w));
            }
        }
        self.buffer.pop_front().unwrap().parse::<T>().ok().unwrap()
    }
}


print(String(readLine()!.characters.sort())=="   1479" ?"YES":"NO")


print(String(readLine()!.characters.sorted())=="   1479" ?"YES":"NO")


print(String(readLine()!.sorted())=="   1479" ?"YES":"NO")


function Main(raw: string) {
    const lines = raw.split("\n");
    const [firstLine] = lines;
    const N = firstLine.split(" ").map(str=>parseInt(str, 10));
    N.sort();
    const ans = N[0]==1 &&
        N[1]==4 &&
        N[2]==7 &&
        N[3]==9;
    console.log(ans?"YES":"NO");
}

//DO NOT EDIT
Main(require("fs").readFileSync("/dev/stdin", "utf8"));


function Main(raw: string) {
    const lines = raw.split("\n");
    const [firstLine] = lines;
    const N = firstLine.split(" ").map(str=>parseInt(str, 10));
    N.sort();
    const ans = N[0]==1 &&
        N[1]==4 &&
        N[2]==7 &&
        N[3]==9;
    console.log("%d", ans?"YES":"NO");
}

//DO NOT EDIT
Main(require("fs").readFileSync("/dev/stdin", "utf8"));


import sys
sys.setrecursionlimit(1000000)

def main():
    def gcd(a, b):
        if a % b == 0:
            return b
        else:
            return gcd(b, a % b)

    def cul(n,x):
        l=len(x)
        b=[x[i] for i in range(l)]
        b.pop(n)
        tmp=b[0]
        for i in range(1,l-1):
            tmp=gcd(tmp,b[i])
        return tmp

    ans=0
    for i in range(p):
        s=cul(i,a[:p])
        if s>ans: ans=s
    print(ans)

if __name__=='__main__':
    N, *a = map(int, sys.stdin.read().split())
    p=50
    if p>N: p=N
    main()


def gcd(a, b):
    if b > a:
        a, b = b, a
    while b:
        a, b = b, a%b
    return a

def cul(n, x):
    l = len(x)
    b = x
    b.pop(n)
    tmp = b[0]
    for i in range(1, l-1):
        tmp = gcd(tmp, b[i])
    return tmp

import sys
p = 50
N = int(input())
if p>N: p=N
a = list(map(int, input().split()))

ans = 0
for i in range(p):
    s = cul(i, a[:p])
    if s>ans: ans=s

print(ans)


def gcd(a,b):
    if b>a:
        a,b=b,a
    while b:
        a,b=b, a%b
    return a

def cul(n,x):
    l=len(x)
    b=[x[i] for i in range(l)]
    b.pop(n)
    tmp=b[0]
    for i in range(1,l-1):
        tmp=gcd(tmp,b[i])
    return tmp

import sys
p=50
N=int(input())
if p>N: p=N
a=list(map(int,input().split()))

ans=0
for i in range(p):
    s=cul(i,a[:p])
    if s>ans: ans=s

print(ans)


class SegmentTree:
    # 初期化処理
    # f : SegmentTreeにのせるモノイド
    # default : fに対する単位元
    def __init__(self, size, f=lambda x,y : x+y, default=0):
        self.size = 2**(size-1).bit_length() # 簡単のため要素数Nを2冪にする
        self.default = default
        self.dat = [default]*(self.size*2) # 要素を単位元で初期化
        self.f = f

    def update(self, i, x):
        i += self.size
        self.dat[i] = x
        while i > 0:
            i >>= 1
            self.dat[i] = self.f(self.dat[i*2], self.dat[i*2+1])

    def query(self, l, r):
        l += self.size
        r += self.size
        lres, rres = self.default, self.default
        while l < r:
            if l & 1:
                lres = self.f(lres, self.dat[l])
                l += 1

            if r & 1:
                r -= 1
                rres = self.f(self.dat[r], rres) # モノイドでは可換律は保証されていないので演算の方向に注意
            l >>= 1
            r >>= 1
        res = self.f(lres, rres)
        return res

import math

n = int(input())
seg = SegmentTree(n, math.gcd)

A = list(map(int,input().split()))
for i in range(n):
    seg.update(i, A[i])

ans = 1
for i in range(n):
    tmp = A[i]
    seg.update(i, A[i-1])
    ans = max(ans, seg.query(0,n))
    seg.update(i, tmp)

print(ans)


import math
import sys
sys.setrecursionlimit(10**6)
class SegmentTree:
    """
    単位元のメモ書き（各演算に対する単位元の対応）
    f(x,y) := x+y -> 0
    f(x,y) := x-y -> 0
    f(x,y) := x*y -> 1
    f(x,y) := gcd(x, y) -> 0
    """

    def __init__(self, size, func=lambda x,y:x+y, default=0):
        """
        size : 配列のサイズ
        func : queryの内容(e.g. 区間和ならf(x, y)=x+y)
        default : 単位元
        """
        self.size = 2**(size-1).bit_length()
        self.default = default
        self.dat = [default for _ in range(self.size*2-1)]
        self.f = func

    def update(self, i, x):
        """
        i番目の値をxに変更する。0-indexedなので注意
        """
        i = i + self.size - 1 #一番下の層の値
        self.dat[i] = x

        while i > 0:
            i = (i-1)>>1
            self.dat[i] = self.f(self.dat[i*2+1], self.dat[i*2+2])

    def query(self, a, b, k=0, L=0, R=None):
        """
        区間[a, b]に関するクエリを処理します。
        例えばi=1,2,3に関して処理したいなら外からquery(1, 3+1)と呼ぶ必要があります。
        """
        if R is None:
            R = self.size

        #区間がかぶっていない場合
        if R <= a or b <= L:
            return self.default

        #区間が完全に収まっている場合
        if a <= L and R <= b:
            return self.dat[k]

        else:
            lres = self.query(a, b, 2*k+1, L, (L+R)>>1)
            rres = self.query(a, b, 2*k+2, (L+R)>>1, R)
            return self.f(lres, rres)

N = int(input())
A = list(map(int, input().split()))

segTree = SegmentTree(N, func=lambda x,y:math.gcd(x,y), default=0)
for i in range(N):
    segTree.update(i, A[i])

ans = -1
for i in range(N-1):
    a = segTree.query(0, i)
    b = segTree.query(i+1, N)
    ans = max(ans, math.gcd(a,b))

print(ans)


import math
import sys
sys.setrecursionlimit(10**6)
class SegmentTree:

    def __init__(self, size, func=lambda x,y:x+y, default=0):
        """
        size : 配列のサイズ
        func : queryの内容(e.g. 区間和ならf(x, y)=x+y)
        default : 単位元
        """
        self.size = 2**(size-1).bit_length()
        self.default = default
        self.dat = [default for _ in range(self.size*2-1)]
        self.f = func

    def update(self, i, x):
        """
        i番目の値をxに変更する。0-indexedなので注意
        """
        i = i + self.size - 1 #一番下の層の値
        self.dat[i] = x

        while i > 0:
            i = (i-1)>>1
            self.dat[i] = self.f(self.dat[i*2+1], self.dat[i*2+2])

    def query(self, a, b, k=0, L=0, R=None):
        """
        区間[a, b]に関するクエリを処理します。
        例えばi=1,2,3に関して処理したいなら外からquery(1, 3+1)と呼ぶ必要があります。
        """
        if R is None:
            R = self.size

        #区間がかぶっていない場合
        if R <= a or b <= L:
            return self.default

        #区間が完全に収まっている場合
        if a <= L and R <= b:
            return self.dat[k]

        else:
            lres = self.query(a, b, 2*k+1, L, (L+R)>>1)
            rres = self.query(a, b, 2*k+2, (L+R)>>1, R)
            return self.f(lres, rres)

N = int(input())
A = list(map(int, input().split()))

segTree = SegmentTree(N, func=lambda x,y:math.gcd(x,y), default=0)
for i in range(N):
    segTree.update(i, A[i])

ans = -1
for i in range(N-1):
    a = segTree.query(0, i)
    b = segTree.query(i+1, N)
    ans = max(ans, math.gcd(a,b))

print(ans)


import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.InputMismatchException;

public class Main {
    static InputStream is;
    static PrintWriter out;
    static String INPUT = "";
    static int lenbuf = 0, ptrbuf = 0;
    private static byte[] inbuf = new byte[1024];

    static int gcd(int a, int b) {
        while (b != 0) {
            int t = a % b;
            a = b;
            b = t;
        }
        return a;
    }
//    private static int gcd(int a, int b) {
//        if (b == 0L) {
//            return a;
//        }
//        return gcd(b, a % b);
//    }

    static void solve() {
        int n = ni();
        int[] a = new int[n + 2];
        for (int i = 1; i <= n; i++) {
            a[i] = ni();
        }
        int[] left = new int[n + 2], right = new int[n + 2];

        for (int i = 1; i <= n; i++) {
            left[i] = gcd(left[i - 1], a[i]);
        }
        for (int i = n; i >= 1; i--) {
            right[i] = gcd(right[i + 1], a[i]);
        }
        int res = 1;
        for (int i = 1; i <= n; i++) {
            int t = gcd(left[i - 1], right[i + 1]);
            res = Math.max(res, t);
        }
        System.out.println(res);

    }

    static void execute() throws IOException {
            solve();
    }

    public static void main(String[] args) throws Exception {
        long S = System.currentTimeMillis();
        is = INPUT.isEmpty() ? System.in : new ByteArrayInputStream(INPUT.getBytes());
        out = new PrintWriter(System.out);

        execute();
        out.flush();
        long G = System.currentTimeMillis();
        tr(G - S + "ms");
    }

    private static boolean eof() {
        if (lenbuf == -1) {
            return true;
        }
        int lptr = ptrbuf;
        while (lptr < lenbuf) {
            if (!isSpaceChar(inbuf[lptr++])) {
                return false;
            }
        }

        try {
            is.mark(1000);
            while (true) {
                int b = is.read();
                if (b == -1) {
                    is.reset();
                    return true;
                } else if (!isSpaceChar(b)) {
                    is.reset();
                    return false;
                }
            }
        } catch (IOException e) {
            return true;
        }
    }

    private static int readByte() {
        if (lenbuf == -1) {
            throw new InputMismatchException();
        }
        if (ptrbuf >= lenbuf) {
            ptrbuf = 0;
            try {
                lenbuf = is.read(inbuf);
            } catch (IOException e) {
                throw new InputMismatchException();
            }
            if (lenbuf <= 0) {
                return -1;
            }
        }
        return inbuf[ptrbuf++];
    }

    private static boolean isSpaceChar(int c) {
        return !(c >= 33 && c <= 126);
    }

    //	private static boolean isSpaceChar(int c) { return !(c >= 32 && c <= 126); }
    private static int skip() {
        int b;
        while ((b = readByte()) != -1 && isSpaceChar(b)) {
            ;
        }
        return b;
    }

    private static double nd() {
        return Double.parseDouble(ns());
    }

    private static char nc() {
        return (char) skip();
    }

    private static String ns() {
        int b = skip();
        StringBuilder sb = new StringBuilder();
        while (!(isSpaceChar(b))) {
            sb.appendCodePoint(b);
            b = readByte();
        }
        return sb.toString();
    }

    private static char[] ns(int n) {
        char[] buf = new char[n];
        int b = skip(), p = 0;
        while (p < n && !(isSpaceChar(b))) {
            buf[p++] = (char) b;
            b = readByte();
        }
        return n == p ? buf : Arrays.copyOf(buf, p);
    }

    private static char[][] nm(int n, int m) {
        char[][] map = new char[n][];
        for (int i = 0; i < n; i++) {
            map[i] = ns(m);
        }
        return map;
    }

    private static int[] na(int n) {
        int[] a = new int[n];
        for (int i = 0; i < n; i++) {
            a[i] = ni();
        }
        return a;
    }

    private static int ni() {
        int num = 0, b;
        boolean minus = false;
        while ((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-')) {
            ;
        }
        if (b == '-') {
            minus = true;
            b = readByte();
        }

        while (true) {
            if (b >= '0' && b <= '9') {
                num = num * 10 + (b - '0');
            } else {
                return minus ? -num : num;
            }
            b = readByte();
        }
    }

    private static long nl() {
        long num = 0;
        int b;
        boolean minus = false;
        while ((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-')) {
            ;
        }
        if (b == '-') {
            minus = true;
            b = readByte();
        }

        while (true) {
            if (b >= '0' && b <= '9') {
                num = num * 10 + (b - '0');
            } else {
                return minus ? -num : num;
            }
            b = readByte();
        }
    }

    private static void tr(Object... o) {
        if (INPUT.length() != 0) {
            System.out.println(Arrays.deepToString(o));
        }
    }
}


import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.InputMismatchException;

public class Main {
    static InputStream is;
    static PrintWriter out;
    static String INPUT = "";
    static int lenbuf = 0, ptrbuf = 0;
    private static byte[] inbuf = new byte[1024];

//    static int gcd(int a, int b) {
//        while (b != 0) {
//            int t = a % b;
//            a = b;
//            b = t;
//        }
//        return a;
//    }
    private static int gcd(int a, int b) {
        if (b == 0L) {
            return a;
        }
        return gcd(b, a % b);
    }

    static void solve() {
        int n = ni();
        int[] a = new int[n + 2];
        for (int i = 1; i <= n; i++) {
            a[i] = ni();
        }
        int[] left = new int[n + 2], right = new int[n + 2];

        for (int i = 1; i <= n; i++) {
            left[i] = gcd(left[i - 1], a[i]);
        }
        for (int i = n; i >= 1; i--) {
            right[i] = gcd(right[i + 1], a[i]);
        }
        int res = 1;
        for (int i = 1; i <= n; i++) {
            int t = gcd(left[i - 1], right[i + 1]);
            res = Math.max(res, t);
        }
        System.out.println(res);

    }

    static void execute() throws IOException {
            solve();
    }

    public static void main(String[] args) throws Exception {
        long S = System.currentTimeMillis();
        is = INPUT.isEmpty() ? System.in : new ByteArrayInputStream(INPUT.getBytes());
        out = new PrintWriter(System.out);

        execute();
        out.flush();
        long G = System.currentTimeMillis();
        tr(G - S + "ms");
    }

    private static boolean eof() {
        if (lenbuf == -1) {
            return true;
        }
        int lptr = ptrbuf;
        while (lptr < lenbuf) {
            if (!isSpaceChar(inbuf[lptr++])) {
                return false;
            }
        }

        try {
            is.mark(1000);
            while (true) {
                int b = is.read();
                if (b == -1) {
                    is.reset();
                    return true;
                } else if (!isSpaceChar(b)) {
                    is.reset();
                    return false;
                }
            }
        } catch (IOException e) {
            return true;
        }
    }

    private static int readByte() {
        if (lenbuf == -1) {
            throw new InputMismatchException();
        }
        if (ptrbuf >= lenbuf) {
            ptrbuf = 0;
            try {
                lenbuf = is.read(inbuf);
            } catch (IOException e) {
                throw new InputMismatchException();
            }
            if (lenbuf <= 0) {
                return -1;
            }
        }
        return inbuf[ptrbuf++];
    }

    private static boolean isSpaceChar(int c) {
        return !(c >= 33 && c <= 126);
    }

    //	private static boolean isSpaceChar(int c) { return !(c >= 32 && c <= 126); }
    private static int skip() {
        int b;
        while ((b = readByte()) != -1 && isSpaceChar(b)) {
            ;
        }
        return b;
    }

    private static double nd() {
        return Double.parseDouble(ns());
    }

    private static char nc() {
        return (char) skip();
    }

    private static String ns() {
        int b = skip();
        StringBuilder sb = new StringBuilder();
        while (!(isSpaceChar(b))) {
            sb.appendCodePoint(b);
            b = readByte();
        }
        return sb.toString();
    }

    private static char[] ns(int n) {
        char[] buf = new char[n];
        int b = skip(), p = 0;
        while (p < n && !(isSpaceChar(b))) {
            buf[p++] = (char) b;
            b = readByte();
        }
        return n == p ? buf : Arrays.copyOf(buf, p);
    }

    private static char[][] nm(int n, int m) {
        char[][] map = new char[n][];
        for (int i = 0; i < n; i++) {
            map[i] = ns(m);
        }
        return map;
    }

    private static int[] na(int n) {
        int[] a = new int[n];
        for (int i = 0; i < n; i++) {
            a[i] = ni();
        }
        return a;
    }

    private static int ni() {
        int num = 0, b;
        boolean minus = false;
        while ((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-')) {
            ;
        }
        if (b == '-') {
            minus = true;
            b = readByte();
        }

        while (true) {
            if (b >= '0' && b <= '9') {
                num = num * 10 + (b - '0');
            } else {
                return minus ? -num : num;
            }
            b = readByte();
        }
    }

    private static long nl() {
        long num = 0;
        int b;
        boolean minus = false;
        while ((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-')) {
            ;
        }
        if (b == '-') {
            minus = true;
            b = readByte();
        }

        while (true) {
            if (b >= '0' && b <= '9') {
                num = num * 10 + (b - '0');
            } else {
                return minus ? -num : num;
            }
            b = readByte();
        }
    }

    private static void tr(Object... o) {
        if (INPUT.length() != 0) {
            System.out.println(Arrays.deepToString(o));
        }
    }
}


import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.InputMismatchException;

public class Main {

	InputStream is;
	PrintWriter out;
	String INPUT = "";

	int gcd(int a, int b) {
		while (b != 0) {
			int t = b;
			b = a % b;
			a = t;
		}
		return a;
	}

	void solve() {

		int n = ni();
		int a[] = na(n);
		int gcd1[] = new int[n + 1];
		gcd1[0] = 0;
		for (int i = 0; i < n; i++)
			gcd1[i + 1] = gcd(gcd1[i], a[i]);
		int gcd2[] = new int[n + 1];
		gcd2[n] = 0;
		for (int i = n - 1; i >= 0; i--)
			gcd2[i] = gcd(gcd2[i + 1], a[i]);
		int ans = 0;
		for (int i = 0; i < n; i++)
			ans = Math.max(gcd(gcd1[i], gcd2[i + 1]), ans);
		out.println(ans);

	}

	void run() throws Exception {
		is = INPUT.isEmpty() ? System.in : new ByteArrayInputStream(INPUT.getBytes());
		out = new PrintWriter(System.out);

		long s = System.currentTimeMillis();
		solve();
		out.flush();
		if (!INPUT.isEmpty())
			tr(System.currentTimeMillis() - s + "ms");
	}

	public static void main(String[] args) throws Exception {
		new Main().run();
	}

	private byte[] inbuf = new byte[1024];
	public int lenbuf = 0, ptrbuf = 0;

	private int readByte() {
		if (lenbuf == -1)
			throw new InputMismatchException();
		if (ptrbuf >= lenbuf) {
			ptrbuf = 0;
			try {
				lenbuf = is.read(inbuf);
			} catch (IOException e) {
				throw new InputMismatchException();
			}
			if (lenbuf <= 0)
				return -1;
		}
		return inbuf[ptrbuf++];
	}

	private boolean isSpaceChar(int c) {
		return !(c >= 33 && c <= 126);
	}

	private int skip() {
		int b;
		while ((b = readByte()) != -1 && isSpaceChar(b))
			;
		return b;
	}

	private double nd() {
		return Double.parseDouble(ns());
	}

	private char nc() {
		return (char) skip();
	}

	private String ns() {
		int b = skip();
		StringBuilder sb = new StringBuilder();
		while (!(isSpaceChar(b))) { // when nextLine, (isSpaceChar(b) && b != '
									// ')
			sb.appendCodePoint(b);
			b = readByte();
		}
		return sb.toString();
	}

	private char[] ns(int n) {
		char[] buf = new char[n];
		int b = skip(), p = 0;
		while (p < n) {
			if (!(isSpaceChar(b)))
				buf[p++] = (char) b;
			b = readByte();
		}
		return n == p ? buf : Arrays.copyOf(buf, p);
	}

	private char[][] nm(int n, int m) {
		char[][] map = new char[n][];
		for (int i = 0; i < n; i++)
			map[i] = ns(m);
		return map;
	}

	private int[] na(int n) {
		int[] a = new int[n];
		for (int i = 0; i < n; i++)
			a[i] = ni();
		return a;
	}

	private int[][] na(int n, int m) {
		int[][] a = new int[n][];
		for (int i = 0; i < n; i++)
			a[i] = na(m);
		return a;
	}

	private int ni() {
		int num = 0, b;
		boolean minus = false;
		while ((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'))
			;
		if (b == '-') {
			minus = true;
			b = readByte();
		}

		while (true) {
			if (b >= '0' && b <= '9') {
				num = num * 10 + (b - '0');
			} else {
				return minus ? -num : num;
			}
			b = readByte();
		}
	}

	private long nl() {
		long num = 0;
		int b;
		boolean minus = false;
		while ((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'))
			;
		if (b == '-') {
			minus = true;
			b = readByte();
		}

		while (true) {
			if (b >= '0' && b <= '9') {
				num = num * 10 + (b - '0');
			} else {
				return minus ? -num : num;
			}
			b = readByte();
		}
	}

	private static void tr(Object... o) {
		System.out.println(Arrays.deepToString(o));
	}
}


import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.InputMismatchException;

public class Main {
    static InputStream is;
    static PrintWriter out;
    static String INPUT = "";
    static int lenbuf = 0, ptrbuf = 0;
    private static byte[] inbuf = new byte[1024];

//    static int gcd(int a, int b) {
//        while (b != 0) {
//            int t = a % b;
//            a = b;
//            b = t;
//        }
//        return a;
//    }
    private static int gcd(int a, int b) {
        if (b == 0L) {
            return a;
        }
        return gcd(b, a % b);
    }

    static void solve() {
        int n = ni();
        int[] a = new int[n + 2];
        for (int i = 1; i <= n; i++) {
            a[i] = ni();
        }
        int[] left = new int[n + 2], right = new int[n + 2];

        for (int i = 1; i <= n; i++) {
            left[i] = gcd(left[n - 2], a[i]);
        }
        for (int i = n; i >= 1; i--) {
            right[i] = gcd(right[i + 1], a[i]);
        }
        int res = 1;
        for (int i = 1; i <= n; i++) {
            int t = gcd(left[i - 1], right[i + 1]);
            res = Math.max(res, t);
        }
        System.out.println(res);

    }

    static void execute() throws IOException {
            solve();
    }

    public static void main(String[] args) throws Exception {
        long S = System.currentTimeMillis();
        is = INPUT.isEmpty() ? System.in : new ByteArrayInputStream(INPUT.getBytes());
        out = new PrintWriter(System.out);

        execute();
        out.flush();
        long G = System.currentTimeMillis();
        tr(G - S + "ms");
    }

    private static boolean eof() {
        if (lenbuf == -1) {
            return true;
        }
        int lptr = ptrbuf;
        while (lptr < lenbuf) {
            if (!isSpaceChar(inbuf[lptr++])) {
                return false;
            }
        }

        try {
            is.mark(1000);
            while (true) {
                int b = is.read();
                if (b == -1) {
                    is.reset();
                    return true;
                } else if (!isSpaceChar(b)) {
                    is.reset();
                    return false;
                }
            }
        } catch (IOException e) {
            return true;
        }
    }

    private static int readByte() {
        if (lenbuf == -1) {
            throw new InputMismatchException();
        }
        if (ptrbuf >= lenbuf) {
            ptrbuf = 0;
            try {
                lenbuf = is.read(inbuf);
            } catch (IOException e) {
                throw new InputMismatchException();
            }
            if (lenbuf <= 0) {
                return -1;
            }
        }
        return inbuf[ptrbuf++];
    }

    private static boolean isSpaceChar(int c) {
        return !(c >= 33 && c <= 126);
    }

    //	private static boolean isSpaceChar(int c) { return !(c >= 32 && c <= 126); }
    private static int skip() {
        int b;
        while ((b = readByte()) != -1 && isSpaceChar(b)) {
            ;
        }
        return b;
    }

    private static double nd() {
        return Double.parseDouble(ns());
    }

    private static char nc() {
        return (char) skip();
    }

    private static String ns() {
        int b = skip();
        StringBuilder sb = new StringBuilder();
        while (!(isSpaceChar(b))) {
            sb.appendCodePoint(b);
            b = readByte();
        }
        return sb.toString();
    }

    private static char[] ns(int n) {
        char[] buf = new char[n];
        int b = skip(), p = 0;
        while (p < n && !(isSpaceChar(b))) {
            buf[p++] = (char) b;
            b = readByte();
        }
        return n == p ? buf : Arrays.copyOf(buf, p);
    }

    private static char[][] nm(int n, int m) {
        char[][] map = new char[n][];
        for (int i = 0; i < n; i++) {
            map[i] = ns(m);
        }
        return map;
    }

    private static int[] na(int n) {
        int[] a = new int[n];
        for (int i = 0; i < n; i++) {
            a[i] = ni();
        }
        return a;
    }

    private static int ni() {
        int num = 0, b;
        boolean minus = false;
        while ((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-')) {
            ;
        }
        if (b == '-') {
            minus = true;
            b = readByte();
        }

        while (true) {
            if (b >= '0' && b <= '9') {
                num = num * 10 + (b - '0');
            } else {
                return minus ? -num : num;
            }
            b = readByte();
        }
    }

    private static long nl() {
        long num = 0;
        int b;
        boolean minus = false;
        while ((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-')) {
            ;
        }
        if (b == '-') {
            minus = true;
            b = readByte();
        }

        while (true) {
            if (b >= '0' && b <= '9') {
                num = num * 10 + (b - '0');
            } else {
                return minus ? -num : num;
            }
            b = readByte();
        }
    }

    private static void tr(Object... o) {
        if (INPUT.length() != 0) {
            System.out.println(Arrays.deepToString(o));
        }
    }
}


import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.InputMismatchException;

public class Main {
    static InputStream is;
    static PrintWriter out;
    static String INPUT = "";
    static int lenbuf = 0, ptrbuf = 0;
    private static byte[] inbuf = new byte[1024];

    static void solve() {
        int n = ni();
        int[] a = na(n);
        int max = 0;
        for (int num : a) {
            max = Math.max(max, num);
        }

        for (int i = max; i >= 2; i--) {
            int cnt = 0;
            boolean ok = true;
            for (int num : a) {
                if (num %i != 0) {
                    cnt++;
                }
                if (cnt >= 2) {
                    ok = false;
                    break;
                }
            }
            if (ok) {
                out.println(i);
                return;
            }
        }

    }

    static void execute() throws IOException {
            solve();
    }

    public static void main(String[] args) throws Exception {
        long S = System.currentTimeMillis();
        is = INPUT.isEmpty() ? System.in : new ByteArrayInputStream(INPUT.getBytes());
        out = new PrintWriter(System.out);

        execute();
        out.flush();
        long G = System.currentTimeMillis();
        tr(G - S + "ms");
    }

    private static boolean eof() {
        if (lenbuf == -1) {
            return true;
        }
        int lptr = ptrbuf;
        while (lptr < lenbuf) {
            if (!isSpaceChar(inbuf[lptr++])) {
                return false;
            }
        }

        try {
            is.mark(1000);
            while (true) {
                int b = is.read();
                if (b == -1) {
                    is.reset();
                    return true;
                } else if (!isSpaceChar(b)) {
                    is.reset();
                    return false;
                }
            }
        } catch (IOException e) {
            return true;
        }
    }

    private static int readByte() {
        if (lenbuf == -1) {
            throw new InputMismatchException();
        }
        if (ptrbuf >= lenbuf) {
            ptrbuf = 0;
            try {
                lenbuf = is.read(inbuf);
            } catch (IOException e) {
                throw new InputMismatchException();
            }
            if (lenbuf <= 0) {
                return -1;
            }
        }
        return inbuf[ptrbuf++];
    }

    private static boolean isSpaceChar(int c) {
        return !(c >= 33 && c <= 126);
    }

    //	private static boolean isSpaceChar(int c) { return !(c >= 32 && c <= 126); }
    private static int skip() {
        int b;
        while ((b = readByte()) != -1 && isSpaceChar(b)) {
            ;
        }
        return b;
    }

    private static double nd() {
        return Double.parseDouble(ns());
    }

    private static char nc() {
        return (char) skip();
    }

    private static String ns() {
        int b = skip();
        StringBuilder sb = new StringBuilder();
        while (!(isSpaceChar(b))) {
            sb.appendCodePoint(b);
            b = readByte();
        }
        return sb.toString();
    }

    private static char[] ns(int n) {
        char[] buf = new char[n];
        int b = skip(), p = 0;
        while (p < n && !(isSpaceChar(b))) {
            buf[p++] = (char) b;
            b = readByte();
        }
        return n == p ? buf : Arrays.copyOf(buf, p);
    }

    private static char[][] nm(int n, int m) {
        char[][] map = new char[n][];
        for (int i = 0; i < n; i++) {
            map[i] = ns(m);
        }
        return map;
    }

    private static int[] na(int n) {
        int[] a = new int[n];
        for (int i = 0; i < n; i++) {
            a[i] = ni();
        }
        return a;
    }

    private static int ni() {
        int num = 0, b;
        boolean minus = false;
        while ((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-')) {
            ;
        }
        if (b == '-') {
            minus = true;
            b = readByte();
        }

        while (true) {
            if (b >= '0' && b <= '9') {
                num = num * 10 + (b - '0');
            } else {
                return minus ? -num : num;
            }
            b = readByte();
        }
    }

    private static long nl() {
        long num = 0;
        int b;
        boolean minus = false;
        while ((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-')) {
            ;
        }
        if (b == '-') {
            minus = true;
            b = readByte();
        }

        while (true) {
            if (b >= '0' && b <= '9') {
                num = num * 10 + (b - '0');
            } else {
                return minus ? -num : num;
            }
            b = readByte();
        }
    }

    private static void tr(Object... o) {
        if (INPUT.length() != 0) {
            System.out.println(Arrays.deepToString(o));
        }
    }
}


import java.util.Arrays;
import java.util.Scanner;
import java.util.stream.IntStream;

public class Main {

	public static void main(String[] args) {
		try (Scanner scanner = new Scanner(System.in)) {
			int n = scanner.nextInt();
			long[] a = IntStream.range(0, n).mapToLong(i -> scanner.nextLong()).toArray();
			System.out.println(getResult(0, n, a));
		}
	}

	/**
	 * 配列のstartからlength個の数字の中でlength-1個の数字のgcdの最大値を計算する
	 *
	 * @param start  開始位置
	 * @param length 処理する個数
	 * @param a      配列
	 * @return startからlength個の数字の中でlength-1個の数字のgcdの最大値
	 */
	private static long getResult(int start, int length, long[] a) {
		if (length >= 4) {
			return max(gcd(gcd(start, length / 2, a), getResult(start + length / 2, length - length / 2, a)),
					gcd(getResult(start, length / 2, a), gcd(start + length / 2, length - length / 2, a)));
		} else if (3 == length) {
			return max(gcd(a[start], a[start + 1]), gcd(a[start], a[start + 2]), gcd(a[start + 1], a[start + 2]));
		} else if (2 == length) {
			return max(a[start], a[start + 1]);
		}
		return 1_000_000_000L;
	}

	/**
	 * 配列のstartからlength個の数字のgcdを計算する
	 *
	 * @param start  開始位置
	 * @param length 処理する個数
	 * @param a      配列
	 * @return
	 */
	private static long gcd(int start, int length, long[] a) {
		long result = a[start];
		for (int i = 1; i < length; i++) {
			result = gcd(result, a[start + i]);
		}
		return result;
	}

	/**
	 * mとnの最大公約数を返す
	 *
	 * @param m
	 * @param n
	 * @return mとnの最大公約数
	 */
	private static long gcd(long m, long n) {
		if (0L == n) {
			return m;
		}
		return gcd(n, m % n);
	}

	/**
	 * 配列の最大値を計算する
	 *
	 * @param a 配列
	 * @return 配列の最大値
	 */
	private static long max(long... a) {
		return Arrays.stream(a).max().getAsLong();
	}
}


#pragma GCC optimize ("O3")
#pragma GCC target ("avx")
//#include<bits/stdc++.h>
#include<cstdio>
#include<algorithm>
#include<set>
#include<cmath>
using namespace std;
typedef long long ll;
#define rep(i, n) for(int i = 0; i < (n); i++)
#define rep1(i, n) for(int i = 1; i <= (n); i++)
#define co(x) cout << (x) << "\n"
#define cosp(x) cout << (x) << " "
#define ce(x) cerr << (x) << "\n"
#define cesp(x) cerr << (x) << " "
#define pb push_back
#define mp make_pair
#define chmin(x, y) x = min(x, y)
#define chmax(x, y) x = max(x, y)
#define Would
#define you
#define please

const int cm = 1 << 17;
char cn[cm], * ci = cn + cm, ct;
inline char getcha() {
	if (ci - cn == cm) { fread_unlocked(cn, 1, cm, stdin); ci = cn; }
	return *ci++;
}
inline int getint() {
	int A = 0;
	if (ci - cn + 16 > cm) while ((ct = getcha()) >= '0') A = A * 10 + ct - '0';
	else while ((ct = *ci++) >= '0') A = A * 10 + ct - '0';
	return A;
}

int main() {
	int N = getint();
	int A[100000];
	rep(i, N) A[i] = getint();

	set<int> ST;
	int M = sqrt(A[0]);
	for (int i = M; i >= 1; i--) {
		if (A[0] % i == 0) {
			ST.insert(i);
			ST.insert(A[0] / i);
		}
	}
	M = sqrt(A[1]);
	for (int i = M; i >= 1; i--) {
		if (A[1] % i == 0) {
			ST.insert(i);
			ST.insert(A[1] / i);
		}
	}
	for (auto itr = ST.rbegin(); itr != ST.rend(); itr++) {
		int k = 0;
		rep(i, N) {
			if (A[i] % (*itr)) k++;
			if (k > 1) break;
		}
		if (k <= 1) {
			printf("%d", *itr);
			break;
		}
	}

	Would you please return 0;
}


#pragma GCC optimize ("O3")
#pragma GCC target ("avx")
//#include<bits/stdc++.h>
#include<cstdio>
#include<algorithm>
#include<vector>
#include<cmath>
using namespace std;
typedef long long ll;
#define rep(i, n) for(int i = 0; i < (n); i++)
#define rep1(i, n) for(int i = 1; i <= (n); i++)
#define co(x) cout << (x) << "\n"
#define cosp(x) cout << (x) << " "
#define ce(x) cerr << (x) << "\n"
#define cesp(x) cerr << (x) << " "
#define pb push_back
#define mp make_pair
#define chmin(x, y) x = min(x, y)
#define chmax(x, y) x = max(x, y)
#define Would
#define you
#define please

const int cm = 1 << 17;
char cn[cm], * ci = cn + cm, ct;
inline char getcha() {
	if (ci - cn == cm) { fread_unlocked(cn, 1, cm, stdin); ci = cn; }
	return *ci++;
}
inline int getint() {
	int A = 0;
	if (ci - cn + 16 > cm) while ((ct = getcha()) >= '0') A = A * 10 + ct - '0';
	else while ((ct = *ci++) >= '0') A = A * 10 + ct - '0';
	return A;
}

int main() {
	int N = getint();
	int A[100000];
	rep(i, N) A[i] = getint();

	vector<int> V;
	int M = sqrt(A[0]);
	for (int i = M; i >= 1; i--) {
		if (A[0] % i == 0) {
			V.pb(i);
			V.pb(A[0] / i);
		}
	}
	M = sqrt(A[1]);
	for (int i = M; i >= 1; i--) {
		if (A[1] % i == 0) {
			V.pb(i);
			V.pb(A[1] / i);
		}
	}
	sort(V.begin(), V.end());
	for (auto itr = V.rbegin(); itr != V.rend(); itr++) {
		int k = 0;
		rep(i, N) {
			if (A[i] % (*itr)) k++;
			if (k > 1) break;
		}
		if (k <= 1) {
			printf("%d", *itr);
			break;
		}
	}

	Would you please return 0;
}


#include <iostream>
#include <vector>
#include <set>
#include <algorithm>
#include <math.h>
#include <string.h>
#include <map>
#include <numeric>
#include <random>
using namespace std;

const int cm = 1 << 17;
char cn[cm], *ci = cn + cm, ct;
inline char getcha() {
	if (ci - cn == cm) { fread(cn, 1, cm, stdin); ci = cn; }
	return *ci++;
}
inline int getint() {
	int A = 0;
	if (ci - cn + 16 > cm) while ((ct = getcha()) >= '0') A = A * 10 + ct - '0';
	else while ((ct = *ci++) >= '0') A = A * 10 + ct - '0';
	return A;
}

int gcd(int a, int b) {
	if (b == 0) {
		return a;
	}
	return gcd(b, a % b);
}

int gcd_of_vector(int A[100000], int begin, int end){
  int result = A[begin];
  for(int i=begin;i<end;i++){
    result = gcd(A[i],result);
  }
  return result;
}

int gcd_of_vector_with_skip(int A[100000], int skip, int size){
  int result = A[0];
  if(skip==0)result=A[1];
  for(int i=1;i<size;i++){
    if(i==skip)continue;
    result = gcd(A[i],result);
  }
  return result;
}

int main() {
  int gcd1,gcd2,ans,N=getint();
  int A[100000];
  for(int i=0;i<N;i++)A[i]=getint();

  if(N>=100){
    ans=1000000010;
    gcd1 = gcd_of_vector(A,0,N/2);
    gcd2 = gcd_of_vector(A,N/2,N);
    ans = max(gcd1,gcd2);
  }else{
    ans=0;
    for(int i=0;i<N;i++){
      ans=max(ans,gcd_of_vector_with_skip(A,i,N));
    }
  }

  cout<<ans<<"\n";

  return 0;
}


#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ld = long double;
#define rep(i, n) for (int i = 0; i < (int)(n); i++)
#define rrep(i, n) for (int i = 1; i < (int)(n+1); i++)
const int MAX = 510000;
const int MOD = 1000000007;

//二項係数ライブラリ
long long fac[MAX], finv[MAX], inv[MAX];
// テーブルを作る前処理
void COMinit() {
    fac[0] = fac[1] = 1;
    finv[0] = finv[1] = 1;
    inv[1] = 1;
    for (int i = 2; i < MAX; i++) {
        fac[i] = fac[i - 1] * i % MOD;
        inv[i] = MOD - inv[MOD % i] * (MOD / i) % MOD;
        finv[i] = finv[i - 1] * inv[i] % MOD;
    }
}

// 二項係数計算
long long COM(ll n, ll k) {
    if (n < k)
        return 0;
    if (n < 0 || k < 0)
        return 0;
    if (n == k) {
        return 1;
    }
    return fac[n] * (finv[k] * finv[n - k] % MOD) % MOD;
}
int main() {
    int N;
    cin>>N;
    vector<int>A(N);
    vector<int>ansa(N+1);
    vector<int>ansb(N+1);
    int g=0;
    rep(i,N){
        cin>>A[i];
            g=__gcd(g,A[i]);
        	ansa[0]=A[N-1];
        ansa[i+1]=g;
    }
    int gc=0;
    rep(i,N+1){
            gc=__gcd(gc,A[N-i-1]);
        ansb[i+1]=gc;
    }
      ansb[0]=A[0];
    ll ans=0;
    rep(i,N+1){
        if(ans<__gcd(ansa[i],ansb[N-i-1])){
            ans=__gcd(ansa[i],ansb[N-i-1]);
        }
    }
    cout<<ans<<endl;
}


#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ld = long double;
#define rep(i, n) for (int i = 0; i < (int)(n); i++)
#define rrep(i, n) for (int i = 1; i < (int)(n+1); i++)
int main() {
    int N;
    cin>>N;
    vector<int>A(N);
    vector<int>ansa(N+1);
    vector<int>ansb(N+1);
    int g=0;
    rep(i,N){
        cin>>A[i];
            g=__gcd(g,A[i]);
        	ansa[0]=A[N-1];
        ansa[i+1]=g;
    }
    int gc=0;
    rep(i,N+1){
            gc=__gcd(gc,A[N-i-1]);
        ansb[i+1]=gc;
    }
      ansb[0]=A[0];
    ll ans=0;
    rep(i,N){
        if(ans<__gcd(ansa[i],ansb[N-i])){
            ans=__gcd(ansa[i],ansb[N-i]);
        }
    }
    cout<<ans<<endl;
}


#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ld = long double;
#define rep(i, n) for (int i = 0; i < (int)(n); i++)
#define rrep(i, n) for (int i = 1; i < (int)(n+1); i++)
const int MAX = 510000;
const int MOD = 1000000007;

//二項係数ライブラリ
long long fac[MAX], finv[MAX], inv[MAX];
// テーブルを作る前処理
void COMinit() {
    fac[0] = fac[1] = 1;
    finv[0] = finv[1] = 1;
    inv[1] = 1;
    for (int i = 2; i < MAX; i++) {
        fac[i] = fac[i - 1] * i % MOD;
        inv[i] = MOD - inv[MOD % i] * (MOD / i) % MOD;
        finv[i] = finv[i - 1] * inv[i] % MOD;
    }
}

// 二項係数計算
long long COM(ll n, ll k) {
    if (n < k)
        return 0;
    if (n < 0 || k < 0)
        return 0;
    if (n == k) {
        return 1;
    }
    return fac[n] * (finv[k] * finv[n - k] % MOD) % MOD;
}
int main() {
    ll N;
    cin>>N;
    vector<ll>A(N);
    vector<ll>ansa(N+1);
    vector<ll>ansb(N+1);
    ll g=0;
    rep(i,N){
        cin>>A[i];
            g=__gcd(g,A[i]);
        	ansa[0]=A[N-1];
        ansa[i+1]=g;
    }
    ll gc=0;
    rep(i,N+1){
            gc=__gcd(gc,A[N-i-1]);
        ansb[i+1]=gc;
    }
      ansb[0]=A[0];
    ll ans=0;
    rep(i,N+1){
        if(ans<__gcd(ansa[i],ansb[N-i])){
            ans=__gcd(ansa[i],ansb[N-i]);
        }
    }
    cout<<ans<<endl;
}


#include <float.h>
#include <inttypes.h>
#include <limits.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include <math.h>
#ifdef __cplusplus
#include <bits/stdc++.h>
#endif

__asm__ (
	"asm_my_gcd2_in:"
	"movl $0, %edx;"
	"divl %ecx;"
	"cmpl $0, %edx;"
	"jz asm_my_gcd2_in2;"
	"asm_my_gcd2_in1:"
	"movl %ecx, %eax;"
	"movl %edx, %ecx;"
	"movl $0, %edx;"
	"divl %ecx;"
	"cmpl $0, %edx;"
	"jnz asm_my_gcd2_in1;"
	"asm_my_gcd2_in2:"
	"ret;"
);

inline int gcd(uint32_t a, uint32_t b){
	if(a==0 || b==0) return a==0?b:a;
	uint32_t ans;
	__asm__ (
	"movl %1, %%ecx;"
	"movl %2, %%eax;"
	"call asm_my_gcd2_in;"
	"movl %%ecx, %0;"
		:"=r"(ans)
		:"r"(a),"r"(b)
		:"%eax", "%ecx", "%edx", "cc"
		);
	return ans;
}

uint32_t nextpint(void){ char c=getc_unlocked(stdin); while(c<'0'||'9'<c) c=getc_unlocked(stdin); uint32_t x=0; while('0'<=c && c<='9'){ x=x*10+c-'0'; c=getc_unlocked(stdin); } return x; }
int a[100001];
int l[100002], r[100002];
int main(void){
	int n=nextpint();
	for(int i=1; i<=n; i++){
		a[i]=nextpint();
	}
	l[0]=0;
	for(int i=1; i<=n; i++){
		l[i] = gcd(l[i-1], a[i]);
	}
	r[n+1]=0;
	for(int i=n; i>0; i--){
		r[i] = gcd(r[i+1], a[i]);
	}
	int max=0;
	for(int i=1; i<=n; i++){
		int now=gcd(l[i-1], r[i+1]);
		if(now>max) max=now;
	}
	printf("%d\n", max);
}


G(int a,int b){
	if(a==0||b==0)return(a>b?a:b);
	if(a%b==0)return b;
	return G(b,a%b);
}
main(){
	int i,n,a[100002],l[100002]={0},r[100002]={0},ans=0;
	scanf("%d",&n);
	for(i=1;i<=n;i++){scanf("%d",&a[i]);l[i+1]=G(a[i],l[i]);}
	for(i=n;i>0;i--)r[i]=G(a[i],r[i+1]);
	for(i=1;i<=n;i++)ans=(ans>G(l[i],r[i+1])?ans:G(l[i],r[i+1]));
	printf("%d",ans);
}


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <limits.h>

#define REP(i,n) for(i=0;i<n;i++)

//prototype declaration
int iin();
long long llin();
double din();
char cin();
void stin(char *s);
void iout(int i);
void llout(long long i);
void dout(double i);
void cout(char c);
void stout(char *s);
int dfs(int v, int n, int *visited, int table[n][n]);
int gcd(int a, int b);
int lcm(int a, int b);
long long llgcd(long long a, long long b);
long long lllcm(long long a, long long b);

//main function
int main() {
    int n = iin(), i;
    if (n == 2) {
        int a = iin(), b = iin();
        iout(a > b ? a : b);
        return 0;
    }
    int a1 = iin(), a2 = iin(), a3 = iin(), hold, gcdmax;
    if (gcd(a1, a2) >= gcd(a2, a3) && gcd(a1, a2) >= gcd(a1, a3)) {
        gcdmax = gcd(a1, a2);
        hold = a3;
    } else if (gcd(a2, a3) > gcd(a1, a2) && gcd(a2, a3) > gcd(a1, a3)) {
        gcdmax = gcd(a2, a3);
        hold = a1;
    } else if (gcd(a1, a3) > gcd(a1, a2) && gcd(a1, a3) > gcd(a2, a3)) {
        gcdmax = gcd(a1, a3);
        hold = a2;
    }
    REP(i, n - 3) {
        a1 = iin();
        if (gcd > gcd(gcdmax, a1)) {
            if (gcd(gcdmax, a1) < gcd(gcdmax, hold)) {
                gcdmax = gcd(gcdmax, hold);
                hold = a1;
            } else {
                gcdmax = gcd(gcdmax, a1);
            }
        }
    }
    iout(gcdmax);
    return 0;
}

//body function
int iin() {
    int i;
    scanf("%d", &i);
    return i;
}

long long llin() {
    long long i;
    scanf("%lld", &i);
    return i;
}

double din() {
    double i;
    scanf("%lf", &i);
    return i;
}

char cin() {
    char c;
    scanf("%c", &c);
    return c;
}

void stin(char *s) {
    scanf("%s", s);
}

void iout(int i) {
    printf("%d\n", i);
}

void llout(long long i) {
    printf("%lld\n", i);
}

void dout(double i) {
    printf("%lf\n", i);
}

void cout(char c) {
    printf("%c\n", c);
}

void stout(char *s) {
    printf("%s\n", s);
}

int dfs(int v, int n, int *visited, int table[n][n]) {
    int all_visited = 1, i;

    REP(i,n) {
        if (!visited[i]) {
            all_visited = 0;
            break;
        }
    }

    if (all_visited) {
        return 1;
    }

    int count = 0;

    REP(i,n) {
        if (!table[v][i]) continue;
        if (visited[i]) continue;

        visited[i] = 1;
        count += dfs(i, n, visited, table);
        visited[i] = 0;
    }

    return count;
}

int gcd(int a, int b) {
    int r;

    if (a < b) {
        r = a;
        a = b;
        b = r;
    }

    r = a % b;
    while (r != 0) {
        a = b;
        b = r;
        r = a % b;
    }

    return b;
}

int lcm(int a, int b) {
    int r = llgcd(a, b);
    a /= r;
    return a * b;
}

long long llgcd(long long a, long long b) {
    long long r;

    if (a < b) {
        r = a;
        a = b;
        b = r;
    }

    r = a % b;
    while (r != 0) {
        a = b;
        b = r;
        r = a % b;
    }

    return b;
}

long long lllcm(long long a, long long b) {
    long long r = llgcd(a, b);
    a /= r;
    return a * b;
}


#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
#include<string.h>
#include<math.h>
#include<ctype.h>

typedef long long ll;

ll gcd(ll a, ll b) { if (b == 0) return a; return gcd(b, a % b); }

ll lcm(ll a, ll b) { return a / gcd(a, b) * b; }

ll max(ll a, ll b) { return (a > b) ? a : b; }

ll min(ll a, ll b) { return (a < b) ? a : b; }

ll asc(const void* a, const void* b) { return *(ll*)a - *(ll*)b; }

ll dsc(const void* a, const void* b) { return *(ll*)b - *(ll*)a; }

bool flag;

int main() {
	ll n, a[100000];
	scanf("%lld", &n);
	for (ll i = 0; i < n; i++) scanf("%lld", &a[i]);
	ll gcdA = a[0], gcdB = a[1];
	for (ll i = 1; i < n; i++) {
		if (!flag&&(gcd(gcdA, a[i]) == 1)) { flag = true; }
		else gcdA = gcd(gcdA, a[i]);
		gcdB = gcd(gcdB, a[i]);
	}
	ll gcdC = a[0] / gcdA;
	if (flag) { printf("%lld", max(gcdA, gcdB)); return 0; }
	else {
      	flag=false;
      	gcdB=a[1]/gcdA;
		for (int i = 1; i < n; i++){
			a[i] /= gcdA;
			if(!flag&&(gcd(gcdC,a[i])==1)) flag=true;
          	else gcdC = gcd(gcdC, a[i]);
          	gcdB = gcd(gcdB, a[i]);
		}
		printf("%lld", max(gcdC * gcdA, gcdB*gcdA));
    }

	return 0;
}


#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
#include<string.h>
#include<math.h>
#include<ctype.h>

typedef long long ll;

ll gcd(ll a, ll b) { if (b == 0) return a; return gcd(b, a % b); }

ll lcm(ll a, ll b) { return a / gcd(a, b) * b; }

ll max(ll a, ll b) { return (a > b) ? a : b; }

ll min(ll a, ll b) { return (a < b) ? a : b; }

ll asc(const void* a, const void* b) { return *(ll*)a - *(ll*)b; }

ll dsc(const void* a, const void* b) { return *(ll*)b - *(ll*)a; }

bool flag;

int main() {
	ll n, a[100000];
	scanf("%lld", &n);
	for (ll i = 0; i < n; i++) scanf("%lld", &a[i]);
	ll gcdA = a[0], gcdB = a[1];
	for (ll i = 1; i < n; i++) {
		if (gcd(gcdA, a[i]) == 1) { flag = true; }
		else gcdA = gcd(gcdA, a[i]);
		gcdB = gcd(gcdB, a[i]);
	}
	ll gcdC=1;
	if (!flag) {
      	gcdC=a[0]/gcdA;
		for (int i = 0; i < n; i++) a[i] /= gcdA;
		for (int i = 1; i < n; i++) {
			if(gcd(gcdC,a[i])!=1) gcdC = gcd(gcdC, a[i]);
		}
	}
	printf("%lld", max(gcdC * gcdA, gcdB));

	return 0;
}


#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
#include<string.h>
#include<math.h>
#include<ctype.h>

typedef long long ll;

ll gcd(ll a, ll b) { if (b == 0) return a; return gcd(b, a % b); }

ll lcm(ll a, ll b) { return a / gcd(a, b) * b; }

ll max(ll a, ll b) { return (a > b) ? a : b; }

ll min(ll a, ll b) { return (a < b) ? a : b; }

ll asc(const void* a, const void* b) { return *(ll*)a - *(ll*)b; }

ll dsc(const void* a, const void* b) { return *(ll*)b - *(ll*)a; }

bool flag;

int main() {
	ll n, a[100000];
	scanf("%lld", &n);
	for (ll i = 0; i < n; i++) scanf("%lld", &a[i]);
	ll gcdA = a[0], gcdB = a[1];
	for (ll i = 1; i < n; i++) {
		if (gcd(gcdA, a[i]) != 1) gcdA = gcd(gcdA, a[i]);
		else flag = true;
		gcdB = gcd(gcdB, a[i]);
	}
  	ll gcdC = a[0]/gcdA;
	if (!flag) {
		for (int i = 0; i < n; i++) a[i] /= gcdA;
      	gcdB = a[1];
		for (ll i = 1; i < n; i++) {
			if (gcd(gcdC, a[i]) != 1) gcdC= gcd(gcdC, a[i]);
		}
	}
	printf("%lld", (gcdC*gcdA > gcdB) ? gcdC*gcdA : gcdB);

	return 0;
}


console.log((args=>{
  const [[N],A] = args.trim().split('\n').map(r=>r.split(' ').map(v=>v|0));
  if ( N === 2 ) return `${Math.max(...A)}`;
  const D = [A[0],A[1]];
  for ( let i = 0; i < 2; i++ ) {
    let a = A[i];
    for ( let j = 2; j*j <= a; j++ ) {
      if ( a % j ) continue;
      D.push( j, a / j );
    }
  }
  D.sort((a,b)=>b-a);
  DIVISOR: for( const d of D ) {
    let n = 0;
    for ( let i = 0; i < N; i++ ) {
      if ( A[i] % d && ++n > 1 ) continue DIVISOR;
    }
    return `${d}`;
  }
  return '1';
})(require('fs').readFileSync('/dev/stdin', 'utf8')));


"use strict";

process.stdin.resume();
process.stdin.setEncoding('utf8');

var g_input = '';
process.stdin.on('data', function(chunk) {
    g_input += chunk;
});

process.stdin.on('end', function() {
    Main(g_input.split(/\r?\n/));
});

function Main(input) {

    const n = parseInt(input[0], 10);
    const a = input[1].split(' ').map(function(value) { return parseInt(value, 10); });
    let l = Array(n + 1);
    let r = Array(n + 1);
    let ans = 0;

    l[0] = 0;
    for (let i = 1; i < n; i++) {
        l[i] = gcd(l[i - 1], a[i - 1]);
    }

    r[n - 1] = 0;
    for (let i = n - 2; i >= 0; i--) {
        r[i] = gcd(r[i + 1], a[i + 1]);
    }

    for (let i = 0; i < n; i++) {
        ans = Math.max(ans, gcd(l[i], r[i]));
    }

    console.log(ans);

    return 0;
}

function gcd(a, b) {

    if (b === 0) {
        return a;
    } else {
        return gcd(b, a % b);
    }
}


module.exports=function(t){var r={};function e(n){if(r[n])return r[n].exports;var i=r[n]={i:n,l:!1,exports:{}};return t[n].call(i.exports,i,i.exports,e),i.l=!0,i.exports}return e.m=t,e.c=r,e.d=function(t,r,n){e.o(t,r)||Object.defineProperty(t,r,{enumerable:!0,get:n})},e.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},e.t=function(t,r){if(1&r&&(t=e(t)),8&r)return t;if(4&r&&"object"==typeof t&&t&&t.__esModule)return t;var n=Object.create(null);if(e.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:t}),2&r&&"string"!=typeof t)for(var i in t)e.d(n,i,function(r){return t[r]}.bind(null,i));return n},e.n=function(t){var r=t&&t.__esModule?function(){return t.default}:function(){return t};return e.d(r,"a",r),r},e.o=function(t,r){return Object.prototype.hasOwnProperty.call(t,r)},e.p="",e(e.s=0)}([function(t,r,e){"use strict";var n=e(1);e(2)(n.readFileSync("/dev/stdin","utf8"))},function(t,r){t.exports=require("fs")},function(t,r,e){"use strict";var n=e(3),i=e(5);t.exports=function(t){var r=new n(t);i(r)}},function(t,r,e){"use strict";var n=e(4);t.exports=class{constructor(t){var r=t.trim().split(/\s+/g);this.inp=new n(r)}inr(){return this.inp.deq()}in(){return parseInt(this.inp.deq(),10)}fin(){this.inp.clear()}}},function(t,r,e){"use strict";t.exports=class{constructor(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[];this.size=t.length,this.items=t,this.ind=0}enq(t){this.size+=1,this.items.push(t)}deq(){var t=this.items[this.ind];return this.size-=1,this.ind+=1,t}clear(){this.items=[],this.size=0,this.ind=0}}},function(t,r,e){"use strict";function n(t,r){var e=Math.max(t,r),n=Math.min(t,r);if(e==n)return e;for(;0!=n;){var i=n;n=e%n,e=i}return e}t.exports=function(t){for(var r=t.in(),e=new Array(r),i=0;i<r;i++)e[i]=t.in();var o=new Array(r+1);o[0]=0;var s=new Array(r+1);s[r]=0;for(var u=0;u<r;u++)o[u+1]=n(o[u],e[u]),s[r-1-u]=n(s[r-u],e[r-1-u]);for(var a=1,c=0;c<r;c++){var f=n(o[c],s[c+1]);a=Math.max(a,f)}console.log(a)}}]);


console.log((args=>{
  const [[N],A] = args.trim().split('\n').map(r=>r.split(' ').map(v=>v|0));
  if ( N === 2 ) return `${Math.max(...A)}`;
  const D = [A[0],A[1]];
  for ( let i = 0; i < 2; i++ ) {
    let a = A[i];
    for ( let j = 2; j*j <= a; j++ ) {
      if ( a % j ) continue;
      let k = 0;
      while ( a % j === 0 ) D.push( j * ++k, a /= j );
    }
  }
  D.sort((a,b)=>b-a);
  DIVISOR: for( const d of D ) {
    let n = 0;
    for ( let i = 0; i < N; i++ ) {
      if ( A[i] % d && ++n > 1 ) continue DIVISOR;
    }
    return `${d}`;
  }
  return '1';
})(require('fs').readFileSync('/dev/stdin', 'utf8')));


console.log((args=>{
  const [[N],A] = args.trim().split('\n').map(r=>r.split(' ').map(v=>v|0));
  const gcd = (a,b) => {while(a)[a,b]=[b%a,a];return b;};
  if ( N === 2 ) return `${Math.max(...A)}`;
  const D = [gcd(A[0],A[A.length-1])];
  for( let i = 0; i < N - 1; i++ ) {
    D.push( gcd(A[i],A[i+1]) );
  }
  D.sort((a,b)=>b-a);
  DIVISOR: for( const d of D ) {
    let n = 0;
    for ( let i = 0; i < N; i++ ) {
      if ( A[i] % d && ++n > 1 ) continue DIVISOR;
    }
    return `${d}`;
  }
  return '1';
})(require('fs').readFileSync('/dev/stdin', 'utf8')));


// 最大公約数
_gcd = function(m, n, t) {
    if (n == 0) {
        console.log(m, n)
        return m
    }
	while (m % n !== 0) {
		t = n;
		n = m % n;
		m = t;
	}
	return n;
}

input = require('fs').readFileSync('/dev/stdin', 'utf8')
lines = input.split('\n')
N = lines.shift() * 1
A = lines.shift().split(' ')

B = [0]
for (i=0; i<N; i++) {
    B[i+1] = _gcd(B[i], A[i])
}

C = []
C[N] = 0
for (i=N-1; i >=0; i--) {
    C[i] = _gcd(C[i+1], A[i])
}

max = 0
for (i=0; i<N; i++) {
    gcd = _gcd(B[i], C[i+1])
    if (max < gcd) {
        max = gcd
    }
}

console.log(max)


// 別解

package main

import (
	"bufio"
	"fmt"
	"os"
	"sort"
)

var sc = bufio.NewScanner(os.Stdin)

func ri() (n int) {
	sc.Scan()
	for _, v := range sc.Bytes() {
		n = n*10 + int(v-48)
	}
	return
}

func main() {
	sc.Split(bufio.ScanWords)
	n := ri()
	a := make([]int, n)
	for i := 0; i < n; i++ {
		a[i] = ri()
	}

	cs := make([]int, 0, 200000)
	x := a[0]
	for i := 1; i*i <= x; i++ {
		if x%i == 0 {
			cs = append(cs, i, x/i)
		}
	}
	y := a[1]
	for i := 1; i*i <= y; i++ {
		if y%i == 0 {
			cs = append(cs, i, y/i)
		}
	}
	sort.Sort(sort.Reverse(sort.IntSlice(cs)))

	for i := 0; i < len(cs); i++ {
		indivisible := 0
		for _, aa := range a {
			if aa%cs[i] != 0 {
				indivisible++
			}
			if indivisible >= 2 {
				break
			}
		}
		if indivisible <= 1 {
			fmt.Println(cs[i])
			return
		}
	}
}


package main

import (
	"bufio"
	"fmt"
	"os"
)

var sc = bufio.NewScanner(os.Stdin)

func ri() (n int) {
	sc.Scan()
	for _, v := range sc.Bytes() {
		n = n*10 + int(v-48)
	}
	return
}

func gcd(a, b int) int {
	for b != 0 {
		c := a % b
		a, b = b, c
	}
	return a
}

func main() {
	sc.Split(bufio.ScanWords)
	n := ri()
	a := make([]int, n)
	for i := 0; i < n; i++ {
		a[i] = ri()
	}
	cL := make([]int, n)
	gcdL := a[0]
	for i := 0; i < n; i++ {
		gcdL = gcd(gcdL, a[i])
		cL[i] = gcdL
	}
	cR := make([]int, n)
	gcdR := a[n-1]
	for i := n - 1; i >= 0; i-- {
		gcdR = gcd(gcdR, a[i])
		cR[i] = gcdR
	}
	cL = append([]int{cR[n-1]}, cL[:n-1]...)
	cR = append(cR[1:], cL[1])
	mx := -1
	for i := 0; i < n; i++ {
		if x := gcd(cL[i], cR[i]); x > mx {
			mx = x
		}
	}
	fmt.Println(mx)
}


package main

import (
	"bufio"
	"fmt"
	basicIO "io"
	"math"
	"os"
	"strconv"
)

func main() {
	protagonist(os.Stdin, os.Stdout)
}

func protagonist(r basicIO.Reader, w basicIO.Writer) {
	io := NewIO(r, w)
	N, _ := io.nextInt()
	A := make([]int, N)

	min := math.MaxInt64
	sec := math.MaxInt64
	for i := 0; i < N; i++ {
		A[i], _ = io.nextInt()
		if A[i] < sec {
			if A[i] < min {
				sec = min
				min = A[i]
			} else {
				sec = A[i]
			}
		}
	}

	solution := 1

	for num := sec; num > 0; num-- {
		isLimit := false
		for j := 0; j < N; j++ {
			if A[j]%num == 0 {
				continue
			}
			if isLimit {
				goto NotFound
			}
			isLimit = true
		}
		solution = num
		goto Done
	NotFound:
	}

Done:
	io.PutInt(solution)
}

type IO struct {
	Scanner *bufio.Scanner
	Writer  basicIO.Writer
}

func NewIO(r basicIO.Reader, w basicIO.Writer) *IO {
	s := bufio.NewScanner(r)
	s.Split(bufio.ScanWords)
	return &IO{
		Scanner: s,
		Writer:  w,
	}
}

func (io *IO) nextString() string {
	io.Scanner.Scan()
	return io.Scanner.Text()
}

func (io *IO) nextInt() (int, error) {
	io.Scanner.Scan()
	i, err := strconv.Atoi(io.Scanner.Text())
	return i, err
}

func (io *IO) PutInt(v int) {
	fmt.Fprintf(io.Writer, "%d\n", v)
}

func (io *IO) PutString(s string) {
	fmt.Fprintf(io.Writer, "%s\n", s)
}


//go:generate echo "https://atcoder.jp/contests/abc125/tasks/abc125_c"
package main

import (
	"bufio"
	"fmt"
	"io"
	"math/big"
	"os"
	"strconv"
)

var scan = newScanner(os.Stdin)

func solve(As []int) int {
	m := map[[2]int]int{}
	for _, A := range As {
		for f, n := range factor(A) {
			for i := 1; i <= n; i++ {
				m[[2]int{f, i}]++
			}
		}
	}

	maxfn := [2]int{0, 0}
	for fn, x := range m {
		if x == len(As)-1 {
			if ipow(maxfn[0], maxfn[1]) < ipow(fn[0], fn[1]) {
				maxfn = fn
			}
		}
	}
	m[maxfn]++

	fnmaxs := map[int]int{}
	for fn, x := range m {
		if x == len(As) {
			if fnmaxs[fn[0]] < fn[1] {
				fnmaxs[fn[0]] = fn[1]
			}
		}
	}

	ans := 1
	for f, n := range fnmaxs {
		ans *= ipow(f, n)
	}
	return ans
}

func main() {
	N := scan.Int()
	As := scan.Ints(N)
	fmt.Println(solve(As))
}

type scanner struct {
	*bufio.Scanner
}

func newScanner(r io.Reader) *scanner {
	s := bufio.NewScanner(r)
	s.Split(bufio.ScanWords)
	s.Buffer(nil, 100000000)
	return &scanner{s}
}

func (s *scanner) String() string {
	s.Scan()
	return s.Text()
}

func (s *scanner) Strings(l int) []string {
	if l == 0 {
		return []string{}
	}
	sl := make([]string, l, l)
	for i := range sl {
		sl[i] = s.String()
	}
	return sl
}

func (s *scanner) Int() int {
	n, _ := strconv.Atoi(s.String())
	return n
}

func (s *scanner) Ints(l int) []int {
	if l == 0 {
		return []int{}
	}
	sl := make([]int, l, l)
	for i := range sl {
		sl[i] = s.Int()
	}
	return sl
}

func (s *scanner) Float64() float64 {
	f, _ := strconv.ParseFloat(s.String(), 64)
	return f
}

func (s *scanner) Float64s(l int) []float64 {
	if l == 0 {
		return []float64{}
	}
	sl := make([]float64, l, l)
	for i := range sl {
		sl[i] = s.Float64()
	}
	return sl
}

func (s *scanner) BigInt() *big.Int {
	n, _ := strconv.ParseInt(s.String(), 10, 64)
	return big.NewInt(n)
}

func (s *scanner) BigInts(l int) []*big.Int {
	if l == 0 {
		return []*big.Int{}
	}
	sl := make([]*big.Int, l, l)
	for i := range sl {
		sl[i] = s.BigInt()
	}
	return sl
}

func iabs(x int) int {
	if x < 0 {
		return -x
	}
	return x
}

func imax(x, y int) int {
	if x > y {
		return x
	}
	return y
}

func chmax(x *int, v int) {
	*x = imax(*x, v)
}

func imin(x, y int) int {
	if x < y {
		return x
	}
	return y
}

func chmin(x *int, v int) {
	*x = imin(*x, v)
}

func ipow(x, n int) int {
	if n == 0 {
		return 1
	}
	a := ipow(x, n>>1)
	a *= a
	if n&1 != 0 {
		a *= x
	}
	return a
}

func isum(X []int) int {
	s := 0
	for _, x := range X {
		s += x
	}
	return s
}

func factor(n int) map[int]int {
	m := map[int]int{}
	for i := 2; i*i <= n; i++ {
		for n%i == 0 {
			n /= i
			m[i]++
		}
	}
	if n != 1 {
		m[n]++
	}
	return m
}

// mint: https://github.com/atcoder/live_library/blob/master/mint.cpp
type mint int

var mod = 1000000007

func setMintMod(x int) {
	mod = x
}

func newMint(v int) mint {
	return mint((v%mod + mod) % mod)
}

func (x mint) Add(y mint) mint {
	v := x + y
	if v >= mint(mod) {
		return v - mint(mod)
	}
	return v
}

func (x mint) Sub(y mint) mint {
	v := x + mint(mod) - y
	if v >= mint(mod) {
		return v - mint(mod)
	}
	return v
}

func (x mint) Mul(y mint) mint {
	return (x * y) % mint(mod)
}

func (x mint) Pow(p int) mint {
	if p == 0 {
		return mint(1)
	}
	a := x.Pow(p >> 1)
	a = a.Mul(a)
	if p&1 != 0 {
		a = a.Mul(x)
	}
	return a
}

func (x mint) Inverse() mint {
	return x.Pow(mod - 2)
}

func (x mint) Div(y mint) mint {
	return x.Mul(y.Inverse())
}

func (x mint) Neg() mint {
	return newMint(int(-x))
}

type factorial struct {
	fact        []mint
	factInverse []mint
}

func newFactorial(n int) *factorial {
	f := new(factorial)
	f.init(n)
	return f
}

func (f *factorial) init(n int) {
	fact := make([]mint, n+1, n+1)
	fact[0] = newMint(1)
	for i := 1; i <= n; i++ {
		fact[i] = fact[i-1].Mul(newMint(i))
	}

	inv := make([]mint, n+1, n+1)
	inv[n] = fact[n].Inverse()
	for i := n; i >= 1; i-- {
		inv[i-1] = inv[i].Mul(newMint(i))
	}

	f.fact = fact
	f.factInverse = inv
}

func (f *factorial) Get(n int) mint {
	return f.fact[n]
}

func (f *factorial) GetInverse(n int) mint {
	return f.factInverse[n]
}

func (f *factorial) Permutation(n, k int) mint {
	if k < 0 || n < k {
		return 0
	}
	return f.fact[n].Mul(f.factInverse[n-k])
}

func (f *factorial) Combination(n, k int) mint {
	if k < 0 || n < k {
		return 0
	}
	return f.fact[n].Mul(f.factInverse[k]).Mul(f.factInverse[n-k])
}

// sieve: https://github.com/atcoder/live_library/blob/master/prime.cpp
type sieve struct {
	n          int
	primes     []int
	maxFactors []int
}

func newSieve(n int) *sieve {
	s := &sieve{
		n:          n,
		primes:     []int{},
		maxFactors: make([]int, n+1, n+1),
	}
	s.init()
	return s
}

func (s *sieve) init() {
	s.maxFactors[0] = -1
	s.maxFactors[1] = -1
	for i := 2; i <= s.n; i++ {
		if s.maxFactors[i] != 0 {
			continue
		}
		s.primes = append(s.primes, i)
		s.maxFactors[i] = i
		for j := i * i; j <= s.n; j += i {
			if s.maxFactors[j] == 0 {
				s.maxFactors[j] = i
			}
		}
	}
}

func (s *sieve) IsPrime(x int) bool {
	return s.maxFactors[x] == x
}

func (s *sieve) Factor(x int) map[int]int {
	m := map[int]int{}
	for x != 1 {
		m[s.maxFactors[x]]++
		x /= s.maxFactors[x]
	}
	return m
}


package main

import (
	"bufio"
	"bytes"
	"fmt"
	"io"
	"os"
	"strconv"
)

var DEBUG = true

// -----------------------------------------------------------------------------

// IO helper functions

// Returns next token from input.  It must be initialized by SetInput()
// before the first call.
var nextToken func() ([]byte, error)
var nextLine func() ([]byte, error)

// Holds a buffer for output.  It must be initialized by SetOutput().
// All IO functions (read*() and [e]print*()) should write to OutputWriter
// instead of this.
var OutputBuffer *bufio.Writer

// Holds an io.Writer.  It must be initialized by SetOutput()
var OutputWriter io.Writer

// Set IO functions for interactive input/output.
func SetInteractive(w io.Writer, r io.Reader) {
	SetUnbufferedInput(r)
	OutputBuffer = nil
	OutputWriter = w
}

// Setup OutputBuffer and OutputWriter.
func SetOutput(w io.Writer) {
	OutputBuffer = bufio.NewWriter(w)
	OutputWriter = OutputBuffer
}

// Flushes OutputBuffer
func Flush() {
	if OutputBuffer != nil {
		OutputBuffer.Flush()
	}
}

// Returns true if c is a white space
func IsSpace(c byte) bool {
	switch c {
	case '\t', '\n', '\v', '\f', '\r', ' ':
		return true
	}
	return false
}

func IsNewLine(c byte) bool {
	switch c {
	case '\n', '\r':
		return true
	}
	return false
}

// Setup nextToken with input buffer.
func SetInput(r io.Reader) {
	buf := new(bytes.Buffer)
	var b []byte

	var i int
	rest := func() ([]byte, error) {
		for i < len(b) && IsSpace(b[i]) {
			i++
		}
		if i == len(b) {
			return nil, io.ErrUnexpectedEOF
		}
		j := i
		for i < len(b) && !IsSpace(b[i]) {
			i++
		}
		return b[j:i], nil
	}
	initial := func() ([]byte, error) {
		io.Copy(buf, r)
		b = buf.Bytes()
		nextToken = rest
		return rest()
	}
	nextToken = initial

	restLn := func() ([]byte, error) {
		for i < len(b) && IsNewLine(b[i]) {
			i++
		}
		if i == len(b) {
			return nil, io.ErrUnexpectedEOF
		}
		j := i
		for i < len(b) && !IsNewLine(b[i]) {
			i++
		}
		return b[j:i], nil
	}

	initialLn := func() ([]byte, error) {
		io.Copy(buf, r)
		b = buf.Bytes()
		nextLine = restLn
		return restLn()
	}
	nextLine = initialLn
}

// Setup nextToken without input buffer.
func SetUnbufferedInput(r io.Reader) {
	buf := bufio.NewReader(r)
	var b []byte

	var i int
	nextToken = func() ([]byte, error) {
		var err error
		if i == len(b) {
			b, err = buf.ReadBytes('\n')
			if err != nil {
				return nil, err
			}
			i = 0
			j := len(b) - 1
			for 0 <= j && IsSpace(b[j]) {
				j--
			}
			b = b[0 : j+1]
		}
		for i < len(b) && IsSpace(b[i]) {
			i++
		}
		j := i
		for i < len(b) && !IsSpace(b[i]) {
			i++
		}
		if i == j {
			return nil, io.ErrUnexpectedEOF
		}
		return b[j:i], nil
	}
}

// -----------------------------------------------------------------------------

// IO functions

// Reads next token and return it as []byte
func readb() []byte {
	b, err := nextToken()
	if err != nil {
		panic(err)
	}
	return b[:len(b):len(b)]
}

// Reads next token and return it as string
func reads() string {
	return string(readb())
}

// Read next line as []byte.  Trailing '\n' will not be included.
// See also comments on readb()
func readbln() []byte {
	b, err := nextLine()
	if err != nil {
		panic(err)
	}
	return b[:len(b):len(b)]
}

// Read next line as string
func readsln() string {
	return string(readbln())
}

// Reads next token and return it as int64
func readll() int64 {
	i, err := strconv.ParseInt(reads(), 10, 64)
	if err != nil {
		panic(err.Error())
	}
	return i
}

// Reads next token and return it as int
func readi() int {
	return int(readll())
}

// Reads next token and return it as float64
func readf() float64 {
	f, err := strconv.ParseFloat(reads(), 64)
	if err != nil {
		panic(err.Error())
	}
	return f
}

// Write args to OutputWriter with the format f
func printf(f string, args ...interface{}) (int, error) {
	return fmt.Fprintf(OutputWriter, f, args...)
}

// Write args to OutputWriter without format
func println(args ...interface{}) (int, error) {
	return fmt.Fprintln(OutputWriter, args...)
}

// Write args to stderr with the format f
func eprintf(f string, args ...interface{}) (int, error) {
	return fmt.Fprintf(os.Stderr, f, args...)
}

// Write args to stderr without format
func eprintln(args ...interface{}) (int, error) {
	return fmt.Fprintln(os.Stderr, args...)
}

func debugf(f string, args ...interface{}) {
	if !DEBUG {
		return
	}
	fmt.Fprintf(os.Stderr, f, args...)
}

func debug(args ...interface{}) {
	if !DEBUG {
		return
	}
	fmt.Fprintln(os.Stderr, args...)
}

// -----------------------------------------------------------------------------

// Utilities

func sumSlice(a []int) int {
	var res int
	for _, v := range a {
		res += v
	}
	return res
}

func sumSlicell(a []int64) int64 {
	var res int64
	for _, v := range a {
		res += v
	}
	return res
}

func readInts(N int) (int, []int) {
	if N == 0 {
		N = readi()
	}
	a := make([]int, N)
	for i := range a {
		a[i] = readi()
	}
	return N, a
}

func readIntsll(N int) (int, []int64) {
	if N == 0 {
		N = readi()
	}
	a := make([]int64, N)
	for i := range a {
		a[i] = readll()
	}
	return N, a
}

// -----------------------------------------------------------------------------

// Simple math functions

const (
	// big prime
	INF  = 1000000007
	INF2 = 1000000009
	INF3 = 998244353
)

func min(a, b int) int {
	if a < b {
		return a
	}
	return b
}

func minll(a, b int64) int64 {
	if a < b {
		return a
	}
	return b
}

func minf(a, b float64) float64 {
	if a < b {
		return a
	}
	return b
}

func max(a, b int) int {
	if a < b {
		return b
	}
	return a
}

func maxll(a, b int64) int64 {
	if a < b {
		return b
	}
	return a
}

func maxf(a, b float64) float64 {
	if a < b {
		return b
	}
	return a
}

func abs(a int) int {
	if a < 0 {
		return -a
	}
	return a
}

func absll(a int64) int64 {
	if a < 0 {
		return -a
	}
	return a
}

func absf(a float64) float64 {
	if a < 0 {
		return -a
	}
	return a
}

// egcd(a, b) returns d, x, y:
//   d is gcd(a,b)
//   x, y are  integers that satisfy ax + by = d
func egcd(a, b int) (int, int, int) {
	if b == 0 {
		return a, 1, 0
	}
	d, x, y := egcd(b, a%b)
	return d, y, x - a/b*y
}

func egcdll(a, b int64) (int64, int64, int64) {
	if b == 0 {
		return a, 1, 0
	}
	d, x, y := egcdll(b, a%b)
	return d, y, x - a/b*y
}

func gcd(a, b int) int {
	d, _, _ := egcd(a, b)
	return d
}

func gcdll(a, b int64) int64 {
	d, _, _ := egcdll(a, b)
	return d
}

// set up IO functions
func init() {
	// for non-interactive
	SetInput(os.Stdin)
	SetOutput(os.Stdout)

	// Enable below when interactive.  Its ok to leave above intact.
	SetInteractive(os.Stdout, os.Stdin)
}

func main() {
	defer Flush()
	n := readi()
	_, a := readInts(n)
	answer := solve(n, a)
	println(answer)
}

func getNumber(n, i int, a []int) int {
	if i >= n {
		return a[i-n]
	}
	return a[i]
}

func solve(n int, a []int) int {

	if n >= 4 {
		cache := make([]int, n)
		minInCache := 1000000000
		minInCacheIndex := -1
		for i := 0; i < n-1; i += 2 {
			cache[i/2] = gcd(a[i], a[i+1])
			minInCache = min(minInCache, cache[i/2])
			if minInCache == cache[i/2] {
				minInCacheIndex = i / 2
			}
		}
		if n%2 == 1 {
			cache[n/2] = a[n-1]
			minInCache = min(minInCache, cache[n/2])
			if minInCache == cache[n/2] {
				minInCacheIndex = n / 2
			}
		}
		res := 0
		if minInCacheIndex != 0 {
			res = gcd(cache[0], cache[1])
		} else {
			res = gcd(cache[2], cache[3])
		}
		for i := 0; i < n/2; i++ {
			if i != minInCacheIndex {
				res = gcd(res, cache[i])
			}
		}

		candidate := gcd(res, a[minInCacheIndex*2])
		other := gcd(res, a[minInCacheIndex*2+1])
		return max(candidate, other)
	} else {
		if n == 2 {
			return max(a[0], a[1])
		}
		m := 0
		for i := 0; i < n; i++ {

			tmp := gcd(getNumber(n, i+1, a), getNumber(n, i+2, a))
			for j := 0; j < n; j++ {
				if j != i {
					tmp = gcd(tmp, a[j])
				}
			}
			m = max(tmp, m)
		}
		return m
	}

}