stablegradients/pie-gem5-pairs huggingface dataset:
// Slower C++ solution:
#include <bits/stdc++.h>

#define F(i, a, b) for (int i = (a); i < (b); ++i)

#define F2(i, a, b) for (int i = (a); i <= (b); ++i)

#define dF(i, a, b) for (int i = (a); i > (b); --i)

#define dF2(i, a, b) for (int i = (a); i >= (b); --i)

#define maxn 1010

using namespace std;

typedef long long LL;

bool flag[maxn];

struct Point {

    int x, y;

    bool operator < (const Point& p) const {

        return x < p.x && y < p.y;

    }

}a[maxn], b[maxn];

typedef long long LL;

struct Edge {

    int to, ne;

    Edge(int _to=0, int _ne=0) : to(_to), ne(_ne) {}

}edge[20000];

int tot, ne[maxn], match[maxn], vis[maxn];

void add(int u, int v) {

    edge[tot] = Edge(v, ne[u]);

    ne[u] = tot++;

}

int find(int u) {

    for (int i = ne[u]; ~i; i = edge[i].ne) {

        int v = edge[i].to;

        if (!vis[v]) {

            vis[v] = true;

            if (!match[v] || find(match[v])) {

                match[v] = u;

                return true;

            }

        }

    }

    return false;

}

int main() {

    memset(ne, -1, sizeof ne);

    int n, x, y;

    scanf("%d", &n);

    F(i, 0, n) scanf("%d%d", &a[i].x, &a[i].y);

    F(i, 0, n) scanf("%d%d", &b[i].x, &b[i].y);

    F(i, 0, n) {

        F(j, 0, n) {

            if (a[i]<b[j]) add(i+1, j+n+1), add(j+n+1, i+1);

        }

    }

    int cnt=0;

    F2(i, 1, n) {

        memset(vis, 0, sizeof vis);

        if (find(i)) ++cnt;

    }

    printf("%d\n", cnt);

    return 0;

}


// Faster C++ solution for the same problem (measured speedup: 1.160297109524522x):
#include <bits/stdc++.h>

#define F(i, a, b) for (int i = (a); i < (b); ++i)

#define F2(i, a, b) for (int i = (a); i <= (b); ++i)

#define dF(i, a, b) for (int i = (a); i > (b); --i)

#define dF2(i, a, b) for (int i = (a); i >= (b); --i)

#define maxn 110

using namespace std;

typedef long long LL;

struct Point {

    int x,y,type;

    bool operator < (const Point& p) const { return x < p.x; }

}a[maxn<<1];

set<int> st;

int main() {

    int n;

    scanf("%d", &n);

    F(i, 0, n) scanf("%d%d", &a[i].x, &a[i].y), a[i].type=0;

    F(i, 0, n) scanf("%d%d", &a[n+i], &a[n+i].y), a[n+i].type=1;

    sort(a, a+(n<<1));

    int ans=0;

    F(i, 0, n<<1) {

        if (a[i].type) {

            auto it = st.lower_bound(a[i].y);

            if (it==st.begin()) continue;

            else st.erase(--it), ++ans;

        }

        else {

            st.insert(a[i].y);

        }

    }

    printf("%d\n", ans);

    return 0;

}
// Slower C++ solution:
#include <iostream>

#include <cstdio>

#include <cstring>

#include <vector>

#include <algorithm>



using namespace std;

const int N = 1001;

//n1,n2为二分图的顶点集,其中x∈n1,y∈n2

int map[N][N], vis[N], cx[N], cy[N];

//link记录n2中的点y在n1中所匹配的x点的编号

int num;



int path(int u)

{

	int v;

	for (v = 0; v < num; v++)

	{

		if (map[u][v] && !vis[v])

		{

			vis[v] = 1;

			if (cy[v] == -1 || path(cy[v]))//如果y集合中的v元素没有匹配或者是v已经匹配，但是从cy[v]中能够找到一条增广路    

			{

				cx[u] = v; //找到增广路，修改匹配M    

				cy[v] = u;

				return 1;

			}

		}

	}

	return 0;

}



