class DSU property parents_or_size : Array(Int32) def initialize(n : Int32) @parents_or_size = Array.new(n, -1) end def leader(i : Int32) : Int32 if @parents_or_size[i] < 0 i else @parents_or_size[i] = leader(@parents_or_size[i]) @parents_or_size[i] end end def merge(a : Int32, b : Int32) : Int32 a = leader(a) b = leader(b) return a if a == b if -@parents_or_size[a] < -@parents_or_size[b] a, b = b, a end @parents_or_size[a] += @parents_or_size[b] @parents_or_size[b] = a a end def same(a : Int32, b : Int32) : Bool leader(a) == leader(b) end def size(i : Int32) : Int32 -@parents_or_size[leader(i)] end def groups : Array(Array(Int32)) n = @parents_or_size.size arr = Array.new(n) { [] of Int32 } n.times do |i| arr[leader(i)] << i end arr.reject(&.empty?) end end # Main program input = gets.not_nil!.split n = input[0].to_i l = Array(Int64).new(n, 0) s = Array(Int32).new(n, 0) ans = 0_i64 n.times do |i| input = gets.not_nil!.split l[i] = input[0].to_i64 s[i] = input[1].to_i ans += l[i] end uf = DSU.new(n) n.times do |i| uf.merge(i, s[i] - 1) end vis = Array.new(n, false) grps = uf.groups grps.each do |g| u = g[0] while !vis[u] vis[u] = true u = s[u] - 1 end cycle = [] of Int32 while vis[u] vis[u] = false cycle << u u = s[u] - 1 end m = Int64::MAX cycle.each do |x| m = Math.min(m, l[x]) end ans += m end if ans & 1 == 1 puts "#{ans >> 1}.5" else puts "#{ans >> 1}.0" end