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::str::FromStr;
use std::io::*;
use std::cmp::*;
use utils::*;

pub fn main() {
    let i = stdin();
    let mut o = Vec::new();
    run(i.lock(), &mut o);
    stdout().write_all(&o).unwrap();
}

fn run<R: BufRead, W: Write>(i: R, o: &mut W) {
    let mut i = AtRead::from(i);
    let n = i.read::<usize>();
    let mut reds = Vec::new();
    let mut blues = Vec::new();

    for _ in 0..n {
        reds.push(i.read2::<usize, usize>());
    }
    for _ in 0..n {
        blues.push(i.read2::<usize, usize>());
    }
    let mut cp_red = vec![0usize; n];
    let mut cp_blue = vec![0usize; n];

    fn can_pair(red: (usize, usize), blue: (usize, usize)) -> bool {
        red.0 < blue.0 && red.1 < blue.1
    }

    for n_red in 0..n {
        for n_blue in 0..n {
            if can_pair(reds[n_red], blues[n_blue]) {
                cp_red[n_red] += 1;
                cp_blue[n_blue] += 1;
            }
        }
    }
    println!("");
    let mut r = 0;
    loop {
        let min_red = cp_red
            .iter()
            .cloned()
            .enumerate()
            .filter(|&x| x.1 != 0)
            .min_by_key(|&x| x.1);
        let min_blue = cp_blue
            .iter()
            .cloned()
            .enumerate()
            .filter(|&x| x.1 != 0)
            .min_by_key(|&x| x.1);
        if let (Some((mut n_red, c_red)), Some((mut n_blue, c_blue))) = (min_red, min_blue) {
            if c_red < c_blue {
                n_blue = (0..n)
                    .filter(|&n_blue| can_pair(reds[n_red], blues[n_blue]) && cp_blue[n_blue] != 0)
                    .min_by_key(|&n_blue| cp_blue[n_blue])
                    .unwrap();
            } else {
                n_red = (0..n)
                    .filter(|&n_red| can_pair(reds[n_red], blues[n_blue]) && cp_red[n_red] != 0)
                    .min_by_key(|&n_red| cp_red[n_red])
                    .unwrap();
            }

            r += 1;
            for n_red in 0..n {
                if can_pair(reds[n_red], blues[n_blue]) && cp_red[n_red] != 0 {
                    cp_red[n_red] -= 1;
                }
            }
            for n_blue in 0..n {
                if can_pair(reds[n_red], blues[n_blue]) && cp_blue[n_blue] != 0 {
                    cp_blue[n_blue] -= 1;
                }
            }
            cp_red[n_red] = 0;
            cp_blue[n_blue] = 0;
        } else {
            break;
        }
    }
    writeln!(o, "{}", r).unwrap();
}
fn solve(_n: usize) -> usize {
    unimplemented!()
}

mod utils {
    #![allow(dead_code)]
    use super::*;
    use std::ops::*;

    pub struct AtRead<R: BufRead> {
        r: R,
        s: String,
    }

    macro_rules! fn_read {
        {$f:ident($($v:ident: $t:ident),*)} => {
            pub fn $f<$($t: FromStr),*>(&mut self) -> ($($t),*) {
                let i = &mut self.read_line().split(' ');
                $(
                    let $v = next(i);
                )*
                ($($v),*)
            }
        };
    }

    impl<R: BufRead> AtRead<R> {
        pub fn from(r: R) -> Self {
            AtRead {
                r: r,
                s: String::new(),
            }
        }
        pub fn read_line(&mut self) -> &str {
            self.s.clear();
            self.r.read_line(&mut self.s).unwrap();
            self.s.trim()
        }

        pub fn read<T: FromStr>(&mut self) -> T {
            self.read_line().parse().ok().unwrap()
        }
        fn_read! { read2(v1: T1, v2: T2) }
        fn_read! { read3(v1: T1, v2: T2, v3: T3) }
        fn_read! { read4(v1: T1, v2: T2, v3: T3, v4: T4) }

        pub fn read_vec<T: FromStr>(&mut self, n: usize) -> Vec<T> {
            self.read_line()
                .split(' ')
                .take(n)
                .map(|x| x.parse().ok().unwrap())
                .collect()
        }
    }

    fn next<'a, T: FromStr, I: std::iter::Iterator<Item = &'a str>>(i: &mut I) -> T {
        i.next().unwrap().parse().ok().unwrap()
    }

    const MOD_BASE: usize = 1000000007;

    #[derive(Debug, Clone, Copy)]
    struct ModNum(usize);

    impl ModNum {
        fn new(n: usize) -> Self {
            ModNum(n % MOD_BASE)
        }
    }
    macro_rules! modnum_op {
        (($ot:ident, $f:ident), ($ot_a:ident, $f_a:ident), $($rhs:ty, $e:expr,)*) => {
            $(
            impl $ot<$rhs> for ModNum {
                type Output = Self;
                fn $f(self, rhs: $rhs) -> Self {
                    Self::new(($e)(self, rhs))
                }
            }
            impl $ot_a<$rhs> for ModNum {
                fn $f_a(&mut self, rhs: $rhs) {
                    *self = Self::new(($e)(*self, rhs))
                }
            }
            )*
        }
    }

    modnum_op!(
        (Add, add),
        (AddAssign, add_assign),
        ModNum,
        |l: ModNum, r: ModNum| l.0 + r.0,
        usize,
        |l: ModNum, r: usize| l.0 + r,
    );

    modnum_op!(
        (Mul, mul),
        (MulAssign, mul_assign),
        ModNum,
        |l: ModNum, r: ModNum| l.0 * r.0,
        usize,
        |l: ModNum, r: usize| l.0 * r,
    );

    modnum_op!(
        (Sub, sub),
        (SubAssign, sub_assign),
        ModNum,
        |l: ModNum, r: ModNum| MOD_BASE + l.0 - r.0,
        usize,
        |l: ModNum, r: usize| MOD_BASE + l.0 - r,
    );

}