CodeEff/ECCO huggingface dataset:
# Original solution
D, G = list(map(int, input().split()))
dic = [0]*(D+1)
for i in range(D):
  p, c = list(map(int, input().split()))
  dic[i+1] = (p,c)
ans = 10**9
for i in range(2**D):
  ls = []
  x = i
  v = 0
  count = 0
  for j in range(D):
    if x%2==1:
      ls += [j+1]
    x = x>>1
  for h in ls:
    p, c = dic[h]
    v += p*h*100 + c
    count += p
  if G>v:
    for j in range(D, 0, -1):
      if not j in ls:
        break
    else:
      continue
    m = dic[j][0]
    while m>1:
      v += j*100
      count += 1
      m -= 1
      if v>=G:
        break
    else:
      continue
  if count<ans:
    ans = count
print(ans)

# Optimized solution
D, G, *L = list(map(int, open(0).read().split()))
inf = []
for m in zip(*[iter(L)]*2):
  inf.append(m)

ans = float('inf')
for i in range(2**D):
  m = 0
  cnt = 0
  log = []
  for j in range(D):
    if i%2==0:
      m += 100*(j+1)*inf[j][0]+inf[j][1]
      cnt += inf[j][0]
    else:
      log.append(j)
    i>>=1
  while m<G:
    if log==[]:
      break
    h = log.pop()
    s = 100*(h+1)
    x = (G-m)//s if (G-m)%s==0 else (G-m)//s+1
    c = min(inf[h][0]-1, x)
    m += c*s
    cnt += c
  else:
    ans = min(ans,cnt)
print(ans)
# Original solution
D,G = list(map(int,input().split()))
pc = [list(map(int,input().split())) for i in range(D)]

#print(pc)
ans = float("inf")

