'''
思路
将两个数字都转成10的次幂形式,次幂上的系数相当于多项式的系数,求两个数字对应的多项式的
乘积即可
'''
from typing import List
import math
from collections import deque
N = 300010
PI = math.acos(-1)
aa = [complex(0,0) for _ in range(N)] # 多项式A的系数, 系数用复数表示
bb = [complex(0,0) for _ in range(N)] # 多项式B的系数,系数用复数表示
ret = [complex(0,0) for _ in range(N)] # 多项式的系数序列,用于保存计算结果
rev = [0] * N
# fft变换,inv = 1表示正变换,inv = -1表示反变换, m表示多项式A的最高次数 A = a0 + a1*x + ... ... + am * (x^m)
# 正变换将长度为N+1的系数序列转换为长度为N+1的 (x + yj) 这样的复数序列,(wk, xk+yk*j) 是多项式A上的一个点,wk是第k个n次单位根
# 逆变换将 (wk, xk+yk*j) 点序列变回系数序列
def fft(a: List, m, inv):
tot = m
for i in range(tot):
if i < rev[i]:
a[i], a[rev[i]] = a[rev[i]], a[i]
mid = 1
while mid < tot:
w1 = complex(math.cos(PI/mid), inv * math.sin(PI / mid))
i = 0
while i < tot:
wk = 1+0j
for j in range(mid):
x, y = a[i+j], wk * a[i+j+mid]
a[i+j] = x+y
a[i+j+mid] = x-y
wk = wk * w1
i += mid * 2
mid <<= 1
# 多项式乘法,a, b分别是多项式A和B的系数序列, 结果保存在
# m, n 分别表示多项式A和多项式B的最高次数
# 返回长度为m+n+1的系数序列,表示多项式A*B的每一项的系数
def poly_mul(a: List[complex], m, b: List[complex], n) -> List[complex]:
if m == 0 and n == 0:
return [a[0] * b[0]]
bit = 0
while (1 << bit) < m + n + 1:
bit += 1
tot = 1 << bit
for i in range(tot):
rev[i] = (rev[i>>1] >>1) | ((i&1) << (bit-1))
# 系数不够的部分,都要补上0
for i in range(m+1, tot):
a[i] = 0+0j
# 系数不够的部分,都要补上0
for i in range(n+1, tot):
b[i] = 0+0j
# 正变换将多项式换成点表示形式
fft(a, tot, 1)
fft(b, tot, 1)
# 多项式的点表示法做乘积
for i in range(tot):
ret[i] = a[i] * b[i]
# 结果变换回系数表示法
fft(ret, tot, -1)
# 反变换之后的多项式系数全部要除以tot
for i in range(m+n+1):
ret[i] /= tot
return ret[:m+n+1]
a = input()
b = input()
m = len(a)
for i in range(m):
val = ord(a[i]) - ord('0')
c = m - 1 -i
aa[c] = val+0j
n = len(b)
for i in range(n):
val = ord(b[i]) - ord('0')
c = n-1-i
bb[c] = val+0j
ret = poly_mul(aa, m-1, bb, n-1)
ans = deque()
carry = 0
for i in range(m-1+n-1+1):
val = round(ret[i].real + carry)
ans.appendleft(val % 10)
carry = val.real // 10
while carry != 0:
ans.appendleft(carry % 10)
carry //= 10
while len(ans) >= 2 and ans[0] == 0:
ans.popleft()
for val in ans:
print(val, end = '')
print()