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 C# (Mono 4.6.2.0) (judge verdict: Accepted)

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;

class TEST{
	static void Main(){
		Sol mySol =new Sol();
		mySol.Solve();
	}
}

class Sol{
	public void Solve(){
		
		var mf = new MaxFlow_Dinic();
		int NN = 2 * N + 2;
		int src = 2 * N;
		int sinc = src + 1;
		mf.Init(NN);
		for(int i=0;i<N;i++){
			mf.AddEdge(src, i, (int) 1);
		}
		for(int i=0;i<N;i++){
			mf.AddEdge(i + N, sinc, (int) 1);
		}
		for(int i=0;i<N;i++){
			for(int j=0;j<N;j++){
				if(A[i] < C[j] && B[i] < D[j]) mf.AddEdge(i, j + N, 1);
			}
		}
		
		Console.WriteLine(mf.MaxFlow(src, sinc));
	}
	int N;
	int[] A,B,C,D;
	public Sol(){
		N = ri();
		A = new int[N]; B = new int[N];
		C = new int[N]; D = new int[N];
		for(int i=0;i<N;i++){
			var d = ria();
			A[i] = d[0]; B[i] = d[1];
		}
		for(int i=0;i<N;i++){
			var d = ria();
			C[i] = d[0]; D[i] = d[1];
		}
	}

	static String rs(){return Console.ReadLine();}
	static int ri(){return int.Parse(Console.ReadLine());}
	static long rl(){return long.Parse(Console.ReadLine());}
	static double rd(){return double.Parse(Console.ReadLine());}
	static String[] rsa(char sep=' '){return Console.ReadLine().Split(sep);}
	static int[] ria(char sep=' '){return Array.ConvertAll(Console.ReadLine().Split(sep),e=>int.Parse(e));}
	static long[] rla(char sep=' '){return Array.ConvertAll(Console.ReadLine().Split(sep),e=>long.Parse(e));}
	static double[] rda(char sep=' '){return Array.ConvertAll(Console.ReadLine().Split(sep),e=>double.Parse(e));}
}


class MaxFlow_Dinic{
	// arihon is god
	class Edge {
		public int To,Cap,Rev;
		public Edge(int to = 0,int cap = 0,int rev = 0){
			To = to;
			Cap = cap;
			Rev = rev;
		}
	}
	
	List<Edge>[] G;
	int[] Level;
	int[] Iter;
	
	static int Inf = (int) 1e9;
	public int N;
	public void Init(int n){
		N = n;
		G = new List<Edge>[N];
		for(int i=0;i<N;i++) G[i] = new List<Edge>();
		Level = new int[N];
		Iter = new int[N];
	}
	
	
	public void AddEdge(int from, int to, int cap){
		G[from].Add(new Edge(to,cap,G[to].Count));
		G[to].Add(new Edge(from,0,G[from].Count-1));
	}
	
	void bfs(int s){
		for(int j=0;j<G.Length;j++)Level[j] = -1;
		var Q = new Queue<int>();
		Level[s] = 0;
		Q.Enqueue(s);
		
		while(Q.Count>0){
			var v = Q.Dequeue();
			foreach(var e in G[v]){
				if(e.Cap > 0 && Level[e.To] < 0){
					Level[e.To] = Level[v] + 1;
					Q.Enqueue(e.To);
				}
			}
		}
	}
	
	int dfs(int v, int t, int f){
		if(v == t) return f;
		for(;Iter[v] < G[v].Count; Iter[v]++){
			var e = G[v][Iter[v]];
			if(e.Cap > 0 && Level[v] < Level[e.To]){
				int d = dfs(e.To, t, Math.Min(f,e.Cap));
				if(d > 0){
					e.Cap -= d;
					G[e.To][e.Rev].Cap += d;
					return d;
				}
			}
		}
		return 0;
	}
	
	public int MaxFlow(int s,int t){
		int flow = 0;
		while(true){
			bfs(s);
			if(Level[t] < 0) return flow;
			Iter = new int[N];
			
			int f;
			while( ( f = dfs(s,t,Inf)) > 0){
				flow += f;
			}
		}
	}
	
}