CodeEff/ECCO huggingface dataset:
# Original solution
def f(blue, red, ans):
    c = 0
    for i, b in enumerate(blue):
        for j, r in enumerate(red):
            if b[0] >= r[0] and b[1] >= r[1]:
                blue.pop(i)
                red.pop(j)
                c = max(c, f(blue, red, ans + 1))
                blue.insert(i, b)
                red.insert(j, r)
    return max(c, ans)


def main():
    N = int(eval(input()))
    red = [list(map(int, input().split())) for _ in range(N)]
    blue = [list(map(int, input().split())) for _ in range(N)]
    print((f(blue, red, 0)))


main()


# Optimized solution
def main():
    N = int(eval(input()))
    red = sorted(
        [list(map(int, input().split())) for _ in range(N)],
        key=lambda x: x[1],
        reverse=True
    )
    blue = sorted(
        [list(map(int, input().split())) for _ in range(N)],
        key=lambda x: x[0]
    )
    ans = 0
    for b in blue:
        for i, r in enumerate(red):
            if b[0] > r[0] and b[1] > r[1]:
                ans += 1
                red.pop(i)
                break
    print(ans)


main()
# Original solution
N = int(eval(input()))
R = [tuple([int(x) for x in input().split()]) for _ in range(N)]
B = [tuple([int(x) for x in input().split()]) for _ in range(N)]

xl = [set() for _ in range(2 * N + 1)]
yl = [set() for _ in range(2 * N + 1)]

for b in B:
    x, y = b
    for i in range(x):
        xl[i].add(b)
    for j in range(y):
        yl[j].add(b)

cands = []
for r in R:
    x, y = r
    s = xl[x].intersection(yl[y])
    cands.append([r, len(s), s])

def f(cands, used, n):
    if not cands:
        return n
    ret = 0
    hd, tl = cands[0], cands[1:]
    r, _, s = hd
    for t in s - used:
        u = used.union({t})
        ret = max(ret, f(tl, u, n + 1))
    ret = max(ret, f(tl, used, n))
    return ret

import operator
cands.sort(key=operator.itemgetter(1))
print((f(cands, set(), 0)))

# Optimized solution
N = int(eval(input()))
R = [[int(x) for x in input().split()] for _ in range(N)]
B = [[int(x) for x in input().split()] for _ in range(N)]

import operator
R.sort(key=operator.itemgetter(1), reverse=True)
B.sort()

ans = 0
for b in B:
    xb, yb = b
    for r in R:
        xr, yr = r
        if xr < xb and yr < yb:
            ans += 1
            R.remove(r)
            break
print(ans)
# Original solution
from operator import itemgetter

n = int(eval(input()))
r = [tuple(map(int, input().split())) for i in range(n)]
b = [tuple(map(int, input().split())) for i in range(n)]

r = sorted(r, key=itemgetter(1), reverse=True)
b.sort()

ans = 0
pair = [False]*n

for i in range(n):
    for j in range(n):
        if b[i][0] > r[j][0] and b[i][1] > r[j][1] and pair[j] == False:
            pair[j] = True
            ans += 1
            break

print(ans)


# Optimized solution
from operator import itemgetter

n = int(eval(input()))
r = [tuple(map(int, input().split())) for i in range(n)]
b = [tuple(map(int, input().split())) for i in range(n)]

r = sorted(r, key=itemgetter(1), reverse=True)
b.sort()

pair = [False]*n

for i in range(n):
    for j in range(n):
        if b[i][0] > r[j][0] and b[i][1] > r[j][1] and pair[j] == False:
            pair[j] = True
            break

print((sum(pair)))
# Original solution
N = int(eval(input()))
R = [(-1, -1)] * N
for n in range(N):
    x, y = list(map(int, input().split()))
    R[n] = (x, y)
B = [(-1, -1)] * N
for n in range(N):
    x, y = list(map(int, input().split()))
    B[n] = (x, y)

B = sorted(B)
R = sorted(R, reverse=True)