struct Node

{

	int x, y;

	Node(int a = -1, int b = -1)

	{

		x = a;

		y = b;

	}

};



vector<Node> vx, vy;



void init()

{

	scanf("%d", &num);

	for (int i = 0; i <  num; i++)

	{

		int a, b;

		scanf("%d%d", &a, &b);

		vx.push_back(Node(a, b));

	}

	for (int i = 0; i < num; i++)

	{

		int a, b;

		scanf("%d%d", &a, &b);

		vy.push_back(Node(a, b));

	}



	memset(vis, false, sizeof(vis));

	memset(map, 0, sizeof(map));

	memset(cx, -1, sizeof(cx));

	memset(cy, -1, sizeof(cy));



	for (int i = 0; i < num; i++)

	{

		for (int j = 0; j < num; j++)

		{

			if (vx[i].x < vy[j].x && vx[i].y < vy[j].y)

			{

				map[i][j] = 1;

			}

		}

	}

}



int main()

{



	init();

	int res = 0;

	for (int i = 0; i < num; i++)

	{

		if (cx[i] == -1)   //还没被匹配，执行内部代码    

		{

			memset(vis, 0, sizeof(vis));  //重置标记为为访问    

			res += path(i);   //以 i 为起点开始查找增广路，返回true ，匹配数+1    

		}

	}

	printf("%d\n", res);

	return 0;

}

// Faster C++ solution for the same problem (measured speedup: 5.05295545219844x):
#include <iostream>

#include <cstdio>

#include <cstring>

#include <vector>

#include <set>

#include <algorithm>



using namespace std;

const int N = 1001;



int num, res;



struct Node

{

	int x, y, flag;

	Node(int a = -1, int b = -1, int f = 0)

	{

		x = a;

		y = b;

		flag = f;

	}

};



bool cmp(Node a, Node b)

{

	return a.x < b.x;

}



vector<Node> vn;



void work()

{

	multiset<int> ms;

	for (int i = 0; i < vn.size(); i++)

	{

		if (!vn[i].flag)

			ms.insert(vn[i].y);

		else

		{

			int k = -1;

			for (int j = vn[i].y - 1; j >= 0; j--)

			{

				if (ms.count(j))

				{

					k = j;

					break;

				}

			}

			if (k >= 0)

			{

				ms.erase(k);

				res++;

			}

		}

	}

}





int main()

{





	scanf("%d", &num);

	for(int i = 0;i < 2 * num;i++)

	{

		int a, b, flag = 0;

		scanf("%d%d", &a, &b);



		if (i >= num)

			flag = 1;

		vn.push_back(Node(a, b, flag));

	}

	sort(vn.begin(), vn.end(), cmp);

	work();



	printf("%d\n", res);

	return 0;

}
// Slower C++ solution:
#include <iostream>

#include <cstdio>

#include <cstring>

#include <vector>

#define N 10005

using namespace std;



int n, s, a[N], b[N], c[N], d[N];

bool v[N];

struct st {

	int c1, c2, c3;

};

vector<st> e[N];

void pu(int p, int q) {

	e[p].push_back({q, 1, e[q].size()});

	e[q].push_back({p, 0, e[p].size() - 1});

}



int f(int p, int q) {

	int i, t2;

	st t;

	if (p == n * 2 + 1) return q;

	v[p] = 1;

	for (i = 0; i < e[p].size(); i++) {

		t = e[p][i];

		if (!v[t.c1] && t.c2 > 0) {

			t2 = f(t.c1, min(q, t.c2));

			if (t2 > 0) {

				e[p][i].c2 -= t2;

				e[t.c1][t.c3].c2 += t2;

				return t2;

			}

		}

	}

	return 0;

}

int main()

