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

from collections import defaultdict
from collections import deque
from heapq import heappush, heappop
import sys
import math
import bisect
import random
import itertools
sys.setrecursionlimit(10**5)
stdin = sys.stdin
def LI(): return list(map(int, stdin.readline().split()))
def LF(): return list(map(float, stdin.readline().split()))
def LI_(): return list(map(lambda x: int(x)-1, stdin.readline().split()))
def II(): return int(stdin.readline())
def IF(): return float(stdin.readline())
def LS(): return list(map(list, stdin.readline().split()))
def S(): return list(stdin.readline().rstrip())
def IR(n): return [II() for _ in range(n)]
def LIR(n): return [LI() for _ in range(n)]
def FR(n): return [IF() for _ in range(n)]
def LFR(n): return [LI() for _ in range(n)]
def LIR_(n): return [LI_() for _ in range(n)]
def SR(n): return [S() for _ in range(n)]
def LSR(n): return [LS() for _ in range(n)]
mod = 1000000007


def A():
    return


def B():
    return


def C():
    n = II()
    ab = LIR(n)
    cd = LIR(n)
    ab.sort()
    cd.sort()
    check = [0 for i in range(n)]
    ans = 0
    
    for i, c in enumerate(cd):
        d = c[1]
        c = c[0]
        maxy = -1
        x = -1
        for k, a in enumerate(ab):
            b = a[1]
            a = a[0]
            if maxy < b and c > a and check[k] == 0 and d > b:
                maxy = b
                x = k
                
        if x != -1:
            ans += 1
            check[x] += 1
    print(ans)


    return


def D():
    n = II()
    ab = LI()
    cd = LI()
    binab = []
    bincd = []
    warerua = [0 for i in range(28)]
    wareruc = [0 for i in range(28)]
    warenaib = [0 for i in range(28)]
    warenaid = [0 for i in range(28)]
    for i in range(n):
        ab[i] = list(bin(ab[i]))[2:]
        ab[i] = ab[i][::-1]
        cd[i] = list(bin(cd[i]))[2:]
        cd[i] = cd[i][::-1]
    for i in range(n):
        for k in range(len(ab[i])):
            
            if ab[i][k] == "1":
                warenaib[k] += 1
            else:
                warerua[k] += 1
        for k in range(len(ab[i]), 28):
            warerua[k] += 1
        for k in range(len(cd[i])):
            if cd[i][k] == "1":
                warenaid[k] += 1
            else:
                wareruc[k] += 1
        for k in range(len(ab[i]), 28):
            wareruc[k] += 1
    ans = 0
    print(warerua, warenaib, wareruc, warenaid)
    for i in range(28):
        kisu = warerua[i] * warenaid[i] + warenaib[i] * wareruc[i]
        gusu = warerua[i] * wareruc[i] + warenaib[i] * warenaid[i]
        if kisu % 2:
            ans += 1 << i
    print(ans)
    return


def E():
    return


def F():
    return


def G():
    return


def H():
    return


if __name__ == '__main__':
    C()

Solution (Python):

from collections import defaultdict
from collections import deque
from heapq import heappush, heappop
import sys
import math
import bisect
import random
import itertools
sys.setrecursionlimit(10**5)
stdin = sys.stdin
def LI(): return list(map(int, stdin.readline().split()))
def LF(): return list(map(float, stdin.readline().split()))
def LI_(): return list(map(lambda x: int(x)-1, stdin.readline().split()))
def II(): return int(stdin.readline())
def IF(): return float(stdin.readline())
def LS(): return list(map(list, stdin.readline().split()))
def S(): return list(stdin.readline().rstrip())
def IR(n): return [II() for _ in range(n)]
def LIR(n): return [LI() for _ in range(n)]
def FR(n): return [IF() for _ in range(n)]
def LFR(n): return [LI() for _ in range(n)]
def LIR_(n): return [LI_() for _ in range(n)]
def SR(n): return [S() for _ in range(n)]
def LSR(n): return [LS() for _ in range(n)]
mod = 1000000007


def A():
    return


def B():
    return


