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):
N = int(input())
xs = []
ys = []

for _ in range(N):
    a, b = map(int, input().split())
    xs.append((a, b))
xs.sort(key=lambda l: l[0])

for _ in range(N):
    c, d = map(int, input().split())
    ys.append((c, d))
ys.sort(key=lambda l: l[0])

used = []
ret = 0
for (c, d) in ys:
    l = []
    for (a, b) in xs:
        if a < c and b < d:
            l.append((a, b))

    ab = None
    for (a, b) in l:
        if used.count((a, b)) == 1:
            continue
        if ab is None:
            ab = (a, b)
        elif ab[1] < b:
            ab = (a, b)

    if ab is not None:
        used.append(ab)
        ret += 1

print(ret)

Solution (Python):
n = int(input())
p = [list(map(int,input().split()))+[0] for _ in range(n)]
p += [list(map(int,input().split()))+[1] for _ in range(n)]
p.sort()
ans = 0
l = set()
for x, y, c in p:
  if c == 0:
    l.add(y)
  else:
    t = -1
    for y_dash in l:
      if t < y_dash < y:
        t = y_dash
    if t != -1:
      ans += 1
      l.discard(t)
print(ans)

Solution (Python):
import sys
N = int(sys.stdin.readline().rstrip())

grid_r = [[0] * 2 * N for _ in range(2 * N)]

for _ in range(N):
    a, b = tuple(map(int, sys.stdin.readline().rstrip().split()))
    grid_r[a][b] = 1

b = [tuple(map(int, sys.stdin.readline().rstrip().split())) for _ in range(N)]
b = sorted(b, key=lambda x: x[1])

ans = 0
for b_x, b_y in b:
    for x in range(b_x + 1)[::-1]:
        for y in range(b_y + 1):
            if grid_r[x][y] and (x != b_x or y != b_y):
                grid_r[x][y] = 0
                ans += 1
                break
        else:
            continue
        break
print(ans)

Solution (Python):

from heapq import heappop,heappush

def main():
    N = int(input())
    red = []
    blue = []
    for i in range(N):
        a, b = map(int, input().split())
        red.append([a,b])
    for i in range(N):
        c, d = map(int, input().split())
        blue.append([c,d])
    blue.sort()
    ans = 0

    for i in range(N):
        pairs = []
        for j in range(len(red)):
            x = blue[i][0] - red[j][0]
            y = blue[i][1] - red[j][1]
            if x > 0 and y > 0:
                heappush(pairs, (y,j))

        if len(pairs) > 0:
            ans += 1
            _, index = heappop(pairs)
            del red[index]
    
    print(ans)


    

if __name__ == "__main__":
    main()

Solution (Python):

import sys
sys.setrecursionlimit(10**9)
INF=10**18
MOD=10**9+7
input=lambda: sys.stdin.readline().rstrip()
YesNo=lambda b: bool([print('Yes')] if b else print('No'))
YESNO=lambda b: bool([print('YES')] if b else print('NO'))
int1=lambda x:int(x)-1

N=int(input())
edge=[[] for _ in range(N*2+2)]
a,b=[0]*N,[0]*N
for i in range(N):
    a[i],b[i]=map(int,input().split())
for i in range(N):
    c,d=map(int,input().split())
    for j in range(N):
        if c>a[j] and d>b[j]:
            edge[i].append([j+N,1,len(edge[j+N])])
            edge[j+N].append([i,0,len(edge[i])-1])
for i in range(N):
    edge[N*2].append([i,1,len(edge[i])])
    edge[i].append([N*2,0,len(edge[N*2])-1])
    edge[N*2+1].append([i+N,0,len(edge[i+N])])
    edge[i+N].append([N*2+1,1,len(edge[N*2+1])-1])

def dfs(v,t,f):
    if v==t:
        return f
    used[v]=True
    for i,(nv,cap,rev) in enumerate(edge[v]):
        if not used[nv] and cap>0:
            d=dfs(nv,t,min(f,cap))
            if d>0:
                edge[v][i][1]-=d
                edge[nv][rev][1]+=d
                return d
    return 0

