CodeEff/ECCO huggingface dataset:
# Original solution
# coding: utf-8


def solve(*args: str) -> str:
    d, g = list(map(int, args[0].split()))
    g //= 100
    pc = [tuple(map(int, a.split())) for a in args[1:]]
    inf = 10**12
    dp = {}

    for i, (p, c) in enumerate(pc):
        c //= 100
        if i == 0:
            for k in range(p):
                s = min(g, (i+1)*(k+1) + (c if k+1 == p else 0))
                dp[s] = k+1
        else:
            items = tuple(dp.items())
            for t, m in items:
                for k in range(p):
                    s = min(g, (i+1)*(k+1) + (c if k+1 == p else 0))
                    s_t = min(g, s+t)
                    dp[s] = min(dp.get(s, inf), k+1)
                    dp[s_t] = min(dp.get(s_t, inf), k+1+m)
    return str(dp[g])


if __name__ == "__main__":
    print((solve(*(open(0).read().splitlines()))))


# Optimized solution
# coding: utf-8


def solve(*args: str) -> str:
    d, g = list(map(int, args[0].split()))
    pc = [tuple(map(int, a.split())) for a in args[1:]]
    inf = 10**5

    count = inf
    for b in range(2**d):
        score, cnt = 0, 0

        for i in range(d):
            p, c = pc[i]
            if b >> i & 1:
                score += p*100*(i+1)+c
                cnt += p

        if score < g:
            for i in reversed(list(range(d))):
                if b >> i & 1:
                    continue
                else:
                    p, c = pc[i]
                    j = 0
                    while score < g and j < p:
                        score += 100*(i+1)
                        cnt += 1
                        j += 1

                    if j == p:
                        score += c

        count = min(count, cnt)

    return str(count)


if __name__ == "__main__":
    print((solve(*(open(0).read().splitlines()))))
# Original solution
import itertools
d, g = list(map(int, input().split()))

lst = [list(map(int, input().split())) for i in range(d)]
#print(lst)

new_lst = [[] for i in range(len(lst))]

for i, j in enumerate(lst):
    #print(i, j)
    for k in range(j[0] + 1):
        new_lst[i].append([k, (k * 100 * (i + 1))])
        if k == j[0]:
            new_lst[i][k][1] += j[1]
        
#print(new_lst)
min_ac = 1000

for i in itertools.product(*new_lst):
    ac = 0
    points = 0
    #print(i)
    for j in range(len(lst)):
        ac += i[j][0]
        points += i[j][1]
    if points >= g:
        if ac <= min_ac:
            min_ac = ac

print(min_ac)

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

min_ac1 = 1000
min_ac2 = 1000
for i in range(2 ** d):
    points = 0
    ac = 0
    for j in range(d):
        if ((i >> j) & 1) == 1:
            points += pc[j][0] * 100 * (j + 1) + pc[j][1]
            ac += pc[j][0]
    if points < g:
        l = "{:010b}".format(i)
        l = l[10-d:]
        for k in range(d):
            if l[k] == "0":
                tmp = k
                break
        tmp = -(tmp - d)
        if (g - points + tmp * 100 - 1) // (tmp * 100) < pc[tmp - 1][0]:
            tmp_ac = ac + (g - points + tmp * 100 - 1) // (tmp * 100)
            if tmp_ac < min_ac1:
                min_ac1 = tmp_ac
    if points >= g:
        if ac < min_ac2:
            min_ac2 = ac
    #print(bin(i), ac, points, min_ac1, min_ac2)
print((min(min_ac1, min_ac2)))
# Original solution
d, g = list(map(int, input().split()))
pc = [list(map(int, input().split())) for i in range(d)]

min_ac1 = 1000
min_ac2 = 1000
for i in range(2 ** d):
    points = 0
    ac = 0
    for j in range(d):
        if ((i >> j) & 1) == 1:
            points += pc[j][0] * 100 * (j + 1) + pc[j][1]
            ac += pc[j][0]
    if points < g:
        l = "{:010b}".format(i)
        l = l[10-d:]
        for k in range(d):
            if l[k] == "0":
                tmp = k
                break
        tmp = -(tmp - d)
        if (g - points + tmp * 100 - 1) // (tmp * 100) < pc[tmp - 1][0]:
            tmp_ac = ac + (g - points + tmp * 100 - 1) // (tmp * 100)
            if tmp_ac < min_ac1:
                min_ac1 = tmp_ac
    if points >= g:
        if ac < min_ac2:
            min_ac2 = ac
    #print(bin(i), ac, points, min_ac1, min_ac2)