ans = 0
for i, b in enumerate(B):
    tmp = []
    for j, r in enumerate(R):
        if r[0] == -1:
            continue
        if r[0] < b[0] and r[1] < b[1]:
            tmp.append((j, r))
    if tmp:
        tmp = sorted(tmp, key=lambda x: x[1][1], reverse=True)
        R[tmp[0][0]] = (-1, -1)
        ans += 1

print(ans)

# Optimized solution
N = int(eval(input()))
R = [tuple(map(int, input().split())) for _ in range(N)]
B = [tuple(map(int, input().split())) for _ in range(N)]
R = sorted(R)
B = sorted(B)

res = 0
for bx, by in B:
    idx = -1
    tmp = -1
    for i, (rx, ry) in enumerate(R):
        if rx < bx and ry < by:
            if ry >= tmp:
                tmp = ry
                idx = i
    if idx != -1:
        R.pop(idx)
        res += 1
print(res)
# Original solution
n = int(eval(input()))
AB = list(list(map(int,input().split())) for _ in range(n))
CD = list(list(map(int,input().split())) for _ in range(n))

CD.sort() # sort x in ascending order
AB.sort(key=lambda z: z[1], reverse=True) # sort x in descending order

dim_b = [[] for _ in range(n)]
for b in range(n):
    for r in range(n):
        if AB[r][0] < CD[b][0] and AB[r][1] < CD[b][1]:
            dim_b[b] += [r]

vis_r = [False]*(n)
for b in range(n): # ascending order of x
    max_ry = max_r = -1
    for r in dim_b[b]: # descending order of y
        if vis_r[r]: continue
        if max_ry < AB[r][1]: max_ry = AB[r][1]; max_r = r
    if max_r >= 0: vis_r[max_r] = True
print((sum(vis_r)))


# Optimized solution
n = int(eval(input()))
AB = list(list(map(int,input().split())) for _ in range(n))
CD = list(list(map(int,input().split())) for _ in range(n))

CD.sort() # sort x in ascending order
AB.sort(key=lambda z: z[1], reverse=True) # sort x in descending order

dim_b = [[] for _ in range(n)]
for b in range(n):
    for r in range(n):
        if AB[r][0] < CD[b][0] and AB[r][1] < CD[b][1]:
            dim_b[b] += [r]

vis_r = [False]*(n)
for b in range(n): # ascending order of x
    for r in dim_b[b]: # descending order of y
        if not vis_r[r]: vis_r[r] = True; break

print((sum(vis_r)))
# Original solution
N=int(eval(input()))
ab=[list(map(int,input().split())) for _ in range(N)]
cd=[list(map(int,input().split())) for _ in range(N)]

ab=[x[0]+x[1]*1j for x in ab]
cd=[x[0]+x[1]*1j for x in cd]

def comp(a,b):
	if a.real<b.real and a.imag<b.imag:
		return True
	else:
		return False

abd=dict()
cdd=dict()

for i in range(len(ab)):
	temp=[]
	for j in range(len(cd)):
		if comp(ab[i],cd[j]):
			temp.append(cd[j])
	if temp!=[]:
		abd[ab[i]]=temp
	
for i in range(len(cd)):
	temp=[]
	for j in range(len(ab)):
		if comp(ab[j],cd[i]):
			temp.append(ab[j])
	if temp!=[]:
		cdd[cd[i]]=temp
	
ans=0
while(len(list(abd.keys()))+len(list(cdd.keys()))):
	m=10**5
	
	for i in list(abd.keys()):
		for j in abd[i]:
			cnt=len(abd[i])+len(cdd[j])
			if cnt<m:
				m=cnt
				abm=i
				cdm=j
	
	cdl=abd[abm]
	abl=cdd[cdm]
	
	for i in abl:
		abd[i].remove(cdm)
	for i in cdl:
		cdd[i].remove(abm)
	
	del abd[abm]
	del cdd[cdm]
	
	abk=[i for i in list(abd.keys())]
	cdk=[i for i in list(cdd.keys())]
	
	for i in abk:
		if abd[i]==[]:
			del abd[i]
	for i in cdk:
		if cdd[i]==[]:
			del cdd[i]
	ans+=1