flow=0
while True:
    used=[False]*(N*2+2)
    f=dfs(N*2,N*2+1,INF)
    if f==0:
        break
    flow+=f
print(flow)

Solution (Python):
N = int(input())
red = list()
blue = list()
for i in range(N):
  red.append(list(map(int, input().split())))
for i in range(N):
  blue.append(list(map(int, input().split())))
blue.sort()
redflag = [0] * N
for i in range(N):
  [c, d] = blue[i]
  tmp = -1
  maxay = -1
  for j in range(N):
    [a, b] = red[j]
    if(c > a and d > b and redflag[j] == 0 and maxay < b):
      tmp = j
      maxay = b
  if(tmp >= 0):
    redflag[tmp] = 1
print(sum(redflag))

Solution (Python):
N=int(input())
a=[[] for i in range(N)]
for i in range(N):
  a1,b1=map(int,input().split())
  a[i].extend([a1,b1])
a.sort()
c=[]
d=[]
for i in range(N):
  c1,d1=map(int,input().split())
  c.append(c1)
  d.append(d1)
count=0
flag=[0 for i in range(N)]
for i in range(N):
  y=a[N-1-i][1]
  tmp=-1
  minb=max(d)
  fl=False
  for j in range(N):
    if(c[j]>a[N-1-i][0]):
      if(d[j]<=minb and d[j]>y and flag[j]==0):
        fl=True
        tmp=j
        minb=d[j]
  if fl:
    flag[tmp]=1
    count+=1
print(count)

Solution (Python):
def main():
    n = int(input())
    r = [list(map(int, input().split())) for _ in range(n)]
    b = [list(map(int, input().split())) for _ in range(n)]

    
    b.sort(key=lambda x: x[0])
    ans = 0

    for nb in b:
        
        r_sorted = [i for i in r if i[0] < nb[0] and i[1] < nb[1]]
        
        if r_sorted:
            
            r_sorted.sort(key=lambda x: x[1], reverse=True)
            r.remove(r_sorted[0])
            ans += 1

    print(ans)

if __name__ == "__main__":
    main()

Solution (Python):
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):
        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 = [None]*self.N
        d = deque([s])
        self.level[s] = 0
        while d:
            v = d.popleft()
            lv = self.level[v] + 1
            for w, cap, _ in self.G[v]:
                if cap and self.level[w] is None:
                    self.level[w] = lv
                    d.append(w)
        return self.level[t] is not None
    
    def dfs(self, v, t, f):
        if v == t:
            return f
        for e in self.it[v]:
            w, cap, rev = e
            if cap and self.level[v] < self.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 = 10**9 + 7
        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+1))
for i in range(1, N+1):
  dinic.add_edge(0, i, 1)
  dinic.add_edge(N+i, 2*N+1, 1)

ab = [list(map(int, input().split())) for i in range(N)]
cd = [list(map(int, input().split())) for i in range(N)]
for i, (a, b) in enumerate(ab, 1):
  for j, (c, d) in enumerate(cd, N+1):
    if a < c and b < d:
      dinic.add_edge(i, j, 1)

print(dinic.flow(0, 2*N+1))

Solution (Python):
N = int(input())
point = []
for i in range(2*N):
  x, y = map(int, input().split())
  point.append((x, y, i>=N))

point.sort()

ans = 0
Y = set()
for x, y, color in point:
  if color == 0:
    Y.add(y)
  else:
    t = -1
    for _y in Y:
      if t < _y < y:
        t = _y
    if t != -1:
      ans += 1
      Y.discard(t)

print(ans)

Solution (Python):
import sys
sys.setrecursionlimit(10 ** 5 + 10)


def input(): return sys.stdin.readline().strip()


def resolve():

    N = int(input())
    reds = [tuple(map(int, input().split())) for _ in range(N)]
    blues = [tuple(map(int, input().split())) for _ in range(N)]
    cnt = 0

    blues = sorted(blues, key=lambda x: x[0])
    for i in blues:
        temp = (-1, -1)

        for j in reds:
            if j[0] < i[0] and j[1] < i[1]:
                if j[1] > temp[1]:
                    temp = (j[0], j[1])
                    tempind = j
        if temp != (-1, -1):
            cnt += 1
            
            reds.remove(tempind)
    print(cnt)


