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()))
N = int(eval(input()))

rs = [tuple(map(int,input().split())) for i in range(N)]

bs = [tuple(map(int,input().split())) for i in range(N)]



bs.sort()

rs.sort(key=lambda x:-x[1])



removed = [0]*N

ans = 0

for bx,by in bs:

    for ri in range(N):

        if removed[ri]: continue

        rx,ry = rs[ri]

        if rx < bx and ry < by:

            removed[ri] = 1

            ans += 1

            break

print(ans)
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()))

N = int(eval(input()))
rs = [tuple(map(int, input().split())) for i in range(N)]
bs = [tuple(map(int, input().split())) for i in range(N)]
bs.sort()
rs.sort(key=lambda x: -x[1])
removed = [0] * N
ans = 0
for bx, by in bs:
    for ri in range(N):
        if removed[ri]:
            continue
        rx, ry = rs[ri]
        if rx < bx and ry < by:
            removed[ri] = 1
            ans += 1
            break
print(ans)

-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())) +rs = [tuple(map(int, input().split())) for i in range(N)] +bs = [tuple(map(int, input().split())) for i in range(N)] +bs.sort() +rs.sort(key=lambda x: -x[1]) +removed = [0] * N +ans = 0 +for bx, by in bs: +    for ri in range(N): +        if removed[ri]: +            continue +        rx, ry = rs[ri] +        if rx < bx and ry < by: +            removed[ri] = 1 +            ans += 1 +            break +print(ans)