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())
ab = []
cd = []
for i in range(n):
    ai, bi = map(int, input().split())
    ab.append([ai, bi])
for i in range(n):
    ci, di = map(int, input().split())
    cd.append([ci, di])

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

count = 0
while True:
    if len(cd) == 0:
        break

    flag = 0
    for i in range(len(ab)):
        if ab[i][0] < cd[0][0] and ab[i][1] < cd[0][1]:
            flag = 1
            break

    if flag:
        ab.pop(i)
        count += 1
    cd.pop(0)

print(count)

Solution (Python):
Red  = []
Blue = []

def match_and_remove(x,y):
    maxy  = -1
    index = -1
    for i in range(len(Red)):
        rx,ry = Red[i]
        if rx < x and ry < y:
            if maxy < ry:
                maxy = ry
                index = i
    if index != -1:
        a = Red.pop(index)
        
        return True
    else:
        return False

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

Red.sort(key=lambda x:x[0])
Blue.sort(key=lambda x:x[0])

ans = 0
for blue in Blue:
    x = blue[0]
    y = blue[1]
    ret = match_and_remove(x,y) 
    if ret:
        ans += 1
print(ans)

Solution (Python):
from operator import itemgetter

N = int(input())
red = [(0,0) for i in range(N)]
blue = [(0,0) for i in range(N)]

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

for i in range(N):
  bx = blue[i][0]
  by = blue[i][1]
  R = len(red)
  for j in range(R):
    rx = red[R-j-1][1]
    ry = red[R-j-1][0]
    if rx < bx and ry < by:
      del red[R-j-1]
      break
      
print(N-len(red))

Solution (Python):
from operator import itemgetter
n=int(input())
A=[tuple(map(int,input().split())) for i in range(n)]
B=[tuple(map(int,input().split())) for j in range(n)]
A.sort()
B.sort()
count=0
for i in range(n):
    box=[A[j] for j in range(len(A)) if (A[j][0]<B[i][0]) and (A[j][1]<B[i][1])]
    
    if any(box):
        box=sorted(box, key=itemgetter(1))
        A.remove(box[-1])
        count +=1
print(count)

Solution (Python):
from operator import itemgetter
n=int(input())
A=[tuple(map(int,input().split())) for i in range(n)]
B=[tuple(map(int,input().split())) for j in range(n)]
A.sort()
B.sort()
count=0
for i in range(n):
    box=[A[j] for j in range(len(A)) if (A[j][0]<B[i][0]) and (A[j][1]<B[i][1])]
    if any(box):
        box=sorted(box, key=itemgetter(1))
        A.remove(box[-1])
        count +=1
print(count)

Solution (Python):
import sys
from functools import reduce
import copy
import math
from pprint import pprint


sys.setrecursionlimit(4100000)


def inputs(num_of_input):
    ins = [input() for i in range(num_of_input)]
    return ins


def int_inputs(num_of_input):
    ins = [int(input()) for i in range(num_of_input)]
    return ins


def solve(inputs):
    int_inputs = list(map(string_to_int, inputs))
    N = len(inputs) // 2
    reds = int_inputs[:N]
    blues = int_inputs[N:]

    reds.sort(key=lambda x: x[0])
    blues.sort(key=lambda x: x[0])

    count = 0
    for bi in range(N):
        candidates = []
        for ri in range(len(reds)):
            if blues[bi][0] > reds[ri][0] and blues[bi][1] > reds[ri][1]:
                candidates.append([ri, reds[ri][0], reds[ri][1]])
        if len(candidates) > 0:
            candidates.sort(key=lambda x: x[2])

            reds.pop(candidates[-1][0])
            count += 1

    return count


def string_to_int(string):
    return list(map(int, string.split()))


if __name__ == "__main__":
    N = int(input())
    ret = solve(inputs(N*2))
    print(ret)

Solution (Python):
n=int(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:
    bmax=-1
    acheck=-1
    for a,b in ab:
        if a<c and b<d:
            if b>=bmax:
                bmax=b
                acheck=a
    if acheck!=-1:
        ab.remove([acheck,bmax])
        ans+=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)]
