import qualified Data.IntMap as M
import Data.Array.IO
import Data.Maybe (fromJust)
import Data.List
import Control.Monad
import Control.Applicative

type Arr = IOUArray Int Bool
type Edge = (Int, Int)
type Weight = Int
type Vertex = (Int, Weight)
--key:頂点番号, value:隣接点集合
type GraphW = M.IntMap Neighbor
--key:ある点の隣接点の頂点番号, value:辺の重さ
type Neighbor = M.IntMap Weight

main = do
  n <- readLn :: IO Int
  red <- map ((\[x, y] -> (read x, read y)) . words) <$> replicateM n getLine :: IO [(Int, Int)]
  blue <- map ((\[x, y] -> (read x, read y)) . words) <$> replicateM n getLine :: IO [(Int, Int)]
  let rr = zip red [1..n]
      bb = zip blue [n+i | i <- [1..n]]
      edge = concat $ map (check rr) bb
      graph = foldl' makeGraphW M.empty edge
      graph' = foldl' makeGraphW graph [(0, i) | i <- [1..n]]
      graph'' = foldl' makeGraphW graph' [(n+i, 2*n+1) | i <- [1..n]]
  (ans, g) <- fordFulkerson (2*n+1) (0, graph'') 0
  print ans

check :: [((Int, Int), Int)] -> ((Int, Int), Int) -> [(Int, Int)]
check [] _ = []
check (((a, b), i):xx) ((c, d), j) =
  if a < c && b < d
    then (i, j) : check xx ((c, d), j)
    else check xx ((c, d), j)


--Ford-Fulkerson
inf = 10^8

fordFulkerson :: Int -> (Int, GraphW) -> Int -> IO (Int, GraphW)
fordFulkerson dst (flow, graph) v = do
  used <- newArray (0, dst) False :: IO Arr
  (f, g) <- dfsFF used v dst (inf, graph)
  if f == 0
    then return (flow, g)
    else fordFulkerson dst (flow + f, g) v

dfsFF :: Arr -> Int -> Int -> (Int, GraphW) -> IO (Int, GraphW)
dfsFF used v dst (flow, graph)
  | v == dst = return (flow, graph)
  | otherwise = do
    writeArray used v True
    let ne = M.lookup v graph
    if ne /= Nothing
      then do
        dfsFF' used v dst (flow, graph) $ fst . unzip . M.toList $ fromJust ne
      else return (0, graph)

dfsFF' :: Arr -> Int -> Int -> (Int, GraphW) -> [Int] -> IO (Int, GraphW)
dfsFF' _    _ _   (flow, graph) []      = return (0, graph)
dfsFF' used v dst (flow, graph) (to:ts) = do
  isMark <- readArray used to
  let cap = fromJust $ M.lookup to $ fromJust $ M.lookup v graph
  if not isMark && cap > 0
    then do
      (f, g) <- dfsFF used to dst (min flow cap, graph)
      if f > 0
        then do
          let neV = M.adjust (subtract f) to $ fromJust $ M.lookup v graph
              g' = M.insert v neV g
              neTo = M.adjust (+f) v $ fromJust $ M.lookup to g'
              g'' = M.insert to neTo g'
          return (f, g'')
        else dfsFF' used v dst (flow, graph) ts
    else dfsFF' used v dst (flow, graph) ts


--重み付き隣接リスト
makeGraphW :: GraphW -> Edge -> GraphW
makeGraphW graph (x, y) =
  let nX = M.lookup x graph
      nY = M.lookup y graph
      vX = if nX == Nothing
             then M.insert x (addNeighbor (y, 1) M.empty) graph
             else M.insert x (addNeighbor (y, 1) $ fromJust nX) graph
  in if nY == Nothing
       then M.insert y (addNeighbor (x, 1) M.empty) vX
       else M.insert y (addNeighbor (x, 1) $ fromJust nY) vX

addNeighbor :: Vertex -> Neighbor -> Neighbor
addNeighbor (i, weight) ne = M.insert i weight ne