print(ans)

# Optimized solution
N=int(eval(input()))
ab=sorted([list(map(int,input().split())) for _ in [0]*N],key=lambda x:x[1],reverse=True)
cd=sorted([list(map(int,input().split())) for _ in [0]*N],key=lambda x:x[0])
cnt=0
for i in range(N):
    for a in ab:
        if a[0]<cd[i][0] and a[1]<cd[i][1]:
            ab.remove(a)
            cnt+=1
            break
print(cnt)
# Original solution
casen=0
if casen==0:
    a=[]
    c=[]
    n=int(eval(input()))
    for i in range(n):
        ai,bi=list(map(int,input().split()))
        a.append([ai,bi])
    for i in range(n):
        ci,di=list(map(int,input().split()))
        c.append([ci,di])
elif casen==1:
    n=3
    a=[[2,0],[3,1],[1,3]]
    c=[[4,2],[0,4],[5,5]]
elif casen==2:
    n=3
    a=[[0,0],[1,1],[5,2]]
    c=[[2,3],[3,4],[4,5]]
elif casen==3:
    n=2
    a=[[2,2],[3,3]]
    c=[[0,0],[1,1]]
elif casen==4:
    n=5
    a=[[0,0],[7,3],[2,2],[4,8],[1,6]]
    c=[[8,5],[6,9],[5,4],[9,1],[3,7]]
elif casen==5:
    n=5
    a=[[0,0],[1,1],[5,5],[6,6],[7,7]]
    c=[[2,2],[3,3],[4,4],[8,8],[9,9]]

t=[]
for ia in range(n):
    s=set()
    for ic in range(n):
        if a[ia][0]<c[ic][0] and a[ia][1]<c[ic][1]:
            s.add(ic)
    t.append(s)

icnt=0

from collections import deque
tyn3 = deque()

def pcnt(icnt,ia,t,n,tyn3,icntmax,r,t2,it):
    ia1=ia
    if ia>=n-1:
        icnt2=len(r)
        icntmax=max(icnt2,icntmax)
        if len(tyn3)>0:
            it2=tyn3.pop()
            r.remove(it2)
        ia=ia-1
        return icntmax,ia
    t3=t[ia]-r
    r1=r.copy()
    for it in t3:
        ia=ia1+1
        t2=t[ia]
        r1.add(it)
        tyn3.append(it)
        icntmax,ia=pcnt(icnt,ia,t,n,tyn3,icntmax,r1,t2,it)
    ia=ia+1
    t2=t[ia]
    icntmax,ia=pcnt(icnt,ia,t,n,tyn3,icntmax,r,t2,it)
    return icntmax,ia

ia=-1    
icntmax=0
r=set()
t2=t[0]
it=0
icntmax,ia=pcnt(icnt,ia,t,n,tyn3,icntmax,r,t2,it)

print(icntmax)        
    

# Optimized solution
casen=0
if casen==0:
    a=[]
    c=[]
    n=int(eval(input()))
    for i in range(n):
        ai,bi=list(map(int,input().split()))
        a.append([ai,bi])
    for i in range(n):
        ci,di=list(map(int,input().split()))
        c.append([ci,di])
elif casen==1:
    n=3
    a=[[2,0],[3,1],[1,3]]
    c=[[4,2],[0,4],[5,5]]
elif casen==2:
    n=3
    a=[[0,0],[1,1],[5,2]]
    c=[[2,3],[3,4],[4,5]]
elif casen==3:
    n=2
    a=[[2,2],[3,3]]
    c=[[0,0],[1,1]]
elif casen==4:
    n=5
    a=[[0,0],[7,3],[2,2],[4,8],[1,6]]
    c=[[8,5],[6,9],[5,4],[9,1],[3,7]]
elif casen==5:
    n=5
    a=[[0,0],[1,1],[5,5],[6,6],[7,7]]
    c=[[2,2],[3,3],[4,4],[8,8],[9,9]]

c.sort()
a.sort(key=lambda x:x[1])
#a.reverse()