def C():
    n = II()
    ab = LIR(n)
    cd = LIR(n)
    ab.sort()
    cd.sort()
    check = [0 for i in range(n)]
    ans = 0
    
    for i, c in enumerate(cd):
        d = c[1]
        c = c[0]
        maxy = -1
        x = -1
        for k, a in enumerate(ab):
            b = a[1]
            a = a[0]
            if maxy < b and c > a and check[k] == 0 and d > b:
                maxy = b
                x = k
                
        if x != -1:
            ans += 1
            check[x] += 1
    print(ans)


    return


def D():
    n = II()
    ab = LI()
    cd = LI()
    binab = []
    bincd = []
    warerua = [0 for i in range(28)]
    wareruc = [0 for i in range(28)]
    warenaib = [0 for i in range(28)]
    warenaid = [0 for i in range(28)]
    for i in range(n):
        ab[i] = list(bin(ab[i]))[2:]
        ab[i] = ab[i][::-1]
        cd[i] = list(bin(cd[i]))[2:]
        cd[i] = cd[i][::-1]
    for i in range(n):
        for k in range(len(ab[i])):
            
            if ab[i][k] == "1":
                warenaib[k] += 1
            else:
                warerua[k] += 1
        for k in range(len(ab[i]), 28):
            warerua[k] += 1
        for k in range(len(cd[i])):
            if cd[i][k] == "1":
                warenaid[k] += 1
            else:
                wareruc[k] += 1
        for k in range(len(ab[i]), 28):
            wareruc[k] += 1
    ans = 0
    print(warerua, warenaib, wareruc, warenaid)
    for i in range(28):
        kisu = warerua[i] * warenaid[i] + warenaib[i] * wareruc[i]
        gusu = warerua[i] * wareruc[i] + warenaib[i] * warenaid[i]
        if kisu % 2:
            ans += 1 << i
    print(ans)
    return


def E():
    return


def F():
    return


def G():
    return


def H():
    return


if __name__ == '__main__':
    C()

Solution (Python):

from collections import defaultdict
from collections import deque
from heapq import heappush, heappop
import sys
import math
import bisect
import random
def LI(): return list(map(int, sys.stdin.readline().split()))
def I(): return int(sys.stdin.readline())
def LS():return list(map(list, sys.stdin.readline().split()))
def S(): return list(sys.stdin.readline())[:-1]
def IR(n):
    l = [None for i in range(n)]
    for i in range(n):l[i] = I()
    return l
def LIR(n):
    l = [None for i in range(n)]
    for i in range(n):l[i] = LI()
    return l
def SR(n):
    l = [None for i in range(n)]
    for i in range(n):l[i] = S()
    return l
def LSR(n):
    l = [None for i in range(n)]
    for i in range(n):l[i] = SR()
    return l
mod = 1000000007


def A():
    return


def B():
    return


def C():
    def bfs(a,b):
        bfs_map = [-1 for i in range(2*n+2)]
        q = [a]
        bfs_map[a] = 0
        while q:
            x = q.pop(0)
            for y in out[x]:
                if bfs_map[y] == -1:
                    q.append(y)
                    bfs_map[y] = bfs_map[x]+1
        if bfs_map[b] == -1:return 0
        d = bfs_map[b]
        path = [b]
        y = b
        while d > 0:
            for x in ent[y]:
                if bfs_map[x] == d-1:
                    path.insert(0,x)
                    y = x
                    d -= 1
                    break
        return path

    def ford_fulkerson(a,b,c):
        ans = 0
        while 1:
            path = bfs(a,b)
            if not path:break
            for i in range(len(path)-1):
                out[path[i]].remove(path[i+1])
                ent[path[i+1]].remove(path[i])
                if not c[path[i+1]][path[i]]:
                    c[path[i+1]][path[i]] = 1
                    out[path[i+1]].append(path[i])
                    ent[path[i]].append(path[i+1])
            ans += 1
        return ans
    n = I()
    r = LIR(n)
    b = LIR(n)
    c = [[0 for i in range(2*n+2)] for i in range(2*n+2)]
    out = [[] for i in range(2*n+2)]
    ent = [[] for i in range(2*n+2)]
    for i in range(n):
        c[0][i+1] = 1
        out[0].append(i+1)
        ent[i+1].append(0)
        for j in range(n):
            if r[i][0] < b[j][0] and r[i][1] < b[j][1]:
                c[i+1][n+j+1] = 1
                out[i+1].append(n+j+1)
                ent[n+j+1].append(i+1)
    for j in range(n):
        c[n+j+1][2*n+1] = 1
        out[n+j+1].append(2*n+1)
        ent[2*n+1].append(n+j+1)
    print(ford_fulkerson(0,2*n+1,c))

