Harryxun/stf_run huggingface dataset:
#encoding utf-8

n = int(input())
data = []
for i in range(n):
    x,y,h=map(int,input().split())
    data.append([x,y,h])



def calH(cx,cy,data):
    return data[2]+abs(data[0]-cx)+abs(data[1]-cy)

for i in range(101):
    for j in range(101):
        temH = calH(i,j,data[0])
        for k in range(n):
            if calH(i,j,data[k]) != temH:
                break
            else:
                if k == n-1:
                    answer=[i,j,calH(i,j,data[0])]

print(answer[0],answer[1],answer[2])

### FIXED CODE ###

#!/usr/bin/env python3
# encoding:utf-8
import copy
import random
import bisect #bisect_left　これで二部探索の大小検索が行える
import fractions #最小公倍数などはこっち
import math
import sys
import collections
from decimal import Decimal # 10進数で考慮できる

mod = 10**9+7
sys.setrecursionlimit(mod) # 再帰回数上限はでdefault1000

d = collections.deque()
def LI(): return list(map(int, sys.stdin.readline().split()))

N = int(input())
xyh = []
for i in range(N):
    x, y, h = LI()
    xyh.append([x, y, h])


"""

C_x C_y H

XYの高度はmax(H - abs(X - C_x) - abs(Y - C_y), 0)
"""
xyh = sorted(xyh, key=lambda xyh: xyh[2], reverse=True)

# print(xyh)
ans = (0,0,0)
for c_x in range(101):
    for c_y in range(101):
        H = 0
        flag = True
        for i, (x, y, h) in enumerate(xyh):
            if i == 0:
                H = h + abs(x - c_x) + abs(y - c_y)
            if h != max(H - abs(x - c_x) - abs(y - c_y), 0):
            # if H != max(h + abs(x - c_x) + abs(y - c_y), 0):
                flag = False
        if flag:
            ans = (c_x, c_y, H)
    
X, Y, H = ans
print(X, Y, H)
# -*- coding: utf-8 -*-
import sys

N,K=map(int, sys.stdin.readline().split())
A=map(int, sys.stdin.readline().split())

keta=0

for i in range(15,-1,-1):
	if (K>>i)&1:
		keta=i+1
		break


C=[ 0 for i in range(keta) ]	#桁ごとのbit 1の出現回数

for a in A:
	for k in range(keta,-1,-1):
	#	print k, x>>k, (x>>k)&1
		if (a>>k)&1:		#その桁のbitが1なら、出現回数に+1
			C[k]+=1



X=0	# f(x)が最大となるX


for idx, i in enumerate(C):
	if i<=N/2:
		X+=2**idx	#桁ごとに見て、ゼロの数が多ければ、f(x)が最大となるXとなるXのidx番目の桁は1になる

ans=0
for a in A:
	ans+=X^a

print ans

### FIXED CODE ###

# -*- coding: utf-8 -*-
import sys

N,K=map(int, sys.stdin.readline().split())
A=map(int, sys.stdin.readline().split())

keta=0

for i in range(50,-1,-1):
	if (K>>i)&1:
		keta=i+1
		break



C=[ 0 for i in range(keta) ]	#桁ごとのbit 1の出現回数


for a in A:
	for k in range(keta-1,-1,-1):
		#print "k, a>>k, (a>>k)&1 ::::: ",k, a>>k, (a>>k)&1
		if (a>>k)&1:		#その桁のbitが1なら、出現回数に+1
			C[k]+=1



X=0	# f(x)が最大となるX


len_c=len(C)

for i in range(len_c-1,-1,-1):
	ci=C[i]
	if  C[i]<(N+1)/2:
		if X+2**i<=K:
			X+=2**i		#桁ごとに見て、ゼロの数が多ければ、f(x)が最大となるXとなるXのidx番目の桁は1になる
					#1と0が同数の場合は、その桁を0にしたほうが、Xが小さくなるので有利

ans=0
for a in A:
	ans+=X^a

print ans
a,b =map(int,input().split())
if a%B==0:
  print(a/b)
