### constant

DXYS = [[1, 0], [0, -1], [-1, 0], [0, 1]]
INF = 1 << 30

### main

loop do
  n = gets.to_i
  break if n == 0

  xs = []
  ys = []
  rects = []
  minx = miny = INF
  maxx = maxy = 0
  
  n.times do
    x0, y1, x1, y0 = gets.split.map(&:to_i)
    rects << [x0, y0, x1, y1]
    xs << x0 << x1
    ys << y0 << y1
    minx = x0 if minx > x0
    maxx = x1 if maxx < x1
    miny = y0 if miny > y0
    maxy = y1 if maxy < y1
  end
  xs << minx - 1 << maxx + 1
  ys << miny - 1 << maxy + 1

  xs.sort!.uniq!
  ys.sort!.uniq!
  nxs = xs.length
  nys = ys.length
  
  xhash = {}
  xs.each_with_index{|x, i| xhash[x] = i}
  yhash = {}
  ys.each_with_index{|y, i| yhash[y] = i}
  #p [xhash, yhash]

  rrects =
    rects.map{|x0, y0, x1, y1| [xhash[x0], yhash[y0], xhash[x1], yhash[y1]]}
  #p rrects

  flds = Array.new(nys){Array.new(nxs){0}}
  used = Array.new(nys){Array.new(nxs){false}}
  #p flds

  for i in (0...n)
    x0, y0, x1, y1 = rrects[i]
    b = 1 << i
    for y in (y0...y1)
      for x in (x0...x1)
        flds[y][x] |= b
      end
    end
  end
  #p flds

  nr = 0
  for oy in (0...nys)
    for ox in (0...nxs)
      if ! used[oy][ox]
        nr += 1
        fld = flds[oy][ox]
        used[oy][ox] = true
        q = [[ox, oy]]

        while ! q.empty?
          ux, uy = q.shift
          DXYS.each do |dx, dy|
            vx = ux + dx
            vy = uy + dy
            if vx >= 0 && vx < nxs && vy >= 0 && vy < nys &&
               ! used[vy][vx] && flds[vy][vx] == fld
              used[vy][vx] = true
              q << [vx, vy]
            end
          end
        end
      end
    end
  end

  puts nr
end