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)

    
import sys

from collections import namedtuple



# 完答 + 最大1種類の問題が半端に解けている状態のとき最適

# 1. 完投する問題を全探索する 2^10

# 2. 残りの問題から配点が一番高い問題を目標に達するまで解く

# 3. 1,2の中で最も回答問題数が少ないケースが答え



Problem = namedtuple('Problem', 'score number bonus')                      



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



problems = []



for i in range(D):

  p, c = list(map(int, input().split()))

  problems.append(

    Problem(

      score = (i + 1) * 100,

      number = p,

      bonus = c

    )

  )



min_num_solved = sys.maxsize

  

for m in range(1 << D):

  score = 0

  num_solved = 0

  partial = None  # 部分的に解く問題

  

  for i, p in enumerate(problems):

    if 1 << i & m:

      # 完答

      score += p.score * p.number + p.bonus

      num_solved += p.number

    else:

      partial = p



  # 中途半端に解かなくてもいいのなら次へ

  if score >= G:

    min_num_solved = min(min_num_solved, num_solved)

    continue

    

  if partial is None:

    raise Exception('全問題完答したのに目標に届かない')

         

  # 中途半端に解く

  extra_num_solved = 0

    

  while extra_num_solved <= partial.number:

    if score >= G:

      min_num_solved = min(

        min_num_solved,

        num_solved + extra_num_solved

      )

      break

    score += partial.score

    extra_num_solved += 1 

          

print(min_num_solved)
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)

import sys
from collections import namedtuple

# 完答 + 最大1種類の問題が半端に解けている状態のとき最適
# 1. 完投する問題を全探索する 2^10
# 2. 残りの問題から配点が一番高い問題を目標に達するまで解く
# 3. 1,2の中で最も回答問題数が少ないケースが答え
Problem = namedtuple("Problem", "score number bonus")
D, G = list(map(int, input().split()))
problems = []
for i in range(D):
    p, c = list(map(int, input().split()))
    problems.append(Problem(score=(i + 1) * 100, number=p, bonus=c))
min_num_solved = sys.maxsize
for m in range(1 << D):
    score = 0
    num_solved = 0
    partial = None  # 部分的に解く問題
    for i, p in enumerate(problems):
        if 1 << i & m:
            # 完答
            score += p.score * p.number + p.bonus
            num_solved += p.number
        else:
            partial = p
    # 中途半端に解かなくてもいいのなら次へ
    if score >= G:
        min_num_solved = min(min_num_solved, num_solved)
        continue
    if partial is None:
        raise Exception("全問題完答したのに目標に届かない")
    # 中途半端に解く
    extra_num_solved = 0
    while extra_num_solved <= partial.number:
        if score >= G:
            min_num_solved = min(min_num_solved, num_solved + extra_num_solved)
            break
        score += partial.score
        extra_num_solved += 1
print(min_num_solved)

+from collections import namedtuple -INF = sys.maxsize +# 完答 + 最大1種類の問題が半端に解けている状態のとき最適 +# 1. 完投する問題を全探索する 2^10 +# 2. 残りの問題から配点が一番高い問題を目標に達するまで解く +# 3. 1,2の中で最も回答問題数が少ないケースが答え +Problem = namedtuple("Problem", "score number bonus") - - -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.append(P(i, p, c)) -min_number_of_solved = INF +    problems.append(Problem(score=(i + 1) * 100, number=p, bonus=c)) +min_num_solved = sys.maxsize -    total = 0 -    number_of_solved = 0 -    uncompleted = set() +    score = 0 +    num_solved = 0 +    partial = None  # 部分的に解く問題 -        if 1 << i & m:  # 完答 -            total += p.complete_score -            number_of_solved += p.number +        if 1 << i & m: +            # 完答 +            score += p.score * p.number + p.bonus +            num_solved += p.number -            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) +            partial = p +    # 中途半端に解かなくてもいいのなら次へ +    if score >= G: +        min_num_solved = min(min_num_solved, num_solved) +        continue +    if partial is None: +        raise Exception("全問題完答したのに目標に届かない") +    # 中途半端に解く +    extra_num_solved = 0 +    while extra_num_solved <= partial.number: +        if score >= G: +            min_num_solved = min(min_num_solved, num_solved + extra_num_solved) +            break +        score += partial.score +        extra_num_solved += 1 +print(min_num_solved)