def D():
    n = I()
    a = LI()
    b = LI()
    s = 0
    for i in range(n):
        s ^= b[i]
    ans = 0
    print(s)
    for i in range(n):
        s ^= a[i]
    print(s)


def E():
    return


def F():
    return


def G():
    return


def H():
    return


if __name__ == "__main__":
    C()

Solution (Python):
from sys import stderr
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], reverse=True)
blue.sort()
print(red,file=stderr)
print(blue,file=stderr)

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)

Solution (Python):
from operator import itemgetter

N = int(input())

ab = [[int(j) for j in input().split()] for i in range(N)]

cd = [[int(j) for j in input().split()] for i in range(N)]


def main():
    
    ab.sort(key=itemgetter(1), reverse=True)

    
    cd.sort(key=itemgetter(0))

    
    done = [False] * N

    ans = 0

    for blue in cd:
        i = 0

        for red in ab:
            if not done[i] and red[0] < blue[0] and red[1] < blue[1]:
                done[i] = True
                ans += 1
                break

            i += 1

    print(ans)
    return


main()

Solution (Python):
from sys import stdin
from operator import itemgetter

input = stdin.readline

N = int(input())

ab = [[int(j) for j in input().split()] for i in range(N)]

cd = [[int(j) for j in input().split()] for i in range(N)]


def main():
    
    ab.sort(key=itemgetter(1), reverse=True)

    
    cd.sort(key=itemgetter(0))

    
    done = [False] * N

    ans = 0

    for blue in cd:
        i = 0

        for red in ab:
            if not done[i] and red[0] < blue[0] and red[1] < blue[1]:
                done[i] = True
                ans += 1
                break

            i += 1

    print(ans)
    return


main()

Solution (Python):
from sys import stdin
from operator import itemgetter

input = stdin.readline

N = int(input())

ab = [[int(j) for j in input().split()] for i in range(N)]

cd = [[int(j) for j in input().split()] for i in range(N)]


def main():
    
    ab.sort(key=itemgetter(1), reverse=True)

    
    cd.sort(key=itemgetter(0))

    
    done = [False] * N

    ans = 0

    for i in range(N):
        for j in range(N):
            if not done[j] and ab[j][0] < cd[i][0] and ab[j][1] < cd[i][1]:
                done[j] = True
                ans += 1
                break

    print(ans)
    return


main()

Solution (Python):
import sys
input=sys.stdin.readline
sys.setrecursionlimit(10**9)

class FordFulkerson:
    def __init__(self,n):
        self.visited=[False]*n
        self.G=[[0]*n for _ in range(n)]
        self.n=n
    def add_edge(self,fr,to,cap):
        self.G[fr][to]=cap
    def dfs(self,start,goal,f):
        if start==goal:
            return f
        self.visited[start]=True
        for i in range(self.n):
            if i==start:
                continue
            if (not self.visited[i]) and self.G[start][i]>0:
                d=self.dfs(i,goal,min(f,self.G[start][i]))
                if d>0:
                    self.G[start][i]-=d
                    self.G[i][start]+=d
                    return d
        return 0
    def maxflow(self,source,sink):
        flow=0
        while True:
            self.visited=[False]*self.n
            f=self.dfs(source,sink,float('inf'))
            if f==0:
                break
            flow+=f
        return flow

def BipartiteMatching(Pairs,a,b):
    solver=FordFulkerson(a+b+2)
    for x,y in Pairs:
        solver.add_edge(x+1,a+y+1,1)
    for x in range(a):
        solver.add_edge(0,x+1,1)
    for y in range(b):
        solver.add_edge(a+y+1,a+b+1,1)
    return solver.maxflow(0,a+b+1)

n=int(input())
R=[list(map(int,input().split())) for _ in range(n)]
B=[list(map(int,input().split())) for _ in range(n)]
Pairs=[]
for i in range(n):
    for j in range(n):
        if R[i][0]<B[j][0] and R[i][1]<B[j][1]:
            Pairs.append((i,j))
print(BipartiteMatching(Pairs,n,n))

Solution (Python):
import sys
input=sys.stdin.readline
sys.setrecursionlimit(10**9)
from collections import deque

