Problem:
 Score : 400 points    Problem Statement On a two-dimensional plane, there are N red points and N blue points.
The coordinates of the i -th red point are (a_i, b_i) , and the coordinates of the i -th blue point are (c_i, d_i) .  A red point and a blue point can form a friendly pair when, the x -coordinate of the red point is smaller than that of the blue point, and the y -coordinate of the red point is also smaller than that of the blue point.  At most how many friendly pairs can you form? Note that a point cannot belong to multiple pairs.      Constraints  All input values are integers.  1 \leq N \leq 100  0 \leq a_i, b_i, c_i, d_i < 2N  a_1, a_2, ..., a_N, c_1, c_2, ..., c_N are all different.  b_1, b_2, ..., b_N, d_1, d_2, ..., d_N are all different.         Input Input is given from Standard Input in the following format:  N  a_1  b_1  a_2  b_2  :  a_N  b_N  c_1  d_1  c_2  d_2  :  c_N  d_N       Output Print the maximum number of friendly pairs.        Sample Input 1 3
2 0
3 1
1 3
4 2
0 4
5 5      Sample Output 1 2  For example, you can pair (2, 0) and (4, 2) , then (3, 1) and (5, 5) .       Sample Input 2 3
0 0
1 1
5 2
2 3
3 4
4 5      Sample Output 2 2  For example, you can pair (0, 0) and (2, 3) , then (1, 1) and (3, 4) .       Sample Input 3 2
2 2
3 3
0 0
1 1      Sample Output 3 0  It is possible that no pair can be formed.       Sample Input 4 5
0 0
7 3
2 2
4 8
1 6
8 5
6 9
5 4
9 1
3 7      Sample Output 4 5       Sample Input 5 5
0 0
1 1
5 5
6 6
7 7
2 2
3 3
4 4
8 8
9 9      Sample Output 5 4

Solution (Python):
import sys
mod=10**9+7 ; inf=float("inf")
from math import sqrt, ceil
from collections import deque, Counter, defaultdict 
input=lambda: sys.stdin.readline().strip()
sys.setrecursionlimit(11451419)
from decimal import ROUND_HALF_UP,Decimal  
  
from functools import lru_cache
from bisect import bisect_left as bileft, bisect_right as biright





from collections import deque
class Dinic:
    def __init__(self, N):
        self.N= N
        self.G = [[] for i in range(N)]
    def add_edge(self,fr,to,cap=1): 
        forward=[to, cap, None]
        forward[2] = backward = [fr, 0, forward]
        self.G[fr].append(forward)
        self.G[to].append(backward)

    def add_multi_edge(self, v1, v2, cap1, cap2):
        edge1 = [v2, cap1, None]
        edge1[2] = edge2 = [v1, cap2, edge1]
        self.G[v1].append(edge1)
        self.G[v2].append(edge2)

    def bfs(self, s, t):
        self.level = level = [None]*self.N
        deq = deque([s])
        level[s] = 0
        G = self.G
        while deq:
            v = deq.popleft()
            lv = level[v] + 1
            for w, cap, _ in G[v]:
                if cap and level[w] is None:
                    level[w] = lv
                    deq.append(w)
        return level[t] is not None

    def dfs(self, v, t, f):
        if v == t:
            return f
        level = self.level
        for e in self.it[v]:
            w, cap, rev = e
            if cap and level[v] < level[w]:
                d = self.dfs(w, t, min(f, cap))
                if d:
                    e[1] -= d
                    rev[1] += d
                    return d
        return 0

    def flow(self, s, t):
        flow = 0
        INF = inf
        G = self.G
        while self.bfs(s, t):
            *self.it, = map(iter, self.G)
            f = INF
            while f:
                f = self.dfs(s, t, INF)
                flow += f
        return flow
n=int(input())
dinic=Dinic(2*n+2)


A=[] ; B=[]
for i in range(n):
    a,b=map(int,input().split())
    A.append([a,b])
for i in range(n):
    a,b=map(int,input().split())
    B.append([a,b])
for i in range(n):
    dinic.add_edge(2*n,i,1)
    dinic.add_edge(i+n, 2*n+1,1)
for i in range(n):
    for j in range(n):
        if A[i][0]<B[j][0] and A[i][1]<B[j][1]:
            dinic.add_edge(i,j+n)

print(dinic.flow(2*n,2*n+1))