red.sort(reverse=True, key=lambda x: x[1])
blue.sort()
ans = 0
for b in blue:
    for r in red:
        if r[0] < b[0] and r[1] < b[1]:        
            red.remove(r)
            ans += 1
            break
print(ans)

Solution (Python):
import sys

import queue

class Dinic:
    def __init__(self, v, inf=sys.maxsize):
        self.V = v
        self.inf = inf
        self.G = [[] for _ in range(v)]
        self.level = [0 for _ in range(v)]
        self.iter = [0 for _ in range(v)]

    def add_edge(self, from_, to, cap):
        
        self.G[from_].append({'to': to, 'cap': cap, 'rev': len(self.G[to])})
        self.G[to].append({'to': from_, 'cap': 0, 'rev': len(self.G[from_]) - 1})

    
    def bfs(self, s):
        self.level = [-1 for _ in range(self.V)]
        self.level[s] = 0
        que = queue.Queue()
        que.put(s)
        while not que.empty():
            v = que.get()
            for i in range(len(self.G[v])):
                e = self.G[v][i]
                if e['cap'] > 0 and self.level[e['to']] < 0:
                    self.level[e['to']] = self.level[v] + 1
                    que.put(e['to'])

    
    def dfs(self, v, t, f):
        if v == t:
            return f
        for i in range(self.iter[v], len(self.G[v])):
            self.iter[v] = i
            e = self.G[v][i]
            if e['cap'] > 0 and self.level[v] < self.level[e['to']]:
                d = self.dfs(e['to'], t, min(f, e['cap']))
                if d > 0:
                    e['cap'] -= d
                    self.G[e['to']][e['rev']]['cap'] += d
                    return d

        return 0

    def max_flow(self, s, t):
        flow = 0
        while True:
            self.bfs(s)
            
            if self.level[t] < 0:
                return flow
            self.iter = [0 for _ in range(self.V)]
            f = self.dfs(s, t, self.inf)
            while f > 0:
                flow += f
                f = self.dfs(s, t, self.inf)

n = int(input())
data1 = [list(map(int,input().split())) for _ in range(n)]
data2 = [list(map(int,input().split())) for _ in range(n)]
v = 2*n + 2

D = Dinic(v)
for i in range(n):
    D.add_edge(2*n,i,1)
    D.add_edge(n+i,2*n+1,1)

for i,ab in enumerate(data1):
    for j,cd in enumerate(data2):
        if ab[0]<cd[0] and ab[1]<cd[1]:
            D.add_edge(i,n+j,1)

ans = D.max_flow(2*n,2*n+1)
print(ans)

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

data_blue.sort()
data_red.sort(key=lambda x:x[1],reverse=True)

ans = 0
avail = [True for _ in range(n)]
for a,b in data_blue:
    for i,cd in enumerate(data_red):
        if avail[i] and cd[0] < a and cd[1] < b:
            ans += 1
            avail[i] = False
            
            break

print(ans)

Solution (Python):
from operator import itemgetter as get
N,*L = map(int,open(0).read().split())
L1 = L[:N*2]
L2 = L[N*2:]
R = sorted([(x,y) for x,y in zip(*[iter(L1)]*2)], key = get(1), reverse = 1)
B = sorted([(x,y) for x,y in zip(*[iter(L2)]*2)])
cnt = 0
for bx, by in B:
	for rx, ry in R:
		if rx < bx and ry < by:
			R.remove((rx,ry))
			cnt += 1
			break
print(cnt)

Solution (Python):
N = int(input())
Red = [list(map(int,input().split())) for i in range(N)]
Blue = [list(map(int,input().split())) for i in range(N)]
Red.sort(reverse=True)
Blue.sort(key=lambda x: x[1])
count = 0
for red in Red:
    for blue in Blue:
        if red[0]<blue[0] and red[1]<blue[1]:
            count += 1
            Blue.pop(Blue.index(blue))
            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)]

red.sort(key=lambda x: x[0], reverse=True)
blue.sort(key=lambda x: x[1])

paired = [0] * n
for a, b in red:
    for i, (c, d) in enumerate(blue):
        if a < c and b < d and not paired[i]:
            paired[i] = 1
            break

print(sum(paired))

Solution (Python):