for i in range(2**D):
    sum = 0
    count = 0
    rem = set(range(1,D+1))
    for j in range(D):
        if (i >> j) & 1:
            sum += pc[j][0]*100*(j+1)+pc[j][1]
            count += pc[j][0]
            rem.discard(j+1)
    if sum < G:
        k = max(rem)-1
        n = min(pc[k][0],-(-(G-sum)//((k+1)*100)))
        count += n
        sum += n*100*(k+1)
    if sum >= G:
        ans = min(ans,count)

print(ans)


# Optimized solution
def dfs (i,sum,count,rem):
    global ans
    if i == D:
        if sum < G:
            k = max(rem)
            n = min(pc[k-1][0],-(-(G-sum)//(k*100)))
            count += n
            sum += n*100*k
        if sum >= G:
            ans = min(ans,count)
    else:
        dfs(i+1,sum,count,rem)
        dfs(i+1,sum+pc[i][0]*100*(i+1)+pc[i][1],count+pc[i][0],rem-{i+1})

D,G = list(map(int,input().split()))
pc = [list(map(int,input().split())) for i in range(D)]

ans = float("inf")

dfs(0,0,0,set(range(1,D+1)))
print(ans)
# Original solution
from copy import copy
D,G=list(map(int,input().split()))
p=[]
c=[]
for i in range(D):
    a,b=list(map(int,input().split()))
    p.append(a)
    c.append(b)
lst1=[]
lst2=[]
lst3=[]
def func1(l1,l2,l3,p,c,G):
    S=0
    n=0
    ind=0
    for i in range(len(l1)):
        S+=c[i]*l1[i]
        n+=p[i]*l1[i]
        S+=p[i]*100*(i+1)*l1[i]
    for i in range(len(l2)):
        if S>=G:
            break
        kazu=len(l2)-i
        a=l2[kazu-1]
        for j in range(1,a+1):
            if j==a:
                break
            S+=100*kazu
            n+=1
            if S>=G:
                break
    if S>=G:
        l3.append(n)
        l3.append(S)
    return 0
def func(l1,l2,l3,num,p,c,G):
    if num==0:
        func1(l1,l2,l3,p,c,G)
        return 0
    y1=copy(l2)
    y2=copy(l2)
    y2[len(l1)]=0
    x1=copy(l1)
    x1.append(0)
    x2=copy(l1)
    x2.append(1)
    num-=1
    return func(x1,y1,l3,num,p,c,G),func(x2,y2,l3,num,p,c,G)
func(lst1,p,lst3,D,p,c,G)
print((min(lst3)))

# Optimized solution
from math import ceil
D,G=list(map(int,input().split()))
P=[]
C=[]
R=[]
for i in range(D):
    p,c=list(map(int,input().split()))
    P.append(p)
    C.append(c)
    R.append((i+1)*100*p+c)
bit=2**D
ans=10**19
for i in range(bit):
    i=bin(i)[2:].zfill(D)
    su=0
    num=0
    k=-1
    for j in range(D):
        k=int(i[j])
        su+=k*R[j]
        num+=k*P[j]
        if k==0:
            t=j
    if G<=su:
        ans=min(ans,num)
        continue
    if k==-1:
        continue
    if  ceil((G-su)/((t+1)*100))<P[t]:
        ans=min(ans,num+ceil((G-su)/((t+1)*100)))
print(ans)
# Original solution
#### import ####
import sys
import math
from collections import defaultdict

#### 設定 ####
sys.setrecursionlimit(10**7)
def input():
    return sys.stdin.readline()[:-1]

#### 定数 ####
mod = 10**9 + 7

#### 読み込み ####
def I(): return int(eval(input()))
def II(): return list(map(int, input().split()))
def III(): return list(map(int, input().split()))
def Line(N):
    read_all = [tuple(map(int, input().split())) for _ in range(N)]
    return list(map(list,list(zip(*read_all))))

#################

D,G = II()
p,c = Line(D)

def dfs(point,p):
    if point<=0:
        return 0
    else:
        ret = []
        for i in range(D):
            if p[i]==0:
                continue
            num = math.ceil(point/((i+1)*100))
            if num <= p[i]:
                ret.append(num)
            else:
                temp = p[i]
                p[i] = 0
                ret.append(dfs(point-100*(i+1)*temp-c[i],p)+temp)
                p[i] = temp
        return min(ret)

print((dfs(G,p)))

# Optimized solution
#### import ####
import sys
import math
from collections import defaultdict

#### 設定 ####
sys.setrecursionlimit(10**7)
def input():
    return sys.stdin.readline()[:-1]

#### 定数 ####
mod = 10**9 + 7

#### 読み込み ####
def I(): return int(eval(input()))
def II(): return list(map(int, input().split()))
def III(): return list(map(int, input().split()))
def Line(N):
    read_all = [tuple(map(int, input().split())) for _ in range(N)]
    return list(map(list,list(zip(*read_all))))

#################

D,G = II()
p,c = Line(D)

def dfs(point,p):
    if point<=0:
        return 0
    else:
        ret = []
        for i in range(D):
            if p[i]==0:
                continue
            q,mod = divmod(point,(i+1)*100)
            if mod ==0:
                num = q
            else:
                num = q+1
            if num <= p[i]:
                ret.append(num)
            else:
                temp = p[i]
                p[i] = 0
                ret.append(dfs(point-100*(i+1)*temp-c[i],p)+temp)
                p[i] = temp
        return min(ret)

print((dfs(G,p)))
# Original solution
d,g = list(map(int,input().split()))
P,C = [],[]
for i in range(1, d+1):
    p,c = list(map(int,input().split()))
    P.append(p)
    C.append(c)
ans = 10**9
for bin in range(1, 1<<d):
    cnt = tot = 0
    for j in range(d):
        if bin & 1<<j:
            cnt += P[j]
            tot += P[j]*(j+1)*100 + C[j]
    if tot < g: continue
    ans = min(ans, cnt)
    for j in range(d):
        if bin & 1<<j:
            now_cnt = cnt
            now_tot = tot - C[j]
            for k in range(P[j]-1):
                now_cnt -= 1
                now_tot -= (j+1)*100
                if now_tot >= g: ans = min(ans, now_cnt)
print(ans)


# Optimized solution
d,g = list(map(int,input().split()))
g //= 100
P,C = [],[]
for i in range(1, d+1):
    p,c = list(map(int,input().split()))
    P.append(p)
    C.append(c//100)
ans = 10**9
# print(P)
# print(C)
for bin in range(1, 1<<d):
    cnt = tot = 0
    for j in range(d):
        if bin & 1<<j:
            cnt += P[j]
            tot += P[j]*(j+1) + C[j]
    if tot < g: continue
    ans = min(ans, cnt)
    # print('tot',tot, end=' ')
    # print('cnt',cnt, end='\n')
    for j in range(d):
        if bin & 1<<j:
            init_cnt = cnt - P[j]
            init_tot = tot - (P[j]*(j+1) + C[j])
            rest_g = g - init_tot
            k = max(0, (rest_g+j)//(j+1)) # round up, required quantity
            # print('Pj',P[j], end=' ')
            # print('Cj',C[j], end=' ')
            # print('init_cnt',init_cnt, end=' ')
            # print('init_tot',init_tot, end=' ')
            # print('rest_g',rest_g, end=' ')
            # print('k',k, end='\n')
            if k < P[j]:
                # ans = init_cnt + k
                ans = min(ans, init_cnt + k)
                # print('init_cnt+k',init_cnt+k, end='\n')
print(ans)
# Original solution
d,g = list(map(int,input().split()))
P,C = [0]*d,[0]*d
for i in range(d): P[i],C[i] = list(map(int,input().split()))
ans = 10**9
for bin in range(1, 1<<d):
    cnt = tot = 0
    for i in range(d):
        if bin & 1<<i:
            cnt += P[i]
            tot += P[i]*(i+1)*100 + C[i]
    if tot < g: continue
    ans = min(ans, cnt)
    for i in range(d):
        if bin & 1<<i:
            now_cnt = cnt
            now_tot = tot - C[i]
            for k in range(P[i]-1):
                now_cnt -= 1
                now_tot -= (i+1)*100
                if now_tot >= g: ans = min(ans, now_cnt)
print(ans)


# Optimized solution
d,g = list(map(int,input().split()))
g //= 100
P,C = [0]*d,[0]*d
for i in range(d):
    P[i],C[i] = list(map(int,input().split()))
    C[i] //= 100
ans = 10**9
for bin in range(1, 1<<d):
    cnt = tot = 0
    for i in range(d):
        if bin & 1<<i:
            cnt += P[i]
            tot += P[i]*(i+1) + C[i]
    if tot < g: continue
    ans = min(ans, cnt)
    for i in range(d):
        if bin & 1<<i:
            rest_g = g - (tot - P[i]*(i+1) - C[i])
            p = max(0, (rest_g+i)//(i+1)) # round up
            ans = min(ans, cnt - (P[i] - p))
print(ans)
# Original solution
d,g = list(map(int,input().split()))
P,C = [0]*d,[0]*d
for i in range(d): P[i],C[i] = list(map(int,input().split()))
ans = 10**9
for bin in range(1, 1<<d):
    cnt = tot = 0
    for i in range(d):
        if bin & 1<<i:
            cnt += P[i]
            tot += P[i]*(i+1)*100 + C[i]
    if tot < g: continue
    ans = min(ans, cnt)
    for i in range(d):
        if bin & 1<<i:
            t = (i+1)*100
            rest_g = g - (tot - P[i]*t - C[i])
            p = max(0, (rest_g+t-1)//t) # round up
            ans = min(ans, cnt - (P[i] - p))
print(ans)


# Optimized solution
d,g = list(map(int,input().split()))
P,C = [0]*d,[0]*d
for i in range(d): P[i],C[i] = list(map(int,input().split()))
ans = 10**9
for bin in range(0, 1<<d):
    cnt = tot = 0
    rest_max_bit = -1
    for i in range(d):
        if bin & 1<<i:
            t = (i+1)*100
            tot += P[i]*t + C[i]
            cnt += P[i]
        else: rest_max_bit = i
    if tot >= g:
        ans = min(ans, cnt)
        continue
    if rest_max_bit < 0: continue
    t = (rest_max_bit+1)*100
    rest_g = g - tot
    p = min(P[rest_max_bit]-1, (rest_g+t-1)//t) # [0,pi-1]
    if p*t >= rest_g: ans = min(ans, cnt + p)
print(ans)
# Original solution
d,g = list(map(int,input().split()))
P,C = [0]*d,[0]*d
for i in range(d): P[i],C[i] = list(map(int,input().split()))
ans = 10**9
for bin in range(1<<d):
    cnt = tot = rest_max_bit = 0
    for i in range(d):
        if bin & 1<<i:
            t = (i + 1)*100
            tot += P[i]*t + C[i]
            cnt += P[i]
        else: rest_max_bit = i
    if tot < g:
        t = (rest_max_bit + 1)*100
        p = (g - tot + t - 1)//t
        if p >= P[rest_max_bit]: continue
        cnt += p
    ans = min(ans, cnt)
print(ans)


# Optimized solution
d, g = list(map(int,input().split()))
data = [list(map(int,input().split())) for _ in range(d)]

def dfs(d, rest): # difficulty, rest score
    if d <= 0: return 10**9
    num, bonus = data[d-1] # num of problems, bonus
    # now, use or don't use difficulty d?
    use = min(rest//(d*100), num) # num when use
    score = use * d * 100 # score when use
    if use == num: score += bonus # ?perfect
    if rest - score > 0: # ?rest
        use += dfs(d-1, rest - score) # rest of score -> recursion
    not_use = dfs(d-1, rest) # num when don't use -> recursion
    return min(use, not_use)

print((dfs(d, g)))
# Original solution
D, G = list(map(int, input().split()))
pc = []
for n in range(D):
    p, c = list(map(int, input().split()))
    pc.append([p, c, p * (n + 1)*100 + c])

ans = sum(pc[:][0])
for i in range(2 ** D):
    temp = 0
    numberProb = 0
    box = ["-"] * D
    for j in range(D):
        if ((i >> j) & 1):
            box[D - j - 1] = "+"
    for k, l in enumerate(box):
        if l == "+":
            temp += pc[k][2]
            numberProb += pc[k][0]

    if temp >= G:
        ans = min(ans, numberProb)
    else:
        lisind = max( [i for i, x in enumerate(box) if x == '-'])
        for m in range(pc[lisind][0]):
            temp += (lisind + 1) * 100
            numberProb += 1
            if temp >= G:
                ans = min(ans, numberProb)
                break

print(ans)

# Optimized solution
D, G = list(map(int, input().split()))
pc = [list(map(int, input().split())) for _ in range(D)]
# 大問D問中のn問といてG点以上をとる最低の問題数n

ans = int(1e10)
for i in range(2 ** D):
    zen = []
    atemp = 0
    ktemp = 0
    for j in range(D):
        if (i >> j) & 1:
            zen.append(True)
        else:
            zen.append(False)
    for n, tf in enumerate(zen):
        if tf:
            atemp += pc[n][0] * (n+1) * 100 + pc[n][1]
            ktemp += pc[n][0]
        else:
            hanpa = n
    if atemp >= G:
        ans = min(ans, ktemp)
    else:
        if atemp + pc[hanpa][0]*(hanpa+1)*100 < G:
            continue
        else:
            if (G - atemp) % ((hanpa+1)*100) == 0:
                ans = min(ans, ktemp + ((G - atemp) // ((hanpa+1)*100)))
            else:
                ans = min(ans, ktemp + ((G - atemp) // ((hanpa+1)*100)) + 1)

print(ans)
# Original solution
#ABC 104 C - All Green
#順列総当たりでやる

import itertools

d, g = list(map(int, input().split()))
#print(d)
p=[]
c=[]
ld = []
for i in range(d):
  pk, ck = list(map(int, input().split()))
  p.append(pk)
  c.append(ck)
  ld.append(i)

jun = list(itertools.permutations(ld))
ans=10000

for j in jun:
  #順列の数だけ試す。j[番号]で調べてる順列の番号番目の数を返す
  ten = 0
  mondaisu = 0
  for k in range(d):
    bango = j[k]
    katen = (bango + 1)*100*p[bango] + c[bango]
#    print("n問目"+str(bango +1) + "加点"+ str(katen))
    if ten + katen > g:
      nokori = ((g-ten)-1)//((bango + 1)*100) + 1
      if nokori > p[bango]:#ボーナス点がないと届かない場合
        mondaisu += p[bango]
      else:
        mondaisu += nokori
      break
    else:
      ten += katen
      mondaisu += p[bango]
  if ans > mondaisu:
    ans = mondaisu
#  print(str(j) + "問題数" + str(mondaisu) +"答えリスト")
#  print(ans_list)
        
print(ans)      
  
#print(jun[0][1])

  
#print(p)
#print(c)

# Optimized solution
#ABC 104 C - All Green

#ビット総当たりでやる

d, g = list(map(int, input().split()))
#print(d)

p=[]
c=[]

for i in range(d):
  pk, ck = list(map(int, input().split()))
  p.append(pk)
  c.append(ck)
#print(p)
#print(c)
  
ans = 10000#仮の答え

#2^d通り試す
for i in range(2 ** d):
  #右からn番目の桁が1→n+1の配点の問題を完全に解く
  ten = 0
  mondaisu = 0
  for j in range(d):
    if (i>>j)&1 == 1:
      #p[j]個あるj+1の配点の問題を完全に解く
      ten += (j+1)*100*p[j] + c[j]
      mondaisu += p[j]
    else:
      #p[j]個あるj+1の配点の問題は完全にとかない
      k = j
  #フラグの立った配点の問題を全部といた
  if ten > g:
    if ans > mondaisu:
      ans = mondaisu
  else:
    #中途半端に解かないと行けない場合p[k]の問題を中途半端に解く
    if g-ten <= (k+1)*100*p[k] :
      mondaisu += (g-ten-1)//((k+1)*100) +1
      if ans > mondaisu:
        ans = mondaisu
      #中途半端に解いて届かない場合スルー
#  print(mondaisu)    
print(ans)
# Original solution
d,g = list(map(int,input().split()))
p_input = [0]*d
c_input = [0]*d

for i in range(d):
    p_input[i],c_input[i] = list(map(int,input().split()))

ans=float('inf')
for i in range(2**d):
    problem=0
    point=0
    for j in range(d):
        if ((i>>j)&1):
            problem+=p_input[j]
            point+=(1+j)*100*p_input[j]+c_input[j]
    if point>=g:
        ans=min(ans,problem)
    else:
        for j in range(d-1,-1,-1):
            if ((i>>j)&1):
                continue
            for k in range(p_input[j]):
                if point>=g:
                    break
                problem+=1
                point+=100*(j+1)
        ans = min(ans,problem)
            
print(ans)

# Optimized solution
d,g = list(map(int,input().split()))
P = [0]*d
C = [0]*d
for i in range(d):
    P[i],C[i] = list(map(int,input().split()))

ans = float('inf')
for i in range(2**d):
    tmp = 0
    res = 0
    for j in range(d):
        if ((i>>j)&1):
            tmp+=C[j]+(j+1)*100*P[j]
            res+=P[j]
    if tmp<g:
        for j in range(d-1,-1,-1):
            if not ((i>>j)&1):
                if tmp>=g:
                    break
                if tmp+(j+1)*100*P[j]<=g:
                    tmp+=(j+1)*100*P[j]
                    res+=P[j]
                else:
                    for p in range(P[j]):
                        if tmp>=g:
                            break
                        tmp+=(j+1)*100
                        res+=1
    ans = min(ans,res)
print(ans)
# Original solution
import functools
D, G = list(map(int, input().split()))
G = G // 100
sumn = 0
ns = [0] * (D + 1)
cs = [0] * (D + 1)
for i in range(1, D + 1):
    n, c = list(map(int, input().split()))
    ns[i] = n
    cs[i] = c // 100
    sumn += n

minn = [0] * (D + 1)
for i in range(1, D + 1):
    minn[i] = min(ns[1:i+1])

@functools.lru_cache(maxsize=None)
def f(i, rn):
    if i == 1:
        if ns[1] < rn:
            return -1
        p = rn
        if ns[1] == rn:
            p += cs[1]
        return p
    if rn < minn[i]:
        p = 0
        for j in range(i, 0, -1):
            n = min((ns[j], rn))
            p += j * n
            if n == rn:
                break
            rn -= n
        return p
    maxp = 0
    for n in range(min((ns[i], rn)) + 1):
        p = i * n
        if n == ns[i]:
            p += cs[i]
        np = f(i - 1, rn - n)
        if np >= 0:
            p += np
            if maxp < p:
                maxp = p
    return maxp

mn = 1
mx = sumn
while mn < mx:
    x = mn + ((mx - mn) // 2)
    if G <= f(D, x):
        mx = x
    else:
        mn = x + 1
print(mn)


# Optimized solution
from itertools import combinations
D, G = list(map(int, input().split()))
G = G // 100
ns = [0] * (D + 1)
cs = [0] * (D + 1)
for i in range(1, D + 1):
    n, c = list(map(int, input().split()))
    ns[i] = n
    cs[i] = c // 100

ans = sum(ns)
for partialsn in range(1, D + 1):
    for partials in combinations(list(range(1, D + 1)), partialsn):
        sumn = 0
        rp = G
        for i in range(1, D + 1):
            if not i in partials:
                sumn += ns[i]
                rp -= i * ns[i] + cs[i]
        if rp > 0:
            for i in sorted(partials, reverse=True):
                n = ns[i] - 1
                if rp <= i * n:
                    n = rp // i
                    if rp % i != 0:
                        n += 1
                sumn += n
                rp -= i * n
                if rp <= 0:
                    break
        if rp <= 0:
            if sumn < ans:
                ans = sumn
print(ans)
# Original solution
inf = float('inf')


def rec(cur, partially_solved, solve_num, score):
    if cur == d:
        return solve_num if score >= g else inf

    res = rec(cur + 1, partially_solved, solve_num, score)
    res = min(res,
              rec(cur + 1, partially_solved, solve_num + p[cur], score + p[cur] * (cur + 1) * 100 + c[cur]))
    if not partially_solved:
        for i in range(1, p[cur]):
            res = min(res,
                      rec(cur + 1, True, solve_num + i, score + i * (cur + 1) * 100))
    return res


d, g = list(map(int, input().split()))

p, c = [], []
for _ in range(d):
    tp, tc = list(map(int, input().split()))
    p.append(tp)
    c.append(tc)
print((rec(0, False, 0, 0)))


# Optimized solution
def main():
    from itertools import product

    D, G = list(map(int, input().split()))

    prob = []
    for j in range(1, D + 1):
        p, c = list(map(int, input().split()))
        prob.append((j * 100, p, c))  # score,amount,bonus

    ans = -1
    for prd in product([0, 1], repeat=D):
        cnt = 0
        g = 0
        for j, (score, amount, bonus) in zip(prd, prob):
            if j:
                cnt += amount
                g += score * amount + bonus

        if g < G:
            for j, (score, amount, bonus) in reversed(tuple(zip(prd, prob))):
                if (not j) and (score * amount >= G - g):
                    use = (G - g + score - 1) // score
                    cnt += use
                    g += score * use
                    break

        if (g < G) or (~ans and ans <= cnt): continue
        ans = cnt

    print(ans)


if __name__ == '__main__':
    main()
# Original solution
#!/mnt/c/Users/moiki/bash/env/bin/python
D,G = list(map(int, input().split()))
points = [ [int(j) for j in input().split()] for _ in range(D)]
points = [ [x[0], x[1], 100*e*x[0]] for e,x in enumerate(points, 1)]


ans = float("inf")
for i in range(1<<D): # for complete bonus bit set 
    lg = G
    cnt = 0
    for d in range(D):
        if i & (1<<d) != 0:
            lg -= points[d][1] # complete bonus
            lg -= (100*(d+1))*points[d][0] # normal points
            cnt += points[d][0]
            if lg <= 0:
                break
    if lg <= 0:
        ans = min(ans, cnt)
        continue
    
    # other points
    for d in range(D-1, -1, -1):
        if i & (1<<d) != 0: continue

        if lg <= points[d][2]:
            quot = (lg+(100*(d+1)-1)) // (100*(d+1))
            lg -= 100*(d+1)*quot
            cnt += quot;  break
        else:
            cnt += points[d][0]
            lg -= 100*(d+1)*points[d][0]
            cnt += points[d][0]
    if lg <= 0:
        ans = min(ans, cnt)
        continue
print(ans)

        

        



            



# Optimized solution
#!/mnt/c/Users/moiki/bash/env/bin/python
D,G = list(map(int, input().split()))
points = [ [int(j) for j in input().split()] for _ in range(D)]
points = [ [x[0], x[1], 100*e*x[0]] for e,x in enumerate(points, 1)]

ans = float("inf")
for i in range(1<<D): # for complete bonus bit set 
    lg = G
    cnt = 0
    for d in range(D):
        if i & (1<<d) != 0:
            lg -= points[d][1] # complete bonus
            # lg -= (100*(d+1))*points[d][0] # normal points
            lg -= points[d][2] # normal points
            cnt += points[d][0]
            if lg <= 0:
                break
    if lg <= 0:
        ans = min(ans, cnt)
        continue
    
    # other points
    for d in range(D-1, -1, -1):
        if i & (1<<d) != 0: continue

        if lg <= points[d][2]:
            quot = (lg+(100*(d+1)-1)) // (100*(d+1)) # carryUp
            lg -= 100*(d+1)*quot
            cnt += quot;  break
        else:
            cnt += points[d][0]
            lg -= points[d][2]
    if lg <= 0:
        ans = min(ans, cnt)
        continue
print(ans)
# Original solution

D, G = list(map(int, input().split()))
pc = [tuple(map(int, input().split())) for _ in range(D)]

memo = dict()


def rec(crp, crscore, crans):
    global D, G, pc, memo

    if (crp, crscore) in memo:
        return memo[(crp, crscore)] + crans

    if crscore >= G:
        return crans
    elif crp > D:
        return 10**9

    p, c = pc[crp - 1]

    tmp_min = min(
        rec(crp + 1, crscore + 100 * crp * i, crans + i) for i in range(p)
    )

    res = min(tmp_min, rec(crp + 1, crscore + 100 * crp * p + c, crans + p))
    memo[(crp, crscore)] = res - crans
    return res


print((rec(1, 0, 0)))


# Optimized solution
from itertools import product


D, G = list(map(int, input().split()))
pc = [tuple(map(int, input().split())) for _ in range(D)]


ans = 1e9
for selected in product((True, False), repeat=D):
    tmp_score = 0
    tmp_count = 0
    rest_max = 0

    for i, is_select in enumerate(selected):
        if is_select:
            tmp_score += 100 * (i + 1) * pc[i][0] + pc[i][1]
            tmp_count += pc[i][0]
        else:
            rest_max = i

    if tmp_score < G:
        s1 = 100 * (rest_max + 1)
        need = (G - tmp_score + s1 - 1) // s1

        if need >= pc[rest_max][0]:
            continue

        tmp_count += need

    ans = min(ans, tmp_count)

print(ans)