class Dinic:
    def __init__(self,n,edges):
        self.n=n
        self.edges=[[] for _ in range(n)]
        self.iter=[0]*n
        self.level=None
        self.graph(edges)
    def graph(self,E):
        edges=self.edges
        for fr,to,cap in E:
            edges[fr].append([to,cap,len(edges[to])])
            edges[to].append([fr,0,len(edges[fr])-1])
    def maxflow(self,source,sink):
        max_flow=0
        while True:
            self.bfs(source)
            if self.level[sink]<0:
                return max_flow
            self.iter=[0]*self.n
            flow=self.dfs(source,sink,float('inf'))
            while flow:
                max_flow+=flow
                flow=self.dfs(source,sink,float('inf'))
    def bfs(self,source):
        edges=self.edges
        level=[-1]*self.n
        level[source]=0
        q=deque([source])
        while q:
            fr=q.popleft()
            for to,cap,_ in edges[fr]:
                if cap>0>level[to]:
                    level[to]=level[fr]+1
                    q.append(to)
        self.level=level
    def dfs(self,source,sink,flow):
        if source==sink:
            return flow
        while self.iter[source]<len(self.edges[source]):
            to,cap,rev=self.edges[source][self.iter[source]]
            if cap>0 and self.level[source]<self.level[to]:
                f=self.dfs(to,sink,min(flow,cap))
                if f:
                    self.edges[source][self.iter[source]][1]-=f
                    self.edges[to][rev][1]+=f
                    return f
            self.iter[source]+=1
        return 0

def BipartiteMatching(Pairs,a,b):
    Edges=[]
    for x,y in Pairs:
        Edges.append((x+1,a+y+1,1))
    for x in range(a):
        Edges.append((0,x+1,1))
    for y in range(b):
        Edges.append((a+y+1,a+b+1,1))
    solver=Dinic(a+b+2,Edges)
    return solver.maxflow(0,a+b+1)

n=int(input())
R=[list(map(int,input().split())) for _ in range(n)]
B=[list(map(int,input().split())) for _ in range(n)]
Pairs=[]
for i in range(n):
    for j in range(n):
        if R[i][0]<B[j][0] and R[i][1]<B[j][1]:
            Pairs.append((i,j))
print(BipartiteMatching(Pairs,n,n))

Solution (Python):
class Queue:
    def __init__(self):
        self.__count = 0
        self.__data = []

    def count(self) -> int:
        return self.__count

    def empty(self) -> bool:
        return self.__count == 0

    def front(self):
        if self.empty():
            raise Exception('empty')
        return self.__data[0]

    def dequeue(self):
        if self.empty():
            raise Exception('empty')
        res, self.__data = self.__data[0], self.__data[1:]
        self.__count -= 1
        return res

    def enqueue(self, v):
        self.__data.append(v)
        self.__count += 1


class Edge:
    def __init__(self, v: int, cap: int, rev: int):
        """
        :param v: to
        :param cap: capacity
        :param rev: revesed to
        """
        self.v = v
        self.cap = cap
        self.rev = rev

        self.flow = 0


class Graph:
    def __init__(self, num_v: int):
        """
        :param num_v: number of vertex
        """
        self.num_v = num_v
        self.level = [0] * num_v
        self.graph = [[] for _ in range(num_v)]

    def add_edge(self, u: int, v: int, cap: int):
        """add edge
        :param u: from
        :param v: to
        :param cap: capacity
        """
        forward = Edge(v, cap, len(self.graph[v]))
        back = Edge(u, 0, len(self.graph[u]))

        self.graph[u].append(forward)
        self.graph[v].append(back)

    def __bfs(self, s: int, t: int) -> bool:
        """Finds if more flow can be sent from s to t.
        Also assigns level to nodes.
        :param s: source
        :param t: sink
        :return: `True` if finds more flow can be sent from s to t.
        """
        self.level = [-1] * self.num_v
        self.level[s] = 0

        q = Queue()
        q.enqueue(s)
        while not q.empty():
            u = q.dequeue()

            for e in self.graph[u]:
                
                if self.level[e.v] < 0 and e.flow < e.cap:
                    
                    self.level[e.v] = self.level[u] + 1

                    q.enqueue(e.v)

        return self.level[t] >= 0

    def __send_flow(self,
                    u: int, flow: int, t: int, start: list = None) -> int:
        """send `flow` from `u` to `t`.
        :param u: from
        :param flow: flow
        :param t: to
        :param start: explored vertex
        :return: value of flow can be sent from u to t.
        """
        if u == t:
            return flow

        if start is None:
            start = [0] * (self.num_v + 1)

        while start[u] < len(self.graph[u]):
            e = self.graph[u][start[u]]

            if self.level[e.v] != self.level[u] + 1:
                
                
                start[u] += 1
                continue
            if not (e.flow < e.cap):
                
                
                start[u] += 1
                continue

            cur_f = min(flow, e.cap - e.flow)
            tmp_f = self.__send_flow(e.v, cur_f, t, start)

            if tmp_f > 0:
                
                e.flow += tmp_f
                
                self.graph[e.v][e.rev].flow -= tmp_f

                return tmp_f

            start[u] += 1

        return 0

    def maximum_flow(self, s: int, t: int) -> int:
        """maximum flow from s to t.
        :param s: from
        :param t: to
        :return: maximum flow
        """
        if s == t:
            return 0

        max_flow = 0
        while self.__bfs(s, t):
            while True:
                flow = self.__send_flow(s, float('inf'), t)
                if flow == 0:
                    break
                max_flow += flow
        return max_flow