n = int(input())
ab = [list(map(int, input().split())) for _ in range(n)]
cd = [list(map(int, input().split())) for _ in range(n)]

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

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

print(ans)

Solution (Python):
from bisect import bisect_left as bl
N = int(input())
R = [list(map(int, input().split())) + [0] for _ in range(N)]
B = [list(map(int, input().split())) + [1] for _ in range(N)]
P = sorted(R + B, key = lambda x: (x[0], -x[1]))
res = 0
inf = 10 ** 3
Q = []
for i in range(N * 2):
  if P[i][2] == 0:
    Q.append(P[i][1])
    Q.sort()
  elif len(Q):
    j = min(bl(Q, P[i][1]), len(Q) - 1)
    if Q[j] < P[i][1]:
      res += 1
      Q.pop(j)
    elif Q[j - 1] < P[i][1]:
      res += 1
      Q.pop(j - 1)
print(res)

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


ab = sorted(ab, reverse=True)

cd = sorted(cd, key=lambda x: x[1])

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

Solution (Python):
import bisect
n=int(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)

Solution (Python):
import sys
from pprint import pprint

n = int(sys.stdin.readline().strip())

red = []
for _ in range(n):
    a, b = map(int, sys.stdin.readline().strip().split())
    red.append((a, b))
red = sorted(red, reverse=True)


blue = []
for _ in range(n):
    c, d = map(int, sys.stdin.readline().strip().split())
    blue.append((c, d))
blue = sorted(blue)


ans = 0
used = set()
for x, y in blue:
    
    
    
    tmp_red = red[:]
    cand = []
    max_j = -1
    while tmp_red:
        i, j = tmp_red.pop()
        
        if (i, j) in used:
            continue
        if i < x and j < y:
            if j > max_j:
                max_j = j
                cand = (i, j)
        if i > x:
            break
    if cand:
        ans += 1
        used.add(cand)
        

print(ans)

Solution (Python):
import sys
from bisect import *
from collections import *
from copy import deepcopy
from heapq import *
from itertools import *
from math import *
from operator import *
from pprint import *

sys.setrecursionlimit(10**8)

input = sys.stdin.readline


def main():
    """ main """
    N = int(input())
    REDS = [tuple(map(int, input().split())) for _ in range(N)]
    BLUES = [tuple(map(int, input().split())) for _ in range(N)]
    REDS.sort(reverse=True)
    BLUES.sort(key=itemgetter(1))

    ans = 0
    for ax,ay in REDS:
        bs = [(bx,by) for bx,by in BLUES if ax < bx and ay < by]
        if 0<len(bs):
            BLUES.remove(bs[0])
            ans += 1
    print(ans)

if __name__ == '__main__':
    main()

Solution (Python):
n = int(input())
rs = [[0, 0] for _ in range(n)]
bs = [[0, 0] for _ in range(n)]

for i in range(n):
  a, b = map(int, input().split())
  rs[i][0] = a
  rs[i][1] = b

for i in range(n):
  c, d = map(int, input().split())
  bs[i][0] = c
  bs[i][1] = d








rb = [[] for _ in range(n)]
for i in range(n):
  for j in range(n):
    if rs[i][0]<bs[j][0] and rs[i][1]<bs[j][1]:
      rb[i].append(j)
rb.sort(key=lambda x: len(x))


br = [[] for _ in range(n)]
for i in range(n):
  for j in range(n):
    if rs[j][0]<bs[i][0] and rs[j][1]<bs[i][1]:
      br[i].append(j)


use = [False]*n
ans = 0
for i in range(n):
  min_br = n+1
  min_b = n+1
  for j in rb[i]:
    if use[j]:
      continue
    if len(br[j]) <= min_br:
      min_br = len(br[j])
      min_b = j
  if min_b != n+1:
    use[min_b] = True
    ans += 1

print(ans)

Solution (Python):
n = int(input())
rs = [[0, 0] for _ in range(n)]
bs = [[0, 0] for _ in range(n)]

for i in range(n):
  a, b = map(int, input().split())
  rs[i][0] = a
  rs[i][1] = b

for i in range(n):
  c, d = map(int, input().split())
  bs[i][0] = c
  bs[i][1] = d