{

	int i, j, t;

	cin >> n;

	for (i = 1; i <= n; i++) {

		scanf ("%d %d", &a[i], &b[i]);

	}

	for (i = 1; i <= n; i++) {

		scanf ("%d %d", &c[i], &d[i]);

	}

	for (i = 1; i <= n; i++) {

		for (j = 1; j <= n; j++) {

			if (a[i] < c[j] && b[i] < d[j]) pu(i, n + j);

		}

	}

	for (i = 1; i <= n; i++) pu(0, i);

	for (i = 1; i <= n; i++) pu(n + i, n * 2 + 1);

	while (1) {

			memset(v, 0, sizeof(v));

		t = f(0, 2e9);

		if (t == 0) break;

		s += t;

	}

	cout << s;

    return 0;

}


// Faster C++ solution for the same problem (measured speedup: 1.2647712200671495x):
#include <iostream>

#include <cstdio>

#include <algorithm>

#include <set>

#define F first

#define S second

using namespace std;



int n, s;

set<int> b;

struct st {

	int c1, c2, z;

} a[205];



bool comp(st p, st q) {

	return p.c1 < q.c1;

}

int main()

{

	int i;

	set<int>::iterator it;

	cin >> n;

	for (i = 0; i < n * 2; i++) {

		scanf ("%d %d", &a[i].c1, &a[i].c2);

		a[i].z = i;

	}

	sort(a, a + n * 2, comp);

	for (i = 0; i < n * 2; i++) {

		if (a[i].z < n) {

			b.insert(a[i].c2);

		} else {

			it = b.lower_bound(a[i].c2);

			if (it != b.begin()) {

				it--;

				b.erase(it);

				s++;

			}

		}

	}

	cout << s;

    return 0;

}
// Slower C++ solution:
#include <bits/stdc++.h>

using namespace std;

int main()

{

    int n;

    cin >> n;

    vector<vector<int>> r(201, vector<int>(201));

    vector<vector<int>> b(201, vector<int>(201));

    for(int i = 0; i < n; i++)

    {

        int x, y;

        cin >> x >> y;

        r[x][y] = 1;

    }

    for(int i = 0; i < n; i++)

    {

        int x, y;

        cin >> x >> y;

        b[x][y] = 1;

    }



    int count = 0;

    for(int i = 1; i < 200; i++)

    {

        for(int j = 1; j < 200; j++)

        {

            if(b[i][j] == 0) continue;

            bool flag = false;

            for(int k = j-1; k >= 0; k--)

            {

                for(int m = i-1; m >= 0; m--)

                {

                    if(r[m][k] == 0) continue;

                    r[m][k] = 0;

                    count++;

                    flag = true;

                    break;

                }

                if(flag) break;

            }

        }

    }

    cout << count << endl;

}


// Faster C++ solution for the same problem (measured speedup: 1.6975936429300604x):
#include <bits/stdc++.h>

using namespace std;

using P = pair<int, int>;

int main()

{

    int n;

    cin >> n;

    set<P> a;

    vector<P> b(n);



    for(int i = 0; i < n; i++)

    {

        int x, y;

        cin >> x >> y;

        a.insert(P(x,y));

    }

    for(int i = 0; i < n; i++)

    {

        int x, y;

        cin >> x >> y;

        b[i] = P(x, y);

    }

    sort(b.begin(), b.end());



    int ans = 0;

    for(int i = 0; i < n; i++)

    {

        P p = b[i];

        int bx = p.first;

        int by = p.second;

        auto pos = a.end();

        int maxy = -1;

        for(auto itr = a.begin(); itr != a.end(); itr++)

        {

            P pa = *itr;

            int ax = pa.first;

            int ay = pa.second;

            if(ax < bx && ay < by && maxy < ay)

            {

                pos = itr;

                maxy = ay;

            }

        }

        if(pos != a.end())

        {

            ans++;

            a.erase(pos);

        }

    }

    cout << ans << endl;

}
// Slower C++ solution:
#include <bits/stdc++.h>

using namespace std;

