#include <iostream>
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <time.h>
#include <stdlib.h>
#include <string>
#include <bitset>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <algorithm>
#include <sstream>
#include <stack>
#include <iomanip>
using namespace std;
//#define int long long
#define mem(a,b) memset(a,b,sizeof(a))
#define rep(i,l,h) for(int i=(l);i<=(h);++i)
#define drep(i,h,l) for(int i=(h);i>=(l);--i)
#define debug(x) cout<<"#"<<x<<endl
#define pb push_back
#define fi first
#define se second
typedef pair<int,int>pii;

/*
最小费用最大流，求最大费用只需要取相反数，结果取相反数即可。
点的总数为 N，点的编号 0~N-1
*/
const int MAXN = 10000;
const int MAXM = 30000;
const int INF = 0x3f3f3f3f;
struct Edge {
  int to,next,cap,flow,cost;
} edge[MAXM];
int head[MAXN],tol;
int pre[MAXN],dis[MAXN];
bool vis[MAXN];
int N;//节点总个数，节点编号从0~N-1
void init(int n) {
  N = n;
  tol = 0;
  memset(head,-1,sizeof (head));
}
void addedge (int u,int v,int cap,int cost) {
  edge[tol].to = v;
  edge[tol].cap = cap;
  edge[tol].cost = cost;
  edge[tol].flow = 0;
  edge[tol].next = head[u];
  head[u] = tol++;
  edge[tol].to = u;
  edge[tol].cap = 0;
  edge[tol].cost = -cost;
  edge[tol].flow = 0;
  edge[tol].next = head[v];
  head[v] = tol++;
}
bool spfa(int s,int t) {
  queue<int>q;
  for(int i = 0; i < N; i++) {
    dis[i] = INF;
    vis[i] = false;
    pre[i] = -1;
  }
  dis[s] = 0;
  vis[s] = true;
  q.push(s);
  while(!q.empty()) {
    int u = q.front();
    q.pop();
    vis[u] = false;
    for(int i = head[u]; i !=  -1; i = edge[i]. next) {
      int v = edge[i]. to;
      if(edge[i].cap > edge[i].flow &&
          dis[v] > dis[u] + edge[i]. cost ) {
        dis[v] = dis[u] + edge[i]. cost;
        pre[v] = i;
        if(!vis[v]) {
          vis[v] = true;
          q.push(v);
        }
      }
    }
  }
  if(pre[t] == -1)return false;
  else return true;
}
//返回的是最大流，cost存的是最小费用
int MCMF(int s,int t,int &cost) {
  int flow = 0;
  cost = 0;
  while(spfa(s,t)) {
    int Min = INF;
    for(int i = pre[t]; i != -1; i = pre[edge[i^1].to]) {
      if(Min > edge[i].cap - edge[i]. flow)
        Min = edge[i].cap - edge[i].flow;
    }
    for(int i = pre[t]; i != -1; i = pre[edge[i^1].to]) {
      edge[i].flow += Min;
      edge[i^1].flow -= Min;
      cost += edge[i]. cost * Min;
    }
    flow += Min;
  }
  return flow;
}

int a[MAXN],b[MAXN],c[MAXN],d[MAXN];
signed main(){
  ios::sync_with_stdio(false);
  cin.tie(0);
  int n;cin>>n;
  rep(i,1,n){
    cin>>a[i]>>b[i];
  }
  rep(i,1,n){
    cin>>c[i]>>d[i];
  }
  int st=2*n,ed=st+1;
  init(ed+1);
  rep(i,1,n){
    rep(j,1,n){
      if(a[i]<c[j]&&b[i]<d[j])addedge(i-1,j+n-1,1,0);
    }
  }
  rep(i,1,n){
    addedge(st,i-1,1,0);
  }
  rep(j,1,n){
    addedge(j+n-1,ed,1,0);
  }
  int mincost;
  int ans=MCMF(st,ed,mincost);
  cout<<ans<<endl;
  return 0;
}
