Buggy python submission (verdict: Runtime Error):
## C
n, m = map(int,input().split())
a = [0] * n
b = [0] * n
for i in range(0,n):
    a[i], b[i] = map(int,input().split())

dict = {}
for i in range(0,n):
    dict[a[i]] = b[i]

l = sorted(a)

for j in range(0,n-1):
    if l[j] == l[j-1]:
        dic[l[j]] = dic[l[j]]+dic[l[j-1]]
        l[j-1] = -j
        dic[l[j-1]] = 0

#print(l)
#print(dict)

ex = 0
num = 0

for i in range(0,n):
    #print(l[i])
    if num + dict[l[i]] <= m:
        ex = ex + l[i] * dict[l[i]]
        num = num + dict[l[i]]
    else:
        ex = ex + l[i] * (m - num)
        num = m
    #print([ex,num])
    if num == m:
        break

print(ex)






Fixed submission:
##### C 再チャレンジ

##以下、二次元配列を、各リストの最初の要素でソートするアルゴリズム

def two_dim_merge_sort(arr):#＃arrは二次元配列
    if len(arr) <= 1:
        return arr

    mid = len(arr) // 2
    # ここで分割を行う
    left = arr[:mid]
    right = arr[mid:]

    # 再帰的に分割を行う
    left = two_dim_merge_sort(left)
    right = two_dim_merge_sort(right)

    # returnが返ってきたら、結合を行い、結合したものを次に渡す
    return two_dim_merge(left, right)


def two_dim_merge(left, right):
    merged = []
    l_i, r_i = 0, 0

    # ソート済み配列をマージするため、それぞれ左から見ていくだけで良い
    while l_i < len(left) and r_i < len(right):
        # ここで=をつけることで安定性を保っている
        if left[l_i][0] <= right[r_i][0]:
            merged.append(left[l_i])
            l_i += 1
        else:
            merged.append(right[r_i])
            r_i += 1

    # 上のwhile文のどちらかがFalseになった場合終了するため、あまりをextendする
    if l_i < len(left):
        merged.extend(left[l_i:])
    if r_i < len(right):
        merged.extend(right[r_i:])
    return merged

##ここまで

n, m = map(int,input().split())

l = [0]*n

for i in range(0,n):
    l[i] = list(map(int,input().split()))

s = two_dim_merge_sort(l)

num = 0
ex = 0

for i in range(0,n):
    if num + s[i][1] <= m:
        ex = ex + s[i][0] * s[i][1]
        num = num + s[i][1]
    else:
        ex = ex + s[i][0] * (m-num)
        num = m
    if num == m:
        break
        
print(ex)

Buggy python submission (verdict: Runtime Error):
## C
n, m = map(int,input().split())
a = [0] * n
b = [0] * n
for i in range(0,n):
    a[i], b[i] = map(int,input().split())

dict = {}
for i in range(0,n):
    dict[a[i]] = b[i]

l = sorted(a)

for j in range(0,n-1):
    if l[j] == l[j-1]:
        dic[l[j]] = dic[l[j]]+dic[l[j-1]]
        dic[l[j-1]] = 0
        l[j-1] = -j

#print(l)
#print(dict)

ex = 0
num = 0

for i in range(0,n):
    #print(l[i])
    if num + dict[l[i]] <= m:
        ex = ex + l[i] * dict[l[i]]
        num = num + dict[l[i]]
    else:
        ex = ex + l[i] * (m - num)
        num = m
    #print([ex,num])
    if num == m:
        break

print(ex)






Fixed submission:
##### C 再チャレンジ

##以下、二次元配列を、各リストの最初の要素でソートするアルゴリズム

def two_dim_merge_sort(arr):#＃arrは二次元配列
    if len(arr) <= 1:
        return arr

    mid = len(arr) // 2
    # ここで分割を行う
    left = arr[:mid]
    right = arr[mid:]

    # 再帰的に分割を行う
    left = two_dim_merge_sort(left)
    right = two_dim_merge_sort(right)

    # returnが返ってきたら、結合を行い、結合したものを次に渡す
    return two_dim_merge(left, right)


def two_dim_merge(left, right):
    merged = []
    l_i, r_i = 0, 0

    # ソート済み配列をマージするため、それぞれ左から見ていくだけで良い
    while l_i < len(left) and r_i < len(right):
        # ここで=をつけることで安定性を保っている
        if left[l_i][0] <= right[r_i][0]:
            merged.append(left[l_i])
            l_i += 1
        else:
            merged.append(right[r_i])
            r_i += 1

    # 上のwhile文のどちらかがFalseになった場合終了するため、あまりをextendする
    if l_i < len(left):
        merged.extend(left[l_i:])
    if r_i < len(right):
        merged.extend(right[r_i:])
    return merged

##ここまで

n, m = map(int,input().split())

l = [0]*n

for i in range(0,n):
    l[i] = list(map(int,input().split()))

s = two_dim_merge_sort(l)

num = 0
ex = 0