def _2d_plane_2n_points(N: int, reds: list, blues: list) -> int:
    reds = sorted(reds, key=lambda x: x[0])
    blues = sorted(blues, key=lambda x: x[0])

    
    g = Graph(2*N + 2)
    s, t = 0, 2*N+1

    def blue_idx(i): return i + 1
    def red_idx(i): return N + i + 1

    
    
    for i in range(N):
        b, r = blue_idx(i), red_idx(i)
        g.add_edge(s, b, 1)
        g.add_edge(r, t, 1)

    
    
    for i, (bx, by) in enumerate(blues):
        bi = blue_idx(i)

        for j, (rx, ry) in enumerate(reds):
            if not (rx < bx):
                break
            if not (ry < by):
                continue

            ri = red_idx(j)
            g.add_edge(bi, ri, 1)

    return g.maximum_flow(s, t)


if __name__ == "__main__":
    N = int(input())
    reds = [tuple(map(int, input().split())) for _ in range(N)]
    blues = [tuple(map(int, input().split())) for _ in range(N)]
    ans = _2d_plane_2n_points(N, reds, blues)
    print(ans)

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,key=lambda x:x[1])
Blue.sort()
count = 0
for B in Blue:
    for i in range(len(Red)):
        
        
        
        if (B[0] > Red[i][0]) and (B[1] > Red[i][1]) :
            
            
            count += 1
            Red[i][0] = 1000
            B[0] = -1
            continue
        
print(count)

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

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

Solution (Python):
def ans():
  N = int(input())
  AB = sorted([list(map(int,input().split())) for _ in range(N)], key = lambda x: -x[1])
  CD = sorted([list(map(int,input().split())) for _ in range(N)])
  cnt = 0
  for c, d in CD:
    for a, b in AB:
      if(a < c and b < d):
        cnt += 1
        AB.remove([a,b])
        break
  print(cnt)
ans()

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)]
blue.sort(key=lambda x:x[0])
red.sort(key=lambda x:x[1], reverse=True)
pairs = 0
flag = [True for i in range(N)]
for i in range(N):
    for j in range(N):
        if blue[i][0] > red[j][0] and blue[i][1] > red[j][1] and flag[j]:
            pairs += 1
            flag[j] = False
            break
print(pairs)

Solution (Python):

def DFS(L, s, t):
  S = [[s, 0]]
  P = [0] * T
  D = [0] * len(L)
  while S != []:
    k = S.pop()
    P[k[1]] = k[0]
    if L[k[0]][T - 1] > 0:
      P[k[1] + 1] = T - 1
      return P
    for i in range(len(L)):
      if D[i] == 0 and L[k[0]][i] > 0:
        S.append([i, k[1] + 1])
        D[i] = 1
  return False  

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

T = 2 * N + 2
L = [[0] * T for i in range(T)]






ab.sort()
cd.sort()
cnt = 0


for i in range(0, N):
  L[0][i + 1] = 1
  L[N + 1 + i][T - 1] = 1
  for j in range(cnt, N):
    if ab[i][0] > cd[j][0]:
      cnt += 1
      continue
    if ab[i][1] < cd[j][1]:
      L[i + 1][N + 1 + j] = 1