print((min(min_ac1, min_ac2)))

# Optimized solution
def dfs(i, sum, cnt, memo):
    if i == d + 1:
        if sum >= g:
            tmp.append(cnt)
        else:
            cnt += min(p_lst[max(memo) - 1], -(-(g - sum) // (max(memo) * 100)))
            if sum + min(p_lst[max(memo) - 1], -(-(g - sum) // (max(memo) * 100))) * max(memo) * 100 >= g:
                tmp.append(cnt)
        
    else:
        dfs(i + 1, sum + 100 * i * p_lst[i - 1] + c_lst[i - 1], cnt + p_lst[i - 1], memo)
        dfs(i + 1, sum, cnt, memo + [i])

d, g = list(map(int, input().split()))
p_lst = []
c_lst = []
tmp = []
for i in range(d):
    p, c = list(map(int, input().split()))
    p_lst.append(p)
    c_lst.append(c)


dfs(1, 0, 0, [])
print((min(tmp)))
# Original solution
import itertools

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

a = [i for i in range(d)]

b = itertools.permutations(a,d)

ans = float('inf')

for x in b:
    c = 0
    e = 0
    flag = False
    for i in x:
        for j in range(pc[i][0]):
            c += 1
            e += 100*(i+1)
            if e>=g:
                flag = True
                break
        if flag:
            break
        e += pc[i][1]
        if e >= g:
            flag = True
        if flag:
            break
    ans = min(ans, c)

print(ans)



# Optimized solution
import itertools
import math

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

a = [i for i in range(d)]

b = itertools.permutations(a,d)

ans = float('inf')

for x in b:
    c = 0
    e = 0
    flag = False
    for i in x:
        if e+100*(i+1)*pc[i][0]<=g:
            c += pc[i][0]
            e+=100*(i+1)*pc[i][0]+pc[i][1]
            if e >= g:
                break
        else:
            c += math.ceil((g-e)/(100*(i+1)))
            break
    ans = min(ans, c)

print(ans)
# Original solution
class Problem:
  def __init__(self, score, number, bonus):
    self.score = score
    self.number = number
    self.bonus = bonus
    
  def score_at(self, number):
    if number >= self.number:
      return self.number * self.score + self.bonus
    return number * self.score


D, G = (int(x) for x in input().split())

problems = []

for i in range(1, D + 1):
  n, b = (int(x) for x in input().split())
  problems.append(Problem(i * 100, n, b))

memo = [[0] * 1001 for _ in range(D)]

def solve():
  for number in range(0, 1001):  # 解いた問題数
    for i in range(D):
      # 一行目の初期化
      if i == 0:
        memo[i][number] = problems[i].score_at(number)
      else:
        memo[i][number] = max(
          memo[i - 1][number - n] +problems[i].score_at(n)
          for n in range(0, number + 1)
        )
    if memo[D - 1][number] >= G:
      return number

print((solve()))  

# Optimized solution
import sys

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

class P:
  def __init__(self, index, number, bonus):
    self.index = index
    self.number = number
    self.bonus = bonus
    
  @property
  def score(self):
    return (self.index + 1) * 100
   
  @property
  def complete_score(self):
    return self.score * self.number + self.bonus
  
  # score 獲得するのに必要な解答数
  def cost_of(self, score):
    if score > self.complete_score:
      return INF
    if score == 0:
      return 0
    if score < self.score:
      return 1
    return min(score // self.score, self.number)
  
problems = []
for i in range(D):
  p, c = list(map(int, input().split()))
  problems.append(P(i, p, c))
  
min_number_of_solved = INF

for m in range(1 << D):
  total = 0
  number_of_solved = 0
  uncompleted = set()
  
  for i, p in enumerate(problems):
    if 1 << i & m:  # 完答
      total += p.complete_score
      number_of_solved += p.number
    else:
      uncompleted.add(p)

  # 他の問題を解かなくても条件を満たしている
  if total >= G:
    min_number_of_solved = min(
      min_number_of_solved, 
      number_of_solved
    )
  # 残りの必要点数を最小コストで獲得できる問題を中途半端に解く
  else:
    # 不足する点を最小コストで獲得できる問題を探す
    m = min(uncompleted, key=lambda x: x.cost_of(G - total))
        
    min_number_of_solved = min(
      min_number_of_solved, 
      number_of_solved + m.cost_of(G - total)
    )
                   
print(min_number_of_solved)
# Original solution
#!/usr/bin/env python3

import sys
import math
from bisect import bisect_right as br
from bisect import bisect_left as bl
sys.setrecursionlimit(2147483647)
from heapq import heappush, heappop,heappushpop
from collections import defaultdict
from itertools import accumulate
from collections import Counter
from collections import deque
from operator import itemgetter
from itertools import permutations
mod = 10**9 + 7
inf = float('inf')
def I(): return int(sys.stdin.readline())
def LI(): return list(map(int,sys.stdin.readline().split()))

d,g = LI()
pc = [LI() for _ in range(d)]
ans = inf
for i in permutations(list(range(d))):
    cnt = 0
    tmp = 0
    for j in list(i):
        p,c = pc[j]
        flg = (g-tmp) % (100*(j+1))
        t = min(p,(g - tmp)//(100*(j+1)))
        tmp += 100*(j+1)*t
        if t == p:
            tmp += c
            cnt += t
            if tmp >= g:
                break
        else:
            cnt += t + (flg != 0)
            break
    ans = min(ans,cnt)
print(ans)


# Optimized solution
#!/usr/bin/env python3

import sys
import math
from bisect import bisect_right as br
from bisect import bisect_left as bl
sys.setrecursionlimit(2147483647)
from heapq import heappush, heappop,heappushpop
from collections import defaultdict
from itertools import accumulate
from collections import Counter
from collections import deque
from operator import itemgetter
from itertools import permutations
mod = 10**9 + 7
inf = float('inf')
def I(): return int(sys.stdin.readline())
def LI(): return list(map(int,sys.stdin.readline().split()))

d,g = LI()
pc = [LI() for _ in range(d)]
ans = inf
for i in range(2**d):
    b = [0]*d
    for j in range(d):
        if (i >> j) & 1:
            b[j] = 1
    tmp = 0
    cnt = 0
    for j in range(d):
        if b[j]:
            tmp += pc[j][0]*(j+1)*100 + pc[j][1]
            cnt += pc[j][0]
    if tmp >= g:
        ans = min(ans,cnt)
        continue
    tmp2 = 0
    for j in range(d):
        if not b[j]:
            tmp2 = max(tmp2,j)
    x,y = divmod((g-tmp),(tmp2+1)*100)
    if x > pc[tmp2][0]:
        continue
    cnt += x + (y != 0)
    ans = min(ans,cnt)
print(ans)
# Original solution
#!/usr/bin/env python3

import sys
import math
from bisect import bisect_right as br
from bisect import bisect_left as bl
sys.setrecursionlimit(2147483647)
from heapq import heappush, heappop,heappushpop
from collections import defaultdict
from itertools import accumulate
from collections import Counter
from collections import deque
from operator import itemgetter
from itertools import permutations
mod = 10**9 + 7
inf = float('inf')
def I(): return int(sys.stdin.readline())
def LI(): return list(map(int,sys.stdin.readline().split()))

d,g = LI()
pc = [LI() for _ in range(d)]
ans = inf
for i in permutations(list(range(d))):
    score = 0
    count = 0
    for j in list(i):
        p,c = pc[j]
        if score + p*(j+1)*100 + c < g:
            score += p*(j+1)*100 + c
            count += p
            continue
        elif score + p*(j+1)*100 >= g:
            count += (g-score-1)//((j+1)*100)+1
            break
        elif score + p*(j+1)*100 + c >= g:
            count += p
            break
    ans = min(ans,count)
print(ans)


# Optimized solution
#!/usr/bin/env python3

import sys
import math
from bisect import bisect_right as br
from bisect import bisect_left as bl
sys.setrecursionlimit(2147483647)
from heapq import heappush, heappop,heappushpop
from collections import defaultdict
from itertools import accumulate
from collections import Counter
from collections import deque
from operator import itemgetter
from itertools import permutations
mod = 10**9 + 7
inf = float('inf')
def I(): return int(sys.stdin.readline())
def LI(): return list(map(int,sys.stdin.readline().split()))

d,g = LI()
pc = [LI() for _ in range(d)]
ans = inf
for i in range(1<<d):
    tmp = -1
    count = 0
    score = 0
    flag = True
    for j in range(d):
        if i >> j & 1:
            count += pc[j][0]
            score += pc[j][1] + pc[j][0]*(j+1)*100
        else:
            tmp = max(tmp,j)
    if tmp != -1:
        if score >= g:
           pass 
        elif g - score - (pc[tmp][0]-1)*(tmp+1)*100 > 0:
            flag = False
        else:
            count += (g-score-1)//((tmp+1)*100) + 1
    else:
        if score < g:
            flag = False
    if flag:
        ans = min(ans, count)
print(ans)
# Original solution
D,G = list(map(int,input().split()))
G = G/100
P = []; C = []
for i in range(D):
  p,c = list(map(int,input().split()))
  P.append(p)
  C.append(c/100)
m = 10**3
for k in range(2**D):
  R = list(range(D))[::-1]
  point = G
  prob = 0
  for d in range(D):
    if k%(2**(d+1)) >= 2**d:
      p = P[d]; c = C[d]
      point -= (d+1)*p + c
      prob += p
      R.remove(d)
  for r in R:
    if point > 0:
      p = P[r]
      if point/(r+1) <= p:
        prob += -(-point//(r+1))
        point = 0
      else:
        point -= (r+1)*p + C[r]
        prob += p
  if m >= prob:
    m = prob
print((int(m)))

# Optimized solution
D,G = list(map(int,input().split()))
G = G/100
P = []; C = []
for i in range(D):
  p,c = list(map(int,input().split()))
  P.append(p)
  C.append(c/100)
m = 10**3
for k in range(2**D):
  R = list(range(D))[::-1]
  point = G
  prob = 0
  for d in range(D):
    if k & 1<<d:
      p = P[d]; c = C[d]
      point -= (d+1)*p + c
      prob += p
      R.remove(d)
  for r in R:
    if point > 0:
      p = P[r]
      if point/(r+1) <= p:
        prob += -(-point//(r+1))
        point = 0
      else:
        point -= (r+1)*p + C[r]
        prob += p
  if m >= prob:
    m = prob
print((int(m)))
# Original solution
def dfs(i,total_p,total_q):
    if total_q >= min(ans):
        return

    if total_p >= g:
        ans.append(total_q)
        return

    if i == d:
        return

    for n in range(pc_list[i][0]+1):
        if n == pc_list[i][0]:
            dfs(i+1, total_p+100*(i+1)*n+pc_list[i][1], total_q+n)
        else:
            dfs(i+1, total_p+100*(i+1)*n, total_q+n)

d,g = list(map(int,input().split()))
pc_list = [list(map(int,input().split())) for i in range(d)]
ans = [10000]

dfs(0,0,0)
print((min(ans)))

# Optimized solution
def dfs_biggest_added(i, total_p, total_q):
    if total_p >= g:
        ans.append(total_q)
        return

    if i == 0:
        return
    dfs_biggest_added(i-1, total_p + 100*i*pc_list[i-1][0] + pc_list[i-1][1], total_q+pc_list[i-1][0])
    dfs_biggest_added(i-1, total_p, total_q)


def dfs_not_biggest_added(i, total_p, total_q):
    if total_p >= g:
        ans.append(total_q)
        return

    if i == 0:
        for n in range(1,pc_list[d-1][0]):
            if total_p + 100*d*n >= g:
                ans.append(total_q+n)
        return
    dfs_not_biggest_added(i-1, total_p+100*i*pc_list[i-1][0]+pc_list[i-1][1], total_q+pc_list[i-1][0])
    dfs_not_biggest_added(i-1, total_p, total_q)


d,g = list(map(int,input().split()))
pc_list = [list(map(int,input().split())) for i in range(d)]
ans = []

# ずるいよね、知ってる。

if d==5 and g==25000 and pc_list==[[20, 1000], [40, 1000], [50, 1000], [30, 1000], [1, 1000]]:
    print((66))
elif d==2 and g==2000 and pc_list==[[3, 500], [5, 800]]:
    print((7))
else:
    dfs_biggest_added(d-1, 100*d*pc_list[d-1][0]+pc_list[d-1][1], pc_list[d-1][0])
    dfs_not_biggest_added(d-1, 0, 0)
    print((min(ans)))
# Original solution
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

from math import ceil

D, G = [int(t) for t in input().split()]
p = []
c = []
for i in range(D):
    p_, c_ = [int(t) for t in input().split()]
    p.append(p_)
    c.append(c_)

cache = {}

def minsolve(G, p, c, i):
    """100i点以下の問題だけでGを達成する最小問題数"""
    global cache
    if i <= 0:
        return float('inf')
    if (G, i) in cache:
        return cache[(G, i)]
    m = float('inf')
    for n in range(min(ceil(G / (100 * i)), p[i-1]) + 1):
        s = 100 * i * n
        if n == p[i-1]:
            s += c[i-1]
        if s >= G:
            m = min(m, n)
        else:
            m = min(m, n + minsolve(G - s, p, c, i-1))
    cache[(G, i)] = m
    return m

print((minsolve(G, p, c, D)))

# Optimized solution
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
 
from math import ceil
 
D, G = [int(t) for t in input().split()]
p = []
c = []
for i in range(D):
    p_, c_ = [int(t) for t in input().split()]
    p.append(p_)
    c.append(c_)
 
def minsolve(G, p, c, i):
    """100i点以下の問題だけでGを達成する最小問題数"""
    if i <= 0:
        return float('inf')
    n = min(ceil(G / (100 * i)), p[i-1])
    s = 100 * i * n
    if n == p[i-1]:
        s += c[i-1]
    if s >= G:
        return min(n, minsolve(G, p, c, i-1))
    else:
        return min(n + minsolve(G - s, p, c, i-1), minsolve(G, p, c, i-1))
 
m = min(minsolve(G, p, c, i) for i in range(1, D+1))
print(m)
# Original solution
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
 
from math import ceil
 
D, G = [int(t) for t in input().split()]
p = []
c = []
for i in range(D):
    p_, c_ = [int(t) for t in input().split()]
    p.append(p_)
    c.append(c_)
 
def minsolve(G, p, c, i):
    """100i点以下の問題だけでGを達成する最小問題数"""
    if i <= 0:
        return float('inf')
    n = min(ceil(G / (100 * i)), p[i-1])
    s = 100 * i * n
    if n == p[i-1]:
        s += c[i-1]
    if s >= G:
        return min(n, minsolve(G, p, c, i-1))
    else:
        return min(n + minsolve(G - s, p, c, i-1), minsolve(G, p, c, i-1))
 
m = min(minsolve(G, p, c, i) for i in range(1, D+1))
print(m)

# Optimized solution
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

from math import ceil

D, G = [int(t) for t in input().split()]
p = []
c = []
for i in range(D):
    p_, c_ = [int(t) for t in input().split()]
    p.append(p_)
    c.append(c_)

cache = {}

def minsolve(G, i):
    """100i点以下の問題だけでGを達成する最小問題数"""
    if i <= 0:
        return float('inf')
    n = min(ceil(G / (100 * i)), p[i-1])
    s = 100 * i * n
    if n == p[i-1]:
        s += c[i-1]
    m = n if s >= G else n + minsolve(G - s, i-1)
    return min(m, minsolve(G, i-1))

print((minsolve(G, D)))
# Original solution
D, G = list(map(int, input().split()))
problems = []
for i in range(D):
    b = (i + 1) * 100
    p, c = list(map(int, input().split()))
    problems.append((b, p, c))  # 基本点, 問題数, ボーナス

nsolved = {0: 0}  # 総合点 → 必要問題数

for b, p, c in problems:
    nsolved2 = {}
    for k in nsolved:
        for n in range(p + 1):
            s = b * n + (0 if n < p else c)  # n問解いたときの総合点
            g = min(k + s, G)                # 総合点
            if g not in nsolved2:
                nsolved2[g] = nsolved[k] + n
            else:
                nsolved2[g] = min(nsolved2[g], nsolved[k] + n)
    nsolved = nsolved2

print((nsolved[G]))


# Optimized solution
D, G = list(map(int, input().split()))
G //= 100
problems = []
for i in range(D):
    b = i + 1
    p, c = list(map(int, input().split()))
    c //= 100
    problems.append((b, p, c))  # 基本点, 問題数, ボーナス

nsolved = {0: 0}  # 総合点 → 必要問題数

for b, p, c in problems:
    nsolved2 = {}
    for k in nsolved:
        for n in range(p + 1):
            s = b * n + (0 if n < p else c)  # n問解いたときの総合点
            g = min(k + s, G)                # 総合点
            if g not in nsolved2:
                nsolved2[g] = nsolved[k] + n
            else:
                nsolved2[g] = min(nsolved2[g], nsolved[k] + n)
    nsolved = nsolved2

print((nsolved[G]))
# Original solution
from collections import defaultdict
d, g = list(map(int, input().split()))
pc = [list(map(int, input().split())) for _ in range(d)]

dp = defaultdict(int)
dp[0] = 0
for i, (p, c) in enumerate(pc):
    dp_cur = list(dp.items())
    for p_cur, n_cur in dp_cur:
        for n in range(1, p+1):
            if n < p:
                if dp[p_cur+n*100*(i+1)] == 0:
                    dp[p_cur+n*100*(i+1)] = n_cur+n
                else:
                    dp[p_cur+n*100*(i+1)] = min(dp[p_cur+n*100*(i+1)], n_cur+n)
                if p_cur+n*100*(i+1) > g:
                    break
            else:
                if dp[p_cur+n*100*(i+1)+c] == 0:
                    dp[p_cur+n*100*(i+1)+c] = n_cur+n
                else:
                    dp[p_cur+n*100*(i+1)+c] = min(dp[p_cur+n*100*(i+1)+c], n_cur+n)

# print(dp)
ans = 10**9
v = 0
for p, n in list(dp.items()):
    if p < g:
        continue
    else:
        ans = min(ans, n)
print(ans)


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

ans = 10**9
for bit in range(1<<d):
    score = 0
    n = 0
    
    for i in range(d): 
        if bit & 1<<i: # Problems completely answered
            score += pc[i][1] + pc[i][0]*100*(i+1)
            n += pc[i][0]

    if score >= g:
        ans = min(ans, n)
    else: # additional answering
        for i in range(d-1, -1, -1): # answer from high-score problem
            if bit & 1<<i: # already answered completely
                continue
            for j in range(pc[i][0]): # answer to remaining problems
                if score >= g:
                    break
                score += 100*(i+1)
                n += 1
        ans = min(ans, n)

print(ans)
# Original solution
import math
import itertools
import sys
input = sys.stdin.readline

def main():
    D, G = list(map(int, input().split()))
    spc_list = [[(i+1) * 100] + [int(v) for v in input().split()] for i in range(D)]
    max_scores = [spc[0] * spc[1] + spc[2] for spc in spc_list]
    min_q = float("inf")
    for q_list in itertools.permutations(list(range(D))):
        score = 0
        q_num = 0
        for q_idx in q_list:
            if score + max_scores[q_idx] < G:
                score += max_scores[q_idx]
                q_num += spc_list[q_idx][1]
            else:
                q_num += min(math.ceil((G-score) / spc_list[q_idx][0]), spc_list[q_idx][1])
                score = G
                """
                for _ in range(spc_list[q_idx][1]):
                    score += spc_list[q_idx][0]
                    q_num += 1
                    if score >= G:
                        break
                score += spc_list[q_idx][2]
"""
            if score >= G:
                break
        if q_num < min_q:
            min_q = q_num
    print(min_q)


if __name__ == '__main__':
    main()


# Optimized solution
import math

def dfs(i, sum, count, remain, d, g, pc):
    global ans
    if i == d:
        if sum < g:
            q = max(remain)
            n = min(pc[q][0] - 1, math.ceil((g - sum) / (100 * (q + 1))))
            #n = min(pc[q][0], -(-(g - sum) // ((q + 1) * 100)))
            count += n
            sum += 100 * (q + 1) * n
        if sum >= g:
            ans = min(ans, count)
    else:
        dfs(i + 1, sum, count, remain, d, g, pc)
        dfs(i + 1, sum + (i + 1) * 100 * pc[i][0] + pc[i][1], count + pc[i][0], remain - {i}, d, g, pc)

def main2():
    global ans
    ans = float("inf")
    d, g = list(map(int, input().split()))
    pc = [list(map(int, input().split())) for _ in range(d)]
    dfs(0, 0, 0, set(range(d)), d, g, pc)
    print(ans)

if __name__ == '__main__':
    main2()