#define mp       make_pair

#define pb       push_back

#define all(x)   (x).begin(),(x).end()

#define YES() printf("YES\n")

#define NO() printf("NO\n")

#define Yes() printf("Yes\n")

#define No() printf("No\n")

#define in(x,y,h,w) x >= 0 && x < h && y >= 0 && y < w



#define int long long

//typedef    long long          ll;

typedef    vector<bool>       vb;

typedef    vector<int>        vi;

typedef    vector<vb>         vvb;

typedef    vector<vi>         vvi;

typedef    pair<int,int>      P;



template <typename T> T &chmin(T &a, const T &b) { return a = min(a, b); }

template <typename T> T &chmax(T &a, const T &b) { return a = max(a, b); }

 

const int INF=1e+18;

const double EPS=1e-9;

const int MOD=1000000007;

 

const int dx[]={1,0,-1,0},dy[]={0,-1,0,1};



vector<int> G[100000];

int match[100000];

bool used[100000];



void add_edge(int u,int v){

	G[u].push_back(v);

	G[v].push_back(u);

}



bool dfs(int v){

	used[v] = true;

	for(int i = 0;i < G[v].size();i++){

		int u = G[v][i],w = match[u];

		if(w < 0 || !used[w] && dfs(w)){

			match[v] = u;

			match[u] = v;

			return true;

		}

	}

	return false;

}



int bi_match(int V){

	int res = 0;

	memset(match,-1,sizeof(match));

	for(int v = 0;v < V;v++){

		if(match[v] < 0){

			memset(used,0,sizeof(used));

			if(dfs(v)) res++;

		}

	}

	return res;

}



signed main(){

	int n,a[100],b[100],c[100],d[100];

	cin >> n;

	for(int i = 0;i < n;i++) cin >> a[i] >> b[i];

	for(int i = 0;i < n;i++) cin >> c[i] >> d[i];

	for(int i = 0;i < n;i++){

		for(int j = 0;j < n;j++){

			if(a[i] < c[j] && b[i] < d[j]){

				add_edge(i,n + j);

			}

		}

	}

	cout << bi_match(n * 2) << endl;

	return 0;

}

// Faster C++ solution for the same problem (measured speedup: 4.473195505033931x):
#include <bits/stdc++.h>

using namespace std;



signed main(){

	int n;

	cin >> n;

	vector<tuple<int,int,int>> points;

	for(int t = 0;t < 2;t++){

		for(int i = 0;i < n;i++){

			int x,y;

			cin >> x >> y;

			points.emplace_back(x,y,t);

		}

	}

	sort(points.begin(),points.end());

	set<int> st;

	int ans = 0;

	for(int i = 0;i < n * 2;i++){

		int x,y,isBlue;

		tie(x,y,isBlue) = points[i];

		if(isBlue){

			auto it = st.lower_bound(y);

			if(it != st.begin()){

				it--;

				st.erase(it);

				ans++;

			}

		}else{

			st.insert(y);

		}

	}

	cout << ans << endl;

}
// Slower C++ solution:
#include <bits/stdc++.h>

using namespace std;



using ll = long long;



#define REP(i, n) for (int i = 0; i < (n); ++i)

#define SIZE(a) ((int)(a).size())



// Adam Polak, Michal Glapa

const int N = 100005;

int n1,n2;          // INPUT

vector<int> g[N];   // INPUT

int m1[N], m2[N];   // OUTPUT

bool in_vc1[N], in_vc2[N]; // OUTPUT (Vertex Cover)

bool vis[N];



bool dfs(int u) {

	if (u<0) return true;

	if (vis[u]) return false; else vis[u]=true;

	for(int v : g[u])

		if (dfs(m2[v])) { m1[u] = v; m2[v] = u; return true; }

	return false;

}