rb = [[] for _ in range(n)]
for i in range(n):
  for j in range(n):
    if rs[i][0]<bs[j][0] and rs[i][1]<bs[j][1]:
      rb[i].append(j)
rb.sort(key=lambda x: len(x))


br = [[] for _ in range(n)]
for i in range(n):
  for j in range(n):
    if rs[j][0]<bs[i][0] and rs[j][1]<bs[i][1]:
      br[i].append(j)


use = [False]*n
ans = 0
for i in range(n):
  min_br = n+1
  min_b = n+1
  for j in rb[i]:
    if use[j]:
      continue
    if len(br[j]) <= min_br:
      min_br = len(br[j])
      min_b = j
  if min_b != n+1:
    use[min_b] = True
    ans += 1

print(ans)

Solution (Python):

def main():
    N = int(input())
    small = [tuple(map(int, input().split())) for _ in [0]*N]
    large = [tuple(map(int, input().split())) for _ in [0]*N]
    small.sort(key=lambda x: (x[0], x[1]))
    large.sort(key=lambda x: (x[0], x[1]))
    used = [0]*N
    for l in large:
        high = -1
        idx = 0
        for i, s in enumerate(small):
            if (not used[i]) and s[0] < l[0] and s[1] < l[1]:
                if high < s[1]:
                    high = s[1]
                    idx = i
        if high != -1:
            used[idx] = 1
    print(sum(used))


if __name__ == '__main__':
    main()

Solution (Python):
from collections import deque

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

class FordFulkerson :
    
    def __init__(self, N) :
        self.N = N
        self.G = [[] for _ in range(N)]
        
    def add_edge(self, fr, to, cap) :
        self.G[fr].append([to, cap, len(self.G[to])])
        self.G[to].append([fr, 0, len(self.G[fr])-1])
        
    def bfs(self, fr, to) :
        self.pre_v = [0] * self.N
        self.pre_e = [0] * self.N
        visited = [False] * self.N
        visited[fr] = True
        
        q = deque([fr])
        while q :
            cur = q.popleft()
            
            for i, (nex, cap, _) in enumerate(self.G[cur]) :
                if visited[nex] or cap <= 0 :
                    continue
                
                self.pre_v[nex], self.pre_e[nex] = cur, i
                q.append(nex)
                visited[nex] = True
                
                if nex == to :
                    return True
                    
        return False
        
    def flow(self, fr, to) :
        ret = 0
        while self.bfs(fr, to) :
            cur = to
            min_cap = float('inf')
            while cur != fr :
                min_cap = min(min_cap, self.G[self.pre_v[cur]][self.pre_e[cur]][1])
                cur = self.pre_v[cur]
                
            ret += min_cap
            cur = to
            while cur != fr :
                self.G[self.pre_v[cur]][self.pre_e[cur]][1] -= min_cap
                self.G[cur][self.G[self.pre_v[cur]][self.pre_e[cur]][2]][1] += min_cap
                cur = self.pre_v[cur]
                
        return ret
        
FF = FordFulkerson(2 * N + 2)
for i in range(N) :
    FF.add_edge(0, i + 1, 1)
    FF.add_edge(i + N + 1, 2 * N + 1, 1)
    
for i, (a, b) in enumerate(ab) :
    for j, (c, d) in enumerate(cd) :
        if a < c and b < d :
            FF.add_edge(i + 1, j + N + 1, 1)

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

Solution (Python):
from collections import defaultdict

n=int(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)

Solution (Python):
from collections import defaultdict, deque, Counter
from heapq import heappush, heappop, heapify
import math
import bisect
import random
from itertools import permutations, accumulate, combinations
import sys
import string
from bisect import bisect_left, bisect_right
from math import factorial, ceil, floor
from functools import reduce



INF = float('inf')
def LI(): return list(map(int, sys.stdin.readline().split()))
def I(): return int(sys.stdin.readline())
def LS(): return sys.stdin.readline().split()
def S(): return sys.stdin.readline().strip()
def IR(n): return [I() for i in range(n)]
def LIR(n): return [LI() for i in range(n)]
def SR(n): return [S() for i in range(n)]
def LSR(n): return [LS() for i in range(n)]
def SRL(n): return [list(S()) for i in range(n)]
def MSRL(n): return [[int(j) for j in list(S())] for i in range(n)]
mod = 1000000007


