//include
//------------------------------------------
#include <bits/stdc++.h>
using namespace std;

//typedef
//------------------------------------------
typedef vector<int> VI;
typedef vector<VI> VVI;
typedef vector<string> VS;
typedef pair<int, int> PII;
typedef long long LL;

//container util
//------------------------------------------
#define ALL(a)  (a).begin(),(a).end()
#define RALL(a) (a).rbegin(), (a).rend()
#define PB push_back
#define MP make_pair
#define SZ(a) int((a).size())
#define EACH(i,c) for(typeof((c).begin()) i=(c).begin(); i!=(c).end(); ++i)
#define EXIST(s,e) ((s).find(e)!=(s).end())
#define SORT(c) sort((c).begin(),(c).end())

//constant
//--------------------------------------------
const double EPS = 1e-10;
const double PI  = acos(-1.0);
const int MOD = 1000000007;
const int INF = 2147483647;

//debug
#define dump(x)  cerr << #x << " = " << (x) << endl;
#define debug(x) cerr << #x << " = " << (x) << " (L" << __LINE__ << ")" << " " << __FILE__ << endl;

//myfuncs
//素数判定
template<class T> inline T isPrime(T x) {
	bool ret = true;
	if (x < 2) {
		ret = false;
	}
	for (LL i = 2; i <= sqrt(x); i++) {
		if (x%i == 0) {
			ret = false;
		}
	}
	return ret;
}

//Union FInd
struct UnionFind {
    vector<int> par; // par[i]:iの親の番号　(例) par[3] = 2 : 3の親が2

    UnionFind(int N) : par(N) { //最初は全てが根であるとして初期化
        for(int i = 0; i < N; i++) par[i] = i;
    }

    int root(int x) { // データxが属する木の根を再帰で得る：root(x) = {xの木の根}
        if (par[x] == x) return x;
        return par[x] = root(par[x]);
    }

    void unite(int x, int y) { // xとyの木を併合
        int rx = root(x); //xの根をrx
        int ry = root(y); //yの根をry
        if (rx == ry) return; //xとyの根が同じ(=同じ木にある)時はそのまま
        par[rx] = ry; //xとyの根が同じでない(=同じ木にない)時：xの根rxをyの根ryにつける
    }

    bool same(int x, int y) { // 2つのデータx, yが属する木が同じならtrueを返す
        int rx = root(x);
        int ry = root(y);
        return rx == ry;
    }
};

//main code

int main(int argc, char const* argv[])
{
    int n;
    cin >> n;
    // 二次元の座標 点のある/ないをboolで管理
    vector< vector<bool> > red;
    vector< vector<bool> > blue;
    red = vector< vector<bool> >(2*n,vector<bool>(2*n,false));
    blue = vector< vector<bool> >(2*n,vector<bool>(2*n,false));
    for (int i = 0; i < n; i++) {
        int a,b;
        cin >> a >> b;
        red[a][b] = true;
    }
    for (int i = 0; i < n; i++) {
        int c,d;
        cin >> c >> d;
        blue[c][d] = true;
    }

    // x座標の小さい方からblueの点を探していく -> max 200回
    // 見つけたら、それの中に入るredの点を探す -> blueの点それぞれに対して max 200回
    // 条件を満たすredの点が複数存在していたら、その中で最もy座標が大きいものをペアとする

    LL ans = 0;
    for (int bx = 0; bx < 2*n; bx++) {
        for (int by = 0; by < 2*n; by++) {
            if (blue[bx][by]) {
                int rymax = -1;
                int rymaxx = 0;
                for (int rx = 0; rx < bx; rx++) {
                    for (int ry = 0; ry < by; ry++) {
                        if (red[rx][ry] and rymax < ry) {
                            rymax = ry;
                            rymaxx = rx;
                        }
                    }
                }
                if (rymax != -1) {
                    ans++;
                    red[rymaxx][rymax] = false;
                }
            }
        }
    }
    cout << ans << endl;
    return 0;
}


Measured memory_bytes: 256