icnt=0
ic2=0
for ic in range(len(c)):
    for ia in range(len(a)-1,-1,-1):
        if a[ia][0]<c[ic][0] and a[ia][1]<c[ic][1]:
            icnt=icnt+1
            del a[ia]
            break
        else:
            continue
        break

print(icnt)
# Original solution
casen=0
if casen==0:
    a=[]
    c=[]
    n=int(eval(input()))
    for i in range(n):
        ai,bi=list(map(int,input().split()))
        a.append([ai,bi])
    for i in range(n):
        ci,di=list(map(int,input().split()))
        c.append([ci,di])
elif casen==1:
    n=3
    a=[[2,0],[3,1],[1,3]]
    c=[[4,2],[0,4],[5,5]]
elif casen==2:
    n=3
    a=[[0,0],[1,1],[5,2]]
    c=[[2,3],[3,4],[4,5]]
elif casen==3:
    n=2
    a=[[2,2],[3,3]]
    c=[[0,0],[1,1]]
elif casen==4:
    n=5
    a=[[0,0],[7,3],[2,2],[4,8],[1,6]]
    c=[[8,5],[6,9],[5,4],[9,1],[3,7]]
elif casen==5:
    n=5
    a=[[0,0],[1,1],[5,5],[6,6],[7,7]]
    c=[[2,2],[3,3],[4,4],[8,8],[9,9]]

c.sort()
a.sort(key=lambda x:x[1])
#a.reverse()

icnt=0
ic2=0
for ic in range(len(c)):
    for ia in range(len(a)-1,-1,-1):
        if a[ia][0]<c[ic][0] and a[ia][1]<c[ic][1]:
            icnt=icnt+1
            del a[ia]
            break
        else:
            continue
        break

print(icnt)               

# Optimized solution

n=int(eval(input()))
r=[[0]*3 for i in range(n)]
b=[[0]*2 for i in range(n)]
for i in range(n):
    r[i]=list(map(int,input().split()))+[0]
for i in range(n):
    b[i]=list(map(int,input().split()))

r.sort(key=lambda x:x[1],reverse=True)
b.sort()

psum=0
for i in range(n):
    for ii in range(n):
#        print("b:",i,b[i][0],b[i][1],"r:",ii,r[ii][0],r[ii][1])
        if b[i][0]>r[ii][0] and b[i][1]>r[ii][1] and r[ii][2]==0:
            r[ii][2]=1
            psum+=1
            break
print(psum)
# Original solution
from collections import defaultdict

n=int(eval(input()))
ab=[[int(i) for i in input().split()] for j in range(n)]
cd=[[int(i) for i in input().split()] for j in range(n)]
ab.sort()
cd.sort()
    
ans=0

for i in cd:
    check=-1
    pair=[-1,-1]
    for j in ab:
        
        if j[0]>i[0]:
            break
        if check<j[1]<i[1]:
            check=j[1]
            pair=j
    if pair != [-1,-1]:
        ans+=1
        ab.remove(pair)
print(ans)
    

# Optimized solution
import bisect
n=int(eval(input()))
ab=[[int(i) for i in input().split()] for j in range(n)]
cd=[[int(i) for i in input().split()] for j in range(n)]
ab.sort()
cd.sort()

ans=0

for c,d in cd:
    now_y=-1
    check=False
    for a,b in ab:
        if a>=c:
            break
        if b<d and b>now_y:
            now_id=bisect.bisect_left(ab,[a,b])
            now_y=b
            check=True

    if check:
        ans+=1
        ab.pop(now_id)
print(ans)
# Original solution
n = int(eval(input()))
red_list = []
blue_list = []

for i in range(n):
    x, y = list(map(int, input().split()))
    red_list.append([x, y])
for i in range(n):
    x, y = list(map(int, input().split()))
    blue_list.append([x, y])

#2. search
#2.1 red:descending order in y
red_list.sort(key=lambda x:(x[1], x[0]), reverse=True)

#2.2 blue: ascending order
blue_list.sort(key=lambda x:(x[0], x[1]), reverse=False)

