{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE OverloadedStrings #-}

import Control.Monad
import Control.Monad.Trans.State.Strict
import Data.List
import Data.Char (isSpace)
import Data.Maybe (fromJust)
import qualified Data.ByteString.Lazy.Char8 as B
--
type Parser a = StateT B.ByteString Maybe a

parseInt :: Parser Int
parseInt = StateT (B.readInt . B.dropWhile isSpace)

parseInt2 :: Parser (Int,Int)
parseInt2 = liftM2 (,) parseInt parseInt

parse :: Parser ([(Int,Int)], [(Int,Int)])
parse = do
    n <- parseInt
    liftM2 (,) (replicateM n parseInt2) (replicateM n parseInt2)

main=do
    (rs,bs) <- (\(xs,ys)->(sort xs, sort ys)).fromJust.evalStateT parse <$> B.getContents
--    print rs
--    print bs
    print.sum $ unfoldr f (rs,bs)

f :: ([(Int,Int)], [(Int,Int)]) -> Maybe(Int, ([(Int,Int)], [(Int,Int)]))
f ([], _ ) = Nothing
f (_ , []) = Nothing
f ((r:rs), bs) = g (r:rs) $ dropWhile (<r) bs

g :: [(Int,Int)] -> [(Int,Int)] -> Maybe(Int, ([(Int,Int)], [(Int,Int)]))
g _ [] = Nothing
g rs (b:bs) = h (span (<b) rs) (b:bs)

h :: ([(Int,Int)],[(Int,Int)]) -> [(Int,Int)] -> Maybe(Int, ([(Int,Int)],[(Int,Int)])) 
h (rs,[]) bs = Just(min (length rs) (length bs), ([],[]))
h (rs1,(r2:rs2)) bs
    = if length rs1 <= length bs1
                then Just (length rs1, ((r2:rs2), bs2))
                else Just (length bs1, ((drop (length bs1) rs1) ++ (r2:rs2), bs2))
    where
        (bs1,bs2) = span (<r2) bs
