stablegradients/pie-gem5-bysrc huggingface dataset:
// Original C++ solution (slower):
#include<cstdio>

#include<cmath>

#include<cstring>

#include<stack>

#include<map>

#include<set>

#include<queue>

#include<vector>

#include<iostream>

#include<algorithm>

#define LL long long

#define ll __int64

#define INF 0x3f3f3f3f

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

#define PI acos(-1)

#define eps 1e-10

#define si(n) scanf("%d",&n)

#define sll(n) scanf("%lld",&n)

#define FAST_IO ios::sync_with_stdio(false);cin.tie(0);

using namespace std;

int gcd(int a,int b){return b?gcd(b,a%b):a;}

int lcm(int a,int b){return a/gcd(a,b)*b;}

LL powmod(LL a,LL b,LL MOD){LL ans=1;while(b){if(b%2)ans=ans*a%MOD;a=a*a%MOD;b/=2;}return ans;}





/*

    1.Shoud it use long long ?

    2.Have you ever test several sample(at least three) yourself?

    3.Can you promise that the solution is right? At least,the main ideal

    4.use the puts("") or putchar() or printf and such things?

    5.init the used array or any value?

    6.use error MAX_VALUE?

    7.use scanf instead of cin/cout?

    8.whatch out the detail input require

*/

const int maxn=1e3+5;

int m[maxn][maxn];

int n;

struct node

{

	int x,y;

}a[maxn],b[maxn];

int used[maxn];

int match[maxn];

bool dfs(int u)

{

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

	{

		if(!used[i]&&m[u][i])

		{

			used[i]=1;

			if(match[i]==-1||dfs(match[i]))

			{

				match[i]=u;

				return 1;

			}

		}

	}

	return 0;

}

int hungry()

{

	int ans=0;

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

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

	{

		mem(used);

		if(dfs(i)) ++ans;

	}

	return ans;

} 



int main()

{

	si(n);

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

	{

		si(a[i].x);si(a[i].y);

	}

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

	{

		si(b[i].x);si(b[i].y);

	}

	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)

			{

				m[i][j+n]=1;

				//m[j+n][i]=1;

			}

		}

	}

	n+=n;

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

}










// Optimized solution to the same problem (faster):
#include<stdio.h>

#include <string.h>

using namespace std;

int n,link[110][110],connect[110];

bool used[110];

bool find(int x)

{

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

    {

        if(link[x][i]&&!used[i])

        {

            used[i]=true;

            if(connect[i]==0||find(connect[i]))

            {

                connect[i]=x;

                return true;

            }

        }

    }

    return false;

}

int main(void)

{

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

	scanf("%d",&n);

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

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

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

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

    memset(connect,0,sizeof connect);

    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]=true;

    int ans=0;

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

    {

        memset(used,false,sizeof used);

        if(find(i)) ans++;

    }

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

	return 0;

}


// Fastest known solution for this problem:
// Original C++ solution (slower):
#include <iostream>

#include <algorithm>

using namespace std;



struct point

{

	int x,y;

}a[1005],b[1005];

int c[1005]; 



int cmp(point x,point y)

{

	if(x.x==y.x) return x.y<y.y;

	return x.x<y.x;

}



int main()

{

	int n;

	cin>>n;

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

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

	}

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

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

	}

	sort(b,b+n,cmp);

	int ans=0;

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

		int maxn=-1;

		int z=-1;

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

			if(!c[j]&&a[j].x<b[i].x&&a[j].y<b[i].y&&a[j].y>maxn){

				maxn=a[j].y;

				z=j;

			}

		}

		if(maxn!=-1){

			c[z]=1;

			ans++;

		}

	}

	cout<<ans<<endl;

	return 0;

}


// Optimized solution to the same problem (faster):
#include<stdio.h>

#include <string.h>

using namespace std;

int n,link[110][110],connect[110];

bool used[110];

bool find(int x)

{

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

    {

        if(link[x][i]&&!used[i])

        {

            used[i]=true;

            if(connect[i]==0||find(connect[i]))

            {

                connect[i]=x;

                return true;

            }

        }

    }

    return false;

}

int main(void)

