Harryxun/sft_time huggingface dataset:
### BUGGY CODE ###

#!/usr/bin/env python3
import sys


def solve(H: int, N: int, A: "List[int]", B: "List[int]"):
    mp = [0] * (H + 1)
    for i in range(1, len(mp)):
        ml = [0 for j in range(N)]
        for j in range(N):
            if i - A[j] < 0:
                ml[j] = mp[0] + B[j]
            else:
                ml[j] = mp[i - A[j]] + B[j]
        mp[i] = min(ml)
    print(mp[-1])   


# Generated by 1.1.6 https://github.com/kyuridenamida/atcoder-tools  (tips: You use the default template now. You can remove this line by using your custom template)
def main():
    def iterate_tokens():
        for line in sys.stdin:
            for word in line.split():
                yield word
    tokens = iterate_tokens()
    H = int(next(tokens))  # type: int
    N = int(next(tokens))  # type: int
    A = [int()] * (N)  # type: "List[int]"
    B = [int()] * (N)  # type: "List[int]"
    for i in range(N):
        A[i] = int(next(tokens))
        B[i] = int(next(tokens))
    solve(H, N, A, B)

if __name__ == '__main__':
    main()


### FIXED CODE ###

#!/usr/bin/env python3
import sys


def solve(H: int, N: int, A: "List[int]", B: "List[int]"):
    mp = [0] * (H + 1)
    for i in range(1, len(mp)):
        ml = [0 for j in range(N)]
        for j in range(N):
            if i - A[j] < 0:
                ml[j] = mp[0] + B[j]
            else:
                ml[j] = mp[i - A[j]] + B[j]
        mp[i] = min(ml)
    print(mp[-1])   


# Generated by 1.1.6 https://github.com/kyuridenamida/atcoder-tools  (tips: You use the default template now. You can remove this line by using your custom template)
def main():
    def iterate_tokens():
        for line in sys.stdin:
            for word in line.split():
                yield word
    tokens = iterate_tokens()
    H = int(next(tokens))  # type: int
    N = int(next(tokens))  # type: int
    A = [int()] * (N)  # type: "List[int]"
    B = [int()] * (N)  # type: "List[int]"
    for i in range(N):
        A[i] = int(next(tokens))
        B[i] = int(next(tokens))
    solve(H, N, A, B)

if __name__ == '__main__':
    main()
### BUGGY CODE ###

import fractions

def gcd_array(x):
    value = x[0]
    for i in range(1, len(x)):
        value = fractions.gcd(value, x[i])
    return value

def lcm(a, b):
    return a * b // fractions.gcd(a, b)

def lcm_array(x):
    value = x[0]
    for i in range(1, len(x)):
        value = lcm(value, x[i])
    return value 

def read():
    N = int(input().strip())
    A = list(map(int, input().strip().split()))
    return N, A