#2.3 search a blue point such as [x_r, y_r] < [x_b, y_b]
ans = 0
for red in red_list:
    for blue in blue_list:
        if (red[0]<blue[0]) and (red[1]<blue[1]):
            blue_list.remove(blue)
            ans += 1
            break

#3. print the result
print(ans)

# Optimized solution
N = int(eval(input()))
R = []
B = []
for i in range(N):
    R.append(list(map(int, input().split())))
for i in range(N):
    B.append(list(map(int, input().split())))

R.sort(key=lambda x:x[0], reverse=True)
B.sort(key=lambda x:x[1], reverse=False)

ans = 0
for r in R:
    for b in B:
        if r[0]<b[0] and r[1]<b[1]:
            ans += 1
            B.remove(b)
            break
            
print(ans)
# Original solution
from itertools import permutations
N = int(eval(input()))
rn = [list(map(int,input().split())) for _ in range(N)]
bn = [list(map(int,input().split())) for _ in range(N)]
ans = 0
for p in permutations(list(range(N))):
  ans = max(ans, sum([1 if rn[i][0] < bn[p[i]][0] and rn[i][1] < bn[p[i]][1] else 0 for i in range(N)]))
print(ans)


# Optimized solution
N = int(eval(input()))
rn = [[True]+list(map(int,input().split())) for _ in range(N)]
bn = sorted([list(map(int,input().split())) for _ in range(N)])
rn.sort(key=lambda x: -x[2])
for bp in bn:
  bx,by = bp
  for rp in rn:
    f,rx,ry = rp
    if f and rx<bx and ry<by:
      rp[0] = False
      break
print((sum([0 if rp[0] else 1 for rp in rn])))
# Original solution
n = int(eval(input()))
red = []
for i in range(n):
    red.append(list(map(int, input().split())))
blue = []
for i in range(n):
    blue.append(list(map(int, input().split())))
red_sort = sorted(red, key=lambda x: x[1], reverse=True)
blue_sort = sorted(blue)
count = 0
flag = [0]*n
for b in blue_sort:
    for i,r in enumerate(red_sort):
        if r[0] < b[0] and r[1] < b[1] and flag[i] == 0:
            count += 1
            flag[i] = 1
            break
print(count)

# Optimized solution
n = int(eval(input()))

red = []
blue = []
for i in range(n):
    a,b = list(map(int,input().split()))
    red.append((a,b))
for i in range(n):
    c,d = list(map(int,input().split()))
    blue.append((c,d))
    
red_sorted = sorted(red,reverse=True)
blue_sorted = sorted(blue,key=lambda x: x[1])

count = 0
check = []
for i in red_sorted:
    for j,k in enumerate(blue_sorted):
        if (i[0] < k[0]) and (i[1] < k[1]):
            blue_sorted.pop(j)
            count += 1
            break
print(count)
# Original solution

N = int(eval(input()))
X = []
Y = []

for i in range(N):
  a, b = list(map(int, input().split()))
  X.append((a, b))

for i in range(N):
  c, d = list(map(int, input().split()))
  Y.append((c, d))


X.sort(key=lambda x: -x[1])
Y.sort(key=lambda x: x[0])

B = []
result = 0

for x in range(N):
  red = list(map(int, X[x]))

  for y in range(N):
    blue = list(map(int, Y[y]))
    if y in B:
      continue
    if red[0] < blue[0] and red[1] < blue[1]:
      result += 1
      B.append(y)
      break
  
print(result)

# Optimized solution



N = int(eval(input()))
RED = []
BLUE = []

for i in range(N):
  a, b = list(map(int, input().split()))
  RED.append((a, b))

for i in range(N):
  a, b = list(map(int, input().split()))
  BLUE.append((a, b))

BLUE.sort(key=lambda x: x[0])
RED.sort(key=lambda x: -x[1])


red_selected = set()
blue_selected = set()
for i in range(N):
  c, d = BLUE[i]
  
  for j in range(N):
    a, b = RED[j]
    if a < c and b < d and j not in red_selected and i not in blue_selected:
      red_selected.add(j)
      blue_selected.add(i)