resolve()

Solution (Python):
N = int(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(key=lambda x:x[1])
cd.sort()
c = 0
for i in range(N):
    k = -1
    for j in range(len(ab)):
        if cd[i][0] > ab[j][0] and cd[i][1] > ab[j][1]:
            k = j
    if k != -1:
        c += 1
        ab = ab[:k] + ab[k + 1:]

print(c)

Solution (Python):
N = int(input())
red = sorted([list(map(int,input().split())) for i in range(N)], key=lambda x: x[0])[::-1]
blue = [list(map(int,input().split())) for i in range(N)]
ans = 0
for i in range(N):
    min_ = 10 ** 9 + 7
    ind = -1
    for j in range(N):
        if red[i][0] <= blue[j][0] and red[i][1] <= blue[j][1] and blue[j][1] < min_:
            ind = j
            min_ = blue[j][1]
    if ind != -1:
        blue[ind][0] = -1
        ans += 1
print(ans)

Solution (Python):
N = int(input())
red = []
blue = []
for i in range(N):
    in1, in2 = list(map(int,input().split()))
    red.append([in1, in2])
for i in range(N):
    in1, in2 = list(map(int,input().split()))
    blue.append([in1, in2])
    
red = sorted(red, key=lambda x: x[0])[::-1]
ans = 0
INF = 10 ** 9 + 7
for i in range(N):
    min_ = INF
    ind = -1
    for j in range(N):
        if red[i][0] <= blue[j][0] and red[i][1] <= blue[j][1] and blue[j][1] < min_:
            ind = j
            min_ = blue[j][1]
    if ind != -1:
        blue[ind][0] = -1
        ans += 1
print(ans)

Solution (Python):
def main():
    N = int(input())
    reds = [list(map(int, input().split(' '))) for _ in range(N)]
    blues = [list(map(int, input().split(' '))) for _ in range(N)]
    blues.sort(key=lambda b: b[0])
    used_reds = [0 for _ in range(N)]
    for b in blues:
        candidates = [(i, reds[i]) for i in range(N) \
                      if used_reds[i] == 0 and reds[i][0] < b[0] and reds[i][1] < b[1]]
        if len(candidates) == 0:
            continue
        highest_index, highest_h = None, -1
        for i, r in candidates:
            if r[1] > highest_h:
                highest_h = r[1]
                highest_index = i
        used_reds[highest_index] = 1
    print(sum(used_reds))


if __name__ == '__main__':
    main()

Solution (Python):



def main():
    N = int(input())
    R = [list(map(int,input().split())) for i in range(N)]
    B = [list(map(int,input().split())) for i in range(N)]
    R.sort(key=lambda x:x[1])
    R.sort()
    B.sort(key=lambda x:x[1])
    B.sort()
    ret = 0
    for b in B:
        pairfg = False
        pair = [1000, -1000]
        for r in R:
            if r[0] < b[0] and r[1] < b[1]:
                if r[1]>pair[1]:
                    pairfg = True
                    pair = r
        if pairfg:
            ret += 1

            R.remove(pair)
    print(ret)

if __name__ == '__main__':
    main()

Solution (Python):


import sys








from collections import deque                





















def main():
    mod = 1000000007                
    inf = float('inf')              
    
    sys.setrecursionlimit(10**6)    
    def input(): return sys.stdin.readline().rstrip()
    def ii():    return int(input())
    def mi():    return map(int, input().split())
    def mi_0():  return map(lambda x: int(x)-1, input().split())
    def lmi():   return list(map(int, input().split()))
    def lmi_0(): return list(map(lambda x: int(x)-1, input().split()))
    def li():    return list(input())


    class Edge:
        def __init__(self, here, to, weight, rev_edge):
            self.here = here
            self.to = to
            self.weight = weight
            self.rev_edge = rev_edge    


    def bipartite_max_matching(adj_list):
        """
        偶数ノードと奇数ノードで二部グラフが構成されているとする
        偶数ノードから奇数ノードへ向かう辺を集めた隣接リストが渡されるので、超入口と出口を追加し、辺を接続し、逆辺も Edge クラスで張った形の隣接リストを作成。
        最大流を求めて最大マッチングを計算する
        """
        n = len(adj_list)
        adj = [[] for _ in range(n+2)]
        
        for i, elm in enumerate(adj_list):
            for j in elm:
                
                
                forward = Edge(i+1, j+1, 1, None)
                backward = Edge(j+1, i+1, 0, forward)
                forward.rev_edge = backward
                adj[i+1].append(forward)
                adj[j+1].append(backward)
        
        start_ind = 0
        for i in range(0, n, 2):
            
            forward = Edge(start_ind, i+1, 1, None)
            backward = Edge(i+1, start_ind, 0, forward)
            forward.rev_edge = backward
            adj[start_ind].append(forward)
            adj[i+1].append(backward)
        goal_ind = n + 1
        for i in range(1, n, 2):
            
            forward = Edge(i+1, goal_ind, 1, None)
            backward = Edge(goal_ind, i+1, 0, forward)
            forward.rev_edge = backward
            adj[i+1].append(forward)
            adj[goal_ind].append(backward)
        
        
        def dfs():
            path = [Edge(None, start_ind, None, None)]    
            visited = [False] * (n+2)
            visited[start_ind] = 0
            while path:
                previous_e = path[-1]
                u = previous_e.to
                visited[u] = True
                if u == goal_ind:
                    return path[1:]    
                for e in adj[u]:
                    if not visited[e.to] and e.weight > 0:
                        path.append(e)
                        break
                else:
                    path.pop()
        def update_flow(path):
            maximum_flow = float('inf')
            for e in path:
                maximum_flow = min(maximum_flow, e.weight)
            for e in path:
                e.weight -= maximum_flow    
                e.rev_edge.weight += maximum_flow    
            return maximum_flow
        
        flow = 0
        while True:
            
            
            p = dfs()
            if not p:
                return flow
            else:
                flow += update_flow(p)
                
        

    n = ii()
    red = [lmi() for _ in range(n)]  
    blue = [lmi() for _ in range(n)]  
    
    adj = [[] for _ in range(2*n)]
    for i in range(n):
        for j in range(n):
            if red[i][0] < blue[j][0] and red[i][1] < blue[j][1]:
                adj[i*2].append(j*2+1)
    
    

    
    print(bipartite_max_matching(adj))
    

    



if __name__ == "__main__":
    main()

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

RED = sorted(RED, key=lambda x: x[0], reverse=True)

count = 0
for r in RED:
    for b in sorted(BLUE, key=lambda x: x[1]):
        if r[0] <= b[0] and r[1] <= b[1]:
            BLUE.remove(b)
            count += 1
            break
    
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)]
blue.sort()
flg = [0]*N
for i in range(N):
    tmp_y = -1
    tmp_index = -1
    for k in range(N):
        if blue[i][0] > red[k][0] and flg[k] == 0:
            if tmp_y < red[k][1] and blue[i][1] > red[k][1]:
                tmp_y = red[k][1]
                tmp_index = k
    if tmp_index != -1:
        flg[tmp_index] = 1
