#include<iostream>
#include<vector>
#include<string>
#include<algorithm>

using namespace std;

struct fast_io {
	fast_io(){
		std::cin.tie(nullptr);
		std::ios::sync_with_stdio(false);
	};
} fio;

#define int long long

class Karatsuba{
	int base = 1'000'000'000; // base > 1
	vector<int> num;
	bool sign; // true : +   false : -
	
public:
	
	Karatsuba(){
		sign = false;
		num.push_back(0);
	}
	
	Karatsuba(size_t size){
		sign = false;
		num.resize(size);
	}
	
	~Karatsuba(){
	}
	
	Karatsuba operator+(const Karatsuba &k) const {
		Karatsuba res;
		
		if(k.sign^sign) {
			int maxs = max(k.num.size(), num.size());
			bool com = true; // num >= k.num
			int index = -1;
			
			for(int i = maxs-1; i >= 0; i--){
				int a = 0, b = 0;
				if(i < num.size()) a = num[i];
				if(i < k.num.size()) b = k.num[i];
				
				if(a < b) {
					com = false;
					index = i;
					break;
				} else if(a > b) {
					com = true;
					index = i;
					break;
				}
			}
			
			if(index == -1){
				res.sign = false;
				res.num.push_back(0);
			} else if(com) {
				res.num.resize(index+1);
				
				for(int i = 0; i <= index; i++){
					if(i <  num.size()) res.num[i] += num[i];
					if(i < k.num.size()) res.num[i] -= k.num[i];
					
					if(res.num[i] < 0) {
						res.num[i] += base;
						
						for(int j = i+1; ; j++){
							if(num[j]) {
								res.num[j]--;
								break;
							} else {
								res.num[j] = base-1;
							}
						}
					}
				}
				
				if(sign == true) res.sign = true;
			} else {
				res.num.resize(index+1);
				
				for(int i = 0; i <= index; i++){
					if(i <  num.size()) res.num[i] -= num[i];
					if(i < k.num.size()) res.num[i] += k.num[i];
					
					if(res.num[i] < 0) {
						res.num[i] += base;
						
						for(int j = i+1; ; j++){
							if(k.num[j]) {
								res.num[j]--;
								break;
							} else {
								res.num[j] = base-1;
							}
						}
					}
				}
				
				if(k.sign == true) res.sign = true;
			}
			
			while(res.num.back() == 0 && res.num.size() >= 2){
				res.num.pop_back();
			}
			
		} else {
			res.num.resize(max(k.num.size(), num.size()));
			res.sign = sign;
			
			for(int i = 0; i < res.num.size(); i++){
				if(i < k.num.size()) res.num[i] += k.num[i];
				if(i <  num.size()) res.num[i] += num[i];
				if(res.num[i] >= base) {
					if(i + 1 == res.num.size()) {
						res.num.push_back(1);
					} else {
						res.num[i+1] += 1;
					}
					
					res.num[i] %= base;
				}
			}
		}
		
		return res;
	}
	
	Karatsuba operator-(const Karatsuba &k) const {
		Karatsuba res;
		
		if(k.sign^sign^1) {
			int maxs = max(k.num.size(), num.size());
			bool com = true; // num >= k.num
			int index = -1;
			
			for(int i = maxs-1; i >= 0; i--){
				int a = 0, b = 0;
				if(i < num.size()) a = num[i];
				if(i < k.num.size()) b = k.num[i];
				
				if(a < b) {
					com = false;
					index = i;
					break;
				} else if(a > b) {
					com = true;
					index = i;
					break;
				}
			}
			
			if(index == -1){
				res.sign = false;
				res.num.push_back(0);
			} else if(com) {
				res.num.resize(index+1);
				
				for(int i = 0; i <= index; i++){
					if(i <  num.size()) res.num[i] += num[i];
					if(i < k.num.size()) res.num[i] -= k.num[i];
					
					if(res.num[i] < 0) {
						res.num[i] += base;
						
						for(int j = i+1; ; j++){
							if(num[j]) {
								res.num[j]--;
								break;
							} else {
								res.num[j] = base-1;
							}
						}
					}
				}
				
				if(sign == true) res.sign = true;
			} else {
				res.num.resize(index+1);
				
				for(int i = 0; i <= index; i++){
					if(i <  num.size()) res.num[i] -= num[i];
					if(i < k.num.size()) res.num[i] += k.num[i];
					
					if(res.num[i] < 0) {
						res.num[i] += base;
						
						for(int j = i+1; ; j++){
							if(k.num[j]) {
								res.num[j]--;
								break;
							} else {
								res.num[j] = base-1;
							}
						}
					}
				}
				
				if(k.sign == false) res.sign = true;
			}
			
			while(res.num.back() == 0 && res.num.size() >= 2){
				res.num.pop_back();
			}
			
		} else {
			res.num.resize(max(k.num.size(), num.size()));
			res.sign = sign;
			
			for(int i = 0; i < res.num.size(); i++){
				if(i < k.num.size()) res.num[i] += k.num[i];
				if(i <  num.size()) res.num[i] += num[i];
				if(res.num[i] >= base) {
					if(i + 1 == res.num.size()) {
						res.num.push_back(1);
					} else {
						res.num[i+1] += 1;
					}
					
					res.num[i] %= base;
				}
			}
		}
		
		return res;
	}
	