print((len(red_selected)))
# Original solution
n = int(eval(input()))  
red_li = [list(map(int, input().split())) for _ in range(n)]
blue_li = [list(map(int, input().split())) for _ in range(n)]
ans = 0
red_li.sort(reverse = True, key = lambda x : (x[0], x[1]))
blue_li.sort( key = lambda x : (x[0], x[1]))

def count(red, blue):
    used_red = []
    used_blue = []
    for i in red:
        if i in used_red:
            continue
        for j in blue:
            if j in used_blue:
                continue
            if i[0] < j[0] and i[1] < j[1]:
                used_red.append(i)
                used_blue.append(j)
                break
    return len(used_red)

ans = count(red_li, blue_li)
red_li.sort(reverse = True,key = lambda x : (x[1], x[0]))
blue_li.sort( key = lambda x : (x[1], x[0]))
ans = max(ans, count(red_li, blue_li))
red_li.sort(reverse = True,key = lambda x : (x[1], x[0]))
blue_li.sort( key = lambda x : (x[0], x[1]))
ans = max(ans, count(red_li, blue_li))
red_li.sort(reverse = True,key = lambda x : (x[0], x[1]))
blue_li.sort( key = lambda x : (x[1], x[0]))
ans = max(ans, count(red_li, blue_li))
print(ans)

# Optimized solution
n = int(eval(input()))  
red_li = [list(map(int, input().split())) for _ in range(n)]
blue_li = [list(map(int, input().split())) for _ in range(n)]
ans = 0
red_li.sort(reverse = True, key = lambda x : (x[0], x[1]))
blue_li.sort( key = lambda x : (x[0], x[1]))

def count(red, blue):
    used_red = []
    used_blue = []
    for i in red:
        if i in used_red:
            continue
        for j in blue:
            if j in used_blue:
                continue
            if i[0] < j[0] and i[1] < j[1]:
                used_red.append(i)
                used_blue.append(j)
                break
    return len(used_red)


red_li.sort(reverse = True,key = lambda x : (x[0], x[1]))
blue_li.sort( key = lambda x : (x[1], x[0]))
ans = max(ans, count(red_li, blue_li))
print(ans)
# Original solution
# coding:utf-8

import sys
import random
# from collections import Counter, defaultdict

INF = float('inf')
MOD = 10 ** 9 + 7

def LI(): return [int(x) for x in sys.stdin.readline().split()]
def LI_(): return [int(x) - 1 for x in sys.stdin.readline().split()]
def LS(): return sys.stdin.readline().split()
def II(): return int(sys.stdin.readline())
def SI(): return eval(input())


def main():
    n = II()
    red = [[a + b, a, b] for a, b in (LI() for _ in range(n))]
    blue = [[a + b, a, b] for a, b in (LI() for _ in range(n))]

    ans = 0
    red.sort()
    for _ in range(n):
        red = red[-1:] + red[:-1]
        used = [0] * n
        res = 0
        for s, a, b in red:
            near = -1
            d = INF
            for i, (ss, x, y) in enumerate(blue):
                if a < x and b < y:
                    tmp = x - a + y - b
                    if tmp < d and not used[i]:
                        near = i
                        d = tmp

            if near != -1:
                used[near] = 1
                res += 1
        ans = max(ans, res)

    red.reverse()
    for _ in range(n):
        red = red[-1:] + red[:-1]
        used = [0] * n
        res = 0
        for s, a, b in red:
            near = -1
            d = INF
            for i, (ss, x, y) in enumerate(blue):
                if a < x and b < y:
                    tmp = x - a + y - b
                    if tmp < d and not used[i]:
                        near = i
                        d = tmp

            if near != -1:
                used[near] = 1
                res += 1
        ans = max(ans, res)

    for _ in range(20):
        random.shuffle(red)
        for _ in range(n):
            red = red[-1:] + red[:-1]
            used = [0] * n
            res = 0
            for s, a, b in red:
                near = -1
                d = INF
                for i, (ss, x, y) in enumerate(blue):
                    if a < x and b < y:
                        tmp = x - a + y - b
                        if tmp < d and not used[i]:
                            near = i
                            d = tmp

                if near != -1:
                    used[near] = 1
                    res += 1
            ans = max(ans, res)

    return ans


