class DisjointSet
  attr_accessor :parent, :rank
  def initialize
    @parent = {}
    @rank = {}
  end
  def make(node)
    @parent[node] = node
    @rank[node] = 0
  end
  def union(node1, node2)
    link(find(node1), find(node2))
  end
  def link(node1, node2)
    node1, node2 = node2, node1 if @rank[node1] < @rank[node2]
    @parent[node2] = node1
    @rank[node1] += 1 if @rank[node1] == @rank[node2]
  end
  def find(node)
    (@parent[node] == node) ? node : (@parent[node] = find(@parent[node]))
  end
end

X, Y, R = (0...3).to_a
Left, Right, Top, Bottom = (0...4).to_a

def touch?(s1, s2)
  t1 = [s1[X]-s1[R], s1[X]+s1[R], s1[Y]-s1[R], s1[Y]+s1[R]]
  t2 = [s2[X]-s2[R], s2[X]+s2[R], s2[Y]-s2[R], s2[Y]+s2[R]]
  intersectW = (t1[Right]-t2[Left]) * (t1[Left]-t2[Right]) < 0.0
  intersectH = (t1[Top]-t2[Bottom]) * (t1[Bottom]-t2[Top]) < 0.0
  intersectW && intersectH
end

data = 0
while (n = gets.to_i) != 0 do
  data += 1
  set = DisjointSet.new
  square = Array.new
  n.times do |i|
    square.push(gets.split.map(&:to_f))
    set.make(i)
  end
  n.times do |i1|
    n.times do |i2|
      next if i1 == i2
      set.union(i1, i2) if touch?(square[i1], square[i2])
    end
  end

  group = Array.new
  n.times do |i|
    group.push(set.parent[i])
  end
  group.sort!.uniq!

  area = 0.0
  group.each do |g|
    edge = Array.new
    n.times do |i|
      next if set.parent[i] != g
      x, y, r = square[i]
      edge.push([y-r, x-r, x+r, Top], [y+r, x-r, x+r, Bottom])
    end
    edge.sort!{|a, b| a[0] <=> b[0]}
    point = Array.new.push(edge.first[1], edge.first[2])
    for i in 1...edge.size do
      area += (point.max - point.min) * (edge[i][0] - edge[i-1][0])
      x1, x2 = edge[i][1], edge[i][2]
      case edge[i][3]
        when Top
          point.push(x1, x2)
        when Bottom
          point.delete_at(point.index(x1))
          point.delete_at(point.index(x2))
      end
    end
  end
  printf "%d %.2f\n", data, area
end