for i in range(0,n):
    if num + s[i][1] <= m:
        ex = ex + s[i][0] * s[i][1]
        num = num + s[i][1]
    else:
        ex = ex + s[i][0] * (m-num)
        num = m
    if num == m:
        break
        
print(ex)

Buggy python submission (verdict: Runtime Error):
n, m = map(int,input().split())
a = [0] * n
b = [0] * n
for i in range(0,n):
    a[i], b[i] = map(int,input().split())

dict = {}
for i in range(0,n):
    dict[a[i]] = b[i]
    
for j in range(0,n-1):
    l = sorted(a)
    if l[j] == l[j-1]:
        dic[l[j]] = dic[l[j]]+dic[l[j-1]]
        dic[l[j-1]] = 0
        l[j-1] = -j

#print(l)
#print(dict)

ex = 0
num = 0

for i in range(0,n):
    #print(l[i])
    if num + dict[l[i]] <= m:
        ex = ex + l[i] * dict[l[i]]
        num = num + dict[l[i]]
    else:
        ex = ex + l[i] * (m - num)
        num = m
    #print([ex,num])
    if num == m:
        break

print(ex)





Fixed submission:
##### C 再チャレンジ

##以下、二次元配列を、各リストの最初の要素でソートするアルゴリズム

def two_dim_merge_sort(arr):#＃arrは二次元配列
    if len(arr) <= 1:
        return arr

    mid = len(arr) // 2
    # ここで分割を行う
    left = arr[:mid]
    right = arr[mid:]

    # 再帰的に分割を行う
    left = two_dim_merge_sort(left)
    right = two_dim_merge_sort(right)

    # returnが返ってきたら、結合を行い、結合したものを次に渡す
    return two_dim_merge(left, right)


def two_dim_merge(left, right):
    merged = []
    l_i, r_i = 0, 0

    # ソート済み配列をマージするため、それぞれ左から見ていくだけで良い
    while l_i < len(left) and r_i < len(right):
        # ここで=をつけることで安定性を保っている
        if left[l_i][0] <= right[r_i][0]:
            merged.append(left[l_i])
            l_i += 1
        else:
            merged.append(right[r_i])
            r_i += 1

    # 上のwhile文のどちらかがFalseになった場合終了するため、あまりをextendする
    if l_i < len(left):
        merged.extend(left[l_i:])
    if r_i < len(right):
        merged.extend(right[r_i:])
    return merged

##ここまで

n, m = map(int,input().split())

l = [0]*n

for i in range(0,n):
    l[i] = list(map(int,input().split()))

s = two_dim_merge_sort(l)

num = 0
ex = 0

for i in range(0,n):
    if num + s[i][1] <= m:
        ex = ex + s[i][0] * s[i][1]
        num = num + s[i][1]
    else:
        ex = ex + s[i][0] * (m-num)
        num = m
    if num == m:
        break
        
print(ex)

Buggy python submission (verdict: Runtime Error):
n, m = map(int,input().split())
dict = {}

for i in range(1,n+1):
    a, b = map(int,input().split())
    dict[a] = b

l = list(dict.keys())
l.sort()

#print(l)
#print(dict)

ex = 0
num = 0

for i in range(0,n):
    #print(l[i])
    if num + dict[l[i]] <= m:
        ex = ex + l[i] * dict[l[i]]
        num = num + dict[l[i]]
    else:
        ex = ex + l[i] * (m - num)
        num = m
    #print([ex,num])
    if num == m:
        break

print(ex)
    

Fixed submission:
##### C 再チャレンジ

##以下、二次元配列を、各リストの最初の要素でソートするアルゴリズム

def two_dim_merge_sort(arr):#＃arrは二次元配列
    if len(arr) <= 1:
        return arr

    mid = len(arr) // 2
    # ここで分割を行う
    left = arr[:mid]
    right = arr[mid:]

    # 再帰的に分割を行う
    left = two_dim_merge_sort(left)
    right = two_dim_merge_sort(right)

    # returnが返ってきたら、結合を行い、結合したものを次に渡す
    return two_dim_merge(left, right)


def two_dim_merge(left, right):
    merged = []
    l_i, r_i = 0, 0

    # ソート済み配列をマージするため、それぞれ左から見ていくだけで良い
    while l_i < len(left) and r_i < len(right):
        # ここで=をつけることで安定性を保っている
        if left[l_i][0] <= right[r_i][0]:
            merged.append(left[l_i])
            l_i += 1
        else:
            merged.append(right[r_i])
            r_i += 1

    # 上のwhile文のどちらかがFalseになった場合終了するため、あまりをextendする
    if l_i < len(left):
        merged.extend(left[l_i:])
    if r_i < len(right):
        merged.extend(right[r_i:])
    return merged

##ここまで

n, m = map(int,input().split())

l = [0]*n

for i in range(0,n):
    l[i] = list(map(int,input().split()))

s = two_dim_merge_sort(l)

num = 0
ex = 0

for i in range(0,n):
    if num + s[i][1] <= m:
        ex = ex + s[i][0] * s[i][1]
        num = num + s[i][1]
    else:
        ex = ex + s[i][0] * (m-num)
        num = m
    if num == m:
        break
        
print(ex)