n = I()
red = sorted(LIR(n), key=lambda x:x[1], reverse=True)
blue = sorted(LIR(n))
red_used = [0] * n
for i in range(n):
    blue_x, blue_y = blue[i]
    for j in range(n):
        red_x, red_y = red[j]
        if red_x < blue_x and red_y < blue_y and not red_used[j]:
            red_used[j] = 1
            break


print(sum(red_used))

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

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

    B.sort(key=lambda x:x[0]) 
    ans = 0
    while B:
        Bm = []
        for b in B:
            if b[0] == B[0][0]:
                Bm.append(b)
        Bm.sort(key=lambda x:x[1]) 

        while Bm:
            b = Bm[0] 
            cr = []
            for r in R:
                if r[0]<=b[0] and r[1]<=b[1]:
                    cr.append(r) 
            if cr:
                cr.sort(key=lambda x:x[1]) 
                R.remove(cr[-1])
                ans += 1
            Bm.remove(b)
            B.remove(b)

    print(ans)

if __name__ == '__main__':
    main()

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

def main():
    N=int(input())
    R=[]
    for _ in range(N):
        R.append(list(map(int, input().split())))
    B=[]
    for _ in range(N):
        B.append(list(map(int, input().split())))
    B.sort(key=lambda x:x[0]) 
    ans = 0
    while B:
        b = B[0] 
        cr = []
        for r in R:
            if r[0]<=b[0] and r[1]<=b[1]:
                cr.append(r) 
        if cr:
            cr.sort(key=lambda x:x[1]) 
            R.remove(cr[-1])
            ans += 1
        B.remove(b)

    print(ans)

if __name__ == '__main__':
    main()

Solution (Python):
N = int(input())
ABs = []
for i in range(N):
  a, b = map(int, input().split())
  ABs.append((a, b))
CDs = []
for i in range(N):
  c, d = map(int, input().split())
  CDs.append((c, d))
ABs.sort()
CDs.sort()
r = 0
s = set()
for c, d in CDs:
  ma, mb = -1, -1
  for a, b in ABs:
    if a < c and b < d and b > mb and (a, b) not in s:
      ma, mb = a, b
  if not ma < 0:
    r += 1
    s.add((ma, mb))
    
print(r)

Solution (Python):
n = int(input())
points = []
for _ in range(n):
    a, b = map(int, input().split())
    points.append((a, b, 'red'))
for _ in range(n):
    c, d = map(int, input().split())
    points.append((c, d, 'blue'))
points.sort()

used = set()
for i in range(len(points)):
    x1, y1, color1 = points[i]
    if color1 == 'red':
        continue
    
    y = -1
    k = -1
    for j in range(0, i):
        x2, y2, color2 = points[j]
        if color2 == 'red' and not j in used and y2 < y1 and abs(y2 - y1) < abs(y - y1):
            y = y2
            k = j
    
    if k != -1:
        used.add(k)

print(len(used))

Solution (Python):
N = int(input())
ab = sorted([list(map(int,input().split())) for _ in range(N)],key=lambda x:x[1], reverse=True)
cd = sorted([list(map(int,input().split())) for _ in range(N)])
cnt = 0
for a, b in ab:
  for c, d in cd:
    if a<c and b<d:
      cd.remove([c,d])
      cnt+=1
      break

print(cnt)

Solution (Python):
n = int(input())
ls0 = [list(map(int, input().split())) for _ in range(n)]
ls1 = [list(map(int, input().split())) for _ in range(n)]
ls0.sort(key=lambda x: x[0], reverse=True)
count = 0
for x0, y0 in ls0:
    val = float('inf')
    index = -1
    for i, (x1, y1) in enumerate(ls1):
        if x0 <= x1:
            if y0 <= y1 < val:
                index = i
                val = y1
    if index >= 0:
        count += 1
        ls1.remove(ls1[index])
print(count)

Solution (Python):
from collections import defaultdict
from heapq import heappush, heappop

n = int(input())
red = [list(map(int, input().split())) for i in range(n)]
blue = [list(map(int, input().split())) for i in range(n)]
blue.sort()


