#include <iostream> // cout, endl, cin
#include <string> // string, to_string, stoi
#include <vector> // vector
#include <algorithm> // min, max, swap, sort, reverse, lower_bound, upper_bound
#include <utility> // pair, make_pair
#include <tuple> // tuple, make_tuple
#include <cstdint> // int64_t, int*_t
#include <cstdio> // printf
#include <map> // map
#include <queue> // queue, priority_queue
#include <set> // set
#include <stack> // stack
#include <deque> // deque
#include <unordered_map> // unordered_map
#include <unordered_set> // unordered_set
#include <bitset> // bitset
#include <cctype> // isupper, islower, isdigit, toupper, tolower
#include <cmath>
#include <limits>
#include <list>
#define ALL(x) (x).begin(),(x).end()
#define rep(i, n) for(int i = 0; i < (int)(n); i++)
#define int_INF 2147483647
#define pint_INF 2000000000
#define ll_INF 	9223372036854775807
#define MOD 1000000007
#define vi vector<int>
#define vvi vector<vector<int>>
#define vvll vector<vector<long long>>
#define vvc vector<vector<char>>
#define vll vector<long long>
#define pii pair<int,int>
#define vpii vector<pair<int,int>>
#define sysp system("PAUSE")
#define pno cout << "no" << endl
#define pyes cout << "yes" << endl
#define pYes cout << "Yes" << endl
#define pNo cout << "No" << endl
#define pNO cout << "NO" << endl
#define pYES cout << "YES" << endl
#define endl "\n"
#define pi 3.14159265358979
using namespace std;
using ll = long long;

struct Edge {
    int to, weight, rev;
    //rev indicates when this edge is added
};

class FordFulkerson {
private:
    vector<bool> isVisited;
    vector<vector<Edge>> Graph;
public:
    void init(int N) {
        Graph.resize(N,vector<Edge>());
        isVisited.resize(N, false);
    }
    void add_edge(int from, int to, int weight) {
        int g_to_size = Graph[to].size();
        int g_from_size = Graph[from].size();
        Graph[from].push_back(Edge{ to,weight,g_to_size });
        Graph[to].push_back(Edge{ from,0,g_from_size });
    }

    void add_undirected_edge(int from, int to, int weight) {
        this->add_edge(from, to, weight);
        this->add_edge(to, from, weight);
    }
    int flow_dfs(int cur, int goal, int mincap) {
        if (cur == goal) {
            return mincap;
        }
        isVisited[cur] = true;
        for (auto& e : Graph[cur]){
            if (!isVisited[e.to] && e.weight > 0) {
                int d = flow_dfs(e.to, goal, min(mincap, e.weight));
                if (d > 0) {
                    e.weight -= d;
                    Graph[e.to][e.rev].weight += d;
                    return d;
                }
            }
        }
        return 0;
    }
    int max_flow(int start, int goal) {
        int flow = 0;
        while (true) {
            fill(ALL(isVisited), false);
            int f = flow_dfs(start, goal, pint_INF);
            if (f == 0) {
                return flow;
            }
            flow += f;
        }
    }
};

int main() {
    int N; cin >> N;
    vector<vector<int>> red(N), blue(N);
    FordFulkerson ff;
    ff.init(2 * N + 2);
    int ind_superS = 0;
    int ind_superT = N + 1;
    for (int i = 1; i < N + 1; i++) {
        ff.add_edge(ind_superS, i, 1);
    }
    for (int i = 0; i < N; i++) {
        int x, y; cin >> x >> y;
        red[i] = { x,y };
    }

    for (int i = N + 2; i < 2 * N + 2; i++) {
        ff.add_edge(i, ind_superT, 1);
    }
    for (int i = 0; i < N; i++) {
        int x, y; cin >> x >> y;
        blue[i] = { x,y };
    }

    for (int i = 1; i < N + 1; i++) {
        for (int j = N + 2; j < 2 * N + 2; j++) {
            // i for reds j for blues
            if (red[i - 1][0] < blue[j - N - 2][0] && red[i - 1][1] < blue[j - N - 2][1]) {
                ff.add_edge(i, j, 1);
            }
        }
    }
    int ans = ff.max_flow(ind_superS, ind_superT);
    cout << ans << endl;
    return 0;
}



Measured memory_bytes: 3752