while True:
  
  
  P = DFS(L, 0, T - 1)
  if P == False:
    break
  
  mi = 10 ** 20
  Last = T
  for i in range(1, Last):
    t = L[P[i - 1]][P[i]]
    if t < mi:
      mi = t
    if P[i] == T - 1:
      Last = i + 1
      break
  
  for i in range(1, Last):
    L[P[i - 1]][P[i]] -= 1
    L[P[i]][P[i - 1]] += 1

print(sum(L[-1]))

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(reverse = True)
cd.sort(reverse = True)

cd += [[1000, 1000]]

L = [0] * N
Ans = 0
for i in range(N):
  t = ab[i]
  mi = N
  for j in range(N):
    k = cd[j]
    if t[0] > k[0]:
      break
    if L[j] == 1: continue
    if t[1] > k[1]: continue
    if cd[mi][1] > k[1]:
      mi = j
  if mi != N:
    L[mi] = 1
    Ans += 1
      
print(Ans)

Solution (Python):

N = int(input())
red_ls = list()
blue_ls = list()
for i in range(N):
    red_ls.append([int(i) for i in input().split()])
for i in range(N):
    blue_ls.append([int(i) for i in input().split()])


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

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

cnt = 0
pre_ind = -1
yet_ls = list()
for (blue_x, blue_y) in blue_ls:
    flg = 0
    for ind, (red_x, red_y) in enumerate(red_ls):
        if red_y >= blue_y:
            continue
        if red_x >= blue_x:
            continue
        if ind in yet_ls:
            continue
        cnt += 1
        yet_ls.append(ind)
        break
print(cnt)

Solution (Python):
n=int(input())
a=[list(map(int,input().split()))for i in range(n)]
b=[list(map(int,input().split()))for i in range(n)]
b.sort()
a=sorted(a,key=lambda x:-x[1])
d=0
for i in range(n):
    for j in range(len(a)):
        if b[i][0]>a[j][0] and b[i][1]>a[j][1]:
            d+=1
            del a[j]
            break
print(d)

Solution (Python):
import heapq


def main():
    N = int(input())
    R = [list(map(int, input().split())) + ['R'] for _ in range(N)]
    B = [list(map(int, input().split())) + ['B'] for _ in range(N)]
    P = R + B
    P.sort(key=lambda x: (x[0], x[1]))
    solo = []
    ans = 0
    for p in P:
        x, y, c = p
        if c == 'R':
            solo.append((x, y))
        else:
            tmp = (-1, -1)
            for s in solo:
                if s[0] < x and tmp[1] < s[1] < y:
                    tmp = s
            if tmp != (-1, -1):
                solo.remove(tmp)
                ans += 1
    print(ans)


if __name__ == "__main__":
    main()

Solution (Python):
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()
r = sorted(r,key=lambda x:-x[1])
ans = 0
for i,b_ in enumerate(b):
    for j,r_ in enumerate(r):
        if b_[0]>r_[0] and b_[1]>r_[1]:
            ans+=1
            del r[j]
            break

print(ans)

Solution (Python):
import sys

def main():
    input = sys.stdin.readline
    N = int(input())
    R = []
    for _ in range(N):
        a, b = map(int, input().split())
        R.append([a, b])
    B = []
    for _ in range(N):
        c, d =  map(int, input().split())
        B.append([c, d])
    R = sorted(R, key=lambda x: x[0])
    B = sorted(B, key=lambda x: x[0])

    ans = 0
    used = []
    for i in range(N):
        x, y = -1, -1
        j = 0
        while j < N and R[j][0] < B[i][0]:
            s, t = R[j][0], R[j][1]
            if t < B[i][1] and t > y and s not in set(used):
                x = s
                y = t
            j += 1
                
        if x >= 0:
            used.append(x)
    print(len(used))


if __name__ == '__main__':
    main()

Solution (Python):


"""
参考：https://www.hamayanhamayan.com/entry/2018/03/18/085108
　　　http://vartkw.hatenablog.com/entry/2016/12/02/002703
　　　https://ikatakos.com/pot/programming_algorithm/graph_theory/maximum_flow
・二部最大マッチング
・最大流アルゴリズム(Dinic法)
・まだ理解不十分な点はあると思うけど、初めて見た時よりは見慣れた。
"""