int matching() {

	REP(i,n1) m1[i] = -1;

	REP(i,n2) m2[i] = -1;

	bool changed;

	do {

		changed = 0;

		REP(i,n1) vis[i] = false;

		REP(i,n1) if (m1[i] < 0) changed |= dfs(i);

	} while(changed);

	REP(i, n1) if (m1[i] != -1) { //Vertex Cover

		if (vis[i]) in_vc2[m1[i]] = true; // Vertex Cover

		else in_vc1[i] = true; // Vertex Cover

	}

	int siz = 0;

	REP(i,n1) siz += (m1[i] != -1);

	return siz;

}



int X1[N], Y1[N];

int X2[N], Y2[N];



int main() {

	ios::sync_with_stdio(false);

	cin.tie(0);



	cin >> n1;

	n2 = n1;

	REP(i, n1) cin >> X1[i] >> Y1[i];

	REP(i, n2) cin >> X2[i] >> Y2[i];



	REP(i, n1) REP(j, n2) {

		if (X1[i] < X2[j] && Y1[i] < Y2[j]) {

			g[i].push_back(j);

		}

	}



	cout << matching() << '\n';



	return 0;

}

// Faster C++ solution for the same problem (measured speedup: 3.4794479679705472x):
#include <cstdio>

#include <cstdlib>

#include <cstring>

#include <algorithm>

#include <vector>

#include <iostream>

using namespace std;



const int kMaxN = 105;



int n;

int a[kMaxN], b[kMaxN], c[kMaxN], d[kMaxN];

vector<int> g[kMaxN];

int vis[kMaxN], tim, lk[kMaxN];



inline void Link(int u, int v) {

  g[u].push_back(v);

}



int Find(int x) {

  for (int nxt : g[x]) {

    if (vis[nxt] != tim) {

      vis[nxt] = tim;

      if (!lk[nxt] || Find(lk[nxt])) {

        lk[nxt] = x;

        return true;

      }

    }

  }

  return false;

}



int main() {

  ios::sync_with_stdio(false);

  cin >> n;

  for (int i = 1; i <= n; ++i) {

    cin >> a[i] >> b[i];

  }

  for (int i = 1; i <= n; ++i) {

    cin >> c[i] >> d[i];

  }

  for (int i = 1; i <= n; ++i) {

    for (int j = 1; j <= n; ++j) {

      if (a[i] < c[j] && b[i] < d[j])

        Link(i, j);

    }

  }

  int ans = 0;

  tim = 0;

  for (int i = 1; i <= n; ++i) {

    ++tim;

    ans += Find(i);

  }

  cout << ans << endl;

  return 0;

}
// Slower C++ solution:
#include <bits/stdc++.h>

using namespace std;



using ll = long long;



#define REP(i, n) for (int i = 0; i < (n); ++i)

#define SIZE(a) ((int)(a).size())



// Adam Polak, Michal Glapa

const int N = 100005;

int n1,n2;          // INPUT

vector<int> g[N];   // INPUT

int m1[N], m2[N];   // OUTPUT

bool in_vc1[N], in_vc2[N]; // OUTPUT (Vertex Cover)

bool vis[N];



bool dfs(int u) {

	if (u<0) return true;

	if (vis[u]) return false; else vis[u]=true;

	for(int v : g[u])

		if (dfs(m2[v])) { m1[u] = v; m2[v] = u; return true; }

	return false;

}



int matching() {

	REP(i,n1) m1[i] = -1;

	REP(i,n2) m2[i] = -1;

	bool changed;

	do {

		changed = 0;

		REP(i,n1) vis[i] = false;

		REP(i,n1) if (m1[i] < 0) changed |= dfs(i);

	} while(changed);

	REP(i, n1) if (m1[i] != -1) { //Vertex Cover

		if (vis[i]) in_vc2[m1[i]] = true; // Vertex Cover

		else in_vc1[i] = true; // Vertex Cover

	}

	int siz = 0;

	REP(i,n1) siz += (m1[i] != -1);

	return siz;

}



int X1[N], Y1[N];

int X2[N], Y2[N];