print(flg.count(1))

Solution (Python):
def c_2d_plane_2n_points():
    N = int(input())
    R = [tuple([int(i) for i in input().split()]) for j in range(N)]
    B = [tuple([int(i) for i in input().split()]) for j in range(N)]

    red = sorted(R, key=lambda x: x[1], reverse=True)  
    blue = sorted(B)  
    ans = 0
    for x_b, y_b in blue:
        for x_r, y_r in red:
            
            
            if x_b > x_r and y_b > y_r:
                ans += 1
                red.remove((x_r, y_r))  
                break  
    return ans

print(c_2d_plane_2n_points())

Solution (Python):
n = int(input())
ab = []
cd = []
ans = 0
item = set()

for _ in range(n):
    a,b = map(int,input().split())
    ab.append((a,b))

for _ in range(n):                                                                                                               
    c,d = map(int,input().split())
    cd.append((c,d))

cd.sort()

for i in cd:
    c,d = i
    li = []
    for j in ab:
        a,b = j
        if a < c and b < d:
            li.append((a,b))
    li.sort(key=lambda x:(x[1]*(-1),x[0]))
    for k in li:
        if k not in item:
            ans += 1
            item.add(k)
            break

print(ans)

Solution (Python):
N = int(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)

Solution (Python):
def solve():
    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()
    red.sort(key=lambda x:-x[1])
    pairs = [False]*N
    for bx,by in blue:
        for i, (ax,ay) in enumerate(red):
            if pairs[i]==False and ay<by and ax<bx:
                pairs[i] = True
                break
    ans = pairs.count(True)
    return ans