Solution (Python):
n = int(input())
ab = []
cd = []
for i in range(n):
    ab.append(tuple(map(int,input().split())))

for g in range(n):
    cd.append(tuple(map(int,input().split())))

ab.sort(key=lambda x: x[1], reverse = True)
cd.sort()
used = [False]*n

ans = 0
for i in range(n):
    for g in range(n):
        if ab[i][0] < cd[g][0] and ab[i][1] < cd[g][1] and not used[g]:
            used[g] = True
            ans += 1
            break
print(ans)

Solution (Python):
N=int(input())
AB=sorted([list(map(int, input().split())) for _ in range(N)])
CD=sorted([list(map(int, input().split())) for _ in range(N)])

paira=-1
pairb=-1
ans=0

for i in range(N):
	tempcd=CD[i]
	for h in range(len(AB)):
		tempab=AB[h]
		if tempab[0]<tempcd[0] and tempab[1]<tempcd[1]:
			if pairb<tempab[1]:
				paira=tempab[0]
				pairb=tempab[1]
				pairnum=h
	if paira!=-1 and pairb!=-1:
		ans+=1
		AB.pop(pairnum)
		paira=-1
		pairb=-1

print(ans)

Solution (Python):
ma = lambda :map(int,input().split())
lma = lambda :list(map(int,input().split()))
tma = lambda :tuple(map(int,input().split()))
ni = lambda:int(input())
yn = lambda fl:print("YES") if fl else print("NO")
import collections
import math
import itertools
import heapq as hq
n = ni()
ab = []
for i in range(n):
    ab.append(lma())
ab.sort(key=lambda x:x[1],reverse=True)
ab.sort(reverse=True)
cd = []
for i in range(n):
    cd.append(lma())
cd.sort()
cd.sort(key=lambda x:x[1])
cnt=0
INF=10**9
for a,b in ab:
    
    for i in range(n):
        c,d = cd[i]
        if a<c and b<d:
            
            cnt+=1
            cd[i][0]=-INF
            cd[i][1]=-INF
            break
print(cnt)

Solution (Python):
import sys
input = sys.stdin.readline

class FordFulkerson:
    def __init__(self, n):
        self.N = n
        self.G = [[] for _ in range(n)]
        
    def add_edge(self, fr, to, cap):
        forward = [to, cap, None]
        forward[2] = backward = [fr, 0, forward]
        self.G[fr].append(forward)
        self.G[to].append(backward)
        
    def add_multi_edge(self, v1, v2, cap1, cap2):
        edge1 = [v2, cap1, None]
        edge1[2] = edge2 = [v1, cap2, edge1]
        self.G[v1].append(edge1)
        self.G[v2].append(edge2)
    
    def dfs(self, v, t, f):
        if v == t:
            return f
        used = self.used
        used[v] = 1
        for e in self.G[v]:
            w, cap, rev = e
            if cap and not used[w]:
                d = self.dfs(w, t, min(f, cap))
                if d:
                    e[1] -= d
                    rev[1] += d
                    return d
        return 0
    

    def flow(self, s, t):
        flow = 0
        f = INF = 10**9 + 7
        N = self.N
        while f:
            self.used = [0]*N
            f = self.dfs(s, t, INF)
            flow += f
        return flow
    
def main():
    n = int(input())
    red = [list(map(int, input().split())) for _ in range(n)]
    blue = [list(map(int, input().split())) for _ in range(n)]
    
    flow = FordFulkerson(n*2+2)
    for i in range(n):
        flow.add_edge(0, i+1, 1)
        flow.add_edge(n+i+1, 2*n+1, 1)
        for j in range(n):
            if red[i][0] < blue[j][0] and red[i][1] < blue[j][1]:
                flow.add_edge(i+1, n+j+1, 1)
    
    
    ans = flow.flow(0, 2*n+1)
    print(ans)
    
if __name__ == "__main__":
    main()

Solution (Python):
import sys, re
from collections import deque, defaultdict, Counter
from math import ceil, sqrt, hypot, factorial, pi, sin, cos, tan, asin, acos, atan, radians, degrees, log2, gcd
from itertools import accumulate, permutations, combinations, combinations_with_replacement, product, groupby
from operator import itemgetter, mul
from copy import deepcopy
from string import ascii_lowercase, ascii_uppercase, digits
from bisect import bisect, bisect_left, insort, insort_left
from heapq import heappush, heappop
from functools import reduce
def input(): return sys.stdin.readline().strip()
def INT(): return int(input())
def MAP(): return map(int, input().split())
def LIST(): return list(map(int, input().split()))
def TUPLE(): return tuple(map(int, input().split()))
def ZIP(n): return zip(*(MAP() for _ in range(n)))
sys.setrecursionlimit(10 ** 9)
INF = float('inf')
mod = 10 ** 9 + 7 

