module Graphical
	require 'set'

	def reachable_from(s, max_depth = nil)
		reached = Set[s]
		queue = [s]
		depth = 0
		loop {
			break if max_depth && depth >= max_depth
			next_queue = []
			until queue.empty?
				u = queue.shift
				each_out_connection_of(u){|v, _|
					next if reached.include?(v)
					reached << v
					next_queue << v
				}
			end
			break if next_queue.empty?
			queue = next_queue
			depth += 1
		}
		return reached
	end
end

def compress(used_x)
	x_map = {}
	used_x.to_a.uniq.sort.each_with_index{|x, i| x_map[x] = i}
	x_map
end

loop {
	n = gets.to_i
	break if n == 0
	rects = (1..n).map{ gets.split.map &:to_i }

	x_map = compress( rects.map{|r| [r[0], r[2]]}.flatten )
	y_map = compress( rects.map{|r| [r[1], r[3]]}.flatten )
	rects.map!{|x1, y1, x2, y2| [x_map[x1]+1 ,y_map[y1]+1, x_map[x2]+1 ,y_map[y2]+1]}

	a = (0..y_map.size+2).map{ (0..x_map.size+2).map{ 0 } }
	rects.each_with_index{|(x1, y1, x2, y2), k| 
		(y2..y1-1).each{|i|
			(x1..x2-1).each{|j|
				a[i][j] |= (1 << k)
			}
		}
	}

	a.extend Graphical
	def a.each_out_connection_of(u)
		y, x = u
		[[1,0],[-1,0],[0,1],[0,-1]].each{|dy, dx|
			u, v = y+dy, x+dx	
			yield([u, v], 1) if (0..self.size-1) === u && (0..self[0].size-1) === v && self[u][v] == self[y][x]
		}
	end

	hash = {}
	c = 0
	(0..a.size-1).each{|i|
		(0..a[i].size-1).each{|j|
			next if hash[[i, j]]	
			c += 1
			a.reachable_from([i,j]).each{|y, x|
				hash[[y,x]] = 1
			}
		}
	}
	p c
}