print(solve())

Solution (Python):
n = int(input())
rlst = []
blst = []

for _ in range(n):
    w, h = map(int, input().split())
    rlst.append([w, h, 0])
for _ in range(n):
    w, h = map(int, input().split())
    blst.append([w, h, 0])
    
rlst = sorted(rlst, key=lambda x:(x[1],x[0]))
blst = sorted(blst, key=lambda x:(x[0],x[1]))

ans = 0
for b in blst:
    i = 0
    for r in rlst:
        if r[0] < b[0] and r[1] < b[1] and r[2] == 0:
            ridx = i
            b[2] = 1
        i += 1
    if b[2] == 1:
        ans += 1
        rlst[ridx][2] = 1
print(ans)

Solution (Python):
n = int(input())
ab = [list(map(int,input().split())) for i in range(n)]
cd = [list(map(int,input().split())) for i in range(n)]
ab = sorted(ab, key = lambda x:x[1], reverse=True)
cd = sorted(cd)
log = [0] * n
cnt = 0
for i in range(n):
    c, d = cd[i]
    for j in range(n):
        if log[j]:continue
        a, b = ab[j]
        if a < c and b < d:
            cnt += 1
            log[j] = 1
            break
print(cnt)

Solution (Python):
import sys, re
from collections import deque, defaultdict, Counter
from math import ceil, sqrt, hypot, factorial, pi, sin, cos, radians
from itertools import accumulate, permutations, combinations, product, groupby, combinations_with_replacement
from operator import itemgetter, mul
from copy import deepcopy
from string import ascii_lowercase, ascii_uppercase, digits
from bisect import bisect, bisect_left
from fractions import gcd
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 ZIP(n): return zip(*(MAP() for _ in range(n)))
sys.setrecursionlimit(10 ** 9)
INF = float('inf')
mod = 10 ** 9 + 7

from collections import deque
class HopcroftKarp:
    def __init__(self, N0, N1):
        self.N0 = N0
        self.N1 = N1
        self.N = N = 2+N0+N1
        self.G = [[] for i in range(N)]
        for i in range(N0):
            forward = [2+i, 1, None]
            forward[2] = backward = [0, 0, forward]
            self.G[0].append(forward)
            self.G[2+i].append(backward)
        self.backwards = bs = []
        for i in range(N1):
            forward = [1, 1, None]
            forward[2] = backward = [2+N0+i, 0, forward]
            bs.append(backward)
            self.G[2+N0+i].append(forward)
            self.G[1].append(backward)
    def add_edge(self, fr, to):
        
        
        v0 = 2 + fr
        v1 = 2 + self.N0 + to
        forward = [v1, 1, None]
        forward[2] = backward = [v0, 0, forward]
        self.G[v0].append(forward)
        self.G[v1].append(backward)
    def bfs(self):
        G = self.G
        level = [None]*self.N
        deq = deque([0])
        level[0] = 0
        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)
        self.level = level
        return level[1] is not None
    def dfs(self, v, t):
        if v == t:
            return 1
        level = self.level
        for e in self.it[v]:
            w, cap, rev = e
            if cap and level[v] < level[w] and self.dfs(w, t):
                e[1] = 0
                rev[1] = 1
                return 1
        return 0
    def flow(self):
        flow = 0
        G = self.G
        bfs = self.bfs; dfs = self.dfs
        while bfs():
            *self.it, = map(iter, G)
            while dfs(0, 1):
                flow += 1
        return flow
    def matching(self):
        return [cap for _, cap, _ in self.backwards]

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