from decimal import *



N = INT()
ab = [LIST() for _ in range(N)]
cd = [LIST() for _ in range(N)]

check = [0]*N
ab.sort(key = lambda x: (-x[0],-x[1]))
cd.sort(key = lambda x: (x[0], x[1]))

for c, d in cd:
	idx = -1
	tmp = INF
	for i in range(N):
		if check[i] == 0 and ab[i][0] < c and ab[i][1] < d and tmp > d-ab[i][1] :
			tmp = d-ab[i][1]
			idx = i
	if idx != -1:
		check[idx] = 1

print(sum(check))

Solution (Python):
import sys
sys.setrecursionlimit(10**8)
def ii(): return int(sys.stdin.readline())
def mi(): return map(int, sys.stdin.readline().split())
def li(): return list(map(int, sys.stdin.readline().split()))
def li2(N): return [list(map(int, sys.stdin.readline().split())) for _ in range(N)]
def dp2(ini, i, j): return [[ini]*i for _ in range(j)]





N = ii()
A = li2(N)
B = li2(N)

A = sorted(A, key=lambda x:x[1])
B = sorted(B, key=lambda x:x[0])

flag = [0] * N

for i in range(N):
    ind = -1
    for j in range(N):
        if A[j][1] < B[i][1]:
            ind = j
    while ind >= 0:
        if not flag[ind] and A[ind][0] < B[i][0]:
            flag[ind] = 1
            break
        ind -= 1


print(sum(flag))

Solution (Python):
import sys
sys.setrecursionlimit(10**8)
def ii(): return int(sys.stdin.readline())
def mi(): return map(int, sys.stdin.readline().split())
def li(): return list(map(int, sys.stdin.readline().split()))
def li2(N): return [list(map(int, sys.stdin.readline().split())) for _ in range(N)]
def dp2(ini, i, j): return [[ini]*i for _ in range(j)]




'''
N = ii()
A = li2(N)
B = li2(N)

A = sorted(A, key=lambda x:x[0])
B = sorted(B, key=lambda x:x[0])

a_ind = 0
b_ind = 0
cnt = 0

while b_ind < N:
    if A[a_ind][0] < B[b_ind][0] and  A[a_ind][1] < B[b_ind][1]:
        cnt += 1
        a_ind += 1
        b_ind += 1
    else:
        b_ind += 1

print(cnt)
'''
'''

ans = 0

def dfs(a_ind, b_ind, cnt):
    if a_ind >= N or b_ind >= N:
        global ans
        ans = max(ans, cnt)
        return
    if A[a_ind][0] < B[b_ind][0] and  A[a_ind][1] < B[b_ind][1]:
        dfs(a_ind+1, b_ind+1, cnt+1)
    else:
        dfs(a_ind+1, b_ind, cnt)
        dfs(a_ind, b_ind+1, cnt)
        dfs(a_ind+1, b_ind+1, cnt)

dfs(0, 0, 0)

print(ans)
'''





def dfs(v, visited):
    """
    :param v: X側の未マッチングの頂点の1つ
    :param visited: 空のsetを渡す（外部からの呼び出し時）
    :return: 増大路が見つかればTrue
    """
    for u in edges[v]:
        if u in visited:
            continue
        visited.add(u)
        if matched[u] == -1 or dfs(matched[u], visited):
            matched[u] = v
            return True
    return False
 
 


N = ii()
xn = N
yn = N
edges = [set() for _ in range(xn)]
matched = [-1] * yn
 

    
    

A = li2(N)
B = li2(N)

for i in range(N):
    for j in range(N):
        if A[i][0] < B[j][0] and  A[i][1] < B[j][1]:
            edges[i].add(j)
 

print(sum(dfs(s, set()) for s in range(xn)))

Solution (Python):
N = int(input())
ab = [tuple(map(int, input().split())) for _ in range(N)]
cd = [tuple(map(int, input().split())) for _ in range(N)]

ab.sort(key=lambda xy: xy[1], reverse=True)
cd.sort()

