import Control.Monad (replicateM)
import Data.List (sort)
import qualified Data.Map.Strict as Map
import qualified Data.Set as Set

type Rect = (Int,Int,Int,Int)
type Span = (Int,Int)
type Color = Int
type ColorRelation = Map.Map Int Int
type ColorCorrection = Map.Map Int Int

main = do
    [w,h] <- getLine >>= return . map read . words
    if all (==0) [w,h] then return () else do
        n <- readLn
        rs <- replicateM n (getLine >>= return . rect . map read . words)
        print $ solve w h rs
        main
    where
    rect [x1,y1,x2,y2] = (x1,y1,x2,y2)

solve :: Int -> Int -> [Rect] -> Int
solve w h rs = step [] (blankSpansSeq ++ [[]]) 0
    where
    rs' = sort rs

    blankSpansSeq :: [[Span]]
    blankSpansSeq = rs' `seq` map (listBlankSpans w rs') (listScanYs h rs)

    step :: [(Span,Color)] -> [[Span]] -> Int -> Int
    step [] [] num = num

    step prev (curr:spans) num = step curr'' spans num'
        where
        curr' = zip curr [1..]
        joints = listColorJoints prev curr'
        cor = matchColors joints
        curr'' = correctColors cor curr'
        num' = num + Set.size ((setOf (map snd prev)) Set.\\ setOf (map fst joints))

    setOf = foldr Set.insert Set.empty

listScanYs :: Int -> [Rect] -> [Int]
listScanYs h rs = filter' $ 0 : (sort $ concatMap (\(_,y1,_,y2) -> [y1,y2]) rs)
    where
    filter' (y:[])
        | y < h = [y]
        | otherwise = []
    filter' (y1:y2:ys)
        | y1 < y2 = y1 : filter' (y2:ys)
        | otherwise = filter' (y2:ys)

listRectSpans :: [Rect] -> Int -> [Span]
-- assumes rects are sorted by x1
listRectSpans rs y = merge $ map (\(x1,_,x2,_) -> (x1,x2)) $ filter cross rs
    where
    cross (_,y1,_,y2) = y1 <= y && y < y2
    merge [] = []
    merge ((x1,x2):[]) = [(x1,x2)]
    merge ((x1,x2):(x3,x4):ps)
        | x2 < x3 = (x1,x2) : merge ((x3,x4):ps)
        | otherwise = merge ((x1,max x2 x4):ps)

listBlankSpans :: Int -> [Rect] -> Int -> [Span]
listBlankSpans w rs y = blank' ((0,0) : listRectSpans rs y)
    where
    blank' ((0,0):(0,x):ps) = blank' ((0,x):ps)
    blank' ((x1,x2):(x3,x4):ps) = (x2,x3) : blank' ((x3,x4):ps)
    blank' ((x1,x2):[])
        | x2 == w = []
        | otherwise = [(x2,w)]

listColorJoints :: [(Span,Color)] -> [(Span,Color)] -> [(Color,Color)]
listColorJoints [] _ = []
listColorJoints _ [] = []
listColorJoints ps1@(((b1,e1),c1):ps1') ps2@(((b2,e2),c2):ps2')
    | e1 <= b2 = listColorJoints ps1' ps2
    | e2 <= b1 = listColorJoints ps1 ps2'
    | e1 <= e2 = (c1,c2) : listColorJoints ps1' ps2
    | e1 >  e2 = (c1,c2) : listColorJoints ps1 ps2'

matchColors :: [(Color,Color)] -> ColorCorrection
matchColors cps = matchColors' cps Map.empty Map.empty
    where
    matchColors' [] _ cor = cor
    matchColors' ((c1,c2):cps) rel cor = matchColors' cps rel' cor'
        where
        rel' = case Map.lookup c1 rel of
                Nothing -> Map.insert c1 c2 rel
                Just c0 -> case Map.lookup c2 cor of
                        Nothing -> rel
                        Just c0' -> Map.map (replace c0' c0) rel
        cor' = case Map.lookup c1 rel of
                Nothing -> cor
                Just c0 -> case Map.lookup c2 cor of
                        Nothing -> Map.insert c2 c0 cor
                        Just c0' -> Map.insert c0' c0 (Map.map (replace c0' c0) cor)
        replace x x' = \y -> if y == x then x' else y


correctColors :: ColorCorrection -> [(Span,Color)] -> [(Span,Color)]
correctColors cor [] = []
correctColors cor ((s,c):ps) = case Map.lookup c cor of
        Nothing -> (s,c)  : correctColors cor ps
        Just c' -> (s,c') : correctColors cor ps

Measured memory_bytes: 5756