for i, (a, b) in enumerate(ab):
    for j, (c, d) in enumerate(cd):
        if a < c and b < d:
            hk.add_edge(i, j)

print(hk.flow())

Solution (Python):
n=int(input())

red=[]
for _ in range(n):
  a,b=map(int,input().split())
  red.append((a,b))

blue=[]
for _ in range(n):
  c,d=map(int,input().split())
  blue.append((c,d))

blue.sort()
red.sort()
cnt=0



for item1 in blue:
  x,y=item1[0],item1[1]
  result=[]
  for item2 in red:
    xx,yy=item2[0],item2[1]
    if x>xx and y>yy:
      if result==[]:
        result=[xx,yy]
      else:
        if yy>result[1]:
          result=[xx,yy]
  if result!=[]:
    
    red.remove((result[0],result[1]))
    cnt+=1
print(cnt)

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())
r_ls = []
b_ls = []

for i in range(n):
    a, b = map(int, input().split())
    r_ls.append((a, b))

for i in range(n):
    c, d = map(int, input().split())
    b_ls.append((c, d))

edges = [set() for _ in range(n)]
matched = [-1] * n

for i in range(len(r_ls)):
    for j in range(len(b_ls)):
        if r_ls[i][0] < b_ls[j][0] and r_ls[i][1] < b_ls[j][1]:
            edges[i].add(j)

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

Solution (Python):
N = int(input())
A = []
for _ in range(N):
  x,y = list(map(int, input().split()))
  A.append((x,y))

B = []
for _ in range(N):
  x,y = list(map(int, input().split()))
  B.append((x,y))

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

for bx,by in B:
  can = None
  for i in range(len(A)):
    if A[i][0] < bx and A[i][1] < by:
      can = i
      break

  if can is not None:
    A.pop(can)
    cnt += 1

print(cnt)

Solution (Python):
import sys

sys.setrecursionlimit(10 ** 6)
INF = float("inf")
MOD = 10 ** 9 + 7


def main():
    N = int(input())
    reds = []
    for _ in range(N):
        a, b = map(int, input().split())
        reds.append((a, b))

    blues = []
    for _ in range(N):
        c, d = map(int, input().split())
        blues.append((c, d))

    reds.sort(key=lambda x: x[0])
    blues.sort(key=lambda x: x[0])
    used = [False] * N

    ans = 0
    for i in range(N):
        b = blues[i]
        max_r = -1
        max_j = None
        for j in range(N):
            r = reds[j]
            if b[0] < r[0]:
                continue
            if b[1] < r[1]:
                continue

            if not used[j] and max_r < r[1]:
                max_r = r[1]
                max_j = j

        if max_j is not None:
            used[max_j] = True
            ans += 1

    print(ans)


if __name__ == "__main__":
    main()

Solution (Python):
N = int(input())
R = []
B = []
R_tmp = []
for _ in range(N):
    a,b = map(int,input().split())
    R_tmp.append(a)
    R.append([a,b])

for _ in range(N):
    a,b = map(int,input().split())
    B.append([a,b])

B = sorted(B)
R = sorted(R)
R_tmp.sort()
from bisect import bisect_left
ans = 0
for x in B:
    index = bisect_left(R_tmp,x[0])
    tmp = R[:index]
    tmp = sorted(tmp,key=lambda x:x[1])
    for i in range(index)[::-1]:
        if tmp[i][1] < x[1]:
            R.remove([tmp[i][0],tmp[i][1]])
            R_tmp.remove(tmp[i][0])
            ans += 1
            break
print(ans)

Solution (Python):
N = int(input())
R = [list(map(int,input().split())) for i in range(N) ]
B = [list(map(int,input().split()))  for i in range(N) ]
R.sort(key=lambda x:x[1],reverse=1)
B.sort()
ans = 0
for b in B:
    for r in R:
        if b[1]>r[1] and b[0]>r[0]:
            ans += 1
            R.remove(r)
            break
print(ans)

Solution (Python):
import sys
from collections import deque
sys.setrecursionlimit(1000000) 