print((main()))


# Optimized solution
# coding:utf-8

import sys
import random
# from collections import Counter, defaultdict

INF = float('inf')
MOD = 10 ** 9 + 7

def LI(): return [int(x) for x in sys.stdin.readline().split()]
def LI_(): return [int(x) - 1 for x in sys.stdin.readline().split()]
def LS(): return sys.stdin.readline().split()
def II(): return int(sys.stdin.readline())
def SI(): return eval(input())


def main():
    n = II()
    red = [LI() for _ in range(n)]
    blue = [LI() for _ in range(n)]
    blue.sort()

    used = [0] * n
    res = 0
    for a, b in blue:
        t = -1
        k = -1
        for i, (x, y) in enumerate(red):
            if used[i]:
                continue

            if x < a and b > y > t:
                t = y
                k = i

        if k != -1:
            used[k] = 1
            res += 1

    return res


print((main()))
# Original solution
N = int(eval(input()))
AB = [list(map(int,input().split())) for i in range(N)]
CD = [list(map(int,input().split())) for i in range(N)]

AB.sort()
CD.sort()

#print(AB)
#print(CD)

ans = 0

for i in range(N-1,-1,-1):
    ab = AB[i]
    li = []
    for cd in CD:
        if ab[0] < cd[0] and ab[1] < cd[1]:
            li.append(cd)
    li.sort(key=lambda x: x[1])
    if len(li) != 0:
        CD.remove(li[0])
        ans += 1
print(ans)


# Optimized solution
N = int(eval(input()))
AB = [tuple(map(int,input().split())) for i in range(N)]
CD = [tuple(map(int,input().split())) for i in range(N)]
AB.sort(key=lambda x: x[0])
CD.sort(key=lambda x: x[0])
ans = 0
for c,d in CD:
    idx = 10000
    for i in range(N):
        if AB[i] == -1:
            continue
        if c < AB[i][0]:
            break
        if AB[i][1] < d:
            if idx == 10000:
                idx = i
            elif AB[idx][1] < AB[i][1]:
                idx = i
    if idx != 10000:
        ans += 1
        AB[idx] = -1
print(ans)
# Original solution
N = int(eval(input()))
ps = [tuple(map(int,input().split())) for i in range(2*N)]

es = [[] for i in range(2*N)]
for ri,(rx,ry) in enumerate(ps[:N]):
    for bi,(bx,by) in enumerate(ps[N:]):
        bi += N
        if rx < bx and ry < by:
            es[ri].append(bi)
            es[bi].append(ri)

used = [False] * (2*N)
match = [-1] * (2*N)

def _dfs(v):
    global used, match
    used[v] = True
    for u in es[v]:
        w = match[u]
        if w < 0 or not used[w] and _dfs(w):
            match[v] = u
            match[u] = v
            return True
    return False

def bipartite_matching():
    global used, match
    ret = 0
    for v in range(2*N):
        if match[v] < 0:
            used = [False] * (2*N)
            if _dfs(v):
                ret += 1
    return ret

print((bipartite_matching()))


# Optimized solution
N = int(eval(input()))
src = [tuple(map(int,input().split())) for i in range(2*N)]
es = [[] for i in range(2*N)]
for i,(x1,y1) in enumerate(src[:N]):
    for j,(x2,y2) in enumerate(src[N:]):
        if x1 < x2 and y1 < y2:
            es[i].append(j+N)
            es[j+N].append(i)

used = [False] * (2*N)
match = [-1] * (2*N)

def _dfs(v):
    global used, match
    used[v] = True
    for u in es[v]:
        w = match[u]
        if w < 0 or not used[w] and _dfs(w):
            match[v] = u
            match[u] = v
            return True
    return False

def bipartite_matching():
    global used, match
    ret = 0
    for v in range(2*N):
        if match[v] < 0:
            used = [False] * (2*N)
            if _dfs(v):
                ret += 1
    return ret

print((bipartite_matching()))