from collections import deque

class BipartiteMatching:

	def __init__(self, n, m):
		self.n = n
		self.m = m
		
		self.E = [[] * (n+m+2) for i in range(n+m+2)]
		
		self.match = [0] * (n+m+2)
		
		self.dist = [0] * (n+m+2)
	
	def bfs(self):
		que = deque()
		for i in range(1, self.n+1):
			
			if not self.match[i]:
				self.dist[i] = 0
				que.append(i)
			else:
				self.dist[i] = float('inf')
		self.dist[0] = float('inf')
		while len(que) != 0:
			u = que.popleft()
			if u != 0:
				for v in self.E[u]:
					if self.dist[self.match[v]] == float('inf'):
						self.dist[self.match[v]] = self.dist[u] + 1
						
						que.append(self.match[v])
		
		return self.dist[0] != float('inf')

	def dfs(self, u):
		if u != 0:
			for v in self.E[u]:
				if self.dist[self.match[v]] == self.dist[u] + 1:
					if self.dfs(self.match[v]):
						
						self.match[v] = u
						self.match[u] = v
						return True
			
			self.dist[u] = float('inf')
			return False
		return True
	
	def add(self, a, b):
		b += self.n
		self.E[a+1].append(b+1)
		self.E[b+1].append(a+1)

	def whois(self, x):
		return self.match[x+1]-1

	def solve(self):
		for i in range(self.n+self.m+1):
			self.match[i] = 0
		res = 0
		while self.bfs():
			for i in range(1, self.n+1):
				
				
				if not self.match[i] and self.dfs(i):
					res += 1
		return res

N = int(input())
aN, bN, cN, dN = [0] * N, [0] * N, [0] * N, [0] * N

for i in range(N):
	aN[i], bN[i] = map(int, input().split())

for i in range(N):
	cN[i], dN[i] = map(int, input().split())


bm = BipartiteMatching(N, N)
for i in range(N):
	for j in range(N):
		if aN[i] < cN[j] and bN[i] < dN[j]:
			
			bm.add(i, j)
print(bm.solve())

Solution (Python):
import math

N = int(input())
ab = []
cd = []

for i in range(N):
    ab.append(list(map(int,input().split())))

for i in range(N):
    cd.append(list(map(int,input().split())))

res = 0

cd.sort()

for i in range(len(cd)):
    c,d = cd[i]
    max_b = -1
    index = -1
    tmp_list = 0
    for j in range(len(ab)):
        a,b = ab[j]
        if a > c or b > d:
            continue
        
        tmp_b = b

        if max_b < b:
            max_b = tmp_b
            index = j

    if index > -1:
        ab.pop(index)
        res += 1

print(res)

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


main()

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()
blue.sort()

ret = 0
used = set()
for x, y in blue:
    koho = -1
    mostright = -1
    for i in range(len(red)):
        if i not in used:
            if red[i][0] >= x:
                break
            elif y > red[i][1] > mostright:
                koho = i
                mostright = red[i][1]
    if koho != -1:
        ret += 1
        used.add(koho)
print(ret)

Solution (Python):

n=int(input())
red=[]
blue=[]
for i in range(n):
    red.append(tuple(map(int,input().split())))
for j in range(n):
    blue.append(tuple(map(int,input().split())))
blue.sort(key=lambda x:x[0])
red.sort(key=lambda x:x[0])
ans=0
for i in range(n):
    ymax=-1
    maxidx=-1
    for j in range(len(red)):
        if red[j][0]>=blue[i][0]:break
        if ymax< red[j][1] <blue[i][1]:
            ymax=red[j][1]
            maxidx=j
    if maxidx==-1:continue
    else:
        red.pop(maxidx)
        ans+=1
print(ans)

Solution (Python):
n = int(input())
A = [list(map(int,input().split())) for i in range(n)]
B = [list(map(int,input().split())) for i in range(n)]
A.sort(reverse=1, key=lambda x:x[1])
B.sort()            



ans=0

for i in range(n):
    ma=-1
    mai=-1
    for j in range(len(A)):
        
        
        if B[i][0]>A[j][0] and B[i][1]>A[j][1] :
            if ma<A[j][1] :
                mai=j
                ma=A[j][1]
                
    if mai!=-1 :
        del A[mai]
        ans+=1
            

print(ans)