int main() {

	ios::sync_with_stdio(false);

	cin.tie(0);



	cin >> n1;

	n2 = n1;

	REP(i, n1) cin >> X1[i] >> Y1[i];

	REP(i, n2) cin >> X2[i] >> Y2[i];



	REP(i, n1) REP(j, n2) {

		if (X1[i] < X2[j] && Y1[i] < Y2[j]) {

			g[i].push_back(j);

		}

	}



	cout << matching() << '\n';



	return 0;

}

// Faster C++ solution for the same problem (measured speedup: 3.260116155389098x):
#include <iostream>

#include <string>

#include <cstring>

#include <math.h>

#include <algorithm>

#include <iomanip> 

#include <stack>

#include <stdlib.h>	

#include <stdio.h>

#define INF 0x3f3f3f3f

#include <set> 

#include <map>  

#include <queue>

#define maxn 300

using namespace std;

typedef long long ll;

struct node {

	int x,y;

}a[205],b[160];

int girl[160],line[160][160];

bool used[160];

int n,x,y;



bool found(int x){

	for(int i=1;i<=n;i++){

		if(line[x][i]&&!used[i]){

			used[i]=1;

			if((girl[i]==0)||found(girl[i])){

				girl[i]=x;

				return 1;

			}

		}

	}

	return 0;

}

int main(){

	scanf("%d",&n);

	for(int i=1;i<=n;i++){

		scanf("%d%d",&x,&y);

		a[i].x=x;

		a[i].y=y;

	}

	for(int i=1;i<=n;i++){

		scanf("%d%d",&x,&y);

		b[i].x=x;

		b[i].y=y;

	}

	memset(line,0,sizeof(line));

	for(int i=1;i<=n;i++){

		for(int j=1;j<=n;j++){

			if((a[i].x<b[j].x)&&(a[i].y<b[j].y)){

				line[i][j]=1;

			}

		}

	}

	memset(girl,0,sizeof(girl));

	int sum=0;

	for(int i=1;i<=n;i++){

		memset(used,0,sizeof(used));

		if(found(i)) sum++;

	}

	printf("%d\n",sum);

	return 0;

}
// Slower C++ solution:
//#include <bits/stdc++.h>

#include <iostream>

#include <cmath>

#include <cstring>

#define FAST_IO ios::sync_with_stdio(false)

#define mem(a) memset(a,0,sizeof(a))

using namespace std;

typedef long long ll;

const double pi = acos(-1.0);

const int INF = 0x3f3f3f3f;

const int maxn = 105;



int n;

struct node{

	int x,y;

}p1[maxn],p2[maxn];

int g[maxn][maxn],vis[maxn],nxt[maxn];



bool fd(int x){

	for(int i=1;i<=n;i++){

		if(g[x][i]&&!vis[i]){

			vis[i] = 1;

			if(nxt[i]==0||fd(nxt[i])){

				nxt[i] = x;		//第i个人匹配的是x 

				return 1;

			}

		}

	}

	return 0;

}



int match(){

	int ans = 0;

	for(int i=1;i<=n;i++){

		mem(vis);

		if(fd(i)) ans++;

	}

	return ans;

}



int main(){

	FAST_IO;

	cin >> n;

	for(int i=1;i<=n;i++){

		cin >> p1[i].x >> p1[i].y;

	}

	for(int i=1;i<=n;i++){

		cin >> p2[i].x >> p2[i].y;

		for(int j=1;j<=n;j++){

			if(p1[j].x<p2[i].x&&p1[j].y<p2[i].y){

				g[i][j] = 1;

			}

		}

	}

	cout << match() << endl; 

    return 0;

}

// Faster C++ solution for the same problem (measured speedup: 5.246727449493926x):
#include<cstdio>

#include<cstring>



const int N=100,inf=0x5FFFFFFF;

struct node

{

	int x,y;

}R[N+5],B[N+5];

int n,ans;

bool vis[N+5];

int Ma[N+5][N+5],fa[N+5];



int Dfs(int u)

{

	for(int v=1;v<=n;v++)

		if(Ma[u][v]&&!vis[v])

		{

			vis[v]=1;

			if(fa[v]==-1||Dfs(fa[v]))

			{

				fa[v]=u;

				return true;

			}

		}

	return false;

}



void Solve()

{

	memset(fa,-1,sizeof(fa));

	for(int i=1;i<=n;i++)

	{

		memset(vis,0,sizeof(vis));

		ans+=Dfs(i);

	}

}



int main()

{

	scanf("%d",&n);

	for(int i=1;i<=n;i++)

		scanf("%d %d",&R[i].x,&R[i].y);

	for(int i=1;i<=n;i++)

	{

		scanf("%d %d",&B[i].x,&B[i].y);

		for(int j=1;j<=n;j++)

			if(R[j].x<B[i].x&&R[j].y<B[i].y)

				Ma[j][i]=1;

	}

	Solve();

	printf("%d\n",ans);

	return 0;

}
// Slower C++ solution:
/**  ~*BISMILLAHIR RAHMANIR RAHIM*~  **/



#include <bits/stdc++.h>



using namespace std;



#define F first

#define S second



typedef long long intl;

typedef pair<int, int> pii;



const int MX = 212;

int n;

pii P[MX];



struct Hopcroft_Karp {

    int N, M, match[MX], dist[MX];

    vector<int> G[MX];



    Hopcroft_Karp( int nn, int mm ) {

      N = nn, M = mm;

      memset(match, 0, sizeof match);

    }

    bool bfs() {

      queue<int> Q;

      for(int i=1; i<=N; i++) {

        if( !match[i] ) dist[i] = 0, Q.push(i);

        else dist[i] = INT_MAX;

      }

      dist[0] = INT_MAX;



      while( !Q.empty() ) {

        int u = Q.front(); Q.pop();

        if( !u ) continue;

        for(int v : G[u]) {

          if( dist[match[v]]==INT_MAX ) {

            dist[match[v]] = dist[u]+1;

            Q.push(match[v]);

          }

        }

      }

      return dist[0]!=INT_MAX;

    }

    bool dfs( int u ) {

      if( u ) {

        for(int v : G[u]) {

          if( dist[match[v]]==dist[u]+1 ) {

            if( dfs( match[v] ) ) {

              match[u] = v;

              match[v] = u;

              return true;

            }

          }

        }

        dist[u] = INT_MAX;

        return false;

      }

      return true;

    }

    int maximum_match() {

      int matching = 0;

      while( bfs() ) {

        for(int i=1; i<=N; i++) {

          if( !match[i] && dfs( i ) ) matching++;

        }

      }

      return matching;

    }



};



int main() {

  ios_base :: sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);

  cin>>n;

  for(int i=1; i<=2*n; i++) {

    cin>>P[i].F>>P[i].S;

  }

  Hopcroft_Karp BPM(n, n);

  for(int i=1; i<=n; i++) {

    for(int j=n+1; j<=2*n; j++) {

      if( P[i].F<P[j].F && P[i].S<P[j].S ) {

        BPM.G[i].push_back(j);

      }

    }

  }

  int res = BPM.maximum_match();

  cout<<res<<endl;

  return 0;

}


// Faster C++ solution for the same problem (measured speedup: 5.3141503810741835x):
#include<cstdio>

#include<cstring>



const int N=100,inf=0x5FFFFFFF;

struct node

{

	int x,y;

}R[N+5],B[N+5];

int n,ans;

bool vis[N+5];

int Ma[N+5][N+5],fa[N+5];



int Dfs(int u)

{

	for(int v=1;v<=n;v++)

		if(Ma[u][v]&&!vis[v])

		{

			vis[v]=1;

			if(fa[v]==-1||Dfs(fa[v]))

			{

				fa[v]=u;

				return true;

			}

		}

	return false;

}



void Solve()

