n = read_line.to_i a = read_line.split.map(&.to_i) sieve = Array.new(100001, false) primes = [] of Int64 2.upto(sieve.size - 1) do |i| if !sieve[i] primes << i i.step(to: sieve.size - 1, by: i) do |j| sieve[j] = true end end end q = PriorityQueue(Tuple(Int32, Int32, Int32)).new(n) n.times do |i| primes.each do |p| if a[i] % p == 0 d = p a[i] //= p while a[i] % p == 0 d *= p a[i] //= p end q.add({d.to_i, p.to_i, i}) end end end uf = UnionFind.new(n) pos = Array.new(1000001, -1) ans = 0i64 while q.size > 0 d, p, i = q.pop if pos[p] == -1 pos[p] = i else if uf.find(pos[p], i) ans += d else uf.union(pos[p], i) end end end puts ans class UnionFind def initialize(size : Int32) @root = Array(Int32).new(size, -1) end def union(i, j) a = root(i) b = root(j) if a != b @root[a] += @root[b] @root[b] = a end end def find(i, j) root(i) == root(j) end def root(i) return i if @root[i] < 0 @root[i] = root(@root[i]) end def size(i) -@root[root(i)] end end class PriorityQueue(T) def initialize(capacity : Int32) @elem = Array(T).new(capacity) end def initialize(list : Enumerable(T)) @elem = list.to_a 1.upto(size - 1) { |i| fixup(i) } end def size @elem.size end def add(v) @elem << v fixup(size - 1) end def top @elem[0] end def pop ret = @elem[0] last = @elem.pop if size > 0 @elem[0] = last fixdown(0) end ret end def clear @elem.clear end def decrease_top(new_value : T) @elem[0] = new_value fixdown(0) end def to_s(io : IO) io << @elem end private def fixup(index : Int32) while index > 0 parent = (index - 1) // 2 break if @elem[parent] >= @elem[index] @elem[parent], @elem[index] = @elem[index], @elem[parent] index = parent end end private def fixdown(index : Int32) while true left = index * 2 + 1 break if left >= size right = index * 2 + 2 child = right >= size || @elem[left] > @elem[right] ? left : right if @elem[child] > @elem[index] @elem[child], @elem[index] = @elem[index], @elem[child] index = child else break end end end end