from abc import abstractmethod
from collections import defaultdict
from math import inf


class Edge:
    def __init__(self):
        self.flow = 0
        self.residual: Edge
        self.from_node = None
        self.to_node = None
        self.capacity = None

    @classmethod
    def by_nodes(cls, from_node, to_node, capacity):
        c = cls()
        c.connect(from_node, to_node, capacity)
        return c

    def connect(self, from_node, to_node, capacity):
        self.from_node = from_node
        self.to_node = to_node
        self.capacity = capacity

    def is_residual(self):
        return self.capacity == 0

    def remaining_capacity(self):
        return self.capacity - self.flow

    def augument(self, bottle_neck):
        self.flow += bottle_neck
        self.residual.flow -= bottle_neck

    def __repr__(self):
        return f"{self.from_node}-({self.flow}/{self.capacity})->{self.to_node}"


class NetworkFlowSolverBase:
    def __init__(self, n, s, t):
        self.visited_token = 1
        self.visited = defaultdict(int)
        self.solved = False
        self.max_flow = 0
        self.graph = defaultdict(list)
        # n: the number of nodes in the graph including s(src) and t(sink)
        self.n = n
        # s: the index of the src node
        self.s = s
        # t: the index of the sink node
        self.t = t

    def add_edge(self, from_node, to_node, capacity):
        assert capacity >= 0, f"forward-edge capacity must be >= 0: input={capacity}"
        e_f = Edge.by_nodes(from_node, to_node, capacity)
        e_b = Edge.by_nodes(to_node, from_node, 0)
        e_f.residual = e_b
        e_b.residual = e_f
        self.graph[from_node].append(e_f)
        self.graph[to_node].append(e_b)

    def get_graph(self):
        self.execute()
        return self.graph

    def get_max_flow(self):
        self.execute()
        return self.max_flow

    def execute(self):
        if self.solved:
            return
        self.solve()
        self.solved = True

    @abstractmethod
    def solve(self):
        pass


class FordFulkersonDfsSover(NetworkFlowSolverBase):
    def __init__(self, n, s, t):
        super().__init__(n, s, t)

    def solve(self):
        while True:
            f = self.dfs(self.s, inf)
            self.visited_token += 1
            self.max_flow += f
            if f == 0:
                break

    def dfs(self, nd, flow):
        if nd == self.t:
            return flow
        self.visited[nd] = self.visited_token

        for e in self.graph[nd]:
            if (
                e.remaining_capacity() > 0
                and self.visited[e.to_node] != self.visited_token
            ):
                bottle_neck = self.dfs(e.to_node, min(flow, e.remaining_capacity()))
                if bottle_neck > 0:
                    e.augument(bottle_neck)
                    return bottle_neck
        return 0


if __name__ == "__main__":
    N = int(input())
    reds = [tuple(map(int, input().split())) for _ in range(N)]
    blues = [tuple(map(int, input().split())) for _ in range(N)]
    s = 2 * N
    t = 2 * N + 1
    G = FordFulkersonDfsSover(2 * N + 2, s, t)
    [G.add_edge(s, r, 1) for r in range(N)]
    [G.add_edge(b, t, 1) for b in range(N, 2 * N)]
    for r, (rx, ry) in enumerate(reds):
        for b, (bx, by) in enumerate(blues, N):
            if rx < bx and ry < by:
                G.add_edge(r, b, 1)

    print(G.get_max_flow())



Measured memory_bytes: 10132