red_flag = [0] * n
ans = 0
for i in range(n):
    idx = -1
    for j in range(n):
        if red[j][0] >= blue[i][0] or red[j][1] >= blue[i][1] or red_flag[j] == 1:
            continue
        if idx == -1 or red[idx][1] < red[j][1]:
            idx = j

    if idx >= 0:
        red_flag[idx] = 1
        ans += 1

print(ans)

Solution (Python):
from operator import itemgetter

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(key=itemgetter(0), reverse=True)
checked = [False for _ in range(N)]

c = 0
for rx, ry in Red:
    P = []
    for i, (bx, by) in enumerate(Blue):
        if bx > rx and by > ry and not checked[i]:
            P.append((i, by))
    if P:
        P.sort(key=itemgetter(1))
        ip, _ = P[0]
        checked[ip] = True
        c += 1

print(c)

Solution (Python):
import queue

class Dinic:
    """Implementation of Dinic's Alogorithm"""

    def __init__(self, v, inf = 1000000007):
        self.V = v
        self.inf = inf
        self.G = [[] for _ in range(v)]
        self.level = [0 for _ in range(v)]
        self.iter = [0 for _ in range(v)]

    def add_edge(self, from_, to, cap):
        
        self.G[from_].append({'to':to, 'cap':cap, 'rev':len(self.G[to])})
        self.G[to].append({'to':from_, 'cap':0, 'rev':len(self.G[from_])-1})

    
    def bfs(self, s):
        self.level = [-1 for _ in range(self.V)]
        self.level[s] = 0;
        que = queue.Queue()
        que.put(s)
        while not que.empty():
            v = que.get()
            for i in range(len(self.G[v])):
                e = self.G[v][i]
                if e['cap'] > 0 and self.level[e['to']] < 0:
                    self.level[e['to']] = self.level[v] + 1
                    que.put(e['to'])

    
    def dfs(self, v, t, f):
        if v == t: return f
        for i in range(self.iter[v], len(self.G[v])):
            self.iter[v] = i
            e = self.G[v][i]
            if e['cap'] > 0 and self.level[v] < self.level[e['to']]:
                d = self.dfs(e['to'], t, min(f, e['cap']))
                if d > 0:
                    e['cap'] -= d
                    self.G[e['to']][e['rev']]['cap'] += d
                    return d

        return 0

    def max_flow(self, s, t):
        flow = 0
        while True:
            self.bfs(s)
            
            if self.level[t] < 0 : return flow
            self.iter = [0 for _ in range(self.V)]
            f = self.dfs(s, t, self.inf)
            while f > 0:
                flow += f
                f = self.dfs(s,t, self.inf)
                
N = int(input())
red = [list(map(int,input().split())) for i in range(N)]
blue = [list(map(int,input().split())) for i in range(N)]


red = sorted(red, key = lambda a: a[1])
red = sorted(red, key = lambda a: a[0])
blue = sorted(blue, key = lambda a: a[1])
blue = sorted(blue, key = lambda a: a[0])

btor = [[] for i in range(N)]

for i in range(N):
    by,bx = blue[i]
    for j in range(N):
        ry,rx = red[j]
        if ry < by and rx < bx:
            btor[i].append(j)

A = Dinic(2*N+2)

for i in range(N):
    A.add_edge(0,i+1,1)
    A.add_edge(N+i+1,2*N+1,1)

for i in range(N):
    for j in btor[i]:
        A.add_edge(i+1, N+1+j,1)
        
ans = A.max_flow(0,2*N+1)
            
print(ans)

Solution (Python):
n = int(input())
aka = []
ao = []
for _ in range(n):
    ab = list(map(int, input().split()))
    aka.append(ab)
aka = sorted(aka, key=lambda x:x[1], reverse=True)
for _ in range(n):
    cd = list(map(int, input().split()))
    ao.append(cd)
ao = sorted(ao)
count = 0
for a, b in aka:
    for c, d in ao:
        if a<c and b<d:
            ao.remove([c,d])
            count+=1
            break
print(count)

Solution (Python):
n=int(input())
Rb=sorted([list(map(int,input().split())) for _ in range(n)],key=lambda x:x[1],reverse=True)
Bc=sorted([list(map(int,input().split())) for _ in range(n)])

