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

using namespace std;

const int N = 5010;

bool canleft[N][N], canright[N][N];

int n, K;

int a[N];

bool can[N];

int main(){

	ios::sync_with_stdio(0);

	cin.tie(0), cout.tie(0);

	cin >> n >> K;

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

		cin >> a[i];

	canleft[0][0] = 1;

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

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

			canleft[i][j] = canleft[i - 1][j];

			if(j >= a[i])

				canleft[i][j] |= canleft[i - 1][j - a[i]];

		}

	}

	canright[n + 1][0] = 1;

	for(int i = n; i >= 2; i--){

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

			canright[i][j] = canright[i + 1][j];

			if(j >= a[i])

				canright[i][j] |= canright[i + 1][j - a[i]];

		}

	}

	int cnt = 0;

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

		bool nece = false;

		vector<int> A, B;

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

			if(canleft[i - 1][j]) A.push_back(j);

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

			if(canright[i + 1][j]) B.push_back(j);

		for(int val : A){

			int tmp = K - a[i] - val;

			vector<int>::iterator it = lower_bound(B.begin(), B.end(), tmp);

			if(it != B.end()){

				if((*it) + val < K)

					nece = true;

			}

		}

		if(!nece) cnt++;

	}

	cout << cnt << "\n";

	return 0;

}


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

using namespace std;

//#define cerr if (false) cerr

#define db(x) cerr << #x << "=" << x << endl

#define db2(x, y) cerr << #x << "=" << x << "," << #y << "=" << y << endl

#define db3(x, y, z) cerr << #x << "=" << x << "," << #y << "=" << y << "," << #z << "=" << z << endl

#define dbv(v) cerr << #v << "="; for (auto _x : v) cerr << _x << ", "; cerr << endl

#define dba(a, n) cerr << #a << "="; for (int _i = 0; _i < (n); ++_i) cerr << a[_i] << ", "; cerr << endl

template <typename A, typename B>

ostream& operator<<(ostream& os, const pair<A, B>& x) {

	return os << "(" << x.first << "," << x.second << ")";

}

typedef long long ll;

typedef long double ld;

int main() {

	int n, k;

	scanf("%d%d", &n, &k);

	vector<int> A(n);

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

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

		A[i] = min(A[i], k);

	}

	vector<vector<bool>> dp(n + 1, vector<bool>(k + 1));

	vector<vector<bool>> dp2(n + 1, vector<bool>(k + 1));

	vector<int> S(k + 1);

	dp[n][0] = 1;

	for (int i = n - 1; i >= 0; --i) {

		dp[i] = dp[i + 1];

		for (int j = A[i]; j <= k; ++j) {

			dp[i][j] = dp[i][j] || dp[i + 1][j - A[i]];

		}

	}

	dp2[0][0] = 1;

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

		dp2[i + 1] = dp2[i];

		for (int j = A[i]; j <= k; ++j) {

			dp2[i + 1][j] = dp2[i + 1][j] || dp2[i][j - A[i]];

		}

	}

	int ans = 0;

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

		// Get sum in [k-A[i], k-1].

		bool nec = false;

		S[0] = dp[i + 1][0];

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

			S[j] = S[j - 1] + dp[i + 1][j];

		}

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

			if (!dp2[i][j]) continue;

			int lo = k - A[i] - j;

			int hi = k - 1 - j;

			if (hi < 0) continue;

			int v = S[hi];

			if (lo - 1 >= 0) v -= S[lo - 1];

			if (v >= 1) {

				nec = true;

				break;

			}

		}

		if (!nec) ++ans;

	}

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

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

using namespace std;

const int N = 5010;

bool canleft[N][N], canright[N][N];

int n, K;

int a[N];

bool can[N];

int main(){

	ios::sync_with_stdio(0);

	cin.tie(0), cout.tie(0);

	cin >> n >> K;

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

		cin >> a[i];

	canleft[0][0] = 1;

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

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

			canleft[i][j] = canleft[i - 1][j];

			if(j >= a[i])

				canleft[i][j] |= canleft[i - 1][j - a[i]];

		}

	}

	canright[n + 1][0] = 1;

	for(int i = n; i >= 2; i--){

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

			canright[i][j] = canright[i + 1][j];

			if(j >= a[i])

				canright[i][j] |= canright[i + 1][j - a[i]];

		}

	}

	int cnt = 0;

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

		bool nece = false;

		vector<int> A, B;

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

			if(canleft[i - 1][j]) A.push_back(j);

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

			if(canright[i + 1][j]) B.push_back(j);

		for(int val : A){

			int tmp = K - a[i] - val;

			vector<int>::iterator it = lower_bound(B.begin(), B.end(), tmp);

			if(it != B.end()){

				if((*it) + val < K)

					nece = true;

			}

		}

		if(!nece) cnt++;

	}

	cout << cnt << "\n";

	return 0;

}


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