ans = 0
for c, d in cd:
    for index, (a, b) in enumerate(ab):
        if a < c and b < d:
            ab[index] = (201, 201)
            ans += 1
            break

print(ans)

Solution (Python):
n = int(input())
red  = [tuple(map(int, input().split())) for _ in range(n)]
blue = [tuple(map(int, input().split())) for _ in range(n)]
red.sort(key=lambda x:-x[1])
blue.sort()
count = 0
for xb, yb in blue:
    for i in range(n):
        if xb > red[i][0] and yb > red[i][1]:
            red[i] = (201, 201)
            count += 1
            break
print(count)

Solution (Python):
n = int(input())
red  = [tuple(map(int, input().split())) for _ in range(n)]
blue = [tuple(map(int, input().split())) for _ in range(n)]

red.sort(key=lambda x:x[1])
blue.sort()

count = 0
for xb, yb in blue:
    max_y = -1
    max_i = -1
    for i in range(n):
        xr, yr = red[i]
        if xb > xr and yb > yr and max_y < yr:
            max_y, max_i = yr, i
    if max_y >= 0:
        red[max_i] = (201, 201)
        count += 1
print(count)

Solution (Python):
N = int(input())
red = [list(map(int, input().split())) for _ in range(N)]
blue = [list(map(int, input().split())) for _ in range(N)]
red.sort(reverse=True)
blue.sort(key=lambda x:x[1])
blue_check = [0]*N
for i in range(N):
    for k in range(N):
        if blue_check[k] == 1:
            continue
        if red[i][0] < blue[k][0] and red[i][1] < blue[k][1]:
            blue_check[k] = 1
            break
print(sum(blue_check))

Solution (Python):
from heapq import heapify, heappush, heappop
N = int(input())
A = []
for i in range(N):
    A.append(tuple(map(int, input().split())))
A.sort()

B = []
for i in range(N):
    B.append(tuple(map(int, input().split())))
B.sort()

heap = []
heapify(heap)
aindex = count = 0
for b in B:
    while aindex < len(A) and A[aindex][0] < b[0]:
        heappush(heap, -A[aindex][1])
        aindex += 1
    buf = []
    while heap and b[1] <= -heap[0]:
        ay = heappop(heap)
        buf.append(ay)
    if heap and -heap[0] < b[1]:
        count += 1
        heappop(heap)
    for ay_ in buf:
        heappush(heap, ay_)
print(count)

