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 Rust (1.15.1) (judge verdict: Accepted)

use std::cmp::min;
use std::io::{stdin, Read};
fn dfs(
    g: &Vec<Vec<usize>>,
    s: usize,
    t: usize,
    parents: &mut Vec<usize>,
    seen: &mut Vec<bool>,
) -> bool {
    seen[s] = true;
    if s == t {
        true
    } else {
        let n = g.len();
        for v in 0..n {
            if !seen[v] && g[s][v] > 0 && dfs(g, v, t, parents, seen) {
                parents[v] = s;
                return true;
            }
        }
        false
    }
}

fn calc_maxflow(g: &Vec<Vec<usize>>, s: usize, t: usize) -> usize {
    let n = g.len();
    let mut ret = 0;
    let mut parents = vec![0; n];
    let mut seen = vec![false; n];
    let mut rg = g.clone();
    while dfs(&rg, s, t, &mut parents, &mut seen) {
        let mut d = std::usize::MAX;
        let mut v = t;
        while v != s {
            let u = parents[v];
            d = min(d, rg[u][v]);
            v = u;
        }
        ret += d;
        let mut v = t;
        while v != s {
            let u = parents[v];
            rg[u][v] -= d;
            rg[v][u] += d;
            v = u;
        }
        seen = vec![false; n];
    }
    ret
}

macro_rules! parse {
    ($it: ident) => {
        $it.next().unwrap().parse().unwrap()
    };
    ($it: ident,2) => {
        (parse!($it), parse!($it))
    };
    ($it: ident,3) => {
        (parse!($it), parse!($it), parse!($it))
    };
    ($it: ident,4) => {
        (parse!($it), parse!($it), parse!($it), parse!($it))
    };
    ($it: ident, $n: ident) => {
        (&mut $it).take($n).map(|e| e.parse().unwrap()).collect();
    };
}

fn main() {
    let mut s = String::new();
    stdin().read_to_string(&mut s).unwrap();
    let mut it = s.split_whitespace();
    let n = parse!(it);
    let mut g = vec![vec![0; 2 * n + 2]; 2 * n + 2];
    for i in 0..n {
        g[0][i + 1] = 1;
    }
    for j in 0..n {
        g[j + n + 1][2 * n + 1] = 1;
    }
    let mut r: Vec<(usize, usize)> = (0..n).map(|_| parse!(it, 2)).collect();
    for i in 0..n {
        let j = i + n + 1;
        let bx: (usize, usize) = parse!(it, 2);
        for (i, &rx) in r.iter().enumerate() {
            if rx.0 < bx.0 && rx.1 < bx.1 {
                g[i + 1][j] = 1;
            }
        }
    }
    println!("{}", calc_maxflow(&g, 0, 2 * n + 1));
}