{

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

	scanf("%d",&n);

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

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

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

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

    memset(connect,0,sizeof connect);

    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]=true;

    int ans=0;

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

    {

        memset(used,false,sizeof used);

        if(find(i)) ans++;

    }

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

	return 0;

}


// Fastest known solution for this problem:
// Original C++ solution (slower):
#include<bits/stdc++.h> //Ithea Myse Valgulious

namespace chtholly{

typedef long long ll;

#define re0 register int

#define rec register char

#define rel register ll

#define gc getchar

#define pc putchar

#define p32 pc(' ')

#define pl puts("")

/*By Citrus*/

inline int read(){

  int x=0,f=1;char c=gc();

  for (;!isdigit(c);c=gc()) f^=c=='-';

  for (;isdigit(c);c=gc()) x=(x<<3)+(x<<1)+(c^'0');

  return f?x:-x;

  }

template <typename mitsuha>

inline bool read(mitsuha &x){

  x=0;int f=1;char c=gc();

  for (;!isdigit(c)&&~c;c=gc()) f^=c=='-';

  if (!~c) return 0;

  for (;isdigit(c);c=gc()) x=(x<<3)+(x<<1)+(c^'0');

  return x=f?x:-x,1;

  }

template <typename mitsuha>

inline int write(mitsuha x){

  if (!x) return 0&pc(48);

  if (x<0) x=-x,pc('-');

  int bit[20],i,p=0;

  for (;x;x/=10) bit[++p]=x%10;

  for (i=p;i;--i) pc(bit[i]+48);

  return 0;

  }

inline char fuhao(){

  char c=gc();

  for (;isspace(c);c=gc());

  return c;

  }

}using namespace chtholly;

using namespace std;



struct point{

int x,y;

void rd(){x=read(),y=read();}

}a[105],b[105];

int n,pp[105],vis[105],dp[105][105];



int dfs(int p){

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

  if (dp[p][i]&&!vis[i]){

    vis[i]=1;

    if (!pp[i]||dfs(pp[i])) return pp[i]=p,1;

    }

  }return 0;

}

int main(){

int i,j;n=read();

for (i=1;i<=n;++i) a[i].rd();

for (i=1;i<=n;++i) b[i].rd();

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

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

    if (a[i].x<b[j].x&&a[i].y<b[j].y) dp[i][j]=1;

    }

  }

int llx=0;

for (i=1;i<=n;++i) memset(vis,0,sizeof vis),llx+=dfs(i);

write(llx);

}

// Optimized solution to the same problem (faster):
#include<stdio.h>

#include <string.h>

using namespace std;

int n,link[110][110],connect[110];

bool used[110];

bool find(int x)

{

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

    {

        if(link[x][i]&&!used[i])

        {

            used[i]=true;

            if(connect[i]==0||find(connect[i]))

            {

                connect[i]=x;

                return true;

            }

        }

    }

    return false;

}

int main(void)

{

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

	scanf("%d",&n);

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

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

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

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

    memset(connect,0,sizeof connect);

    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]=true;

    int ans=0;

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

    {

        memset(used,false,sizeof used);

        if(find(i)) ans++;

    }

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

	return 0;

}


// Fastest known solution for this problem:
// Original C++ solution (slower):
#include<bits/stdc++.h>

using namespace std;

int main()

{

    int n,i,j;

    cin>>n;

    vector< pair<int,int> > r(n),b(n);

    for(i=0;i<n;i++){cin>>r[i].second>>r[i].first;}

    for(i=0;i<n;i++){cin>>b[i].first>>b[i].second;}

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

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

    vector<int> a(n);

    int mj,ans=0;

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

    {

        bool f=false;

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

        {

            if(r[j].second<b[i].first&&r[j].first<b[i].second)

            {

                if(a[j]==0)

                {

                    f=true;

                    mj=j;

                }

            }

        }

        if(f)

        {ans++;a[mj]=1;}

    }

    cout<<ans<<endl;

    return 0;

}


// Optimized solution to the same problem (faster):
#include<stdio.h>

#include <string.h>

using namespace std;

int n,link[110][110],connect[110];

bool used[110];

bool find(int x)