{

	memset(fa,-1,sizeof(fa));

	for(int i=1;i<=n;i++)

	{

		memset(vis,0,sizeof(vis));

		ans+=Dfs(i);

	}

}



int main()

{

	scanf("%d",&n);

	for(int i=1;i<=n;i++)

		scanf("%d %d",&R[i].x,&R[i].y);

	for(int i=1;i<=n;i++)

	{

		scanf("%d %d",&B[i].x,&B[i].y);

		for(int j=1;j<=n;j++)

			if(R[j].x<B[i].x&&R[j].y<B[i].y)

				Ma[j][i]=1;

	}

	Solve();

	printf("%d\n",ans);

	return 0;

}
// Slower C++ solution:
#include <bits/stdc++.h>

using namespace std;



using ll = long long;



#define REP(i, n) for (int i = 0; i < (n); ++i)

#define SIZE(a) ((int)(a).size())



// Adam Polak, Michal Glapa

const int N = 100005;

int n1,n2;          // INPUT

vector<int> g[N];   // INPUT

int m1[N], m2[N];   // OUTPUT

bool in_vc1[N], in_vc2[N]; // OUTPUT (Vertex Cover)

bool vis[N];



bool dfs(int u) {

	if (u<0) return true;

	if (vis[u]) return false; else vis[u]=true;

	for(int v : g[u])

		if (dfs(m2[v])) { m1[u] = v; m2[v] = u; return true; }

	return false;

}



int matching() {

	REP(i,n1) m1[i] = -1;

	REP(i,n2) m2[i] = -1;

	bool changed;

	do {

		changed = 0;

		REP(i,n1) vis[i] = false;

		REP(i,n1) if (m1[i] < 0) changed |= dfs(i);

	} while(changed);

	REP(i, n1) if (m1[i] != -1) { //Vertex Cover

		if (vis[i]) in_vc2[m1[i]] = true; // Vertex Cover

		else in_vc1[i] = true; // Vertex Cover

	}

	int siz = 0;

	REP(i,n1) siz += (m1[i] != -1);

	return siz;

}



int X1[N], Y1[N];

int X2[N], Y2[N];



int main() {

	ios::sync_with_stdio(false);

	cin.tie(0);



	cin >> n1;

	n2 = n1;

	REP(i, n1) cin >> X1[i] >> Y1[i];

	REP(i, n2) cin >> X2[i] >> Y2[i];



	REP(i, n1) REP(j, n2) {

		if (X1[i] < X2[j] && Y1[i] < Y2[j]) {

			g[i].push_back(j);

		}

	}



	cout << matching() << '\n';



	return 0;

}

// Faster C++ solution for the same problem (measured speedup: 18.44231659539007x):
#include<cstdio>

#include<cstring>



const int N=100,inf=0x5FFFFFFF;

struct node

{

	int x,y;

}R[N+5],B[N+5];

int n,ans;

bool vis[N+5];

int Ma[N+5][N+5],fa[N+5];



int Dfs(int u)

{

	for(int v=1;v<=n;v++)

		if(Ma[u][v]&&!vis[v])

		{

			vis[v]=1;

			if(fa[v]==-1||Dfs(fa[v]))

			{

				fa[v]=u;

				return true;

			}

		}

	return false;

}



void Solve()

{

	memset(fa,-1,sizeof(fa));

	for(int i=1;i<=n;i++)

	{

		memset(vis,0,sizeof(vis));

		ans+=Dfs(i);

	}

}



int main()

{

	scanf("%d",&n);

	for(int i=1;i<=n;i++)

		scanf("%d %d",&R[i].x,&R[i].y);

	for(int i=1;i<=n;i++)

	{

		scanf("%d %d",&B[i].x,&B[i].y);

		for(int j=1;j<=n;j++)

			if(R[j].x<B[i].x&&R[j].y<B[i].y)

				Ma[j][i]=1;

	}

	Solve();

	printf("%d\n",ans);

	return 0;

}