	Karatsuba operator*(const Karatsuba &k) const {
		Karatsuba res;
		
		int maxs = max(k.num.size(), num.size());
		
		res.sign = sign^k.sign;
		
		if(maxs <= 1) {
			int z0;
			res.num.resize(1,0);
			z0 = num[0] * k.num[0];
			res.num[0] = z0 % base;
			if(z0/base) res.num.push_back(z0/base);
		} else {
			int b = (maxs+1)/2;
			Karatsuba z0, z1, z2;
			Karatsuba x0(b), x1, y0(b), y1;
			
			if(num.size() <= b) x1.resize(1);
			else x1.resize(b);
			
			if(k.num.size() <= b) y1.resize(1);
			else y1.resize(b);
			
			for(int i = 0; i < b; i++){
				if(i < num.size()) x0.num[i] = num[i];
				if(i < k.num.size()) y0.num[i] = k.num[i];
			}
			
			for(int i = b; i < 2*b; i++){
				if(i < num.size()) x1.num[i-b] = num[i];
				if(i < k.num.size()) y1.num[i-b] = k.num[i];
			}
			
			while(x0.num.back() == 0 && x0.num.size() >= 2){
				x0.num.pop_back();
			}
			while(x1.num.back() == 0 && x1.num.size() >= 2){
				x1.num.pop_back();
			}
			while(y0.num.back() == 0 && y0.num.size() >= 2){
				y0.num.pop_back();
			}
			while(y1.num.back() == 0 && y1.num.size() >= 2){
				y1.num.pop_back();
			}
			
			z2 = x1 * y1;
			z0 = x0 * y0;
			z1 = z2 + z0 - (x1 - x0) * (y1 - y0);
			
			res.resize(max({(int)z0.size(), (int)z1.size()+b, (int)z2.size()+b*2}));
			
			for(int i = 0; i < res.size(); i++){
				if(i < z0.size()) res.num[i] += z0.num[i];
				if(i >= b && i-b < z1.size()) res.num[i] += z1.num[i-b];
				if(i >= 2*b && i-b*2 < z2.size()) res.num[i] += z2.num[i-b*2];
				
				if(res.num[i] >= base) {
					if(i + 1 < res.num.size()) {
						res.num[i+1] += res.num[i] / base;
						res.num[i] %= base;
					} else {
						res.num.push_back(res.num[i] / base);
						res.num[i] %= base;
					}
				}
			}
			
			while(res.num.back() == 0 && res.num.size() >= 2){
				res.num.pop_back();
			}
		}
		
		if(res.num.size() == 1 && res.num[0] == 0) res.sign = false;
		
		return res;
	}
	
	
	Karatsuba& operator=(const Karatsuba& k) & {
		this->num = k.num;
		this->sign = k.sign;
		
		return *this;
	}
	
	bool operator<(const Karatsuba &k) const {
		if(k.sign^sign) {
			if(sign == false) return false;
			if(k.sign == false) return true;
		} else if(sign){
			if(num.size() > k.num.size()) return true;
			if(num.size() < k.num.size()) return false;
			
			for(int i = (int)num.size()-1; i >= 0; i--){
				int a = num[i];
				int b = k.num[i];
				
				if(b < a) {
					return true;
				} else if(b > a) {
					return false;
				}
			}
		} else {
			if(num.size() > k.num.size()) return false;
			if(num.size() < k.num.size()) return true;
			
			for(int i = (int)num.size()-1; i >= 0; i--){
				int a = num[i];
				int b = k.num[i];
				
				if(b < a) {
					return false;
				} else if(b > a) {
					return true;
				}
			}
		}
		
		return false;
	}

	size_t size() const {
		return num.size();
	}
	
	void resize(size_t size) {
		num.resize(size);
	}
	
	
	string to_string() const {
		string res;
		
		if(sign == true) res += "-";
		
		// for(int i = (int)num.size()-1; i >= 0; i--){
			// res += '0' + num[i];
		// }
		
		int bd = -1, tbase = base;
		
		while(tbase){
			bd++;
			tbase /= 10;
		}
		
		for(int i = (int)num.size()-1; i >= 0; i--){
			
			int tnum = num[i];
			string tstr;
			
			for(int j = bd; j > 0; j--){
				tstr += '0' + tnum % 10;
				tnum /= 10;
				
				if(i + 1 == num.size() && tnum == 0) break;
			}
			
			reverse(tstr.begin(), tstr.end());
			
			res += tstr;
		}
		
		
		return res;
	}
	
	void string_to(string s){
		int b = 0;
		
		sign = false;
		
		if(s[0] == '-') {
			sign = true;
			b++;
		}
		
		num.clear();
		
		
		// for(int i = (int)s.size()-1; i >= b; i--){
			// num.push_back(s[i] - '0');
		// }
		
		int bd = -1, tbase = base;
		
		while(tbase){
			bd++;
			tbase /= 10;
		}
		
		
		int maxd = ((int)s.size()-b+bd-1)/(bd);
		num.resize(maxd);
		
		for(int i = 0, j = (int)s.size()-1; i < maxd; i++){
			for(int k = 0, l = 1; k < bd && j >= b ; k++, j--, l *= 10){
				num[i] += (s[j] - '0') * l;
			}
		}
		
		while(num.back() == 0 && num.size() >= 1){
			num.pop_back();
		}
	
		if(num.size() == 0) {
			sign = false;
			num.push_back(0);
		}
	}
};

std::ostream& operator<<(std::ostream& lhs, const Karatsuba& rhs) {
	
	lhs << rhs.to_string();
	return lhs;
}

std::istream& operator>>(std::istream& lhs, Karatsuba& rhs) {
	string str;
	
	cin>>str;
	
	rhs.string_to(str);
	
	return lhs;
}

signed main(){
	
	Karatsuba a, b;
	
	cin>>a>>b;
	
	cout<<a * b<<endl;
	
	return 0;
}


Measured memory_bytes: 3272