{

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

    {

        if(link[x][i]&&!used[i])

        {

            used[i]=true;

            if(connect[i]==0||find(connect[i]))

            {

                connect[i]=x;

                return true;

            }

        }

    }

    return false;

}

int main(void)

{

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

	scanf("%d",&n);

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

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

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

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

    memset(connect,0,sizeof connect);

    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]=true;

    int ans=0;

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

    {

        memset(used,false,sizeof used);

        if(find(i)) ans++;

    }

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

	return 0;

}


// Fastest known solution for this problem:
// Original C++ solution (slower):
#include <iostream>

#include <string.h>

#include <string>

using namespace std;

const int MAXN = 510;

int uN,vN;//u,v的数目，使用前面必须赋值

int g[MAXN][MAXN];//邻接矩阵

int linker[MAXN];

bool used[MAXN];

int temp;

struct node1{

	int x,y;

}a[105];

struct node2{

	int x,y;

}b[105];

bool dfs(int u)

{

    //if (u!=temp) printf("重新给点%d寻找匹配\n",u);

    for(int v = 0; v < vN; v++)

        if(g[u][v] && !used[v])

        {

            used[v] = true;

            if(linker[v] == -1 || dfs(linker[v]))

            {

                //printf("给点%d匹配到了点%d\n",u,v);

                linker[v] = u;

                return true;

            }

        }

        //printf("失败，没有再找到%d的匹配\n",u);

    return false;

}

int hungary()

{

    int res = 0;

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

    for(int u = 0; u < uN; u++)

    {

       // printf("开始给点%d进行匹配\n",u);

        //temp=u;

        memset(used,false,sizeof(used));

        if(dfs(u))res++;

    }

    return res;

}

int main()

{

	int n; 

    while (~scanf("%d",&n))

    {

    	vN=n;

    	uN=n;

        memset(g,0,sizeof(g));

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

        {

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

        }

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

        {

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

        }

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

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

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

        		g[i][j]=1;

			}

		}

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

    }

}

// Optimized solution to the same problem (faster):
#include<bits/stdc++.h>

using namespace std;

struct node

{

	 int x,y,flag;

};

bool cmp1(const node a,const node b)

{

	 return a.y<b.y;

}

bool cmp2(const node a,const node b)

{

	 return a.x<b.x;

}

int main()

{

	int t;

	scanf("%d",&t);

	vector<struct node>a,b;

	int ans=0,mj;

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

{  int x,y;

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

	 struct node z;

	 z.x=x;

	 z.y=y;

	 z.flag=0;

	 a.push_back(z);

}

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

{  int x,y;

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

	 struct node z;

	 z.x=x;

	 z.y=y;

	 z.flag=0;

	 b.push_back(z);

}

  sort(a.begin(),a.end(),cmp1);



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

 /* printf("\n\n");

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

  printf("%d %d\n",a[i].x,a[i].y);

  printf("\n\n");

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

 printf("%d %d\n",b[i].x,b[i].y);

 */

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

  {int flag=0;

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

  	 {

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

  	 	   {

  	 	   	 

  	 	   	if(a[j].flag==0)

  	 	   	{

  	 	   		flag=1;

  	 	   		mj=j;

				  }

  	 	   	  // printf("%d %d %d %d\n",a[i].x,a[i].y,b[j].x,b[j].y);

  	 	   	  

  	 	   	 

			  }

	   }

	   if(flag)

	   {

	   	ans++;

	   	a[mj].flag=1;

	   }

  }

  cout<<ans;

 } 


// Fastest known solution for this problem:
// Original C++ solution (slower):
#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;

}


// Optimized solution to the same problem (faster):
#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;

}


// Fastest known solution for this problem:
// Original C++ solution (slower):
#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;

}

// Optimized solution to the same problem (faster):
#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;

}

// Fastest known solution for this problem:
// Original C++ solution (slower):
#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;

}


// Optimized solution to the same problem (faster):
#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;

}


// Fastest known solution for this problem:
// Original C++ solution (slower):
#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;

}


// Optimized solution to the same problem (faster):
#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;

}


// Fastest known solution for this problem:
// Original C++ solution (slower):
#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;

}

// Optimized solution to the same problem (faster):
#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;

}

// Fastest known solution for this problem: