Problem:
Score : 400 points

Problem Statement

On a two-dimensional plane, there are N red points and N blue points.
The coordinates of the i-th red point are (a_i, b_i), and the coordinates of the i-th blue point are (c_i, d_i).

A red point and a blue point can form a friendly pair when, the x-coordinate of the red point is smaller than that of the blue point, and the y-coordinate of the red point is also smaller than that of the blue point.

At most how many friendly pairs can you form? Note that a point cannot belong to multiple pairs.

Constraints

All input values are integers.

1 \leq N \leq 100

0 \leq a_i, b_i, c_i, d_i < 2N

a_1, a_2, ..., a_N, c_1, c_2, ..., c_N are all different.

b_1, b_2, ..., b_N, d_1, d_2, ..., d_N are all different.

Input

Input is given from Standard Input in the following format:

N
a_1 b_1
a_2 b_2
:
a_N b_N
c_1 d_1
c_2 d_2
:
c_N d_N

Output

Print the maximum number of friendly pairs.

Sample Input 1

3
2 0
3 1
1 3
4 2
0 4
5 5

Sample Output 1

2

For example, you can pair (2, 0) and (4, 2), then (3, 1) and (5, 5).

Sample Input 2

3
0 0
1 1
5 2
2 3
3 4
4 5

Sample Output 2

2

For example, you can pair (0, 0) and (2, 3), then (1, 1) and (3, 4).

Sample Input 3

2
2 2
3 3
0 0
1 1

Sample Output 3

0

It is possible that no pair can be formed.

Sample Input 4

5
0 0
7 3
2 2
4 8
1 6
8 5
6 9
5 4
9 1
3 7

Sample Output 4

5

Sample Input 5

5
0 0
1 1
5 5
6 6
7 7
2 2
3 3
4 4
8 8
9 9

Sample Output 5

4

Solution in Python (3.4.3) (judge verdict: Accepted)

import collections


class FordFulkerson:
    """
    Verified with http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=GRL_6_A
    """

    def __init__(self):
        self.g = collections.defaultdict(lambda: collections.defaultdict(int))

    def add_edge(self, u, v, c):
        self.g[u][v] = c

    def dfs(self, u, t, f, used: set):
        """
        :param u: visiting node
        :param t: sink
        :param f: flow
        :param used: node u is used?
        :return: min(c, f)
        """
        if u == t:
            return f

        used.add(u)

        # visit next node
        for v, c in self.g[u].items():
            if v not in used and c > 0:
                f = min(c, f)
                d = self.dfs(v, t, f, used)

                # update the graph if a path is found
                if d > 0:
                    self.g[u][v] -= d
                    self.g[v][u] += d
                    return d

        # path is not found
        return 0

    def max_flow(self, s, t):
        """Calculate maximum flow from s to t on the network

        :param s: source
        :param t: sink
        :return: max flow on the network
        """
        f = 0
        while True:
            d = self.dfs(s, t, float("inf"), set())
            if d == 0:  # nothing to update any more
                break
            f += d
        return f


def bipartite_matching(pairs: list, X :int, Y: int):
    solver = FordFulkerson()
    s = X+Y
    t = s+1
    for x, y in pairs:
        solver.add_edge(x, X+y, 1)
    for x in range(X):
        solver.add_edge(s, x, 1)
    for y in range(Y):
        solver.add_edge(X+y, t, 1)

    return solver.max_flow(s, t)


def main():
    N = int(input())
    rs = []
    bs = []
    for i in range(N):
        x, y = map(int, input().split())
        rs.append((x, y))
    for i in range(N):
        x, y = map(int, input().split())
        bs.append((x, y))

    pairs = []
    for i in range(N):
        for j in range(N):
            r = rs[i]
            b = bs[j]
            if r[0]<b[0] and r[1]<b[1]:
                pairs.append((i, j))
    print(bipartite_matching(pairs, N, N))


if __name__ == '__main__':
    main()