← Home
package main

import (
	"bufio"
	"io"
	"math/rand"
	"os"
	"sort"
	"strconv"
	"time"
)

type FastInput struct {
	data []byte
	idx  int
}

func (in *FastInput) nextUint64() uint64 {
	n := len(in.data)
	for in.idx < n {
		c := in.data[in.idx]
		if c >= '0' && c <= '9' {
			break
		}
		in.idx++
	}
	var x uint64
	for in.idx < n {
		c := in.data[in.idx]
		if c < '0' || c > '9' {
			break
		}
		x = x*10 + uint64(c-'0')
		in.idx++
	}
	return x
}

func gcd(a, b uint64) uint64 {
	for b != 0 {
		a, b = b, a%b
	}
	return a
}

func sieve(limit int) []int {
	isComp := make([]bool, limit+1)
	primes := make([]int, 0, 80000)
	for i := 2; i <= limit; i++ {
		if !isComp[i] {
			primes = append(primes, i)
			if i <= limit/i {
				for j := i * i; j <= limit; j += i {
					isComp[j] = true
				}
			}
		}
	}
	return primes
}

func factorize(x uint64, primes []int) ([]uint64, []int) {
	ps := make([]uint64, 0, 12)
	es := make([]int, 0, 12)
	for _, p := range primes {
		pp := uint64(p)
		if pp*pp > x {
			break
		}
		if x%pp == 0 {
			c := 0
			for x%pp == 0 {
				x /= pp
				c++
			}
			ps = append(ps, pp)
			es = append(es, c)
		}
	}
	if x > 1 {
		ps = append(ps, x)
		es = append(es, 1)
	}
	return ps, es
}

func buildDivisors(ps []uint64, es []int) ([]uint64, map[uint64]int, []int) {
	m := len(ps)
	stride := make([]int, m)
	d := 1
	for i := 0; i < m; i++ {
		stride[i] = d
		d *= es[i] + 1
	}
	values := make([]uint64, d)
	idxMap := make(map[uint64]int, d)
	var dfs func(int, uint64, int)
	dfs = func(pos int, cur uint64, idx int) {
		if pos == m {
			values[idx] = cur
			idxMap[cur] = idx
			return
		}
		mul := uint64(1)
		step := stride[pos]
		for e := 0; e <= es[pos]; e++ {
			dfs(pos+1, cur*mul, idx+e*step)
			if e < es[pos] {
				mul *= ps[pos]
			}
		}
	}
	dfs(0, 1, 0)
	return values, idxMap, stride
}

func processSample(x uint64, a []uint64, need int, primes []int, best *uint64) {
	ps, es := factorize(x, primes)
	values, idxMap, stride := buildDivisors(ps, es)
	cnt := make([]int, len(values))
	for _, v := range a {
		cnt[idxMap[gcd(v, x)]]++
	}
	if cnt[idxMap[x]] >= need {
		if x > *best {
			*best = x
		}
		return
	}
	for j := 0; j < len(ps); j++ {
		step := stride[j]
		block := step * (es[j] + 1)
		for base := 0; base < len(values); base += block {
			for off := 0; off < step; off++ {
				start := base + off
				for e := es[j] - 1; e >= 0; e-- {
					cnt[start+e*step] += cnt[start+(e+1)*step]
				}
			}
		}
	}
	b := *best
	for i, v := range values {
		if v > b && cnt[i] >= need {
			b = v
		}
	}
	*best = b
}

func printAns(ans uint64) {
	w := bufio.NewWriterSize(os.Stdout, 32)
	w.WriteString(strconv.FormatUint(ans, 10))
	w.WriteByte('\n')
	w.Flush()
}

func main() {
	data, _ := io.ReadAll(bufio.NewReaderSize(os.Stdin, 1<<20))
	in := FastInput{data: data}
	n := int(in.nextUint64())
	a := make([]uint64, n)
	var maxVal uint64
	var first uint64
	same := true
	for i := 0; i < n; i++ {
		v := in.nextUint64()
		a[i] = v
		if v > maxVal {
			maxVal = v
		}
		if i == 0 {
			first = v
		} else if v != first {
			same = false
		}
	}

	if n <= 2 || same {
		printAns(maxVal)
		return
	}

	need := (n + 1) / 2

	raw := make([]uint64, 0, 64)
	raw = append(raw, a[0], a[n/3], a[n/2], a[2*n/3], a[n-1], maxVal)

	if n <= 500 {
		raw = append(raw, a...)
	} else {
		rng := rand.New(rand.NewSource(time.Now().UnixNano()))
		for i := 0; i < 28; i++ {
			raw = append(raw, a[rng.Intn(n)])
		}
	}

	seen := make(map[uint64]struct{}, len(raw))
	samples := make([]uint64, 0, len(raw))
	for _, v := range raw {
		if _, ok := seen[v]; !ok {
			seen[v] = struct{}{}
			samples = append(samples, v)
		}
	}

	sort.Slice(samples, func(i, j int) bool { return samples[i] > samples[j] })

	primes := sieve(1000000)

	best := uint64(1)
	for _, x := range samples {
		if x <= best {
			break
		}
		processSample(x, a, need, primes, &best)
		if best == maxVal {
			break
		}
	}

	printAns(best)
}