else:
  print(1+a//b)

### FIXED CODE ###

a, b = map(int, input().split())
if a % b == 0:
    print(a//b)
else:
    print(1+a//b)
N = int(input())
A = [int(input()) for _ in range(N)]
 
# M_list = index(max(A_1,...,A_N))
# M = max(A)
# sub_M = sub_max(A)

# iがM_listに含まれるときにはsub_Mを出力
# それ以外ではMを出力

M = max(A)
sub_M = 0
for i in range(N):
  if i not in M_list:
    sub_M = max(sub_M, A[i])
    
M_list = []
for i in range(N):
  if A[i] == M: M_list.append(i)
    
for i in range(N):
  if i in M_list: print(sub_M)
  else: print(M)

### FIXED CODE ###

N = int(input())
A = [int(input()) for _ in range(N)]

M = max(A)
M_index = A.index(M)
sub_M = 0
for i in range(N):
  if i != M_index: sub_M = max(sub_M, A[i])

for i in range(N):
  if i == M_index: print(sub_M)
  else: print(M)
from math import ceil
h,w =map(int,input(),split())
ss = (h*(w+1)//2)
if h>1 and w>1:
	print(ss)
else:
	print(1)


### FIXED CODE ###

a,b =map(int,input().split())
ss = a*b
hf =ss//2
if a>1 and b>1:
	print(ss-hf)
else:
  print(1)
# https://atcoder.jp/contests/abc065/tasks/arc076_b
import copy


class UnionFind():
    def __init__(self, n):
        super().__init__()
        self.n = n
        self.parents = [i for i in range(n)]

    def root(self, x):
        if self.parents[x] == x:
            return x
        else:
            self.parents[x] = self.root(self.parents[x])
            return self.parents[x]

    def union(self, x, y):
        x = self.root(x)
        y = self.root(y)
        if x == y:
            return False
        self.parents[y] = x
        return True


n = int(input())
rows = [[i] + list(map(int, input().split())) for i in range(n)]

# (start, end, cost)
edges = []

# x座標でソートしてx座標が隣り合う点にをedge候補に
rows_x = copy.deepcopy(rows)
rows_x.sort(key=lambda x: x[1])
for i in range(len(rows)-1):
    left = rows_x[i]
    right = rows_x[i+1]
    edges.append((left[0], right[0], right[1] - left[1]))

rows_y = copy.deepcopy(rows)
rows_y.sort(key=lambda x: x[2])
for i in range(len(rows)-1):
    down = rows_y[i]
    up = rows_y[i+1]
    edges.append((down[0], up[0], up[2] - down[2]))

# print(edges)

uf = UnionFind(n)

edges.sort(key=lambda edge: edge[2])

result = 0
for edge in edges:
    s, t, c = edge
    unioned = uf.union(s, t)
    if unioned:
        result += c

print(result)


### FIXED CODE ###

# https://atcoder.jp/contests/abc065/tasks/arc076_b
import copy


class UnionFind():
    def __init__(self, n):
        super().__init__()
        self.n = n
        self.parents = [-1] * n

    def root(self, x):
        if self.parents[x] < 0:
            return x
        else:
            self.parents[x] = self.root(self.parents[x])
            return self.parents[x]

    def union(self, x, y):
        x = self.root(x)
        y = self.root(y)
        if x == y:
            return False
        if self.parents[x] > self.parents[y]:
            x, y = y, x
        self.parents[x] += self.parents[y]
        self.parents[y] = x
        return True


n = int(input())
rows = [[i] + list(map(int, input().split())) for i in range(n)]

# (start, end, cost)
edges = []

# x座標でソートしてx座標が隣り合う点にをedge候補に
rows_x = copy.deepcopy(rows)
rows_x.sort(key=lambda x: x[1])
for i in range(len(rows)-1):
    left = rows_x[i]
    right = rows_x[i+1]
    edges.append((left[0], right[0], right[1] - left[1]))

# print(rows)
rows_y = copy.deepcopy(rows)
rows_y.sort(key=lambda x: x[2])
for i in range(len(rows)-1):
    down = rows_y[i]
    up = rows_y[i+1]
    edges.append((down[0], up[0], up[2] - down[2]))

# print(edges)

uf = UnionFind(n)

edges.sort(key=lambda edge: edge[2])

result = 0
for edge in edges:
    s, t, c = edge
    unioned = uf.union(s, t)
    if unioned:
        result += c

print(result)
?ddd1+**+p

### FIXED CODE ###

a = int(input())
ans = a + a**2 + a*a*a
print(ans)
S = input()

if S == 'Sunny':
  print(Cloudy)
  
if S == 'Cloudy':
  print(Rainy)
  
if S == 'Rainy':
  print(Sunny)


### FIXED CODE ###

S = input()

if S == 'Sunny':
  print('Cloudy')
  
if S == 'Cloudy':
  print('Rainy')
  
if S == 'Rainy':
  print('Sunny')
N=int(input())
A=list(input())
B=list(input())
C=list(input())
litter=[]
c=0
for s in range(N):
    c+=[0,0,1,2][len(set([A[s],B[s],C[s]]))]
print(c)

### FIXED CODE ###

N,A,B=map(int,input().split(" "))
if N-A-B>0:
	W=0
else:
    W=A+B-N
print(min(A,B),W)
import math
from functools import reduce

def lcm(x,y):
  return int((x*y) / math.gcd(x,y))

def lcm_list(nums):
  return reduce(lcm, nums)

n = int(input())
a = list(map(int, input().split()))
m = lcm_list(a) - 1
ans = 0
for i in range(n):
  ans += m % a[i]

print(ans)

### FIXED CODE ###

from functools import reduce


def gcd(a,b):
  x = max([a,b])
  y = min([a,b])
  while y:
    x, y = y, x % y
  return x

def lcm(x,y):
  return (x*y) // gcd(x,y)

def lcm_list(nums):
  return reduce(lcm, nums)
n = int(input())

a = list(map(int, input().split()))




m = lcm_list(a) - 1


ans = 0
for i in range(n):
  ans += m % a[i]
  
  
print(ans)
N = int(input())
tree = [[] for _ in range(N)]

for i in range(N-1):
    a, b, c = map(int, input().split())
    a -= 1
    b -= 1
    tree[a].append((b, c))
    tree[b].append((a, c))

Q, K = map(int, input().split())
K -= 1

depth = [0 for _ in range(N)]

def dfs(v, p = -1, d = 0):
    depth[v] = d
    for i, j in tree[v]:
        if i == p:
            continue
        dfs(i, v, d + j)

dfs(K)

for i in range(Q):
    x, y = map(int,input().split())
    x -= 1; y -= 1
    print (depth[x] + depth[y])

### FIXED CODE ###

N = int(input())
tree = [[] for _ in range(N)]

for i in range(N-1):
    a, b, c = map(int, input().split())
    a -= 1
    b -= 1
    tree[a].append((b, c))
    tree[b].append((a, c))

Q, K = map(int, input().split())
K -= 1

depth = [0 for _ in range(N)]

def dfs(v, p = -1, d = 0):
    St = []
    St.append([v, p, d])
    # 空のシーケンスは偽になる
    while St:
        cur = St.pop()
        depth[cur[0]] = cur[2]
        for i, j in tree[cur[0]]:
            if i == cur[1]:
                continue
            St.append([i, cur[0], cur[2] + j])

dfs(K)

for i in range(Q):
    x, y = map(int, input().split())
    x -= 1; y -= 1
    print (depth[x] + depth[y])
N,M=map(int, input().split())
print(N*(N-1)//2+M*(M-1)//2)


### FIXED CODE ###

N,M=map(int, input().split())
print(N*(N-1)//2+M*(M-1)//2)
def is_possible(x, A):
    current = []
    length = 0
    for a in A:
        if a <= length:
            current = current[:a] + [0] * (a-len(current))
            i = a - 1
            current[i] += 1
            while current[i] >= x:
                if i == 0:
                    return False
                current[i-1] += 1
                current[i] = 0
                i -= 1
        length = a

    return True


def main():
    N = int(input())
    A = list(map(int, input().split()))
    left = 1
    right = N
    while left < right:
        center = (left + right) // 2
        if is_possible(center, A):
            right = center
        else:
            left = center + 1
    print(left)


if __name__ == "__main__":
    main()


### FIXED CODE ###

def is_possible(x, A):
    current = {}
    length = 0
    for a in A:
        if a <= length:
            if x == 1:
                return False
            current = {k: current[k] for k in current if k < a}
            i = a - 1
            if i not in current:
                current[i] = 0
            current[i] += 1
            while i in current and current[i] >= x:
                if i == 0:
                    return False
                if (i-1) not in current:
                    current[i-1] = 0
                current[i-1] += 1
                del current[i]
                i -= 1
        length = a

    return True


def main():
    N = int(input())
    A = list(map(int, input().split()))
    left = 1
    right = N
    while left < right:
        center = (left + right) // 2
        if is_possible(center, A):
            right = center
        else:
            left = center + 1
    print(left)


if __name__ == "__main__":
    main()
N=input()
T=0
for i in (N):
 T+=int(i)
if int(N)%T==0:
 print('Yes')
else:
 print('No')



### FIXED CODE ###

N,A,B=map(int, input().split())
if A*N<=B:
 print(A*N)
else:
 print(B)
N = int(input())
s = [input() for i in range(N)]

print(N, s)

### FIXED CODE ###

N = int(input())
A = list(map(int, input().split())) 
ans = 0
 
for n in range(N-1):
  t = A[n] - A[n+1]
  if t <= 0: continue
  else:
    A[n+1] += t
    ans += t

print(ans)
import sys
s=input()
a,b,c,d=s[0],s[1],s[2],s[3]
if a+b+c+d==7:
  print('a+b+c+d=7')
  sys.exit()
if a+b+c-d==7:
  print('a+b+c-d=7')
  sys.exit()
if a+b-c+d==7:
  print('a+b-c+d=7')
  sys.exit()      
if a-b+c+d==7:
  print('a-b+c+d=7')
  sys.exit()
if a+b-c-d==7:
  print('a+b-c-d=7')
  sys.exit()
if a-b-c+d==7:
  print('a-b-c+d=7')
  sys.exit()
if a-b+c-d==7:
  print('a-b+c-d=7')
  sys.exit()
if a-b-c-d==7:
  print('a-b-c-d=7')
  sys.exit()


### FIXED CODE ###

import sys
S=input()
a,b,c,d=S[0],S[1],S[2],S[3]
lst=['+','-']
for i in lst:
  for j in lst:
    for k in lst:
      if eval(a+i+b+j+c+k+d+'==7'):
        print(a+i+b+j+c+k+d+'=7')
        sys.exit()
n = int(input())
a = list(map(int, input().split()))

x = 0
for i in range(n):
  while True:
    if a[i] > a[i + 1]:
      a[i + 1] += 1
      x += 1
    if a[i] <= a[i + 1]:
      break

print(x)

### FIXED CODE ###

N = int(input())
A = [int(x) for x in input().split()]
ans = 0
for i in range(N-1):
    if A[i]>A[i+1]:
        ans += A[i]-A[i+1]
        A[i+1] = A[i]
print(ans)
# import bisect
from collections import Counter, deque # https://note.nkmk.me/python-scipy-connected-components/
# from copy import copy, deepcopy
# from math import gcd
# from functools import reduce
# from heapq import heapify, heappop, heappush
# from itertools import accumulate, permutations, combinations, combinations_with_replacement, groupby, product
# import math
# import numpy as np  # Pythonのみ！
# from operator import xor
# import re
# from scipy.sparse.csgraph import connected_components  # Pythonのみ！
# ↑cf.  https://note.nkmk.me/python-scipy-connected-components/
# from scipy.sparse import csr_matrix
# import string
import sys

sys.setrecursionlimit(10 ** 5 + 10)


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


def resolve():
    def main():
        N = int(input())
        A = list(map(int, input().split()))

        if all(a == 0 for a in A):
            return True
        if N % 3 != 0:
            return False

        AA = Counter(A)
        if len(AA) == 2:
            AAA = AA.most_common()
            for k, v in AAA.items():
                if v != N * 2 // 3:
                    return False
            return AAA[1][0] == 0

        if len(AA) == 3:
            if any(v != N // 3 for v in AA.values()):
                return False
            k1, k2, k3 = AA.keys()
            return k1 ^ k2 == k3

    print('Yes' if main() else 'No')


resolve()

### FIXED CODE ###

# import bisect
from collections import Counter, deque  # https://note.nkmk.me/python-scipy-connected-components/
# from copy import copy, deepcopy
# from math import gcd
# from functools import reduce
# from heapq import heapify, heappop, heappush
# from itertools import accumulate, permutations, combinations, combinations_with_replacement, groupby, product
# import math
# import numpy as np  # Pythonのみ！
# from operator import xor
# import re
# from scipy.sparse.csgraph import connected_components  # Pythonのみ！
# ↑cf.  https://note.nkmk.me/python-scipy-connected-components/
# from scipy.sparse import csr_matrix
# import string
import sys

sys.setrecursionlimit(10 ** 5 + 10)


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


def resolve():
    def main():
        N = int(input())
        A = list(map(int, input().split()))

        if all(a == 0 for a in A):
            return True
        if N % 3 != 0:
            return False

        AA = Counter(A)
        if len(AA) == 2:
            AAA = AA.most_common()
            if AAA[0][1] != N * 2 // 3:
                return False
            return AAA[1][0] == 0

        if len(AA) == 3:
            if any(v != N // 3 for v in AA.values()):
                return False
            k1, k2, k3 = AA.keys()
            return k1 ^ k2 == k3 or k1 ^ k3 == k2 or k2 ^ k3 == k1

    print('Yes' if main() else 'No')


resolve()
x,a,b = map(int, input().split())
A = max(x,a) - min(x,a)
B = max(x,b - min(x,b)
if A > B:
    print("B")
else:
    print("A")

### FIXED CODE ###

x,a,b = map(int, input().split())
A = max(x,a) - min(x,a)
B = max(x,b) - min(x,b)
if A > B:
    print("B")
else:
    print("A")
s = input()
t = input()
c = 0
a_list =[]
while c < len(t):
  a_list.append(t)
  a = t.pop(0)
  t.append(a)
  c += 1
if s in a_list:
  print('Yes')
else:
  print('No')

### FIXED CODE ###

s = input()
t = input()
c = 0
a_list =[]
while c < len(t):
  a_list.append(t)
  a = t[1:]+t[0:1]
  t = a
  c += 1
if s in a_list:
  print('Yes')
else:
  print('No')
N, X = map(int, input().split())
L = list(map(int, input().split()))
count = 0
location = 0
for i in range(N + 1):
    if location + L[i] <= X:
        count += 1
        location += L[i]
    else:
        break
print(count)

### FIXED CODE ###

N, X = map(int, input().split())
L = list(map(int, input().split()))
count = 1
location = 0
for i in range(N):
    if location + L[i] <= X:
        count += 1
        location += L[i]
    else:
        break
print(count)
a,b = map(int,input())
li = []
for i in range(a):
  li.append(int(input())
sum1 = sum(li)
min1 = min(li)
b = b -sum1
print(a+ b//min1)

### FIXED CODE ###

a,b = map(int,input().split())
li = []
for i in range(a):
  li.append(int(input()))
sum1 = sum(li)
min1 = min(li)
b = b -sum1
print(a+ b//min1)
n = int(input())
a = [int(i) for i in input().split()]

a.sort(reverse= True)

cnt = 0
top = []

for i in range(n):
    if len(top) == 2:
        break    
    for j in range(4):
        if a[i] == a[i+1+j]:
            if len(top) == 2:
                break
            if j == 1:
                top.append(a[i])
            elif j == 3:
                top.append(a[i])

if len(top) != 2:
    print(0)
    exit()

print(int(top[0]*top[1]))

### FIXED CODE ###

n = int(input())
a = [int(i) for i in input().split()]

a.sort(reverse= True)

cnt = 0
top = []

for i in range(n-1):
    #print(i)
    if len(top) == 2:
        break    
    if a[i] == a[i+1]:
        if len(top) == 2:
            break
        if cnt%2 == 0:
            top.append(a[i])
        cnt += 1
    else:
        cnt = 0

if len(top) < 2:
    print(0)
    exit()

print(int(top[0]*top[1]))
def tempDif(h,T,A):
  temp = T - 0.006*h
  dif = A -temp
  if dif < 0:
    dif = -dif
  return dif
 
N = int(input())
T,A = map(int,input().split())
lis = [int(n) for n in input().split()]
 
lisnew = [tempDif(H,T,A) for H in lis]
print(listnew.index(max(listnew)))

### FIXED CODE ###

def tempDif(h,T,A):
  temp = T - 0.006*h
  dif = A -temp
  if dif < 0:
    dif = -dif
  return dif
 
N = int(input())
T,A = map(int,input().split())
lis = [int(n) for n in input().split()]
 
lisnew = [tempDif(H,T,A) for H in lis]
print(lisnew.index(min(lisnew))+1)
import math
import fractions

A , B , C , D = map(int,input().split())

if C > D :
    C , D = D , C

ans = 0

if A < C :
    ans += C - A
    A = C

# A以上B以下の数でXの倍数の個数
def countX(X) :
    if X >= B :
        return 0
    minX = math.ceil(A / X)
    maxX = math.floor(B / X)

    return maxX - minX + 1

# 最小公倍数
Z = C * D / math.fractions(C,D)

ans += B - A + 1 - countX(C) - countX(D) + countX(Z)

print(ans)

### FIXED CODE ###

import math
import fractions

# A以上B以下の数でXの倍数の個数
def countX(X) :
    if X > B :
        return 0

    minX = (A - 1) // X
    maxX = B // X

    return maxX - minX

A , B , C , D = map(int,input().split())

ans = B - A + 1

# 最小公倍数
Z = int(C * D / fractions.gcd(C,D))

ans -= countX(C)
ans -= countX(D)
ans += countX(Z)

print(int(ans))
N, M = mtp(int, input().split())
ks = [list(map(int, input().split())) for i in range(M)]
p = list(map(int, input().split()))

ans = 0
for i in range(2**M):
    cnt = 0
    for j in range(M):
        count = 0
        for k in ks[j][1::]:
            if (i >> k-1)&1 == 1:
                count += 1
        if count%2 == p[j]:
            cnt += 1
    if cnt == M:
        ans += 1
print(ans)

### FIXED CODE ###

N, M = map(int, input().split())
ks = [list(map(int, input().split())) for i in range(M)]
p = list(map(int, input().split()))

ans = 0
for i in range(2**N):
    cnt = 0
    for j in range(M):
        count = 0
        for k in ks[j][1::]:
            if (i >> k-1)&1 == 1:
                count += 1
        if count%2 == p[j]:
            cnt += 1
    if cnt == M:
        ans += 1
print(ans)
import sys
read = sys.stdin.buffer.read
readline = sys.stdin.buffer.readline
readlines = sys.stdin.buffer.readlines
 
N,M = map(int,readline().split())
m = map(int,read().split())
ST = zip(m,m)
 
out_edge = [[] for _ in range(N+1)]
in_edge = [[] for _ in range(N+1)]
 
for s,t in ST:
    out_edge[s].append(t)
    in_edge[t].append(s)

out_deg = [len(x) for x in out_edge]
 
arrive_prob = [0]*(N+1)
arrive_prob[1] = 1.0
for n in range(2,N+1):
    arrive_prob[n] = sum(arrive_prob[p]/out_deg[p] for p in in_edge[n])

expected_from = [0]*(N+1)
for n in range(N-1,0,-1):
    expected_from[n] = 1+sum(expected_from[c] for c in out_edge[n])/out_deg[n]

current_time = expected_from[1]
 
improve = 0
for n in range(1,N):
    if out_deg[n] == 1:
        continue
    x = expected_from[n]
    d = out_deg[n]
    y = (d*(x-1)-max(expected_from[c] for c in out_edge[n]))/(d-1) + 1
    value = (x-y)*arrive_prob[n]
    if improve < value:
        improve = value

answer = current_time - improve
print(answer)
import sys
read = sys.stdin.buffer.read
readline = sys.stdin.buffer.readline
readlines = sys.stdin.buffer.readlines

N,M = map(int,readline().split())
m = map(int,read().split())
ST = zip(m,m)

out_edge = [[] for _ in range(N+1)]
in_edge = [[] for _ in range(N+1)]

for s,t in ST:

### FIXED CODE ###

import sys
read = sys.stdin.buffer.read
readline = sys.stdin.buffer.readline
readlines = sys.stdin.buffer.readlines

N,M = map(int,readline().split())
m = map(int,read().split())
ST = zip(m,m)

out_edge = [[] for _ in range(N+1)]
in_edge = [[] for _ in range(N+1)]

for s,t in ST:
    out_edge[s].append(t)
    in_edge[t].append(s)

out_deg = [len(x) for x in out_edge]

arrive_prob = [0]*(N+1)
arrive_prob[1] = 1.0
for n in range(2,N+1):
    arrive_prob[n] = sum(arrive_prob[p]/out_deg[p] for p in in_edge[n])

# その頂点に辿り着くまでの回数期待値
# いらなかったっぽい
# expected_to = [0]*(N+1)
# for n in range(2,N+1):
#     expected_to[n] = 1 + sum(expected_to[p]*arrive_prob[p]/out_deg[p] for p in in_edge[n])/arrive_prob[n]

# その頂点に辿り着いてからの回数期待値
expected_from = [0]*(N+1)
for n in range(N-1,0,-1):
    expected_from[n] = 1+sum(expected_from[c] for c in out_edge[n])/out_deg[n]

current_time = expected_from[1]

improve = 0
for n in range(1,N):
    if out_deg[n] == 1:
        continue
    x = expected_from[n]
    d = out_deg[n]
    y = (d*(x-1)-max(expected_from[c] for c in out_edge[n]))/(d-1) + 1
    value = (x-y)*arrive_prob[n]
    if improve < value:
        improve = value

answer = current_time - improve
print(answer)
while True:
  try:
    (a, b) = map(int, raw_input().split())
    c = a + b
    i = 0
    while c != 0:
      c /= 10
      i += 1
    print i

  except:
    pass:

### FIXED CODE ###

while True:
	try:
		[a, b] = map(int, raw_input().split())
		sum = a + b
		count = 0
		while sum:
			count += 1
			sum /= 10
		print count
	except (EOFError):
		break;
N, W = map(int, input().split())
w = []
v = []
for i in range(N):
    a, b = map(int, input().split())
    w.append(a)
    v.append(b)
w_adjust = []
for i in range(N):
    w_adjust.append(w[i]-w[0])

a = w[0]
dp = [[[0 for i in range(N+1)] for j in range(N*3+10)] for k in range(N+1)]
#i個目までの物のうちk個選んで重さの和がjになる中での最大価値
for i in range(N):
    for j in range(3*N):
        for k in range(N):
            dp[i+1][j][k] = max(dp[i+1][j][k], dp[i][j][k])
            dp[i+1][j+w_adjust[i]][k+1] = max(dp[i+1][j+w_adjust[i]][k+1], dp[i][j][k] + v[i])

ans = []
for i in range(N+1):
    if W - a*i >= 0:
        ans.append(dp[N][W-a*i][i])
    else:
        ans.append(0)
print(max(ans))


### FIXED CODE ###

N, W = map(int, input().split())
w = []
v = []
for i in range(N):
    a, b = map(int, input().split())
    w.append(a)
    v.append(b)
w_adjust = []
for i in range(N):
    w_adjust.append(w[i]-w[0])

a = w[0]
dp = [[[0 for i in range(N+1)] for j in range(N*3+10)] for k in range(N+1)]
#i個目までの物のうちk個選んで重さの和がjになる中での最大価値
for i in range(N):
    for j in range(3*N):
        for k in range(N):
            if j + w_adjust[i] > W - a*(k+1):
                dp[i+1][j][k] = max(dp[i+1][j][k], dp[i][j][k])
            else:
                dp[i+1][j+w_adjust[i]][k+1] = max(dp[i+1][j+w_adjust[i]][k+1], dp[i][j][k] + v[i])
                dp[i+1][j][k] = max(dp[i+1][j][k], dp[i][j][k])
ans = [0]
for i in range(1, N+1):
    if W - a*i >= 0 and W - a*i < N*3 + 3:
        ans.append(dp[N][W-a*i][i])

if W - a*N > N*3:
    things = W//w[0]
    if things > N:
        ans.append(sum(v))

elif len(ans) == 1:
    things = W//w[0]
    v.sort()
    v.reverse()
    ans_1 = 0
    for i in range(things):
        ans_1 += v[i]
    ans.append(ans_1)

print(max(ans))