cnt=0
for c,d in Bc:
  for a,b in Rb:
      if a<c and b<d:
          Rb.remove([a,b])
          cnt+=1
          break
print(cnt)

Solution (Python):


N = int(input().split()[0])
r_list = []
b_list = []

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

blue_dict = {}

for _ in range(N):
    c, d = list(map(int, input().split()))
    b_list.append((c, d))
    blue_dict[(c, d)] = []
    for ab in r_list:
        a, b = ab
        if a < c and b < d:
            blue_dict[(c, d)] += [(a, b)]

    if blue_dict[(c, d)]:
        
        blue_dict[(c, d)] = sorted(blue_dict[(c, d)], key=lambda x: x[0], reverse=True)


b_list = sorted(b_list, key=lambda x: x[1])
pair_list = []

for b in b_list:
    kouho_r_list = blue_dict[b]
    if kouho_r_list:
        r = kouho_r_list[0]
        pair_list.append((r, a))

        for k, v in blue_dict.items():
            if r in v:
                v.remove(r)

ans = len(pair_list)
print(ans)

Solution (Python):


N = int(input().split()[0])
r_list = []
b_list = []

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

blue_dict = {}

for _ in range(N):
    c, d = list(map(int, input().split()))
    b_list.append((c, d))
    blue_dict[(c, d)] = []
    for ab in r_list:
        a, b = ab
        if a < c and b < d:
            blue_dict[(c, d)] += [(a, b)]

b_list = sorted(b_list, key=lambda x: x[1])
pair_list = []

for b in b_list:
    
    kouho_r_list = blue_dict[b]
    if kouho_r_list:
        kouho_r_list = sorted(kouho_r_list, key=lambda x: x[0], reverse=True)
        r = kouho_r_list[0]
        pair_list.append((r, a))

        for k, v in blue_dict.items():
            if r in v:
                v.remove(r)

ans = len(pair_list)
print(ans)

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

blue.sort()

found=[0]*n
for bx, by in blue:
    y=-1
    pair=-1

    for i,r in enumerate(red):
        rx, ry=r
        if found[i]:
            continue
        if bx>rx and by>ry:
            if ry>y:
                pair=i
                y=ry

    if pair!=-1:
        found[pair]=1

print(sum(found))

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

red.sort(reverse=True)
blue.sort()

found=[0]*n
for bx, by in blue:
    y=-1
    pair=-1

    for i,r in enumerate(red):
        rx, ry=r
        if found[i]:
            continue
        if bx>rx and by>ry:
            if ry>y:
                pair=i
                y=ry

    if pair!=-1:
        found[pair]=1

print(sum(found))

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

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

cnt=0

for a,b in ab:
    flag=False
    for c,d in cd:
        if a<c and b<d:
            cnt+=1
            flag=True
            break
    if flag==True:
        cd.remove((c,d))
print(cnt)

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

red = []
blue = []

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

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

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

for b in blue:
	max_red_y = -1
	paired = (-1, -1)

	for r in red:
		
		if r[0] > b[0]:
			break
		
		
		
		if max_red_y < r[1] < b[1]:
			max_red_y = r[1]
			paired = r
	
	
	
	if paired != (-1, -1):
		red.remove(paired)
		count += 1

print(count)

Solution (Python):

N = int(input())
Red, Blue = [], []
for n in range(N):
  Red.append([int(ab) for ab in input().split()])
Red.sort(key=lambda x: x[1], reverse=True)
for n in range(N):
  Blue.append([int(cd) for cd in input().split()])
Blue.sort(key=lambda x: x[0])

pairs = 0
for B in Blue:
  c, d = B
  for R in Red:
    a, b = R
    if a < c and b < d:
      pairs += 1
      Red.remove(R)
      break

print(pairs)

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

AB.sort(reverse=True)
CD.sort()

res = 0
for a,b in AB:
    tmp = -1
    for i in range(N):
        if CD[i] != -1:
            c,d = CD[i]
            if a < c and b < d:
                if tmp == -1:
                    tmp = i
                else:
                    if CD[tmp][1] > CD[i][1]:
                        tmp = i
    if tmp != -1:
        CD[tmp] = -1
        res += 1
print(res)