#include <iostream>
#include <sstream>
#include <algorithm>
#include <functional>
#include <iterator>
#include <bitset>
#include <string>
#include <list>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>

typedef   signed long long int slli;
typedef unsigned long long int ulli;
const slli MAX_SLLI = 0x7FFFFFFFFFFFFFFF;
const slli MIN_SLLI = 0x8000000000000000;
const ulli MAX_ULLI = 0xFFFFFFFFFFFFFFFF;
const ulli MIN_ULLI = 0x0000000000000000;

#define N_TIMES(i, n)     for (ulli i = 0;     i <  n; ++i)
#define N_TIMES_REV(i, n) for (slli i = n - 1; i >= 0; --i)

#ifdef __DEBUG__
template<typename T>
std::ostream& operator<<(std::ostream &os, const std::list<T> &list)
{
  const std::string delim = ", ";
  typename std::list<T>::const_iterator itr = list.begin();
  while (itr != list.end()) {
    os << *itr;
    ++itr;
    if(itr != list.end()) os << delim;
  }
  return os;
}

template<typename T>
std::ostream& operator<<(std::ostream &os, const std::vector<T> &v)
{
  const std::string delim = ", ";
  for (unsigned n = 0; n < v.size(); ++n) {
    os << v[n];
    if((n + 1) < v.size()) os << delim;
  }
  return os;
}

template<typename T>
std::ostream& operator<<(std::ostream &os, const std::set<T> &set)
{
  const std::string delim = ", ";
  typename std::set<T>::const_iterator itr = set.begin();
  while (itr != set.end()) {
    os << *itr;
    ++itr;
    if(itr != set.end()) os << delim;
  }
  return os;
}
#endif /* __DEBUG__ */

struct Point {
  char color;
  unsigned id, x, y;
  Point(char color = ' ', unsigned id = 0, unsigned x = 0, unsigned y = 0) : color(color), id(id), x(x), y(y) {}
  bool operator==(const Point &rhs) const { return x == rhs.x && y == rhs.y; }
  bool operator< (const Point &rhs) const { return x == rhs.x ? y < rhs.y : x < rhs.x; }
};

std::istream& operator>>(std::istream &is, Point &p) {
  is >> p.x >> p.y;
  return is;
}

std::ostream& operator<<(std::ostream &os, const Point &p) {
  os << '(' << p.x << ", " << p.y << "; " << p.color << ", " << p.id << ')';
  return os;
}

struct compare_with_x {
  bool operator()(const Point &lhs, const Point &rhs) {
    return lhs.x == rhs.x ? lhs.y < rhs.y : lhs.x < rhs.x;
  }
};

struct compare_with_y {
  bool operator()(const Point &lhs, const Point &rhs) { 
    return lhs.y == rhs.y ? lhs.x < rhs.x : lhs.y < rhs.y;
  }
};

bool pred_y(const Point &p, unsigned y) {
  return p.y < y;
}

int main(int argc, char **argv)
{
  unsigned N;
  std::cin >> N;
  
  std::vector<Point> red(N), blue(N);
  N_TIMES(n, N) { std::cin >> red[n];  red[n].id  = n; red[n].color  = 'R'; }
  N_TIMES(n, N) { std::cin >> blue[n]; blue[n].id = n; blue[n].color = 'B'; }
  
  std::set<Point, compare_with_x> points;
  N_TIMES(n, N) {
    points.insert(red[n]);
    points.insert(blue[n]);
  }
  
  unsigned count = 0;
  std::set<Point, compare_with_y> set;
  for (const Point &p : points) {
    if (p.color == 'B') {
      auto itr = std::lower_bound(set.begin(), set.end(), p.y, pred_y);
      if (itr != set.begin()) {
        set.erase(--itr);
        ++count;
      }
    } else {
      set.insert(p);
    }
  }
  std::cout << count << std::endl;
  
  return 0;
}

Measured memory_bytes: 256