def solve(N, A, MOD=1000000007):
    lcmv = lcm_array(A)
    bsum = 0
    for i in range(N):
        bsum += (lcmv // A[i])
        bsum %= MOD
    return bsum


if __name__ == '__main__':
    inputs = read()
    print("%s" % solve(*inputs))


### FIXED CODE ###

import fractions

def modinv(a, MOD=1000000007):
    b = MOD
    u = 1
    v = 0
    while b > 0:
        t = a // b
        a -= (t * b)
        tmp = a
        a = b
        b = tmp
        u -= (t * v)
        tmp = u
        u = v
        v = tmp
    u %= MOD
    if u < 0:
        u += MOD
    return u
            

def lcm(a, b, MOD=1000000007):
    return a * b // fractions.gcd(a, b)

def lcm_array(x):
    value = x[0]
    for i in range(1, len(x)):
        value = lcm(value, x[i])
    return value 

def read():
    N = int(input().strip())
    A = list(map(int, input().strip().split()))
    return N, A

def solve(N, A, MOD=1000000007):
    lcmv = lcm_array(A)
    bsum = 0
    for i in range(N):
        bsum += (lcmv * modinv(A[i]) % MOD)
        bsum %= MOD
    return bsum

if __name__ == '__main__':
    inputs = read()
    print("%s" % solve(*inputs))
### BUGGY CODE ###

s=int(input())
mod=10**9+7


dp=[[0]*(s+1) for _ in range(s)]

for i in range(3,s+1):
    dp[0][i]=1

ans=0
ans+=dp[0][s]

for keta in range(1,s//3+1):
    #print("keta",keta)
    for ss in range(3*keta,s-2):
        for k in range(3,s+1):
            if ss+k<=s:
                dp[keta][ss+k]+=dp[keta-1][ss]%mod
            else:
                break

    ans+=dp[keta][s]%mod

#print(dp)
    

print(ans%mod)






### FIXED CODE ###

s=int(input())
mod=10**9+7

if s<3:
    print(0)
    exit()

dp=[1]*(s+1)

dp[0]=0
dp[1]=0
dp[2]=0

#print(dp)
for i in range(3,s+1):
    for j in range(3,s-i+1):
        dp[i+j]+=dp[i]%mod
    #print(i,dp)
print(dp[s]%mod)
### BUGGY CODE ###

a,b,x=map(int,input().split())
ans=0
for i in range(a,b+1):
    if i%x==0:
        ans +=1
print(ans)

### FIXED CODE ###

a,b,x = map(int,input().split())
p = a//x
q = b//x
if a%x == 0:
    print(q-p+1)
else:
    print(q-p)
### BUGGY CODE ###

n,k=map(int,input().split())
c=[[]for i in range(n+1)]
d=[False]*(n+1)
d[0]=True
m=10**9+7
for i in range(n-1):
    a,b=map(int,input().split())
    c[a].append(b)
    c[b].append(a)
p=k
t=0
pq=[1]
def fom(a,b):
    r=1
    for i in range(b):
        r=r*(a-i)%m
    return r
while d!=[True]*(n+1):
    rom=[]
    if t==0 or t==1:
        t+=1
    for i in pq:
        d[i]=True
        q=0
        for j in c[i]:
            if d[j]==False:
                rom.append(j)
                q+=1
        else:
            if k-t>=q:
                p=(p*fom(k-t,q))%m
            else:
                p*=0
    else:
        pq=rom[:]
print(p)

### FIXED CODE ###

n,k=map(int,input().split())
s=[[]for i in range(n+1)]
for i in range(n-1):
    a,b=map(int,input().split())
    s[a].append(b)
    s[b].append(a)
d=[False]*(n+1)
q=[[0,1]]
c=0
a=k
while q:
    t=[]
    c=0
    for i,j in q:
        c=0
        for p in s[j]:
            if p!=i:
                t.append([j,p])
                c+=1
        r=(k-1 if j==1 else k-2)
        for h in range(r,r-c,-1):
            a=(a*h)%(10**9+7)
    q=t
print(a)
### BUGGY CODE ###

import itertools
n,c=map(int,input().split())
d=[list(map(int,input().split()))for i in range(c)]
s=[i for i in range(c)]
p=list(itertools.permutations(s))
h=[list(map(int,input().split()))for i in range(n)]
a=[[]for i in range(3)]
for i in range(n):
    for j in range(n):
        a[(i+j+2)%3].append(h[i][j])
c=float("inf")
for x in range(len(p)):
    g=0
    for i in range(3):
        for j in range(len(a[i])):
            g+=d[a[i][j]-1][p[x][i]]
    c=min(c,g)
print(c)

### FIXED CODE ###

from collections import defaultdict
n,c=map(int,input().split())
x=[list(map(int,input().split()))for i in range(c)]
e=[[0]*c for i in range(3)]
for i in range(n):
    a=list(map(int,input().split()))
    for j in range(n):
        e[(i+j+2)%3][a[j]-1]+=1
p=float("inf")
for i in range(c):
    for j in range(c):
            if i!=j:
                for h in range(c):
                    if i!=h and j!=h:
                        p=min(p,sum([x[s][i]*d for s,d in enumerate(e[0])]+[x[s][j]*d for s,d in enumerate(e[1])]+[x[s][h]*d for s,d in enumerate(e[2])]))
print(p)
### BUGGY CODE ###

import fractions
import itertools

k=int(input())
tot=0
for l,m,n in itertools.product(range(1,k+1),range(1,k+1),range(1,k+1)):
    ans=fractions.gcd(m,l%m)
    ans=fractions.gcd(ans,n)
    tot+=ans
print(tot)

### FIXED CODE ###

import math
k= int(input())
tot= 0
for i in range(1, k+1):
    for j in range(1, k+1):
        m = math.gcd(i,j)
        for n in range(1, k+1):
            l = math.gcd(m,n)
            tot += l
print(tot)
### BUGGY CODE ###

import itertools, fractions
A, B = map(int, input().split())
cd_list = []
if A >= B:
    for n in range(1, B+1):
        if A%n == 0 and B%n == 0:
            cd_list.append(n)
else:
    for n in range(1, A+1):
        if A%n == 0 and B%n == 0:
            cd_list.append(n)
prime_list = [1]
for i in range(1, len(cd_list)):
    if all([1 if fractions.gcd(cd_list[i], n)==1 else 0 for n in cd_list[:i]]):
        prime_list.append(cd_list[i])
print(len(prime_list))


### FIXED CODE ###

import fractions, math
def factorization(n):
    arr = []
    temp = n
    for i in range(2, int(-(-n**0.5//1))+1):
        if temp%i == 0:
            cnt = 0
            while temp % i == 0:
                cnt += 1
                temp //= i
            arr.append([i, cnt])
    if temp != 1:
        arr.append([temp, 1])
    if arr == []:
        arr.append([n, 2])
    return arr
A, B = map(int, input().split())
N = fractions.gcd(A, B)
prime_list = factorization(N)
if N == 1:
    print(1)
else:
    print(len(prime_list)+1)
### BUGGY CODE ###

n=int(input())
a=list(map(int,input().split()))
ans=0
for i in range(n):
    b=a[i]*sum(a[i+1:n])
    ans=ans+b
d=ans%(10**9+7)
print(d)

### FIXED CODE ###

n=int(input())
a=list(map(int,input().split()))
ans=0
c=sum(a)
for i in range(n):
    c=c-a[i]
    b=(a[i]*c)
    ans=ans+b
d=ans%(1000000007)
print(d)
### BUGGY CODE ###


from collections import defaultdict
import heapq


def dijkstra(n, s, edges, count):
    dist = [float('inf') for _ in range(n)]
    dist[s] = 0
    q = []
    heapq.heappush(q, (0, s))
    while len(q):
        d, p = heapq.heappop(q)
        if s < p:
            count[d] += 1
        if dist[p] < d:
            continue
        for e in edges[p]:
            if d + 1 < dist[e]:
                dist[e] = d + 1
                heapq.heappush(q, (dist[e], e))
    return dist, count


def submit():
    n, x, y = map(int, input().split())
    
    edges = {i: [] for i in range(n)}
    for i in range(n - 1):
        edges[i].append(i + 1)
        edges[i + 1].append(i)
    edges[x - 1].append(y - 1)
    edges[y - 1].append(x - 1)
    
    dist_list = {}
    count = defaultdict(int)
    for s in range(n):
        dist_list[s], count = dijkstra(n, s, edges, count)

    for i in range(1, n):
        print(count[i])


submit()

### FIXED CODE ###

def submit():
    n, x, y = map(int, input().split())

    count = {i: 0 for i in range(1, n)}
    for i in range(1, n + 1):
        for j in range(i + 1, n + 1):
            # i, j <= X, or Y <= i, j
            if (i <= x and j <= x) or (x <= i and y <= j):
                d = j - i
            
            # X < i, j < Y
            if x < i and j < y:
                d = min(j - i, i - x + 1 + y - j)
            
            # i <= X and X < j < Y
            if i <= x and x < j < y:
                d = min(j - i,
                        x - i + 1 + y - j)            

            # X < i < Y and Y <= j
            if x < i < y and y <= j:
                d = min(j - i,
                        j - y + 1 + i - x)

            if i <= x and y <= j:
                d = min(j - i,
                        x - i + j - y + 1)
            count[d] += 1            
            

    for i in range(1, n):
        print(count[i])

submit()
### BUGGY CODE ###

n, k = map(int, input().split())
next = list(map(int, input().split()))
next = list(map(lambda x: x - 1, next))
c = list(map(int, input().split()))

ans = -(10 ** 17)

for i in range(n):
    now = i
    cycle_sum = 0
    cycle_len = 0

    while True:
        cycle_sum += c[now]
        cycle_len += 1
        now = next[now]
        if now == i:
            break

    sum = 0
    cnt = 0

    while cnt < k and cnt < cycle_len:
        sum += c[now]
        cnt += 1
        laps = (k - cnt) // cycle_len
        score = sum + max(0, cycle_sum) * laps
        ans = max(ans, score)

        now = next[now]
        if now == i:
            break

print(ans)

### FIXED CODE ###

n, k = map(int, input().split())
next = list(map(int, input().split()))
next = list(map(lambda x: x - 1, next))
c = list(map(int, input().split()))

ans = -(10 ** 17)

for i in range(n):
    now = i
    cycle_sum = 0
    cycle_len = 0

    while True:
        cycle_sum += c[now]
        cycle_len += 1
        now = next[now]
        if now == i:
            break

    sum = 0
    cnt = 0

    while True:
        sum += c[now]
        cnt += 1

        if cnt > k:
            break

        laps = (k - cnt) // cycle_len
        score = sum + max(0, cycle_sum) * laps
        ans = max(ans, score)

        now = next[now]
        if now == i:
            break

print(ans)
### BUGGY CODE ###

n = int(input())
s = input()

ret = set()

import itertools
for v in itertools.combinations(s, 3):
    ret.add(''.join(v))

print(len(ret))

### FIXED CODE ###

n = int(input())
s = input()

import itertools

d = list()
for d1, d2, d3 in itertools.product(range(10), range(10), range(10)):
    d.append(str(d1) + str(d2) + str(d3))

ret = 0
for di in d:
    ls = list(s)
    try:
        idx1 = ls.index(di[0])
        idx2 = ls[idx1+1:].index(di[1])
        idx3 = ls[idx1+1:][idx2+1:].index(di[2])
        ret += 1
    except:
        continue

print(ret)
### BUGGY CODE ###

n,m,k=map(int,open(0).read().split())
mod=998244353
c=[1]*(k+1)
for i in range(1,k+1):
  c[i]=c[i-1]*(n-i)//i
ans=0
for i in range(k+1):
  ans+=m*pow(m-1,n-1-i,mod)*(c[i]%mod)
  ans%=mod
print(ans)

### FIXED CODE ###

n,m,k=map(int,open(0).read().split())
p=998244353
'''
c=[1]*(k+1)
for i in range(1,k+1):
  c[i]=c[i-1]*(n-i)//i
  c[i-1]%=mod
'''
def cmb(n, r, p):
    if (r < 0) or (n < r):
        return 0
    r = min(r, n - r)
    return fact[n] * factinv[r] * factinv[n-r] % p

p = 998244353
N = n  # N は必要分だけ用意する
fact = [1, 1]  # fact[n] = (n! mod p)
factinv = [1, 1]  # factinv[n] = ((n!)^(-1) mod p)
inv = [0, 1]  # factinv 計算用
 
for i in range(2, N + 1):
    fact.append((fact[-1] * i) % p)
    inv.append((-inv[p % i] * (p // i)) % p)
    factinv.append((factinv[-1] * inv[-1]) % p)
ans=0
for i in range(k+1):
  ans+=m*pow(m-1,n-1-i,p)*cmb(n-1,i, p)
  ans%=p
print(ans)
### BUGGY CODE ###

#D in [S_i-X_i,T_i-X_i) → Xiで止まる
import sys
input = sys.stdin.readline

N,Q = map(int,input().split())
q = []

STX = [[int(x) for x in input().split()] for _ in range(N)]
for s,t,x in STX:
  q.append((s-x,1,x)) # xで死ぬ
  q.append((t-x,0,x)) # xで死ななくなる

for i in range(Q):
  d = int(input())
  q.append((d,2,i))
answer = [-1]*Q

se = set() # 引っかかってる場所

q.sort()

for a,c,b in q:
  if not c:
    se.remove(b)
  elif c&1:
    se.add(b)
  else:
    if se:
      answer[b] = min(se)

print('\n'.join(map(str,answer)))


### FIXED CODE ###

#D in [S_i-X_i,T_i-X_i) → Xiで止まる
import sys
input = sys.stdin.readline

N,Q = map(int,input().split())
q = []

STX = [[int(x) for x in input().split()] for _ in range(N)]
for s,t,x in STX:
  q.append((s-x,1,x)) # xで死ぬ
  q.append((t-x,0,x)) # xで死ななくなる

for i in range(Q):
  d = int(input())
  q.append((d,2,i))
answer = [-1]*Q

se = set() # 引っかかってる場所

q.sort()

min_se = 10**18
flag = False # min_seが正しい

for a,c,b in q:
  if not c:
    se.remove(b)
    if min_se == b:
      flag = False
  elif c&1:
    se.add(b)
    if b < min_se:
      min_se = b
      flag = True
  else:
    if se:
      if not flag:
        min_se = min(se)
        flag = True
      answer[b] = min_se

print('\n'.join(map(str,answer)))
### BUGGY CODE ###

import math
from functools import reduce

def gcd(*numbers):
    return reduce(math.gcd,numbers)
K = int(input())
ans= [[0 for i in range(K)] for j in range(K)]
answ=0
for i in range(1,K+1):
    for j in range(1,K+1):
        ans[i-1][j-1]+=gcd(i,j)

for i in range(1,K+1):
    for j in range(1,K+1):
        for k in range(1,K+1):
            answ+=gcd(ans[i-1][j-1],k)
print(answ)

### FIXED CODE ###

import math
k = int(input())
ans = 0
for i in range(1, k + 1):
    for j in range(1, k + 1):
        gcd1 = math.gcd(i, j)
        for l in range(1, k + 1):
            gcd2 = math.gcd(gcd1, l)
            ans += gcd2
print(ans)
### BUGGY CODE ###

H, W = map(int, input().split())

matrix = []

res = 0

visited = set()

for i in range(H):
    matrix.append(list(input()))

while True:
    visited = set()
    count = 0
    for i in range(H):
        for j in range(W):
            if matrix[i][j] == '#' and (i, j) not in visited:
                for ud, lr in ((-1, 0), (1, 0), (0, -1), (0, 1)):
                    if not(0 <= i+ud < H and 0 <= j+lr < W)  or matrix[i+ud][j+lr] == '#':
                        continue
                    visited.add((i+ud, j+lr))
                    matrix[i+ud][j+lr] = '#'
                    count += 1
    if count == 0:
        break
    res += 1
print(res)



### FIXED CODE ###

H, W = map(int, input().split())

matrix = []

visited = set()

for i in range(H):
    matrix.append(list(input()))

visited = set()

for i in range(H):
    for j in range(W):
        if matrix[i][j] == '#' and (i, j) not in visited:
            for ud, lr in ((-1, 0), (1, 0), (0, -1), (0, 1)):
                if not(0 <= i+ud < H and 0 <= j+lr < W)  or matrix[i+ud][j+lr] == '#':
                    continue
                visited.add((i+ud, j+lr))
                matrix[i+ud][j+lr] = '#'

res = 0

while visited:
    res += 1
    buf = set()
    for i, j in visited:
        if matrix[i][j] == '#' and (i, j) not in buf:
            for ud, lr in ((-1, 0), (1, 0), (0, -1), (0, 1)):
                if not(0 <= i+ud < H and 0 <= j+lr < W)  or matrix[i+ud][j+lr] == '#':
                    continue
                buf.add((i+ud, j+lr))
                matrix[i+ud][j+lr] = '#'
    if not buf:
        break
    visited = buf

print(res)
### BUGGY CODE ###

class SegmentTree(object):
    """
    セグメントツリー (0-indexed)

    1. 値の更新 O(logN)
    2. 区間クエリ O(logN)
    """
    def __BinOp(self, x, y):
        """ セグ木で使用する二項演算 """
        return x | y

    def __init__(self, init_ele, N:int):
        """
        セグ木を構築する

        init_ele: 単位元 
        N: 要素数
        """
        self.__init_ele = init_ele
        self.__n = 1
        while self.__n < N:
            self.__n <<= 1

        self.__dat = [init_ele] * (2 * self.__n)
    
    def update(self, k:int, x):
        """ k番目の値をxに変更する """
        k += self.__n - 1
        self.__dat[k] = x
        while k:
            k = (k - 1) // 2
            self.__dat[k] = self.__BinOp(
                self.__dat[k * 2 + 1], self.__dat[k * 2 + 2]
                )
    
    def query(self, p:int, q:int):
        """ 区間クエリ [p,q) """
        if q <= p: return self.__init_ele
        p += self.__n - 1
        q += self.__n - 2
        res = self.__init_ele
        while q - p > 1:
            if not (p & 1):
                res = self.__BinOp(res, self.__dat[p])
            if q & 1:
                res = self.__BinOp(res, self.__dat[q])
                q -= 1
            p = p // 2
            q = (q - 1) // 2
        res = self.__BinOp(res, self.__dat[p])
        if p != q: res = self.__BinOp(res, self.__dat[q])
        return res
    
    def get_num(self, k:int):
        """ k番目の値を取得する """
        k += self.__n - 1
        return self.__dat[k]

############################################################
N = int(input())

ST = SegmentTree(0, N)
for i, s in enumerate(list(input())):
    ST.update(i, 1 << (ord(s) - ord('a')))

Q = int(input())
for _ in range(Q):
    x,y,z = map(str,input().split())
    x = int(x); y = int(y)
    if x == 1:
        ST.update(y - 1, 1 << (ord(z) - ord('a')))
    else:
        z = int(z)
        print(bin(ST.query(y - 1, z)).count("1"))

### FIXED CODE ###

from collections import defaultdict

alpha = defaultdict(int)
num = 0
for i in sorted(map(chr,range(97,123))):
    alpha[i] = 1 << num
    num += 1

n = int(input())
S = tuple(alpha[i] for i in input())

def init(init_val):
    #set_val
    for i in range(n):
        seg[i+num-1] = init_val[i]
    #built
    for i in range(num-2,-1,-1):
        seg[i] = seg[2*i+1] | seg[2*i+2]
    
def update(k,x):
    k += num-1
    seg[k] = x
    while k:
        k = (k-1)//2
        seg[k] = seg[k*2+1] | seg[k*2+2]
    
def query(p,q):
    if q<=p:
        return 0
    p += num-1
    q += num-2
    res=0
    while q-p>1:
        if p&1 == 0:
            res |= seg[p]
        if q&1 == 1:
            res |= seg[q]
            q -= 1
        p = p//2
        q = (q-1)//2
    if p == q:
        res |= seg[p]
    else:
        res |= (seg[p] | seg[q])
    cnt = 0
    i = 0
    while res:
        cnt += res & 1
        i += 1
        res >>= 1
    return cnt
#num:n以上の最小の2のべき乗
num =2**(n-1).bit_length()
seg=[0 for _ in range(2*num)]

init(S)

Q = int(input())
for _ in range(Q):
    x,y,z = map(str,input().split())
    x = int(x); y = int(y)
    if x == 1:
        update(y-1, alpha[z])
    else:
        z = int(z)
        print(query(y-1,z))
### BUGGY CODE ###

N, M = map(int, input().strip().split())

set_ = set()
for m in range(M):
    s, e = map(int, input().strip().split())
    tmp = set()
    for i in range(s, e+1):
        tmp.add(i)

    if m == 0:
        set_ = tmp
    else:
        set_ = set_ & tmp

print(len(set_))


### FIXED CODE ###

N, M = map(int, input().strip().split())

s_list = list()
e_list = list()

for m in range(M):
    s, e = map(int, input().strip().split())
    s_list.append(s)
    e_list.append(e)

s_max = max(s_list)
e_min = min(e_list)

if s_max > e_min:
    print(0)
else:
    print(e_min-s_max+1)
### BUGGY CODE ###

#!python3

INF = 10 ** 15


# input
N = int(input())
a, b, c, d = [None] * N, [None] * N, [None] * N, [None] * N
for i in range(N):
    a[i], b[i] = list(map(int, input().split()))
for i in range(N):
    c[i], d[i] = list(map(int, input().split()))


class MaxFlow():

    def __init__(self, n):
        self.n = n
        self.c = [[0] * n for _ in range(n)]
        self.visit = [False] * n

    def add_link(self, x, y, capa):
        self.c[x][y] += capa
    
    def solve(self, t, v, f):
        if v == t:
            return f
        self.visit[v] = True
        
        w = 0
        for i in range(self.n):
            if self.visit[i] or self.c[v][i] == 0:
                continue
            d = self.solve(t, i, min(f - w, self.c[v][i]))
            if d > 0:
                self.c[v][i] -= d
                self.c[i][v] += d
                w += d
                if w == f:
                    break
        
        self.visit[v] = False
        return w
        

def main():
    w = MaxFlow(2 * N + 2)
    for i in range(N):
        w.add_link(0, i + 1, 1)
        w.add_link(N + i + 1, 2 * N + 1, 1)
        for j in range(N):
            if a[i] < c[j] and b[i] < d[j]:
                w.add_link(i + 1, N + j + 1, 1)
    
    ans = w.solve(2 * N + 1, 0, INF)
    print(ans)


if __name__ == "__main__":
    main()


### FIXED CODE ###

#!python3

INF = 10 ** 15


# input
N = int(input())
a, b, c, d = [None] * N, [None] * N, [None] * N, [None] * N
for i in range(N):
    a[i], b[i] = list(map(int, input().split()))
for i in range(N):
    c[i], d[i] = list(map(int, input().split()))


class MaxFlow():

    def __init__(self, n):
        self.n = n
        self.c = [[0] * n for _ in range(n)]
        self.visit = [False] * n

    def add_link(self, x, y, capa):
        self.c[x][y] += capa
    
    def dfs(self, v, t, f):
        if v == t:
            return f
        self.visit[v] = True
        
        for i in range(self.n):
            if self.visit[i] or self.c[v][i] == 0:
                continue
            d = self.dfs(i, t, min(f, self.c[v][i]))
            if d > 0:
                self.c[v][i] -= d
                self.c[i][v] += d
                return d
                
        return 0

    
    def max_flow(self, s, t):
        ans = 0
        while True:
            f = self.dfs(s, t, INF)
            self.visit = [False] * self.n
            if f == 0:
                return ans
            else:
                ans += f
        

def main():
    w = MaxFlow(2 * N + 2)
    for i in range(N):
        w.add_link(0, i + 1, 1)
        w.add_link(N + i + 1, 2 * N + 1, 1)
        for j in range(N):
            if a[i] < c[j] and b[i] < d[j]:
                w.add_link(i + 1, N + j + 1, 1)
    
    ans = w.max_flow(0, 2 * N + 1)
    print(ans)


if __name__ == "__main__":
    main()