#define inf 0x7fffffff

#define RG register

#define maxn 500005

#define maxm 205

using namespace std;

typedef long long ll;

const ll mod = 1e9 + 7;

inline ll read(){

    ll x = 0, f = 1;

    char ch = getchar();

    while(ch > '9' || ch < '0') {if(ch == '-') f = -1;ch = getchar();}

    while(ch >= '0' && ch <= '9'){x = x *10 + ch -'0';ch = getchar();}

    return x * f;

}

 

int n, k, ans;

int a[10005], tp;

bitset<5005> f, w;

int main(){

	int i, j, x, l, r, mid;

	n = read(), k = read();

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

		 a[++tp] = read();

		 if(a[tp] >= k) tp--;

	}

	sort(a + 1, a + tp + 1);

	l = 1, r = tp; 

	for(i = tp + 1;i <= 2 * tp;i++) a[i] = a[i - tp];

	while(l <= r){

		f = w, f[0] = 1;

		mid = l + r >> 1;

		for(j = mid + 1;j <= mid + tp - 1;j++) 

			f |= f << a[j];

		bool flag = 0;

		for(j = k - a[mid];j < k;j++) if(f[j]) {flag = 1;break;}

		if(!flag) ans = mid, l = mid + 1; 

		else r = mid - 1;

	}

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

	return 0;

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



using namespace std;



#define pb push_back

#define eb emplace_back

#define ll long long

#define pii pair < int, int >

#define fr first

#define sc second

#define mk make_pair

#define sz(s) (int)s.size()

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

#define ok puts("ok");

#define whatis(x) cerr << #x << " = " << x << endl;



const int N = 223;

const int inf = (int)1e9 + 7;



pii ar[N];

vector < int > gr[N];

bool used[N];

int mt[N];



bool kuhn(int v) {

  if (used[v]) return false;

  used[v] = 1;

  for (int to : gr[v]) {

    if (mt[to] == -1 || kuhn(mt[to])) {

      mt[to] = v;

      return true;

    }

  }

  return false;

}



main() {

  int n;

  scanf("%d", &n);

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

    scanf("%d %d", &ar[i].fr, &ar[i].sc);

  }

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

    scanf("%d %d", &ar[i].fr, &ar[i].sc);

    mt[i] = -1;

  }

  int ans = 0;

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

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

      if (ar[i].fr < ar[j].fr && ar[i].sc < ar[j].sc) {

        gr[i].pb(j);

      }

    }

  }

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

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

    kuhn(i);

  }



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

    if (mt[i] != -1) {

      ans++;

//      cout << i << ' ' << mt[i] << endl;

    }

  }

  cout << ans;

}


// Faster C++ solution for the same problem (measured speedup: 5.199202136141319x):
#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;

}
// Slower C++ solution:
#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());

}










// Faster C++ solution for the same problem (measured speedup: 5.181783654807912x):
#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;

}
// Slower C++ solution:
#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;

}


// Faster C++ solution for the same problem (measured speedup: 5.198016357368789x):
#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;

}
// Slower C++ solution:
#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);

}

// Faster C++ solution for the same problem (measured speedup: 5.1345221079609535x):
#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;

}
// Slower C++ solution:
#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;

}


// Faster C++ solution for the same problem (measured speedup: 5.211593379353533x):
#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;

}
// Slower C++ solution:
#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());

    }

}

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

#include<vector>

#include<cstring>

#include<algorithm>

using namespace std;

char s[505][505];

vector<int>g[4005];

int m,n,ans,mat[4005],tot,tot1;

int a1[5005][5005],b1[505][505];

bool vis[4005];

struct mzls

{

	int x,y;

}a[205],b;

inline bool dfs(int x)

{

	for(int i=0;i<g[x].size();i++)

	{

		int v=g[x][i];

		if(vis[v])

			continue;

		vis[v]=1;

		if(!mat[v]||dfs(mat[v]))

		{

			mat[v]=x;

			return 1;

		}

	}

	return 0;

}

int main()

{

	scanf("%d",&n);

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

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

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

	{

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

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

			{

				g[i].push_back(j);

				g[j].push_back(i);

			}

	}

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

	{

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

		ans+=dfs(i);

	}

	printf("%d",ans);

}
// Slower C++ solution:
#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());

    }

}

// Faster C++ solution for the same problem (measured speedup: 2.0379252136514054x):
#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;

 }