Solution (Python):
import sys
INF = 1 << 60
MOD = 10**9 + 7 
sys.setrecursionlimit(2147483647)
input = lambda:sys.stdin.readline().rstrip()
import networkx as nx
def resolve():
    n = int(input())
    A = [tuple(map(int, input().split())) for _ in range(n)]
    B = [tuple(map(int, input().split())) for _ in range(n)]
    G = nx.Graph()
    G.add_nodes_from(range(n))
    G.add_nodes_from(range(n, 2 * n))
    for i in range(n):
        ax, ay = A[i]
        for j in range(n):
            bx, by = B[j]
            if ax < bx and ay < by:
                G.add_edge(i, n + j)

    A = nx.algorithms.bipartite.maximum_matching(G, top_nodes = range(n))
    print(len(A) // 2)
resolve()

Solution (Python):
import sys
INF = 1 << 60
MOD = 10**9 + 7 
sys.setrecursionlimit(2147483647)
input = lambda:sys.stdin.readline().rstrip()
import networkx as nx
def resolve():
    n = int(input())
    A = [tuple(map(int, input().split())) for _ in range(n)]
    B = [tuple(map(int, input().split())) for _ in range(n)]
    G = nx.Graph()
    G.add_nodes_from(range(n))
    G.add_nodes_from(range(n, 2 * n))
    for i in range(n):
        ax, ay = A[i]
        for j in range(n):
            bx, by = B[j]
            if ax < bx and ay < by:
                G.add_edge(i, n + j)

    A = nx.algorithms.bipartite.matching.hopcroft_karp_matching(G, top_nodes = range(n))
    print(len(A) // 2)
resolve()

Solution (Python):
N = int(input())
Red = [[int(T) for T in input().split()] for TN in range(0,N)]
Red.sort(key=lambda X:X[1],reverse=True)
Blue = [[int(T) for T in input().split()] for TN in range(0,N)]
Blue.sort(key=lambda X:X[0])
Count = 0

for TB in range(0,N):
    DelInd = -1
    for TR in range(0,len(Red)):
        if Blue[TB][0]>Red[TR][0] and Blue[TB][1]>Red[TR][1]:
            DelInd = TR
            break
    if DelInd!=-1:
        del Red[DelInd]
        Count += 1
print(Count)

Solution (Python):
import sys
INF = 1 << 60
MOD = 10**9 + 7 
sys.setrecursionlimit(2147483647)
input = lambda:sys.stdin.readline().rstrip()
from scipy.sparse import coo_matrix
from scipy.sparse.csgraph import maximum_bipartite_matching
def resolve():
    n = int(input())
    A = [tuple(map(int, input().split())) for _ in range(n)]
    B = [tuple(map(int, input().split())) for _ in range(n)]

    weights = []
    rows = []
    columns = []
    for i in range(n):
        ax, ay = A[i]
        for j in range(n):
            bx, by = B[j]
            if ax < bx and ay < by:
                weights.append(1)
                rows.append(i)
                columns.append(j)

    graph = coo_matrix((weights, (rows, columns)), shape = (n, n))
    ans = sum(maximum_bipartite_matching(graph) >= 0)
    print(ans)
resolve()

Solution (Python):
import sys
INF = 1 << 60
MOD = 10**9 + 7 
sys.setrecursionlimit(2147483647)
input = lambda:sys.stdin.readline().rstrip()
from scipy.sparse import csr_matrix
from scipy.sparse.csgraph import maximum_bipartite_matching
def resolve():
    n = int(input())
    A = [tuple(map(int, input().split())) for _ in range(n)]
    B = [tuple(map(int, input().split())) for _ in range(n)]

    graph = csr_matrix([[int(A[i][0] < B[j][0] and A[i][1] < B[j][1]) for j in range(n)] for i in range(n)])
    ans = 0
    for a in maximum_bipartite_matching(graph):
        if a != -1:
            ans += 1
    print(ans)
resolve()

Solution (Python):
def main():
    n = int(input())
    red = []
    red_used = [[False for _ in range(2 * n)] for _ in range(2 * n)]
    for _ in range(n):
        rp = list(map(int, input().split()))
        red.append(rp)
        red_used[rp[0]][rp[1]] = True
    ans = 0
    red.sort(key=lambda x: x[1], reverse=True)
    blue = [list(map(int, input().split())) for _ in range(n)]
    blue.sort(key=lambda x: x[0])
    for bx, by in blue:
        for rx, ry in red:
            if rx < bx and ry < by and red_used[rx][ry]:
                red_used[rx][ry] = False
                ans += 1
                break
    print(ans)


if __name__ == '__main__':
    main()

Solution (Python):
import networkx as nx

n = int(input())
graph = nx.DiGraph()
AB = [list(map(int, input().split())) for _ in range(n)]
CD = [list(map(int, input().split())) for _ in range(n)]

start = 10 ** 4
goal = 10 ** 4 + 1
for i in range(n):
    a, b = AB[i]
    graph.add_edge(start, i, weight=0, capacity=1)
    for j in range(n):
        c, d = CD[j]
        graph.add_edge(200 + j, goal, weight=0, capacity=1)
        if c > a and d > b:
            graph.add_edge(i, 200 + j, weight=0, capacity=1)

ans = nx.maximum_flow(graph, start, goal, capacity="capacity")
print(ans[0])

Solution (Python):
n=int(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)
for x,y in b:
  p,q=-1,-1
  for i,j in r:
    if i<x and j<y and j>q:p,q=i,j
  if (p,q) in r:r.remove((p,q))
print(n-len(r))

Solution (Python):
import sys

read = sys.stdin.read
readline = sys.stdin.readline
readlines = sys.stdin.readlines
sys.setrecursionlimit(10 ** 9)
INF = 1 << 60
MOD = 1000000007


def main():
    N = int(readline())
    P = [0] * (2 * N)
    for i in range(N):
        a, b = map(int, readline().split())
        P[i] = (a, b, 0)
    for i in range(N, 2 * N):
        c, d = map(int, readline().split())
        P[i] = (c, d, 1)

    P.sort(reverse=True)

    vec = [0] * (2 * N + 1)
    ans = 0

    for x, y, p in P:
        if p == 0:
            for i in range(y + 1, 2 * N + 1):
                if vec[i] > 0:
                    vec[i] -= 1
                    ans += 1
                    break
        else:
            vec[y] += 1

    print(ans)
    return


if __name__ == '__main__':
    main()

Solution (Python):
import networkx as nx

N=int(input())
ab=[list(map(int,input().split())) for _ in range(N)]
ab=sorted(ab)
cd=[list(map(int,input().split())) for _ in range(N)]
cd=sorted(cd,reverse=True)

G = nx.DiGraph()
for i in range(N):
  G.add_edge('x',i, capacity=1)
  for j in range(N):
    if i == 0:
      G.add_edge(N+j,'y', capacity=1)
    a,b=ab[i]
    c,d=cd[j]
    if a<c and b<d:
      G.add_edge(i,N+j, capacity=1)
    elif a>=c:break

flow_value, flow_dict = nx.maximum_flow(G, 'x', 'y')
print(flow_value)

Solution (Python):
n = int(input())
red = [list(map(int, input().split())) for _ in range(n)]
blue = [list(map(int, input().split())) for _ in range(n)]

blue.sort()

res = 0
for bx, by in blue:
    dist = -1
    for rx, ry in red:
        if rx < bx and dist < ry < by:
            dist = ry
            mx, my = rx, ry
    
    if dist > -1:
        res += 1
        red.remove([mx, my])

print(res)

Solution (Python):
n = int(input())
ab = [tuple(map(int, input().split())) for _ in range(n)]
cd = [tuple(map(int, input().split())) for _ in range(n)]
ab.sort(key=lambda x: (-x[1], x[0]))
cd.sort(key=lambda x: (x[0], x[1]))
s = [0] * n

for i in range(n):
    for j in range(n):
        if s[j] == 0 and ab[j][0] < cd[i][0] and ab[j][1] < cd[i][1]:
            s[j] = 1
            break
print(sum(s))

Solution (Python):
N = int(input())
R = []
B = []
for i in range(2 * N):
    a, b = map(int, input().split())
    if i < N:
        R.append((a, b))
    else:
        B.append((a, b))
B = sorted(B)

ans = 0
checked = set()
p = []
for b in B:
    x1, y1 = b
    tR = [(x2, y2) for x2, y2 in R if x2 < x1]
    tR = sorted(tR, key=lambda p: p[1], reverse=True)
    for x2, y2 in tR:
        if (x2, y2) in checked:
            continue
        if x1 > x2 and y1 > y2:
            ans += 1
            checked.add((x2, y2))
            p.append((b, (x2, y2)))
            break
print(ans)

Solution (Python):
N = int(input())
ab = [[int(i) for i in input().split()] for _ in range(N)]
cd = [[int(i) for i in input().split()] for _ in range(N)]

ab.sort(key = lambda x: x[1], reverse=True)
cd.sort()

x = 0
for c, d in cd:
    for a, b in ab:
        if a < c and b < d:
            x += 1
            ab.remove([a, b])
            break

print(x)

Solution (Python):
from operator import itemgetter
N=int(input())
R=[list(map(int,input().split())) for n in range(N)]
B=[list(map(int,input().split())) for n in range(N)]
R.sort(key=itemgetter(1),reverse=True)
B.sort()
ans=0

for c,d in B :
    for a,b in R :
        if a<c and b<d :
            ans+=1
            R.remove([a,b])
            break

print(ans)

Solution (Python):
def getN():
    return int(input())
def getNM():
    return map(int, input().split())
def getList():
    return list(map(int, input().split()))
def getArray(intn):
    return [int(input()) for i in range(intn)]
def input():
    return sys.stdin.readline().rstrip()
def rand_N(ran1, ran2):
    return random.randint(ran1, ran2)
def rand_List(ran1, ran2, rantime):
    return [random.randint(ran1, ran2) for i in range(rantime)]
def rand_ints_nodup(ran1, ran2, rantime):
  ns = []
  while len(ns) < rantime:
    n = random.randint(ran1, ran2)
    if not n in ns:
      ns.append(n)
  return sorted(ns)

def rand_query(ran1, ran2, rantime):
  r_query = []
  while len(r_query) < rantime:
    n_q = rand_ints_nodup(ran1, ran2, 2)
    if not n_q in r_query:
      r_query.append(n_q)
  return sorted(r_query)

from collections import defaultdict, deque, Counter
from sys import exit
from decimal import *
import heapq
from math import sqrt, pi
from fractions import gcd
import random
import string
import copy
from itertools import combinations, permutations, product
from operator import mul, itemgetter
from functools import reduce
from bisect import bisect_left, bisect_right

import sys
sys.setrecursionlimit(1000000000)
mod = 10 ** 9 + 7





N = getN()

R = [getList() for i in range(N)]
R_l = [1] * N

B = [getList() for i in range(N)]
B.sort()

















ans = 0
for b in B:
    max_y = -1
    max_index = -1
    for i, a in enumerate(R):
        
        if a[0] < b[0] and a[1] < b[1] and R_l[i] == 1:
            
            if a[1] > max_y:
                max_y = a[1]
                max_index = i
    if max_y >= 0:
        R_l[max_index] = 0
        ans += 1
print(ans)

Solution (Python):
def getN():
    return int(input())
def getNM():
    return map(int, input().split())
def getList():
    return list(map(int, input().split()))
def getArray(intn):
    return [int(input()) for i in range(intn)]
def input():
    return sys.stdin.readline().rstrip()
def rand_N(ran1, ran2):
    return random.randint(ran1, ran2)
def rand_List(ran1, ran2, rantime):
    return [random.randint(ran1, ran2) for i in range(rantime)]
def rand_ints_nodup(ran1, ran2, rantime):
  ns = []
  while len(ns) < rantime:
    n = random.randint(ran1, ran2)
    if not n in ns:
      ns.append(n)
  return sorted(ns)

def rand_query(ran1, ran2, rantime):
  r_query = []
  while len(r_query) < rantime:
    n_q = rand_ints_nodup(ran1, ran2, 2)
    if not n_q in r_query:
      r_query.append(n_q)
  return sorted(r_query)

from collections import defaultdict, deque, Counter
from sys import exit
from decimal import *
import heapq
from math import sqrt, pi
from fractions import gcd
import random
import string
import copy
from itertools import combinations, permutations, product
from operator import mul, itemgetter
from functools import reduce
from bisect import bisect_left, bisect_right

import sys
sys.setrecursionlimit(1000000000)
mod = 10 ** 9 + 7





N = getN()

R = [getList() for i in range(N)]
R_l = [1] * N

B = [getList() for i in range(N)]
B.sort()

















ans = 0
for b in B:
    max_y = -1
    max_index = -1
    for i, a in enumerate(R):
        
        if a[0] < b[0] and a[1] < b[1] and R_l[i] == 1:
            
            if a[1] > max_y:
                max_y = a[1]
                max_index = i
    if max_y >= 0:
        R_l[max_index] = 0
        ans += 1
print(ans)

Solution (Python):
N= int(input())
red=[list(map(int,input().split())) for i in range(N)]
red.sort()
blue=[list(map(int,input().split())) for i in range(N)]
blue.sort()
ans=0
from operator import itemgetter
for i in range(N):
   x,y=blue[i]
   l=[]
   for j in range(N):
      try:
         if x>red[j][0] and y>red[j][1]:
            l.append(red[j])
      except IndexError:
         break
   try:
      l.sort(key=itemgetter(1),reverse=True)
      red.remove(l[0])
   except IndexError:
      pass
print(N-len(red))

Solution (Python):
N = int(input())
R = [list(map(int,input().split())) for n in range(N)]
B = [list(map(int,input().split())) for n in range(N)]
R.sort(key=lambda x:-x[1])
B.sort()
ans=0

for c,d in B:
  for a,b in R:
    if a<c and b<d:
      ans+=1
      R.remove([a,b])
      break

print(ans)

Solution (Python):
import sys,queue,math,copy,itertools,bisect,collections,heapq

def main():
    LI = lambda : [int(x) for x in sys.stdin.readline().split()]
    NI = lambda : int(sys.stdin.readline())

    N = NI()
    goal = N*2+1
    edge = [set() for _ in range(goal+1)]

    red = [LI() for _ in range(N)]
    blue = [LI() for _ in range(N)]

    for i in range(1,N+1):
        edge[0].add(i)
    for i in range(N+1,goal):
        edge[i].add(goal)

    for i in range(N):
        a,b = red[i]
        for j in range(N):
            c,d = blue[j]
            if a < c and b < d:
                edge[i+1].add(N+j+1)

    ans = 0

    while True:
        q = collections.deque()
        node = [-1] * (goal + 1)
        node[0] = 0
        q.append(0)
        while q:
            u = q.pop()
            for v in edge[u]:
                if node[v] >= 0: continue
                node[v] = u
                if v == goal:
                    ans += 1
                    break
                q.append(v)
            else:
                continue
            break
        else:
            break

        v = goal
        while v > 0:
            u = node[v]
            edge[u].remove(v)
            edge[v].add(u)
            v = u

    print(ans)

if __name__ == '__main__':
    main()

Solution (Python):



 
def dfs(v, visited):
    """
    :param v: X側の未マッチングの頂点の1つ
    :param visited: 空のsetを渡す（外部からの呼び出し時）
    :return: 増大路が見つかればTrue
    """
    for u in edges[v]:
        if u in visited:
            continue
        visited.add(u)
        if matched[u] == -1 or dfs(matched[u], visited):
            matched[u] = v
            return True
    return False
 
 

N = int(input())
red_xy = [list(map(int,input().split())) for i in range(N)]
blue_xy = [list(map(int,input().split())) for i in range(N)]

edges = [set() for _ in range(N)]
matched = [-1] * N
 
for i in range(N):
    for j in range(N):
        
        if red_xy[i][0] < blue_xy[j][0] and red_xy[i][1] < blue_xy[j][1]:
            edges[i].add(j)
 

print(sum(dfs(s, set()) for s in range(N)))

Solution (Python):
N = int(input())
AB = [0] * N
for i in range(N):
  AB[i] = list(map(int, input().split()))
AB = sorted(AB)
CD = [0] * N
for i in range(N):
  CD[i] = list(map(int, input().split()))
CD = sorted(CD)


ans = 0

used = [0] * N
for i in range(N):
  now_x, now_y = CD[i][0], CD[i][1]
  max_y = -1
  nn = -1
  for j in range(N):
    if (now_x > AB[j][0]) and (used[j] == 0):
      if now_y > AB[j][1]:
        if max_y < AB[j][1]:
          max_y = AB[j][1]
          nn = j
  if max_y != -1:
    ans += 1
    used[nn] = 1
    
print(ans)

Solution (Python):
N = int(input())
red = [list(map(int, input().split())) for _ in range(N)]
blue = [list(map(int, input().split())) for _ in range(N)]
blue = sorted(blue, key=lambda x: x[0])

used = []
for i in range(N):
    c, d = blue[i]
    m, tmp = -1, -1
    for j in range(N):
        if j in used:
            continue
        a, b = red[j]
        if a < c and b < d:
            if b > m:
                m = b
                tmp = j
    if tmp != -1:
        used.append(tmp)
print(len(used))

Solution (Python):
def main():
    n = int(input())
    B = []
    g = [[0]*(2*n) for _ in range(2*n)]
    for _ in range(n):
        a,b  = map(int,input().split())
        g[b][a] = 1
    for _ in range(n):
        c,d = map(int,input().split())
        B.append((c,d))
    B.sort()
    ans = 0
    for i,j in B:
        f = 0
        for y in range(j,-1,-1):
            for x in range(i,-1,-1):
                if g[y][x]:
                    ans += 1
                    f = 1
                    g[y][x] = 0
                    break
            if f:
                break
    print(ans)

main()

Solution (Python):
N = int(input())
R = [[0, 0] for _ in range(N)]
B = [[0, 0] for _ in range(N)]
Map = [['.' for __ in range(2*N)] for _ in range(2*N)]
for i in range(N):
  R[i][1], R[i][0] = map(int, input().split())
  Map[R[i][1]][R[i][0]] = 'R'
for i in range(N):
  B[i][0], B[i][1] = map(int, input().split())
  Map[B[i][0]][B[i][1]] = 'B'
R.sort(reverse=True)
B.sort()
RF = [True for _ in range(N)]
BF = [True for _ in range(N)]
cnt = 0
for i in range(N):
  for j in range(N):
    if BF[j] == True:
      if R[i][1] < B[j][0] and R[i][0] < B[j][1]:
        cnt += 1
        RF[i] = False
        BF[j] = False
        break
print(cnt)

Solution (Python):
n=int(input())
red=sorted([list(map(int,input().split())) for i in range(n)],key=lambda x:x[1],reverse=True)
blue=sorted([list(map(int,input().split())) for i in range(n)])
ans=0
for bx,by in blue:
    for rx,ry in red:
        if rx<bx and ry<by:
            ans+=1
            red.remove([rx,ry])
            break
print(ans)