def main():
    input = sys.stdin.readline  
    N = int(input())
    red = []
    for _ in range(N):
        a, b = map(int, input().rstrip().split())
        red.append((a, b))
    blue = []
    for _ in range(N):
        c, d = map(int, input().rstrip().split())
        blue.append((c, d))
    red.sort(key=lambda x:x[1], reverse=True)
    blue.sort()

    count = 0
    blue = deque(blue)
    used = set()
    for b in blue:
        for i, r in enumerate(red):
            if i not in used:
                if r[0] < b[0] and r[1] < b[1]:
                    count += 1
                    used.add(i)
                    break
    print(count)

if __name__ == '__main__':
    main()

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, key=lambda x: x[1])
blue.sort()

ans = 0
for i in range(len(blue)):
    c, d = blue[i]
    for j in range(len(red)):
        a, b = red[j]
        if a < c and b < d:
            del red[j]
            ans += 1
            break
print(ans)

Solution (Python):
n = int(input())
R = [0]*n
B = [0]*n
for i in range(n): R[i] = [int(j) for j in input().split()]
for i in range(n): B[i] = [int(j) for j in input().split()]
flag = [False]*n
R.sort(key=lambda x:x[1],reverse=True)
B.sort(key=lambda x:x[0])
ans = 0
for i in range(n):
    c,d = B[i]
    for j in range(n):
        if flag[j]: continue 
        a,b = R[j]
        if c > a and d > b:
            ans += 1
            flag[j] = True
            break
print(ans)

Solution (Python):
n = int(input())
r=[list(map(int, input().split())) for i in range(n)]
b=[list(map(int, input().split())) for i in range(n)]
b.sort(key=lambda x:x[0])
p=[]
r_used=[0]*n
for i in range(n):
    q=[]
    for j in range(n):
        if r[j][0]<b[i][0] and r[j][1]<b[i][1]:
            q.append([r[j][1],j])
    q.sort(key=lambda x:x[0],reverse=True)
    p.append(q)
ans = 0
for i in range(n):
    for j in range(len(p[i])):
        if p[i][j][0]<b[i][1] and r_used[p[i][j][1]]==0:
            ans+=1
            r_used[p[i][j][1]]=1
            break
print(ans)

Solution (Python):
def main():
    n, *abcd = map(int, open(0).read().split())
    red = list(zip(abcd[0:2 * n + 1:2], abcd[1:2 * n + 1:2]))
    blue = list(zip(abcd[2 * n::2], abcd[2 * n + 1::2]))

    r = sorted(red, key=lambda p: p[1], reverse=True)
    b = sorted(blue)
    r = tuple(r)
    b = tuple(b)
    ans = 0
    done = []
    for xb, yb in b:
        for xr, yr in r:
            if xr < xb and yr < yb:
                if [xr, yr] not in done:
                    done.append([xr, yr])
                    ans += 1
                    break
    print(ans)


if __name__ == "__main__":
    main()

Solution (Python):
def main():
    n, *abcd = map(int, open(0).read().split())
    red = list(zip(abcd[0:2 * n + 1:2], abcd[1:2 * n + 1:2]))
    blue = list(zip(abcd[2 * n::2], abcd[2 * n + 1::2]))

    r = sorted(red, key=lambda p: p[1], reverse=True)
    b = sorted(blue)
    ans = 0
    done = []
    for xb, yb in b:
        for xr, yr in r:
            if xr < xb and yr < yb:
                if [xr, yr] not in done:
                    done.append([xr, yr])
                    ans += 1
                    break
    print(ans)


if __name__ == "__main__":
    main()

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)]

for i in range(N):
    AB[i] = (AB[i][0] + 1000000, AB[i][1])
    CD[i] = (CD[i][0] + 1000000, CD[i][1])

AB.sort(key = max, reverse = True)
CD.sort(key = min)



counter = 0
for a, b in AB:
    for c, d in CD:
        if a < c and b < d:
            CD.remove( (c, d) )
            counter += 1
            break

print(counter)

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 = max, reverse = True)
CD.sort(key = min)

counter = 0
for a, b in AB:
    for c, d in CD:
        if a < c and b < d:
            CD.remove( (c, d) )
            counter += 1
            break

print(counter)

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)

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)