#include <bits/stdc++.h>
#define ll long long
#define mod 1000000007
#define upperlimit 1000100
#define INF 1000000100
#define INFL 1000000000000000100
#define eps 1e-8
#define endl '\n'
#define sd(n) scanf("%d",&n)
#define slld(n) scanf("%lld",&n)
#define pd(n) printf("%d",n)
#define plld(n) printf("%lld",n)
#define pds(n) printf("%d ",n)
#define pllds(n) printf("%lld ",n)
#define pdn(n) printf("%d\n",n)
#define plldn(n) printf("%lld\n",n)
#define REP(i,a,b) for(i=a;i<=b;i++)
#define mp make_pair
#define pb push_back
#define pcc pair<char,char>
#define pii pair<int,int>
#define pll pair<ll,ll>
#define vi vector<int>
#define vl vector<ll>
#define vii vector<pii>
#define vll vector<pll>
#define tr(container,it) for(typeof(container.begin()) it=container.begin();it!=container.end();it++)
#define F first
#define S second
#define clr(a) memset(a,0,sizeof(a))
#define FILEIO(name) \
    freopen(name".in", "r", stdin); \
    freopen(name".out", "w", stdout);

using namespace std;

ll gcd(ll n1,ll n2){
    if(!n1)return n2;
    if(!n2)return n1;
    if(n1%n2==0)return n2;
    return gcd(n2,n1%n2);
}
ll powmod(ll base,ll exponent){
    base%=mod;
    ll ans=1;
    while(exponent){
        if(exponent&1)ans=(ans*base)%mod;
        base=(base*base)%mod;
        exponent/=2;
    }
    ans%=mod;
    return ans;
}
int bit[500][500];
int query(int x,int y){
    int ret=0;
    while(x){
        int z=y;
        while(z){
            ret+=bit[x][z];
            z-=(z&(-z));
        }
        x-=(x&(-x));
    }
    return ret;
}
void update(int x,int y){
    while(x<500){
        int z=y;
        while(z<500){
            bit[x][z]++;
            z+=(z&(-z));
        }
        x+=(x&(-x));
    }
}
int a[500],b[500],c[500],d[500];

const int MAXN1 = 22510;
const int MAXN2 = 22510;
const int MAXM = 100010;
int n1, n2, edges, last[MAXN1], Prev[MAXM], head[MAXM];
int matching[MAXN2], dist[MAXN1], Q[MAXN1];
bool used[MAXN1], vis[MAXN1];
void init(int _n1, int _n2) {
    n1 = _n1;
    n2 = _n2;
    edges = 0;
    fill(last, last + n1, -1);
}
void addEdge(int u, int v) {
    head[edges] = v;
    Prev[edges] = last[u];
    last[u] = edges++;
}
void bfs() {
    fill(dist, dist + n1, -1);
    int sizeQ = 0;
    for (int u = 0; u < n1; ++u) {
        if (!used[u]) {
            Q[sizeQ++] = u;
            dist[u] = 0;
        }
    }
    for (int i = 0; i < sizeQ; i++) {
        int u1 = Q[i];
        for (int e = last[u1]; e >= 0; e = Prev[e]) {
            int u2 = matching[head[e]];
            if (u2 >= 0 && dist[u2] < 0) {
                dist[u2] = dist[u1] + 1;
                Q[sizeQ++] = u2;
            }
        }
    }
}
bool dfs(int u1) {
    vis[u1] = true;
    for (int e = last[u1]; e >= 0; e = Prev[e]) {
        int v = head[e];
        int u2 = matching[v];
        if (u2 < 0 || !vis[u2] && dist[u2] == dist[u1] + 1 && dfs(u2)) {
            matching[v] = u1;
            used[u1] = true;
            return true;
        }
    }
    return false;
}
int maxMatching() {
    fill(used, used + n1, false);
    fill(matching, matching + n2, -1);
    for (int res = 0;;) {
        bfs();
        fill(vis, vis + n1, false);
        int f = 0;
        for (int u = 0; u < n1; ++u)
            if (!used[u] && dfs(u))
                ++f;
        if (!f)
            return res;
        res += f;
    }
}

int main()
{
    int i,j,k,n;
    sd(n);
    for(i=1;i<=n;i++){
        sd(a[i]);sd(b[i]);
    }
    for(i=1;i<=n;i++){
        sd(c[i]);sd(d[i]);
    }
    int answer=0;
    init(n+1,n+1);
    for(i=1;i<=n;i++)for(j=1;j<=n;j++)if(a[i]<c[j] && b[i]<d[j]){
        addEdge(i,j);
    }
    answer=maxMatching();
    pdn(answer);
    return 0;
}

Measured memory_bytes: 256