Problem:
Multiplication of Big Integers
Given two integers $A$ and $B$, compute the product, $A \times B$.
Input
Two integers $A$ and $B$ separated by a space character are given in a line.
Output
Print the product in a line.
Constraints
$-1 \times 10^{1000} \leq A, B \leq 10^{1000}$
Sample Input 1
5 8
Sample Output 1
40
Sample Input 2
100 25
Sample Output 2
2500
Sample Input 3
-1 0
Sample Output 3
0
Sample Input 4
12 -3
Sample Output 4
-36

Submitted solutions:

code_snippet: #include<iostream>
#include<string>
using namespace std;

string fixedNum( string a )
{
    if( a.size() == 1 )
        return a;
    for( int i = 0; i < a.size(); i++ )
        if( '1'<= a[i] && a[i] <= '9' )
            return a.substr( i, a.size() );
    return "0";
}

string calcAddition( string a, string b )
{
    a = fixedNum(a); b = fixedNum(b);
    int as = a.size(), bs = b.size(), d = as > bs ? as - bs : bs - as;
    string s = "0", t = "0";
    for( int i = 0; i < d; i++ )
        as > bs ? t += "0" : s += "0";
    s += a; t += b;

    for( int i = s.size() - 1; i >= 1; i-- )
    {
        s[i] += t[i] - '0';
        if( s[i] > '9' )
        {
            s[i] -= 10;
            s[i-1]++;
        }
    }

    return s[0] == '0' ? s.substr( 1, s.size() ) : s;
}

string calcMultiplication( string a, string b )
{
    a = fixedNum(a); b = fixedNum(b);
    int as = a.size(), bs = b.size(), d = as > bs ? as - bs : bs - as;
    string s = "0", t = "0", x = "", sum = "", zero = "", digit = "";
    for( int i = 0; i < d; i++ )
        as > bs ? t += "0" : s += "0";
    s += a; t += b;

    for( int i = 0; i < s.size(); i++ )
        zero += "0";
    
    x = zero;
    sum = zero;

    for( int i = s.size() - 1; i >= 1; i-- )
    {
        for( int j = s.size() - 1; j >= 1; j-- )
            x[j] = ( t[i] - '0' ) * ( s[j] - '0' );
        for( int j = s.size() - 1; j >= 1; j-- )
        {
            int f = x[j] / 10;
            x[j-1] += f;
            x[j] = x[j] - 10 * f + '0';
        }
        x += digit;
        sum = calcAddition( x, sum );
        digit += "0";
        x = zero;
    }
    return sum;
}

int main()
{
    string a, b;

    cin >> a >> b;

    int as = a.size(), bs = b.size();
    string s = a.substr( 1, as ), t = b.substr( 1, bs );

    if( a[0] == '-' && b[0] == '-' )
        cout << calcMultiplication( s, t ) << endl;
    else if( a[0] >= '0' && b[0] >= '0' )
        cout << calcMultiplication( a, b ) << endl;
    else
    {
        if( a == "0" || b == "0" )
            cout << "0" << endl;
        else if( a[0] == '-' )
            cout << '-' << calcMultiplication( s, b ) << endl;
        else
            cout << '-' << calcMultiplication( a, t ) << endl;
    }
    return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 3512
final_rank: 2

code_snippet: #include <iostream>
#include <string>
#include <vector>

template <int BASE>
class BigDecimal {
   public:
    static constexpr std::string_view NUMERAL{
        "0123456789ABCDEF"};  // 16進数まで対応

   private:  // 静的関数
    static int CompareIgnoreSign(const BigDecimal& a, const BigDecimal& b) {
        // a-bの符号で覚えてもよいかも。
        // a<b: -1
        // a>b: +1
        // a==b: 0
        if (a._digit.size() != b._digit.size())
            return a._digit.size() < b._digit.size() ? -1 : 1;
        for (int i = a._digit.size() - 1; i >= 0; --i) {
            if (a._digit[i] == b._digit[i]) continue;
            return a._digit[i] < b._digit[i] ? -1 : 1;
        }
        return 0;
    }

    static BigDecimal Karatsuba(const BigDecimal& a, const BigDecimal& b) {
        // |a| >= |b|にする
        if (a._digit.size() < b._digit.size()) return Karatsuba(b, a);
        // 1桁に絞ったら直に計算して返す
        if (b._digit.size() == 1) {
            BigDecimal ret(a);
            for (int i = 0; i < a._digit.size(); ++i) {
                ret._digit[i] *= b._digit[0];
            }
            ret.carry_and_fix();
            if (b._positive)
                return ret;
            else
                return -ret;
        }
        int N = a._digit.size() / 2;                 // 下半分の桁数
        bool sign = !(a._positive xor b._positive);  // 符号を計算しておく
        BigDecimal a0(a), a1(a), b0(b), b1(b);       // x = concat(x0, x1)
        // aの処理
        // x1の下N桁を残す形で上の桁を取り除く
        while (a1._digit.size() > N) a1._digit.pop_back();
        // x0のデータを消去
        a0._digit.clear();
        // x0に下N桁より上の桁を保存しなおす
        for (int i = 0; N + i < a._digit.size(); ++i)
            a0._digit.emplace_back(a._digit[N + i]);
        if (a0._digit.size() == 0) a0._digit.emplace_back(0);
        // x0, x1の符号を取り除く
        a0._positive = a1._positive = true;
        if (b._digit.size() < N) {  // 一方が他方の半分もない
            BigDecimal p0, c1;
            p0 = Karatsuba(a0, b);
            c1 = Karatsuba(a1, b);
            BigDecimal c0;
            for (int i = 0; i < N - 1; ++i) c0._digit.emplace_back(0);
            for (const auto& d : p0._digit) c0._digit.emplace_back(d);
            BigDecimal ret = c0 + c1;
            ret._positive = sign;
            return ret;
        }
        // bの処理
        // x1の下N桁を残す形で上の桁を取り除く
        while (b1._digit.size() > N) b1._digit.pop_back();
        // x0のデータを消去
        b0._digit.clear();
        // x0に下N桁より上の桁を保存しなおす
        for (int i = 0; N + i < b._digit.size(); ++i)
            b0._digit.emplace_back(b._digit[N + i]);
        if (b0._digit.size() == 0) b0._digit.emplace_back(0);
        // x0, x1の符号を取り除く
        b0._positive = b1._positive = true;
        // 3種類の積
        BigDecimal p0, p1, p2;
        p0 = Karatsuba(a0, b0);
        p2 = Karatsuba(a1, b1);
        p1 = Karatsuba(a0 + a1, b0 + b1) - p0 - p2;
        // 積に対応する数
        BigDecimal c0, c1, c2;
        c0._digit.clear();
        c1._digit.clear();
        c2._digit.clear();
        for (int i = 0; i < N; ++i) {
            c0._digit.emplace_back(0);
            c0._digit.emplace_back(0);
            c1._digit.emplace_back(0);
        }
        for (const auto& d : p0._digit) c0._digit.emplace_back(d);
        for (const auto& d : p1._digit) c1._digit.emplace_back(d);
        for (const auto& d : p2._digit) c2._digit.emplace_back(d);
        BigDecimal ret = c0 + c1 + c2;
        ret._positive = sign;
        return ret;
    }

   private:
    std::vector<int> _digit;
    bool _positive;
    bool is_zero() const { return _digit.size() == 1 && _digit[0] == 0; }

    void carry_and_fix() {
        // 新規の桁が発生しない範疇(最後の桁以外)を処理
        for (int i = 0; i < _digit.size() - 1; ++i) {
            if (_digit[i] >= BASE) {
                // 桁の数が基数以上: 繰り上げる必要あり
                int k = _digit[i] / BASE;  // 繰り上がり発生回数
                _digit[i] -= k * BASE;
                _digit[i + 1] += k;
            } else if (_digit[i] < 0) {
                // 桁の数が負: 繰り下げが必要
                int k = (-_digit[i] - 1) / BASE + 1;
                _digit[i] += k * BASE;
                _digit[i + 1] -= k;
            }
        }
        // 最後の桁を処理する場合
        while (_digit.back() >= BASE) {
            int k = _digit.back() / BASE;  // 繰り上がり発生回数
            _digit.back() -= k * BASE;
            _digit.emplace_back(k);
        }
        // 計算結果がマイナスなら全体に-1をかけて符号反転
        if (_digit.back() < 0) {
            this->_positive = !this->_positive;
            for (int i = 0; i < _digit.size(); ++i) {
                _digit[i] *= -1;
            }
            this->carry_and_fix();
        }
        // 0の桁を上から消す
        while (_digit.size() >= 2 && _digit.back() == 0) _digit.pop_back();
        // 0になったら正の数にしておく(-0表記は困るため)
        if (this->is_zero()) _positive = true;
    }

   public:
    // コンストラクタ
    BigDecimal(int num = 0) : _digit(0), _positive(num >= 0) {
        if (!_positive) num *= -1;
        while (num > 0) {
            _digit.emplace_back(num % BASE);
            num /= BASE;
        }
        if (_digit.size() == 0) _digit.emplace_back(0);
    }
    BigDecimal(std::string s) {
        if (s[0] == '-') {
            s = s.substr(1);
            _positive = false;
        } else {
            _positive = true;
        }
        while (s.size() > 0) {
            int i = NUMERAL.find(s.back());
            _digit.emplace_back(i);
            s.pop_back();
        }
    }
    // コピーコンストラクタ
    BigDecimal(const BigDecimal& x)
        : _digit(x._digit.size()), _positive(x._positive) {
        for (int i = 0; i < x._digit.size(); ++i) {
            this->_digit[i] = x._digit[i];
        }
    }

    // 比較演算子
    bool operator==(const BigDecimal& x) const {
        if (this->_positive != x._positive) return false;
        if (this->_digit.size() != x._digit.size()) return false;
        for (int i = 0; i < this->_digit.size(); ++i) {
            if (this->_digit[i] != x._digit[i]) return false;
        }
        return true;
    }
    bool operator!=(const BigDecimal& x) const { return !(*this == x); }
    bool operator<(const BigDecimal& x) const {
        if (this->_positive) {
            if (!x._positive) return false;  // x < 0 <= this -> this>x
            return CompareIgnoreSign(*this, x) < 0;
        } else {
            if (x._positive) return true;  // this < 0 <= x -> this<x
            return CompareIgnoreSign(*this, x) > 0;
        }
    }
    bool operator>(const BigDecimal& x) const {
        if (this->_positive) {
            if (!x._positive) return true;  // x < 0 <= this -> this>x
            return CompareIgnoreSign(*this, x) > 0;
        } else {
            if (x._positive) return false;  // this < 0 <= x -> this<x
            return CompareIgnoreSign(*this, x) < 0;
        }
    }
    bool operator<=(const BigDecimal& x) const {
        if (this->_positive) {
            if (!x._positive) return false;  // x < 0 <= this -> this>x
            return CompareIgnoreSign(*this, x) <= 0;
        } else {
            if (x._positive) return true;  // this < 0 <= x -> this<x
            return CompareIgnoreSign(*this, x) >= 0;
        }
    }
    bool operator>=(const BigDecimal& x) const {
        if (this->_positive) {
            if (!x._positive) return true;  // x < 0 <= this -> this>x
            return CompareIgnoreSign(*this, x) >= 0;
        } else {
            if (x._positive) return false;  // this < 0 <= x -> this<x
            return CompareIgnoreSign(*this, x) <= 0;
        }
    }

    // 単項演算子
    BigDecimal operator+() const { return *this; }
    BigDecimal operator-() const {
        BigDecimal ret = *this;
        if (!this->is_zero()) ret._positive = !ret._positive;
        return ret;
    }
    // 複号代入演算子
    BigDecimal& operator+=(const BigDecimal& x) {
        // 符号が異なる場合は符号をそろえて引き算に
        if (this->_positive != x._positive) {
            return *this -= (-x);
        }
        // 符号が同じ物にのみ足し算を行う
        while (this->_digit.size() < x._digit.size()) {
            this->_digit.emplace_back(0);
        }
        for (int i = 0; i < x._digit.size(); ++i) {
            this->_digit[i] += x._digit[i];
        }
        this->carry_and_fix();
        return *this;
    }
    BigDecimal& operator-=(const BigDecimal& x) {
        // 符号が異なる場合は符号をそろえて足し算に
        if (this->_positive != x._positive) {
            return *this += (-x);
        }
        // 符号が同じ物にのみ引き算を行う
        while (this->_digit.size() < x._digit.size()) {
            this->_digit.emplace_back(0);
        }
        for (int i = 0; i < x._digit.size(); ++i) {
            this->_digit[i] -= x._digit[i];
        }
        this->carry_and_fix();
        return *this;
    }
    BigDecimal& operator*=(const BigDecimal& x) { return *this; }
    BigDecimal& operator/=(const BigDecimal& x) { return *this; }
    BigDecimal& operator%=(const BigDecimal& x) { return *this; }

    // 二項演算子
    BigDecimal operator+(const BigDecimal& x) const {
        BigDecimal ret(*this);
        return (ret += x);
    }
    BigDecimal operator-(const BigDecimal& x) const {
        BigDecimal ret(*this);
        return (ret -= x);
    }
    BigDecimal operator*(const BigDecimal& x) const {
        return Karatsuba(*this, x);
    }
    BigDecimal operator/(const BigDecimal& x) const {
        BigDecimal ret(*this);
        return (ret /= x);
    }
    BigDecimal operator%(const BigDecimal& x) const {
        BigDecimal ret(*this);
        return (ret %= x);
    }

    // キャスト
    operator std::string() const {
        std::string ret = "";
        for (const auto& c : _digit) {
            ret = NUMERAL.at(c) + ret;
        }
        if (!_positive) ret = "-" + ret;
        return ret;
    }
};

int main() {
    std::string A, B;
    std::cin >> A >> B;
    BigDecimal<10> a(A), b(B);
    std::cout << std::string(a*b) << std::endl;
}
accuracy: 1
time_ms: 30
memory_kb: 3608
final_rank: 7

code_snippet: #include<iostream>
#include<algorithm>
#include<vector>
#include<string>
#include<cmath>
#include<iomanip>
#include<map>
#include<stack>
#include<queue>
#include<set>
#include<deque>
#include<list>
#include<bitset>

using namespace std;
using ll = long long;
using ld = long double;
using P = pair<ll,ll>;

const ld EPS = 1e-10;
const ll MOD = 1000000007LL;
const ll INF = 1LL << 60;
const double PI = M_PI;

#define SWAP( A, B ) { auto tmp = A; A = B; B = tmp; }

struct BigInteger{

    bool minus;
    int size;
    vector<int> val;

    BigInteger(){

        minus = false;
        size = 0;

    }

    BigInteger( string str ){

        minus = ( str[0] == '-' );
        if( minus )
            str = str.substr( 1 );
        size = str.length();
        for( int i = size-1 ; i >= 0 ; i-- )
            val.push_back( str[i] - '0' );
        adjust();

    }

    void adjust(){

        while( size != 0 && val[size-1] == 0 ){
            size--;
            val.pop_back();
        }
        if( size == 0 )
            minus = false;

    }

    bool same( BigInteger bi ){

        if( size != bi.size ) return false;
        for( int i = 0 ; i < size ; i++ ){
            if( val[i] != bi.val[i] )
                return false;
        }
        return true;

    }

    bool greater( BigInteger bi ){

        if( size > bi.size ) return true;
        else if( size < bi.size ) return false;
        if( size == 0 ) return true;
        int id = size - 1;
        while( id >= 0  ){
            if( val[id] > bi.val[id] ) return true;
            else if( val[id] < bi.val[id] ) return false;
            id--;
        }
        return true;
    
    }



    void print(){

        if( size == 0 ){
            minus = false;
            cout << "0" << endl;
            return;
        } 
        if( minus ) cout << "-";
        for( int i = size-1 ; i >= 0 ; i-- )
            cout << val[i];
        cout << endl;

    }

};

BigInteger operator+( BigInteger bi1, BigInteger bi2 );
BigInteger operator-( BigInteger bi1, BigInteger bi2 );
BigInteger operator*( BigInteger bi1, BigInteger bi2 );
BigInteger operator/( BigInteger bi1, BigInteger bi2 );
BigInteger operator%( BigInteger bi1, BigInteger bi2 );


BigInteger operator+( BigInteger bi1, BigInteger bi2 ){

    BigInteger res;
    if( bi1.minus && !bi2.minus ){
        bi1.minus = false;
        res = bi2 - bi1;
        return res;
    }
    if( !bi1.minus && bi2.minus ){
        bi2.minus = false;
        res = bi1 - bi2;
        return res;
    }
    res.minus = bi1.minus;
    res.size = max( bi1.size, bi2.size );
    vector<int> a;
    vector<int> b;
    for( int i = 0 ; i < res.size ; i++ ){
        if( i < bi1.size )
            a.push_back( bi1.val[i] );
        else
            a.push_back( 0 );
        if( i < bi2.size )
            b.push_back( bi2.val[i] );
        else
            b.push_back( 0 );
    }

    int up = 0;
    for( int i = 0 ; i < res.size ; i++ ){
        int sum = a[i] + b[i];
        sum += up;
        up = sum / 10;
        sum %= 10;
        res.val.push_back( sum );
    }
    while( up != 0 ){
        res.size++;
        res.val.push_back( up % 10 );
        up /= 10;
    }

    res.adjust();
    return res;

}

BigInteger operator-( BigInteger bi1, BigInteger bi2 ){

    BigInteger res;
    if( ( bi1.minus && !bi2.minus ) || ( !bi1.minus && bi2.minus ) ){
        bi2.minus = !bi2.minus;
        return bi1 + bi2;
    }
    res.size = max( bi1.size, bi2.size );
    if( bi1.greater( bi2 ) )
        res.minus = bi1.minus;
    else{
        res = bi2 - bi1;
        res.minus = !res.minus;
        return res;
    }
    vector<int> a;
    vector<int> b;
    for( int i = 0 ; i < res.size ; i++ ){
        if( i < bi1.size )
            a.push_back( bi1.val[i] );
        else
            a.push_back( 0 );
        if( i < bi2.size )
            b.push_back( bi2.val[i] );
        else
            b.push_back( 0 );
    }

    int down = 0;
    for( int i = 0 ; i < res.size ; i++ ){
        int diff = a[i] - b[i];
        diff -= down;
        if( diff >= 0 ){
            down = -( diff / 10 );
            diff %= 10;
        }
        else{
            down = ( -diff + 9 ) / 10;
            diff = ( 10 - ( -diff % 10 ) ) % 10;
        }
        res.val.push_back( diff );
    }
        
    res.adjust();
    return res;

}

/*
BigInteger operator*( BigInteger bi1, BigInteger bi2 ){

    BigInteger res;
    if( ( bi1.minus && !bi2.minus ) || ( !bi1.minus && bi2.minus ) ) res.minus = true;
    bi1.minus = bi2.minus = false;
    res.size = bi1.size + bi2.size - 1;
    for( int i = 0 ; i < res.size ; i++ )
        res.val.push_back( 0 );
    
    for( int i = 0 ; i < bi1.size ; i++ ){
        for( int j = 0 ; j < bi2.size ; j++ )
            res.val[i+j] += bi1.val[i] * bi2.val[j];
    }
    int up = 0;
    for( int i = 0 ; i < res.size ; i++ ){
        res.val[i] += up;
        up = res.val[i] / 10;
        res.val[i] %= 10;
    }
    while( up != 0 ){
        res.size++;
        res.val.push_back( up % 10 );
        up /= 10;
    }

    res.adjust();
    return res;
    
}
*/

BigInteger operator*( BigInteger bi1, BigInteger bi2 ){

    BigInteger res;
    if( bi1.size == 0 || bi2.size == 0 ) return res;
    if( ( bi1.minus && !bi2.minus ) || ( !bi1.minus && bi2.minus ) ) res.minus = true;
    bi1.minus = bi2.minus = false;
    if( bi1.size == 1 && bi2.size == 1 ){
        int m = bi1.val[0] * bi2.val[0];
        BigInteger mult( to_string( m ) );
        mult.minus = res.minus;
        mult.adjust();
        return mult;
    }
    int digit = 1;
    while( digit < max( bi1.size, bi2.size ) ) 
        digit *= 2;
    res.size = 2 * digit;
    for( int i = 0 ; i < res.size ; i++ )
        res.val.push_back( 0 );
    vector<int> a;
    vector<int> b;
    for( int i = 0 ; i < digit ; i++ ){
        if( i < bi1.size )
            a.push_back( bi1.val[i] );
        else
            a.push_back( 0 );
        if( i < bi2.size )
            b.push_back( bi2.val[i] );
        else
            b.push_back( 0 );
    }

    BigInteger num1, num2, num3, num4;
    num1.size = num2.size = num3.size = num4.size = digit / 2;
    for( int i = 0 ; i < digit / 2 ; i++ ){
        num1.val.push_back( a[ i + digit / 2 ] );
        num2.val.push_back( a[i]);
        num3.val.push_back( b[ i + digit / 2 ] );
        num4.val.push_back( b[i] );
    }
    num1.adjust();
    num2.adjust();
    num3.adjust();
    num4.adjust();
    BigInteger num5 = num1 * num3;
    BigInteger num6 = num2 * num4;
    BigInteger num7 = ( num1 + num2 ) * ( num3 + num4 ) - num5 - num6;

    for( int i = 0 ; i < num6.size ; i++ )
        res.val[i] += num6.val[i];
    for( int i = 0 ; i < num7.size; i++ )
        res.val[ i + digit / 2 ] += num7.val[i];
    for( int i = 0 ; i < num5.size ; i++ )
        res.val[ i + digit ] += num5.val[i];
    int up = 0;
    for( int i = 0 ; i < res.size ; i++ ){
        res.val[i] += up;
        up = res.val[i] / 10;
        res.val[i] %= 10;
    }

    res.adjust();
    return res;
    
}

BigInteger operator/( BigInteger bi1, BigInteger bi2 ){

    BigInteger res;
    if( !bi1.greater( bi2 ) ) return res;
    if( ( bi1.minus && !bi2.minus ) || ( !bi1.minus && bi2.minus ) ) res.minus = true;
    bi1.minus = bi2.minus = false;
    res.size = bi1.size - bi2.size + 1;

    BigInteger num;
    int id = bi1.size;
    while( id >= 0 ){
        BigInteger tmp;
        for( int i = 1 ; i <= 10 ; i++ ){
            tmp = tmp + bi2;
            if( tmp.greater( num ) ){
                if( tmp.same( num ) ){ 
                    res.val.insert( res.val.begin(), i );
                }
                else{
                    tmp = tmp - bi2;
                    res.val.insert( res.val.begin(), i - 1 );
                }
                num = num - tmp;
                id--;
                if( id >= 0 ){
                    num.val.insert( num.val.begin(), bi1.val[id] );
                    num.size++;
                }
                break;
            }
        }
    }

    res.adjust();
    return res;

}

BigInteger operator%( BigInteger bi1, BigInteger bi2 ){

    return bi1 - bi2 * ( bi1 / bi2 );

}



int main(){

    string A, B;
    cin >> A >> B;
    
    BigInteger a( A );
    BigInteger b( B );
    BigInteger c = a * b;
    c.print();

}
accuracy: 1
time_ms: 280
memory_kb: 3720
final_rank: 14

code_snippet: #include <bits/stdc++.h>
#define forr(i,a,b) for(int i = (a); i <= (b); i++)
#define forw(i,a,b) for(int i = (a); i >= (b); i--)
#define pb push_back
#define f first
#define s second

using namespace std;
typedef pair <int,int> pii;

const int maxn = 1e5 + 5;

string t(string a, string b)
{
    string c;
    long n1= a.length(), n2=b.length(),t,n=0;
    if(n1>n2) b.insert(0,n1-n2,'0');
    if(n2>n1) a.insert(0,n2-n1,'0');
    c=a;
    for(int i=a.length()-1;i>=0;i--)
    {
        t=(a[i]-48)+(b[i]-48)+n;
        n=t/10;
        t=t%10;
        c[i]=char(t+48);
    }
    if(n>0) c= char(n+48) +c;
    return c;
}

string h(string a, string b)
{
    string c;
    long n1= a.length(), n2=b.length(),t,n=0;
    if(n1>n2) b.insert(0,n1-n2,'0');
    c="";
    for(int i=n1-1;i>=0;i--)
    {
        t=(a[i]-48)-(b[i]-48)-n;
        if(t<0)
        {
            t+=10;
            n=1;
        }
        else n=0;
        c=char(t+48)+c;
    }
    while(c.length()>1&&c[0]=='0') c.erase(0,1);
    return c;
}

string n1(string a,int k)
{
    string b;
    long i,n=0,t;
    for(i=a.length()-1;i>=0;i--)
    {
        t=n+(a[i]-48)*k;
        n=t/10;
        t=t%10;
        b=char(t+48) + b;
    }
    if(n!=0) b=char(n+48)+b;
    while(b.length()>1&&b[0]=='0') b.erase(0,1);
    return b;
}

string nhan(string a, string b)
{
    string x,tg1="0",tg2,c;
    long i,j=0;
    for(i=b.length()-1;i>=0;i--)
    {
        tg2=n1(a,(b[i]-48));
        tg2.insert(tg2.length(),j,'0');
        j++;
        c=t(tg2,tg1);
        tg1=c;
    }
    while(c.length()>1&&c[0]=='0') c.erase(0,1);
    return c;
}
string a,b;

int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    cin >> a >> b;
    if(a[0] == '-' && b[0] == '-')
    {
        a.erase(0,1);
        b.erase(0,1);
        cout << nhan(a,b) << "\n";
        return 0;
    }
    else if(a[0] == '-' && b[0] != '-')
    {
        a.erase(0,1);
        string s1 = nhan(a,b);
        if(s1 != "0") s1 = "-" + s1;
        cout << s1 << "\n";
        return 0;
    }
    else if(a[0] != '-' && b[0] == '-')
    {
        b.erase(0,1);
        string s1 = nhan(a,b);
        if(s1 != "0") s1 = "-" + s1;
        cout << s1 << "\n";
        return 0;
    }
    cout << nhan(a,b) << "\n";
    return 0;
}
accuracy: 1
time_ms: 30
memory_kb: 3580
final_rank: 6

code_snippet: #include <bits/stdc++.h>
#define forr(i,a,b) for(int i = (a); i <= (b); i++)
#define forw(i,a,b) for(int i = (a); i >= (b); i--)
#define pb push_back
#define f first
#define s second

using namespace std;
typedef pair <int,int> pii;

const int maxn = 1e5 + 5;

string t(string a, string b)
{
    string c;
    long n1= a.length(), n2=b.length(),t,n=0;
    if(n1>n2) b.insert(0,n1-n2,'0');
    if(n2>n1) a.insert(0,n2-n1,'0');
    c=a;
    for(int i=a.length()-1;i>=0;i--)
    {
        t=(a[i]-48)+(b[i]-48)+n;
        n=t/10;
        t=t%10;
        c[i]=char(t+48);
    }
    if(n>0) c= char(n+48) +c;
    return c;
}

string h(string a, string b)
{
    string c;
    long n1= a.length(), n2=b.length(),t,n=0;
    if(n1>n2) b.insert(0,n1-n2,'0');
    c="";
    for(int i=n1-1;i>=0;i--)
    {
        t=(a[i]-48)-(b[i]-48)-n;
        if(t<0)
        {
            t+=10;
            n=1;
        }
        else n=0;
        c=char(t+48)+c;
    }
    while(c.length()>1&&c[0]=='0') c.erase(0,1);
    return c;
}

string n1(string a,int k)
{
    string b;
    long i,n=0,t;
    for(i=a.length()-1;i>=0;i--)
    {
        t=n+(a[i]-48)*k;
        n=t/10;
        t=t%10;
        b=char(t+48) + b;
    }
    if(n!=0) b=char(n+48)+b;
    while(b.length()>1&&b[0]=='0') b.erase(0,1);
    return b;
}

string nhan(string a, string b)
{
    string x,tg1="0",tg2,c;
    long i,j=0;
    for(i=b.length()-1;i>=0;i--)
    {
        tg2=n1(a,(b[i]-48));
        tg2.insert(tg2.length(),j,'0');
        j++;
        c=t(tg2,tg1);
        tg1=c;
    }
    return c;
}
string a,b;

int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    cin >> a >> b;
    if(a[0] == '-' && b[0] == '-')
    {
        a.erase(0,1);
        b.erase(0,1);
        cout << nhan(a,b) << "\n";
        return 0;
    }
    else if(a[0] == '-' && b[0] != '-')
    {
        a.erase(0,1);
        string s1 = nhan(a,b);
        if(s1 != "0") s1 = "-" + s1;
        cout << s1 << "\n";
        return 0;
    }
    else if(a[0] != '-' && b[0] == '-')
    {
        b.erase(0,1);
        string s1 = nhan(a,b);
        if(s1 != "0") s1 = "-" + s1;
        cout << s1 << "\n";
        return 0;
    }
    cout << nhan(a,b) << "\n";
    return 0;
}
accuracy: 0.84
time_ms: 30
memory_kb: 3612
final_rank: 16

code_snippet: #include<iostream>
#include<algorithm>
#include<vector>
#include<string>
#include<cmath>
#include<iomanip>
#include<map>
#include<stack>
#include<queue>
#include<set>
#include<deque>
#include<list>
#include<bitset>

using namespace std;
using ll = long long;
using ld = long double;
using P = pair<ll,ll>;

const ld EPS = 1e-10;
const ll MOD = 1000000007LL;
const ll INF = 1LL << 60;
const double PI = M_PI;

/////////////////////////////////
// 多倍長整数
// [-10^400000,10^400000] を表せる

struct bigInt;
bool   operator< ( bigInt l, bigInt r );
bigInt operator+ ( bigInt l, bigInt r );
bigInt operator- ( bigInt l, bigInt r );
bigInt operator* ( bigInt l, bigInt r );

struct bigInt{

  bool minus;
  int size;
  vector< vector<ll> > dat;

  // コンストラクタ
  bigInt(){

    Init();

  }

  bigInt( string str ){

    Init();
    if( str[0] == '-' ){
      minus = true;
      str = str.substr(1);
    }
    size = ( str.length() - 1 ) / 4;
    reverse( str.begin(), str.end() );
    int id = 0;
    for( int i = 0 ; i <= size ; i++ ){
      for( int j = 0 ; j < 4 ; j++ ){
        if( id < str.length() ){
          dat[i][j] = (ll)( str[id++] - '0' );
        }
      }
    }

  }

  // 初期化
  void Init(){

    minus = false;
    size = 0;
    for( int i = 0 ; i < 100000 ; i++ ){
      vector<ll> v( 4, 0LL );
      dat.push_back( v );
    }

  }

  // 表示
  void print(){

    ll top = 0LL;
    ll order = 1LL;
    for( int i = 0 ; i < 4 ; i++ ){
      top += dat[size][i] * order;
      order *= 10;
    }
    if( minus && ( size != 0 || top != 0LL ) )
      cout << '-';
    cout << top;
    for( int i = size-1 ; i >= 0 ; i-- ){
      for( int j = 3 ; j >= 0 ; j-- )
        cout << dat[i][j];
    }
    cout << endl;

  }

  // sizeの再計算
  void resize(){

    size = 0;
    for( int i = dat.size()-1 ; i >= 0 ; i-- ){
      for( int j = 3 ; j >= 0 ; j-- ){
        if( dat[i][j] != 0 ){
          size = i;
          return;
        }
      }
    }

  }

};

/////////////////////////////////////////////
// 演算子の定義
bool operator< ( bigInt l, bigInt r ){

  if( l.minus ){
    if( !r.minus ) return true;
    if( l.size == r.size ){
      ll lVal = 0LL, rVal = 0LL;
      ll order = 1LL;
      for( int i = 0 ; i < 4 ; i++ ){
        lVal += order * l.dat[l.size][i];
        rVal += order * r.dat[r.size][i];
        order *= 10;
      }
      return lVal > rVal;
    }
    return l.size > r.size;
  }
  else{
    if( r.minus ) return false;
    if( l.size == r.size ){
      ll lVal = 0LL, rVal = 0LL;
      ll order = 1LL;
      for( int i = 0 ; i < 4 ; i++ ){
        lVal += order * l.dat[l.size][i];
        rVal += order * r.dat[r.size][i];
        order *= 10;
      }
      return lVal < rVal;
    }
    return l.size < r.size;
  }

}

bigInt operator+ ( bigInt l, bigInt r ){

  bigInt res;
  if( l.minus ^ r.minus ){
    if( l.minus ){
      l.minus = false;
      res = r - l;
    }
    else{
      r.minus = false;
      res = l - r;
    }
  }
  else{
    int maxSize = max( l.size, r.size );
    ll up = 0LL; // 繰り上がり
    for( int i = 0 ; i <= maxSize ; i++ ){
      for( int j = 0 ; j < 4 ; j++ ){
        res.dat[i][j] = ( l.dat[i][j] + r.dat[i][j] + up ) % 10;
        up = ( l.dat[i][j] + r.dat[i][j] + up ) / 10;
      }
    }
    res.dat[maxSize+1][0] = up;
    res.minus = l.minus;
  }
  res.resize();
  return res;

}

bigInt operator- ( bigInt l, bigInt r ){

  bigInt res;
  if( l.minus ^ r.minus ){
    if( l.minus ){
      l.minus = false;
      res = l + r;
      res.minus = true;
    }
    else{
      r.minus = false;
      res = l + r;
    }
  }
  else{
    if( l.minus & r.minus ){
      if( l < r ){
        l.minus = false;
        r.minus = false;
        res = l - r;
        res.minus = true;
      }
      else{
        l.minus = false;
        r.minus = false;
        res = r - l;
      }
    }
    else{
      if( l < r ){
        res = r - l;
        res.minus = true;
      }
      else{
        int maxSize = max( l.size, r.size );
        ll down = 0LL; // 繰り下がり
        for( int i = 0 ; i <= maxSize ; i++ ){
          for( int j = 0 ; j < 4 ; j++ ){
            res.dat[i][j] = l.dat[i][j] - down - r.dat[i][j];
            if( res.dat[i][j] < 0 ){
              res.dat[i][j] += 10;
              down = 1;
            }
            else
              down = 0;
          }
        }
      }
    }
  }
  res.resize();
  return res;

}

bigInt operator* ( bigInt l, bigInt r ){

  bigInt res;
  res.minus = l.minus ^ r.minus;
  for( int li = 0 ; li <= l.size ; li++ ){
    for( int lj = 0 ; lj < 4 ; lj++ ){
      for( int ri = 0 ; ri <= r.size ; ri++ ){
        for( int rj = 0 ; rj < 4 ; rj++ )
          res.dat[li+ri+((lj+rj)/4)][(lj+rj)%4] += l.dat[li][lj] * r.dat[ri][rj];
      }
    }
  }
  ll up = 0LL; // 繰り上がり
  for( int i = 0 ; i < res.dat.size() ; i++ ){
    for( int j = 0 ; j < 4 ; j++ ){
      ll now = res.dat[i][j] + up;
      res.dat[i][j] = now % 10;
      up = now / 10;
    }
  }
  res.resize();
  return res;

}

/////////////////////////////////////////////////

int main(){

  string strA, strB;
  cin >> strA >> strB;
  bigInt a( strA );
  bigInt b( strB );
  bigInt mult = a * b;
  mult.print();

}
accuracy: 1
time_ms: 30
memory_kb: 39140
final_rank: 13

code_snippet: #include<iostream>
#include<algorithm>
#include<vector>
#include<string>
#include<cmath>
#include<iomanip>
#include<map>
#include<stack>
#include<queue>
#include<set>
#include<deque>
#include<list>
#include<bitset>

using namespace std;
using ll = long long;
using ld = long double;
using P = pair<ll,ll>;

const ld EPS = 1e-10;
const ll MOD = 1000000007LL;
const ll INF = 1LL << 60;
const double PI = M_PI;

/////////////////////////////////
// 多倍長整数
// [-10^400000,10^400000] を表せる

struct bigInt;
bool   operator< ( bigInt l, bigInt r );
bigInt operator+ ( bigInt l, bigInt r );
bigInt operator- ( bigInt l, bigInt r );
bigInt operator* ( bigInt l, bigInt r );

struct bigInt{

  bool minus;
  int size;
  vector< vector<ll> > dat;

  // コンストラクタ
  bigInt(){

    Init();

  }

  bigInt( string str ){

    Init();
    if( str[0] == '-' ){
      minus = true;
      str = str.substr(1);
    }
    size = ( str.length() - 1 ) / 4;
    reverse( str.begin(), str.end() );
    int id = 0;
    for( int i = 0 ; i <= size ; i++ ){
      for( int j = 0 ; j < 4 ; j++ ){
        if( id < str.length() ){
          dat[i][j] = (ll)( str[id++] - '0' );
        }
      }
    }

  }

  // 初期化
  void Init(){

    minus = false;
    size = 0;
    for( int i = 0 ; i < 100000 ; i++ ){
      vector<ll> v( 4, 0LL );
      dat.push_back( v );
    }

  }

  // 表示
  void print(){

    if( minus )
      cout << '-';
    ll top = 0LL;
    ll order = 1LL;
    for( int i = 0 ; i < 4 ; i++ ){
      top += dat[size][i] * order;
      order *= 10;
    }
    cout << top;
    for( int i = size-1 ; i >= 0 ; i-- ){
      for( int j = 3 ; j >= 0 ; j-- )
        cout << dat[i][j];
    }
    cout << endl;

  }

  // sizeの再計算
  void resize(){

    size = 0;
    for( int i = dat.size()-1 ; i >= 0 ; i-- ){
      for( int j = 3 ; j >= 0 ; j-- ){
        if( dat[i][j] != 0 ){
          size = i;
          return;
        }
      }
    }

  }

};

/////////////////////////////////////////////
// 演算子の定義
bool operator< ( bigInt l, bigInt r ){

  if( l.minus ){
    if( !r.minus ) return true;
    if( l.size == r.size ){
      ll lVal = 0LL, rVal = 0LL;
      ll order = 1LL;
      for( int i = 0 ; i < 4 ; i++ ){
        lVal += order * l.dat[l.size][i];
        rVal += order * r.dat[r.size][i];
        order *= 10;
      }
      return lVal > rVal;
    }
    return l.size > r.size;
  }
  else{
    if( r.minus ) return false;
    if( l.size == r.size ){
      ll lVal = 0LL, rVal = 0LL;
      ll order = 1LL;
      for( int i = 0 ; i < 4 ; i++ ){
        lVal += order * l.dat[l.size][i];
        rVal += order * r.dat[r.size][i];
        order *= 10;
      }
      return lVal < rVal;
    }
    return l.size < r.size;
  }

}

bigInt operator+ ( bigInt l, bigInt r ){

  bigInt res;
  if( l.minus ^ r.minus ){
    if( l.minus ){
      l.minus = false;
      res = r - l;
    }
    else{
      r.minus = false;
      res = l - r;
    }
  }
  else{
    int maxSize = max( l.size, r.size );
    ll up = 0LL; // 繰り上がり
    for( int i = 0 ; i <= maxSize ; i++ ){
      for( int j = 0 ; j < 4 ; j++ ){
        res.dat[i][j] = ( l.dat[i][j] + r.dat[i][j] + up ) % 10;
        up = ( l.dat[i][j] + r.dat[i][j] + up ) / 10;
      }
    }
    res.dat[maxSize+1][0] = up;
    res.minus = l.minus;
  }
  res.resize();
  return res;

}

bigInt operator- ( bigInt l, bigInt r ){

  bigInt res;
  if( l.minus ^ r.minus ){
    if( l.minus ){
      l.minus = false;
      res = l + r;
      res.minus = true;
    }
    else{
      r.minus = false;
      res = l + r;
    }
  }
  else{
    if( l.minus & r.minus ){
      if( l < r ){
        l.minus = false;
        r.minus = false;
        res = l - r;
        res.minus = true;
      }
      else{
        l.minus = false;
        r.minus = false;
        res = r - l;
      }
    }
    else{
      if( l < r ){
        res = r - l;
        res.minus = true;
      }
      else{
        int maxSize = max( l.size, r.size );
        ll down = 0LL; // 繰り下がり
        for( int i = 0 ; i <= maxSize ; i++ ){
          for( int j = 0 ; j < 4 ; j++ ){
            res.dat[i][j] = l.dat[i][j] - down - r.dat[i][j];
            if( res.dat[i][j] < 0 ){
              res.dat[i][j] += 10;
              down = 1;
            }
            else
              down = 0;
          }
        }
      }
    }
  }
  res.resize();
  return res;

}

bigInt operator* ( bigInt l, bigInt r ){

  bigInt res;
  res.minus = l.minus ^ r.minus;
  for( int li = 0 ; li <= l.size ; li++ ){
    for( int lj = 0 ; lj < 4 ; lj++ ){
      for( int ri = 0 ; ri <= r.size ; ri++ ){
        for( int rj = 0 ; rj < 4 ; rj++ )
          res.dat[li+ri+((lj+rj)/4)][(lj+rj)%4] += l.dat[li][lj] * r.dat[ri][rj];
      }
    }
  }
  ll up = 0LL; // 繰り上がり
  for( int i = 0 ; i < res.dat.size() ; i++ ){
    for( int j = 0 ; j < 4 ; j++ ){
      ll now = res.dat[i][j] + up;
      res.dat[i][j] = now % 10;
      up = now / 10;
    }
  }
  res.resize();
  return res;

}

/////////////////////////////////////////////////

int main(){

  string strA, strB;
  cin >> strA >> strB;
  bigInt a( strA );
  bigInt b( strB );
  bigInt mult = a * b;
  mult.print();

}
accuracy: 0.04
time_ms: 20
memory_kb: 39072
final_rank: 20

code_snippet: #include <bits/stdc++.h>
//#include <atcoder/all>
using namespace std;

#define all(x) (x).begin(),(x).end()
#define print(x) cout << (x) << '\n'
typedef long long ll;
typedef long double ld;
using P = pair<int,int>;
using pll = pair<ll,ll>;
using Graph = vector<vector<int>>;

//const ll MOD = 1000000007;
//const ll MOD = 998244353;

template <typename T> inline bool chmax(T &a, T b) {return a < b ? a = b, true : false;}
template <typename T> inline bool chmin(T &a, T b) {return a > b ? a = b, true : false;}

template <typename T>
void vin(vector<T> &v) {
    int l = v.size();
    for(int i = 0; i < l; i++) cin >> v[i];
}

template <typename T>
void vout(vector<T> &v) {
    int l = v.size();
    for(int i = 0; i < l; i++) cout << v[i] << (i < l - 1 ? ' ' : '\n');
}

string calc1(string x, string y, int la, int lb) {
    string ret = "";
    int nex = 0;
    for(int i = la - 1; i >= la - lb; i--) {
        int t = x[i] - '0' + y[i - la + lb] - '0' + nex;
        if(t >= 10) {
            nex = t / 10;
            ret += char('0' + t % 10);
        } else {
            nex = 0;
            ret += char('0' + t);
        }
    }
    for(int i = la - lb - 1; i >= 0; i--) {
        int t = x[i] - '0' + nex;
        if(t >= 10) {
            nex = t / 10;
            ret += char('0' + t % 10);
        } else {
            nex = 0;
            ret += char('0' + t);
        }
    }
    if(nex > 0) {
        ret += char('0' + nex);
    }
    reverse(all(ret));
    int L = ret.length();
    int zero = 0;
    for(int i = 0; i < L; i++) {
        if(ret[i] == '0') {
            zero++;
        } else {
            break;
        }
    }
    ret = ret.substr(zero, L - zero);
    if(ret == "") {
        ret = "0";
    }
    return ret;
}

string calc2(string x, string y, int la, int lb) {
    bool p = true;
    if(la < lb) {
        p = false;
    } else if(la == lb && x < y) {
        p = false;
    }
    if(!p) {
        swap(x, y);
        swap(la, lb);
    }

    string ret = "";
    int nex = 0;
    for(int i = la - 1; i >= la - lb; i--) {
        int t = x[i] - '0' - (y[i - (la - lb)] - '0') - nex;
        if(t < 0) {
            nex = 1;
            ret += char('0' + t + 10);
        } else {
            ret += char('0' + t);
            nex = 0;
        }
    }
    for(int i = la - lb - 1; i >= 0; i--) {
        int t = x[i] - '0' - nex;
        if(t < 0) {
            nex = 1;
            ret += char('0' + t + 10);
        } else {
            nex = 0;
            ret += char('0' + t);
        }
    }
    reverse(all(ret));
    int L = ret.length();
    int zero = 0;
    for(int i = 0; i < L; i++) {
        if(ret[i] == '0') {
            zero++;
        } else {
            break;
        }
    }
    ret = ret.substr(zero, L - zero);
    if(p) {
        ret = "-" + ret;
    }
    if(ret == "-") {
        ret = "0";
    }
    return ret;
}

string calc(string A, string B) {
    int la = A.length();
    int lb = B.length();

    string RET;
    if(A[0] == '-' && B[0] == '-') {
        A = A.substr(1, la - 1);
        B = B.substr(1, lb - 1);
        la--;
        lb--;
        if(la < lb) {
            swap(A, B);
            swap(la, lb);
        }
        RET = calc1(A, B, la, lb);
        RET = "-" + RET;
    } else if(A[0] == '-') {
        A = A.substr(1, la - 1);
        la--;
        RET = calc2(A, B, la, lb);
    } else if(B[0] == '-') {
        swap(A, B);
        swap(la, lb);
        A = A.substr(1, la - 1);
        la--;
        RET = calc2(A, B, la, lb);
    } else {
        if(la < lb) {
            swap(A, B);
            swap(la, lb);
        }
        RET = calc1(A, B, la, lb);
    }
    return RET;
}

string Mcalc2(string A, char b, int la) {
    string ret = "";
    int nex = 0;
    for(int i = la - 1; i >= 0; i--) {
        int t = int(A[i] - '0') * int(b - '0') + nex;
        nex = t / 10;
        ret += char('0' + t % 10);

    }
    while(nex > 0) {
        ret += char('0' + nex % 10);
        nex /= 10;
    }
    reverse(all(ret));
    int L = ret.length();
    int zero = 0;
    for(int i = 0; i < L; i++) {
        if(ret[i] == '0') {
            zero++;
        } else {
            break;
        }
    }
    ret = ret.substr(zero, L - zero);
    if(ret == "") {
        ret = "0";
    }
    return ret;
}

string Mcalc1(string A, string B, int la, int lb) {
    string ret = "0";
    for(int i = lb - 1; i >= 0; i--) {
        string tmp = Mcalc2(A, B[i], la);
        for(int j = 0; j < lb - 1 - i; j++) {
            tmp += '0';
        }
        ret = calc(ret, tmp);
    }
    return ret;
}

string Mcalc(string A, string B) {
    int la = A.length();
    int lb = B.length();
    string Mret;
    if(A[0] == '-' && B[0] == '-') {
        A = A.substr(1, la - 1);
        B = B.substr(1, lb - 1);
        la--;
        lb--;
        Mret = Mcalc1(A, B, la, lb);
    } else if(A[0] == '-') {
        A = A.substr(1, la - 1);
        la--;
        Mret = Mcalc1(A, B, la, lb);
        if(Mret != "0") {
            Mret = "-" + Mret;
        }
    } else if(B[0] == '-') {
        B = B.substr(1, lb - 1);
        lb--;
        Mret = Mcalc1(A, B, la, lb);
        if(Mret != "0") {
            Mret = "-" + Mret;
        }
    } else {
        Mret = Mcalc1(A, B, la, lb);
    }
    return Mret;
}

int main() {
    cin.tie(0); cout.tie(0);
    ios::sync_with_stdio(false);
    cout << fixed << setprecision(18);

    string A, B;
    cin >> A >> B;
    string ans = Mcalc(A, B);
    print(ans);
    return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 3556
final_rank: 3

code_snippet: #include <bits/stdc++.h>


// #include <atcoder/convolution>
#include <iostream>

#include <algorithm>
#include <cassert>
#include <vector>

namespace rklib {

template <class T>
bool chmax(T &a, const T &b) {
    if (a < b) {
        a = b;
        return true;
    }
    return false;
}

template <class T>
bool chmin(T &a, const T &b) {
    if (a > b) {
        a = b;
        return true;
    }
    return false;
}

template <class T>
bool chmin_non_negative(T &a, const T &b) {
    if (a < 0 || a > b) {
        a = b;
        return true;
    }
    return false;
}

template <class T>
T div_floor(T a, T b) {
    if (b < 0) a *= -1, b *= -1;
    return a >= 0 ? a / b : (a + 1) / b - 1;
}

template <class T>
T div_ceil(T a, T b) {
    if (b < 0) a *= -1, b *= -1;
    return a > 0 ? (a - 1) / b + 1 : a / b;
}

}  // namespace rklib

#include <string>
#include <type_traits>
#include <vector>

namespace rklib {

struct BigInt {
   public:
    BigInt() : BigInt(0) {}
    template <typename T, std::enable_if_t<std::is_integral<T>::value,
                                           std::nullptr_t> = nullptr>
    BigInt(T x) : BigInt(std::vector<T>(1, x)) {}
    template <typename T, std::enable_if_t<std::is_integral<T>::value,
                                           std::nullptr_t> = nullptr>
    BigInt(std::vector<T> a) {
        while (a.size() >= 2 && a.back() == 0) a.pop_back();
        if (a.size() == 1 && a[0] == 0) {
            sgn = 0;
            return;
        }
        sgn = (a.back() > 0 ? 1 : -1);
        if (sgn < 0) {
            std::transform(a.begin(), a.end(), a.begin(),
                           [](T x) { return -x; });
        }
        v = normalize(a);
    }
    BigInt(std::string s) : sgn(1) {
        if (s[0] == '-') {
            s.erase(s.begin());
            sgn = -1;
        }
        if (s == "0") {
            sgn = 0;
            v = {0};
            return;
        }
        for (int r = int(s.size()), l = std::max(0, r - log10_base); r > 0;
             r = l, l = std::max(0, r - log10_base)) {
            int tmp = 0;
            for (int i = l; i < r; ++i) {
                tmp = tmp * 10 + (s[i] - '0');
            }
            v.push_back(tmp);
        }
    }

    BigInt& operator+=(const BigInt& rhs) {
        int r_sgn = rhs.sgn;
        if (r_sgn == 0) return *this;
        if (sgn == 0) return *this = rhs;
        if (v.size() < rhs.v.size()) v.resize(rhs.v.size(), 0);
        for (size_t i = 0; i < rhs.v.size(); i++) {
            if (sgn == r_sgn)
                v[i] += rhs.v[i];
            else
                v[i] -= rhs.v[i];
        }
        normalize();
        return *this;
    }
    BigInt& operator-=(const BigInt& rhs) {
        int r_sgn = rhs.sgn;
        if (r_sgn == 0) return *this;
        if (sgn == 0) return *this = -rhs;
        if (v.size() < rhs.v.size()) v.resize(rhs.v.size(), 0);
        for (size_t i = 0; i < rhs.v.size(); i++) {
            if (sgn == r_sgn)
                v[i] -= rhs.v[i];
            else
                v[i] += rhs.v[i];
        }
        normalize();
        return *this;
    }
    BigInt& operator*=(const BigInt& rhs) {
        int r_sgn = rhs.sgn;
        if (sgn == 0) return *this;
        if (r_sgn == 0) return *this = rhs;

        int res_sgn = sgn * r_sgn;

        // if (v.size() <= 10 || rhs.v.size() <= 10) {
        //     v = multiply_naive(v, rhs.v);
        // } else if (v.size() + rhs.v.size() - 1 <= (1 << 24)) {
        //     v = multiply_ntt(v, rhs.v);
        // }

        if (v.size() <= 2 || rhs.v.size() <= 2) {
            v = multiply_naive(v, rhs.v);
        } else {
            BigInt a = *this, b = rhs;
            a.sgn = b.sgn = 1;
            *this = multiply_karatsuba(a, b);
        }

        this->sgn = res_sgn;

        return *this;
    }

    friend BigInt operator+(const BigInt& lhs, const BigInt& rhs) {
        return BigInt(lhs) += rhs;
    }
    friend BigInt operator-(const BigInt& lhs, const BigInt& rhs) {
        return BigInt(lhs) -= rhs;
    }
    friend BigInt operator*(const BigInt& lhs, const BigInt& rhs) {
        return BigInt(lhs) *= rhs;
    }

    BigInt operator+() const { return *this; }
    BigInt operator-() const { return {-sgn, v}; }

    friend std::istream& operator>>(std::istream& is, BigInt& rhs) {
        std::string s;
        is >> s;
        rhs = BigInt(s);
        return is;
    }
    friend std::ostream& operator<<(std::ostream& os, const BigInt& rhs) {
        if (rhs.sgn < 0) os << "-";
        for (int i = int(rhs.v.size()) - 1; i >= 0; i--) {
            if (i == int(rhs.v.size()) - 1) {
                os << rhs.v[i];
            } else {
                os << std::to_string(rhs.v[i] + base).substr(1, log10_base);
            }
        }
        return os;
    }

   private:
    static constexpr int base = 10, log10_base = 1;
    int sgn;
    std::vector<int> v;

    BigInt(int sgn, std::vector<int> v) : sgn(sgn), v(v) {}

    void normalize() {
        if (v.back() < 0) {
            sgn = -sgn;
            std::transform(v.begin(), v.end(), v.begin(),
                           [](int x) { return -x; });
        }
        int carry = 0;
        for (size_t i = 0; i < v.size(); i++) {
            v[i] += carry;
            if (0 <= v[i] && v[i] < base) {
                carry = 0;
                continue;
            }
            carry = div_floor(v[i], base);
            v[i] -= carry * base;
            if (i == v.size() - 1 && carry != 0) {
                v.push_back(carry % base);
                carry /= base;
            }
        }

        while (v.size() >= 2 && v.back() == 0) v.pop_back();
        if (v.size() == 1 && v[0] == 0) sgn = 0;
    }

    template <class T>
    static std::vector<int> normalize(const std::vector<T>& c) {
        std::vector<int> res(c.size());
        T carry = 0;
        for (size_t i = 0; i < c.size(); i++) {
            T tmp = c[i];
            tmp += carry;
            if (0 <= tmp && tmp < T(base)) {
                carry = 0;
                res[i] = int(tmp);
                continue;
            }
            carry = div_floor(tmp, T(base));
            res[i] = int(tmp - carry * base);
        }
        while (carry > 0) {
            res.push_back(int(carry % base));
            carry /= base;
        }

        while (res.size() >= 2 && res.back() == 0) res.pop_back();

        return res;
    }

    static std::vector<int> multiply_naive(const std::vector<int>& a,
                                           const std::vector<int>& b) {
        std::vector<long long> c(a.size() + b.size() - 1, 0);
        for (size_t i = 0; i < a.size(); i++) {
            for (size_t j = 0; j < b.size(); j++) {
                c[i + j] += a[i] * b[j];
            }
        }

        return normalize(c);
    }
    // static std::vector<int> multiply_ntt(const std::vector<int>& a,
    //                                      const std::vector<int>& b) {
    //     std::vector<long long> al(a.size()), bl(b.size());
    //     for (size_t i = 0; i < a.size(); i++) {
    //         al[i] = (long long)a[i];
    //     }
    //     for (size_t i = 0; i < b.size(); i++) {
    //         bl[i] = (long long)b[i];
    //     }

    //     std::vector<long long> c = atcoder::convolution_ll(al, bl);

    //     return normalize(c);
    // }
    static BigInt multiply_karatsuba(BigInt a, BigInt b) {
        // std::cout << a << " " << b << std::endl;
        int na = a.v.size(), nb = b.v.size();
        if (na <= 2 || nb <= 2) return a * b;

        int n = std::max(na, nb);
        if (na < n) a.v.resize(n, 0);
        if (nb < n) b.v.resize(n, 0);

        int k = n / 2;
        BigInt x(std::vector<int>(a.v.begin() + k, a.v.end()));
        BigInt y(std::vector<int>(a.v.begin(), a.v.begin() + k));
        BigInt z(std::vector<int>(b.v.begin() + k, b.v.end()));
        BigInt w(std::vector<int>(b.v.begin(), b.v.begin() + k));

        BigInt xz = multiply_karatsuba(x, z);
        BigInt yw = multiply_karatsuba(y, w);
        BigInt t = multiply_karatsuba(x + y, z + w) - xz - yw;

        a.v = std::vector<int>(2 * k, 0);
        a.v.insert(a.v.end(), xz.v.begin(), xz.v.end());
        b.v = std::vector<int>(k, 0);
        b.v.insert(b.v.end(), t.v.begin(), t.v.end());

        return a + b + yw;
    }
};

}  // namespace rklib


#define For(i, a, b) for (int i = (int)(a); (i) < (int)(b); ++(i))
#define rFor(i, a, b) for (int i = (int)(a)-1; (i) >= (int)(b); --(i))
#define rep(i, n) For(i, 0, n)
#define rrep(i, n) rFor(i, n, 0)
#define fi first
#define se second

using namespace std;
using namespace rklib;

using lint = long long;
using pii = pair<int, int>;
using pll = pair<lint, lint>;

int main() {
    BigInt a, b;
    cin >> a >> b;
    cout << a * b << "\n";
}
accuracy: 1
time_ms: 10
memory_kb: 3660
final_rank: 4

code_snippet: #include<bits/stdc++.h>
using namespace std;
struct BigIntTiny {
    int sign;
    std::vector<int> v;

    BigIntTiny() : sign(1) {}
    BigIntTiny(const std::string& s) { *this = s; }
    BigIntTiny(int v) {
        char buf[21];
        sprintf(buf, "%d", v);
        *this = buf;
    }
    void zip(int unzip) {
        if (unzip == 0) {
            for (int i = 0; i < (int)v.size(); i++)
                v[i] = get_pos(i * 4) + get_pos(i * 4 + 1) * 10 + get_pos(i * 4 + 2) * 100 + get_pos(i * 4 + 3) * 1000;
        }
        else
            for (int i = (v.resize(v.size() * 4), (int)v.size() - 1), a; i >= 0; i--)
                a = (i % 4 >= 2) ? v[i / 4] / 100 : v[i / 4] % 100, v[i] = (i & 1) ? a / 10 : a % 10;
        setsign(1, 1);
    }
    int get_pos(unsigned pos) const { return pos >= v.size() ? 0 : v[pos]; }
    BigIntTiny& setsign(int newsign, int rev) {
        for (int i = (int)v.size() - 1; i > 0 && v[i] == 0; i--)
            v.erase(v.begin() + i);
        sign = (v.size() == 0 || (v.size() == 1 && v[0] == 0)) ? 1 : (rev ? newsign * sign : newsign);
        return *this;
    }
    std::string to_str() const {
        BigIntTiny b = *this;
        std::string s;
        for (int i = (b.zip(1), 0); i < (int)b.v.size(); ++i)
            s += char(*(b.v.rbegin() + i) + '0');
        return (sign < 0 ? "-" : "") + (s.empty() ? std::string("0") : s);
    }
    bool absless(const BigIntTiny& b) const {
        if (v.size() != b.v.size()) return v.size() < b.v.size();
        for (int i = (int)v.size() - 1; i >= 0; i--)
            if (v[i] != b.v[i]) return v[i] < b.v[i];
        return false;
    }
    BigIntTiny operator-() const {
        BigIntTiny c = *this;
        c.sign = (v.size() > 1 || v[0]) ? -c.sign : 1;
        return c;
    }
    BigIntTiny& operator=(const std::string& s) {
        if (s[0] == '-')
            *this = s.substr(1);
        else {
            for (int i = (v.clear(), 0); i < (int)s.size(); ++i)
                v.push_back(*(s.rbegin() + i) - '0');
            zip(0);
        }
        return setsign(s[0] == '-' ? -1 : 1, sign = 1);
    }
    bool operator<(const BigIntTiny& b) const {
        return sign != b.sign ? sign < b.sign : (sign == 1 ? absless(b) : b.absless(*this));
    }
    bool operator==(const BigIntTiny& b) const { return v == b.v && sign == b.sign; }
    BigIntTiny& operator+=(const BigIntTiny& b) {
        if (sign != b.sign) return *this = (*this) - -b;
        v.resize(std::max(v.size(), b.v.size()) + 1);
        for (int i = 0, carry = 0; i < (int)b.v.size() || carry; i++) {
            carry += v[i] + b.get_pos(i);
            v[i] = carry % 10000, carry /= 10000;
        }
        return setsign(sign, 0);
    }
    BigIntTiny operator+(const BigIntTiny& b) const {
        BigIntTiny c = *this;
        return c += b;
    }
    void add_mul(const BigIntTiny& b, int mul) {
        v.resize(std::max(v.size(), b.v.size()) + 2);
        for (int i = 0, carry = 0; i < (int)b.v.size() || carry; i++) {
            carry += v[i] + b.get_pos(i) * mul;
            v[i] = carry % 10000, carry /= 10000;
        }
    }
    BigIntTiny operator-(const BigIntTiny& b) const {
        if (sign != b.sign) return (*this) + -b;
        if (absless(b)) return -(b - *this);
        BigIntTiny c;
        for (int i = 0, borrow = 0; i < (int)v.size(); i++) {
            borrow += v[i] - b.get_pos(i);
            c.v.push_back(borrow);
            c.v.back() -= 10000 * (borrow >>= 31);
        }
        return c.setsign(sign, 0);
    }
    BigIntTiny operator*(const BigIntTiny& b) const {
        if (b < *this) return b * *this;
        BigIntTiny c, d = b;
        for (int i = 0; i < (int)v.size(); i++, d.v.insert(d.v.begin(), 0))
            c.add_mul(d, v[i]);
        return c.setsign(sign * b.sign, 0);
    }
    BigIntTiny operator/(const BigIntTiny& b) const {
        BigIntTiny c, d;
        d.v.resize(v.size());
        double db = 1.0 / (b.v.back() + (b.get_pos((unsigned)b.v.size() - 2) / 1e4) +
            (b.get_pos((unsigned)b.v.size() - 3) + 1) / 1e8);
        for (int i = (int)v.size() - 1; i >= 0; i--) {
            c.v.insert(c.v.begin(), v[i]);
            int m = (int)((c.get_pos((int)b.v.size()) * 10000 + c.get_pos((int)b.v.size() - 1)) * db);
            c = c - b * m, d.v[i] += m;
            while (!(c < b))
                c = c - b, d.v[i] += 1;
        }
        return d.setsign(sign * b.sign, 0);
    }
    BigIntTiny operator%(const BigIntTiny& b) const { return *this - *this / b * b; }
    bool operator>(const BigIntTiny& b) const { return b < *this; }
    bool operator<=(const BigIntTiny& b) const { return !(b < *this); }
    bool operator>=(const BigIntTiny& b) const { return !(*this < b); }
    bool operator!=(const BigIntTiny& b) const { return !(*this == b); }
};
//FFT部分 
const double PI = acos(-1);
typedef complex<double> Complex;
const int maxn = 3e6 + 10;

Complex a[maxn], b[maxn];
int m, n;
int bit = 2, rev[maxn];
int ans[maxn];

void get_rev() {
    memset(rev, 0, sizeof(rev));
    while (bit <= n + m) bit <<= 1;
    for (int i = 0; i < bit; ++i) {
        rev[i] = (rev[i >> 1] >> 1) | (bit >> 1) * (i & 1);
    }
}

void FFT(Complex* a, int op) {
    for (int i = 0; i < bit; ++i) {
        if (i < rev[i]) swap(a[i], a[rev[i]]);
    }
    for (int mid = 1; mid < bit; mid <<= 1) {
        Complex wn = Complex(cos(PI / mid), op * sin(PI / mid));
        for (int j = 0; j < bit; j += mid << 1) {
            Complex w(1, 0);
            for (int k = 0; k < mid; ++k, w = w * wn) {
                Complex x = a[j + k], y = w * a[j + k + mid];
                a[j + k] = x + y, a[j + k + mid] = x - y;
            }
        }
    }
}

string fftmul(string s1, string s2) {
    //cout<<s1<<endl<<s2<<endl;
    n = s1.size(), m = s2.size();
    memset(a, 0, sizeof(a));
    memset(b, 0, sizeof(b));
    for (int i = 0; i < n; ++i) {
        a[i] = s1[n - i - 1] - '0';
    }
    for (int i = 0; i < m; ++i) {
        b[i] = s2[m - i - 1] - '0';
    }
    get_rev();
    FFT(a, 1);
    FFT(b, 1);
    for (int i = 0; i <= bit; ++i) {
        a[i] *= b[i];
    }
    FFT(a, -1);
    for (int i = 0; i < n + m; ++i) {
        ans[i] = (int)(a[i].real() / bit + 0.5);
    }
    for (int i = 1; i < n + m; ++i) {
        ans[i] = ans[i] + ans[i - 1] / 10;
        ans[i - 1] = ans[i - 1] % 10;
    }
    int s = n + m - 1;
    for (; s >= 0; --s) {
        if (ans[s]) break;
    }
    string ret;
    if (s < 0) ret.push_back('0');//printf("0\n");
    else {
        for (int i = s; i >= 0; --i) {
            ret.push_back(ans[i] + '0');//printf("%d", ans[i]);
        }
        //printf("\n");
    }
    return ret;
}

BigIntTiny fastmul(BigIntTiny b1, BigIntTiny b2) {
    //cout<<b1.to_str()<<'\n'<<b2.to_str()<<endl;
    //cout<<fftmul(b1.to_str(),b2.to_str())<<endl;
    bool flag = 0;//要不要变负,1负
    if (b1 < 0)b1 = -b1, flag ^= 1;
    if (b2 < 0)b2 = -b2, flag ^= 1;
    BigIntTiny ans = fftmul(b1.to_str(), b2.to_str());
    return flag ? -ans : ans;
}
const int p = 998244353;
BigIntTiny qpow(BigIntTiny a, BigIntTiny n, BigIntTiny p) {
    BigIntTiny res = 1;
    while (n>0) {
        if (n % 2 == 1) res = res * a % p;
        a = a * a % p;
        n = n / 2;
    }
    return res;
}
BigIntTiny qpow1(BigIntTiny a, BigIntTiny n) {
    BigIntTiny res = 1;
    while (n > 0) {
        if (n % 2 == 1) res = res * a;
        a = a * a;
        n = n / 2;
    }
    return res;
}
BigIntTiny v[51], sum[51];
int main(){
    string a, b;
    cin>>a>>b;
    cout<<(BigIntTiny(a)*BigIntTiny(b)).to_str()<<'\n';
}
accuracy: 1
time_ms: 20
memory_kb: 97060
final_rank: 15

code_snippet: #include <bits/stdc++.h>
#include <sstream>

using namespace std;

//#define InputOutputOperatorOverload

class BigData {
public:
	BigData() {
		this->data = "";
		this->minFlag = false;
	}

#ifdef InputOutputOperatorOverload
	friend istream& operator >>(istream& in, BigData& bigdata) {
		in >> bigdata.data;
		return in;
	}

	friend ostream& operator <<(ostream& out, BigData& bigdata) {
		out << bigdata.data;
		return out;
	}
#else
	string getValue() {
		return this->data;
	}

	void setValue(string value) {
		this->data = value;
	}
#endif

	BigData operator +(const BigData& add) {
		string add1, add2;
		BigData ans;

		add1 = this->data;
		add2 = add.data;
		if (add1[0] != '-' && add2[0] != '-') {
			minFlag = false;
			reverse(add1.begin(), add1.end());
			reverse(add2.begin(), add2.end());
			ans.data = getAdd(add1, add2);
		}
		else if (add1[0] == '-' && add2[0] == '-') {
			minFlag = true;
			add1 = add1.substr(1);
			add2 = add2.substr(1);
			reverse(add1.begin(), add1.end());
			reverse(add2.begin(), add2.end());
			ans.data = getAdd(add1, add2);
		}
		else if (add1[0] == '-' && add2[0] != '-') {
			add1 = add1.substr(1);
			minFlag = compareAndChange(add1, add2) ? false : true;
			if (add1 == add2) {
				minFlag = false;
			}
			reverse(add1.begin(), add1.end());
			reverse(add2.begin(), add2.end());
			ans.data = calculate(add1, add2);
		}
		else if (add1[0] != '-' && add2[0] == '-') {
			add2 = add2.substr(1);
			minFlag = compareAndChange(add1, add2);
			reverse(add1.begin(), add1.end());
			reverse(add2.begin(), add2.end());
			ans.data = calculate(add1, add2);
		}

		if (minFlag) {
			ans.data += "-";
		}
		reverse(ans.data.begin(), ans.data.end());

		return ans;
	}

	BigData operator -(const BigData& sub) {
		string sub1, sub2;
		BigData ans;

		sub1 = this->data;
		sub2 = sub.data;
		if (sub1[0] != '-' && sub2[0] == '-') {
			minFlag = false;
			sub2 = sub2.substr(1);
			reverse(sub1.begin(), sub1.end());
			reverse(sub2.begin(), sub2.end());
			ans.data = getAdd(sub1, sub2);
		}
		else if (sub1[0] == '-' && sub2[0] != '-') {
			minFlag = true;
			sub1 = sub1.substr(1);
			reverse(sub1.begin(), sub1.end());
			reverse(sub2.begin(), sub2.end());
			ans.data = getAdd(sub1, sub2);
		}
		else if (sub1[0] != '-' && sub2[0] != '-') {
			minFlag = compareAndChange(sub1, sub2);
			reverse(sub1.begin(), sub1.end());
			reverse(sub2.begin(), sub2.end());
			ans.data = calculate(sub1, sub2);
		}
		else if (sub1[0] == '-' && sub2[0] == '-') {
			sub1 = sub1.substr(1);
			sub2 = sub2.substr(1);
			minFlag = compareAndChange(sub1, sub2) ? false : true;
			if (sub1 == sub2) {
				minFlag = false;
			}
			reverse(sub1.begin(), sub1.end());
			reverse(sub2.begin(), sub2.end());
			ans.data = calculate(sub1, sub2);
		}

		if (minFlag) {
			ans.data += "-";
		}
		reverse(ans.data.begin(), ans.data.end());

		return ans;
	}

	BigData operator *(const BigData& mul) {
		string mul1, mul2;
		BigData ans;

		mul1 = this->data;
		mul2 = mul.data;
		if (mul1[0] != '-' && mul2[0] != '-') {
			minFlag = false;
		}
		else if (mul1[0] == '-' && mul2[0] == '-') {
			minFlag = false;
			mul1 = mul1.substr(1);
			mul2 = mul2.substr(1);
		}
		else if (mul1[0] == '-' && mul2[0] != '-') {
			minFlag = true;
			mul1 = mul1.substr(1);
		}
		else if (mul1[0] != '-' && mul2[0] == '-') {
			minFlag = true;
			mul2 = mul2.substr(1);
		}

		reverse(mul1.begin(), mul1.end());
		reverse(mul2.begin(), mul2.end());
		ans.data = getMul(mul1, mul2);

		if (ans.data != "0" && minFlag) {
			ans.data += "-";
		}
		reverse(ans.data.begin(), ans.data.end());

		return ans;
	}

	BigData operator /(const BigData& div) {
		string div1, div2, rem;
		BigData ans;

		div1 = this->data;
		div2 = div.data;
		if (div1[0] != '-' && div2[0] != '-') {
			minFlag = false;
		}
		else if (div1[0] == '-' && div2[0] == '-') {
			minFlag = false;
			div1 = div1.substr(1);
			div2 = div2.substr(1);
		}
		else if (div1[0] == '-' && div2[0] != '-') {
			minFlag = true;
			div1 = div1.substr(1);
		}
		else if (div1[0] != '-' && div2[0] == '-') {
			minFlag = true;
			div2 = div2.substr(1);
		}
		
		ans.data = getDiv(div1, div2, rem);
		if (ans.data != "0" && minFlag) {
			ans.data = "-" + ans.data;
		}

		return ans;
	}

	BigData operator %(const BigData& div) {
		string div1, div2, rem;
		BigData ans;

		div1 = this->data;
		div2 = div.data;
		if (div1[0] != '-' && div2[0] != '-') {
			minFlag = false;
		}
		else if (div1[0] == '-' && div2[0] == '-') {
			minFlag = true;
			div1 = div1.substr(1);
			div2 = div2.substr(1);
		}
		else if (div1[0] == '-' && div2[0] != '-') {
			minFlag = true;
			div1 = div1.substr(1);
		}
		else if (div1[0] != '-' && div2[0] == '-') {
			minFlag = false;
			div2 = div2.substr(1);
		}

		ans.data = getDiv(div1, div2, rem);
		ans.data = rem;
		if (ans.data != "0" && minFlag) {
			ans.data = "-" + ans.data;
		}
		
		return ans;
	}


private:
	string data;
	bool minFlag;

	bool compareAndChange(string& d1, string& d2) {
		unsigned int len1, len2;

		len1 = d1.size();
		len2 = d2.size();
		if (len1 > len2) {
			return false;
		}

		if (len1 < len2 || d1 < d2) {
			d1.swap(d2);
			return true;
		}
		return false;
	}

	bool compare(const string& d1, const string& d2) {
		unsigned int len1, len2;

		len1 = d1.size();
		len2 = d2.size();
		if (len1 > len2) {
			return false;
		}

		if (len1 < len2 || d1 < d2) {
			return true;
		}
		return false;
	}

	string getAdd(const string& add1, const string& add2) {
		unsigned int len1, len2, i;
		int acc, sum;
		stringstream ss;

		len1 = add1.size();
		len2 = add2.size();
		//cout << add1 << endl << add2 << endl;

		i = 0;
		acc = 0;
		ss.clear();
		ss.str("");
		while (i < len1 && i < len2) {
			sum = (add1[i] - '0') + (add2[i] - '0') + acc;
			acc = sum / 10;
			sum %= 10;
			ss << sum;
			++i;
		}

		while (i < len1) {
			sum = (add1[i] - '0') + acc;
			acc = sum / 10;
			sum %= 10;
			ss << sum;
			++i;
		}

		while (i < len2) {
			sum = (add2[i] - '0') + acc;
			acc = sum / 10;
			sum %= 10;
			ss << sum;
			++i;
		}

		if (acc == 1) {
			ss << 1;
		}

		return ss.str();
	}

	string getSub(const string& sub1, const string& sub2) {
		unsigned int len1, len2, i;
		int acc, sum;
		stringstream ss;

		len1 = sub1.size();
		len2 = sub2.size();
		//cout << sub1 << endl << sub2 << endl;

		i = 0;
		acc = 0;
		ss.clear();
		ss.str("");
		while (i < len1 && i < len2) {
			sum = (sub1[i] - '0') - acc - (sub2[i] - '0');
			if (sum < 0) {
				acc = 1;
				sum += 10;
			}
			else {
				acc = 0;
			}
			ss << sum;
			++i;
		}

		while (i < len1) {
			sum = (sub1[i] - '0') - acc;
			if (sum < 0) {
				acc = 1;
				sum += 10;
			}
			else {
				acc = 0;
			}
			ss << sum;
			++i;
		}

		while (i < len2) {
			sum = (sub2[i] - '0') - acc;
			if (sum < 0) {
				acc = 1;
				sum += 10;
			}
			else {
				acc = 0;
			}
			ss << sum;
			++i;
		}

		return ss.str();
	}

	string calculate(const string& data1, const string& data2) {
		string ans;

		ans = getSub(data1, data2);
		while (true) {
			auto it = ans.rbegin();
			if (ans.size() == 1 || *it != '0') {
				break;
			}
			ans.pop_back();
		}
		return ans;
	}

	string getMul(const string& mul1, const string& mul2) {
		unsigned int len1, len2;
		int acc, sum, base;
		stringstream ss;
		string curSum;

		if (mul1 == "0" || mul2 == "0") {
			return "0";
		}

		len1 = mul1.size();
		len2 = mul2.size();
		//cout << mul1 << endl << mul2 << endl;

		curSum = "";
		for (unsigned int i = 0; i < len2; ++i) {
			string temp(""), res("");
			for (unsigned int k = 0; k < i; ++k) {
				temp += "0";
			}
			base = mul2[i] - '0';
			acc = 0;
			ss.clear();
			ss.str("");
			for (unsigned int j = 0; j < len1; ++j) {
				sum = base * (mul1[j] - '0') + acc;
				acc = sum / 10;
				sum %= 10;
				ss << sum;
			}
			if (acc != 0) {
				ss << acc;
			}
			res = temp + ss.str();
			//cout << "res=" << res << endl;
			curSum = getAdd(curSum, res);
			//cout << "curSum=" << curSum << endl;
		}

		return curSum;
	}

	string getDiv(const string& div1, const string& div2, string &rem) {
		unsigned int len1, len2, i;
		unsigned int k;
		stringstream ss;
		string curSum, curSumTmp, curNum, div2Tmp, ans;

		if (compare(div1, div2)) {
			rem = "0";
			return "0";
		}

		len1 = div1.size();
		len2 = div2.size();
		//cout << div1 << endl << div2 << endl;

		ans = "";
		curSum = div1.substr(0, len2);
		i = len2 - 1;
		if (curSum < div2) {
			curSum += div1[len2];
			i = len2;
		}
		//cout << "curSum=" << curSum << endl;
		for (; i < len1; ++i) {
			if (compare(curSum, div2)) {
				curSum += div1[i];
			}
			//cout << "1:curSum=" << curSum << endl;
			curSumTmp = curSum;
			div2Tmp = div2;
			reverse(curSumTmp.begin(), curSumTmp.end());
			reverse(div2Tmp.begin(), div2Tmp.end());
			for (k = 0; k < 10; ++k) {
				ss.clear();
				ss.str("");
				ss << k;
				curNum = ss.str();
				string res = getMul(div2Tmp, curNum);
				//cout << " 1:res=" << res << endl;
				res = calculate(curSumTmp, res);
				//cout << " 2:res=" << res << endl;
				reverse(res.begin(), res.end());
				//cout << " 3:res=" << res << endl;
				if (compare(res, div2)) {
					ans += curNum;
					curSum = res;
					break;
				}
			}
		}

		rem = curSum;
		//cout << " rem=" << rem << endl;
		return ans;
	}
};



int main(void) {

	ios::sync_with_stdio(false);
	cin.tie(NULL);
	cout.tie(NULL);

	BigData data1, data2;

#ifdef  InputOutputOperatorOverload
	cin >> data1 >> data2;

	//cout << "data1=" << data1 << endl << "data2=" << data2 << endl;
	cout << data1 + data2 << endl;
	cout << data1 - data2 << endl;
	cout << data1 * data2 << endl;
	cout << data1 / data2 << endl;
	cout << data1 % data2 << endl;
#else
	string d1, d2;
	cin >> d1 >> d2;
	data1.setValue(d1);
	data2.setValue(d2);

	//cout << "data1=" << data1.getValue() << endl << "data2=" << data2.getValue() << endl;
	//cout << (data1 + data2).getValue() << endl;
	//cout << (data1 - data2).getValue() << endl;
	cout << (data1 * data2).getValue() << endl;
	//cout << (data1 / data2).getValue() << endl;
	//cout << (data1 % data2).getValue() << endl;
#endif

	return 0;
}
accuracy: 1
time_ms: 70
memory_kb: 3508
final_rank: 11

code_snippet: #include <bits/stdc++.h>
#include <sstream>

using namespace std;

//#define InputOutputOperatorOverload

class BigData {
public:
#ifdef InputOutputOperatorOverload
	friend istream& operator >>(istream& in, BigData& bigdata) {
		in >> bigdata.data;
		return in;
	}

	friend ostream& operator <<(ostream& out, BigData& bigdata) {
		out << bigdata.data;
		return out;
	}
#else
	string getValue() {
		return this->data;
	}

	void setValue(string value) {
		this->data = value;
	}
#endif

	BigData operator +(const BigData& add) {
		string add1, add2;
		BigData ans;

		add1 = this->data;
		add2 = add.data;
		if (add1[0] != '-' && add2[0] != '-') {
			minFlag = false;
			reverse(add1.begin(), add1.end());
			reverse(add2.begin(), add2.end());
			ans.data = getAdd(add1, add2);
		}
		else if (add1[0] == '-' && add2[0] == '-') {
			minFlag = true;
			add1 = add1.substr(1);
			add2 = add2.substr(1);
			reverse(add1.begin(), add1.end());
			reverse(add2.begin(), add2.end());
			ans.data = getAdd(add1, add2);
		}
		else if (add1[0] == '-' && add2[0] != '-') {
			add1 = add1.substr(1);
			minFlag = compare(add1, add2) ? false : true;
			if (add1 == add2) {
				minFlag = false;
			}
			reverse(add1.begin(), add1.end());
			reverse(add2.begin(), add2.end());
			ans.data = calculate(add1, add2);
		}
		else if (add1[0] != '-' && add2[0] == '-') {
			add2 = add2.substr(1);
			minFlag = compare(add1, add2);
			reverse(add1.begin(), add1.end());
			reverse(add2.begin(), add2.end());
			ans.data = calculate(add1, add2);
		}

		if (minFlag) {
			ans.data += "-";
		}
		reverse(ans.data.begin(), ans.data.end());

		return ans;
	}

	BigData operator -(const BigData& sub) {
		string sub1, sub2;
		BigData ans;

		sub1 = this->data;
		sub2 = sub.data;
		if (sub1[0] != '-' && sub2[0] == '-') {
			minFlag = false;
			sub2 = sub2.substr(1);
			reverse(sub1.begin(), sub1.end());
			reverse(sub2.begin(), sub2.end());
			ans.data = getAdd(sub1, sub2);
		}
		else if (sub1[0] == '-' && sub2[0] != '-') {
			minFlag = true;
			sub1 = sub1.substr(1);
			reverse(sub1.begin(), sub1.end());
			reverse(sub2.begin(), sub2.end());
			ans.data = getAdd(sub1, sub2);
		}
		else if (sub1[0] != '-' && sub2[0] != '-') {
			minFlag = compare(sub1, sub2);
			reverse(sub1.begin(), sub1.end());
			reverse(sub2.begin(), sub2.end());
			ans.data = calculate(sub1, sub2);
		}
		else if (sub1[0] == '-' && sub2[0] == '-') {
			sub1 = sub1.substr(1);
			sub2 = sub2.substr(1);
			minFlag = compare(sub1, sub2) ? false : true;
			if (sub1 == sub2) {
				minFlag = false;
			}
			reverse(sub1.begin(), sub1.end());
			reverse(sub2.begin(), sub2.end());
			ans.data = calculate(sub1, sub2);
		}

		if (minFlag) {
			ans.data += "-";
		}
		reverse(ans.data.begin(), ans.data.end());

		return ans;
	}

	BigData operator *(const BigData& mul) {
		string mul1, mul2;
		BigData ans;

		mul1 = this->data;
		mul2 = mul.data;
		if (mul1[0] != '-' && mul2[0] != '-') {
			minFlag = false;
		}
		else if (mul1[0] == '-' && mul2[0] == '-') {
			minFlag = false;
			mul1 = mul1.substr(1);
			mul2 = mul2.substr(1);
		}
		else if (mul1[0] == '-' && mul2[0] != '-') {
			minFlag = true;
			mul1 = mul1.substr(1);
		}
		else if (mul1[0] != '-' && mul2[0] == '-') {
			minFlag = true;
			mul2 = mul2.substr(1);
		}
		if (mul1 == "0" || mul2 == "0") {
			ans.data = "0";
			return ans;
		}

		reverse(mul1.begin(), mul1.end());
		reverse(mul2.begin(), mul2.end());
		ans.data = getMul(mul1, mul2);

		if (minFlag) {
			ans.data += "-";
		}
		reverse(ans.data.begin(), ans.data.end());

		return ans;
	}


private:
	string data;
	bool minFlag;

	bool compare(string& d1, string& d2) {
		unsigned int len1, len2;

		len1 = d1.size();
		len2 = d2.size();
		if (len1 > len2) {
			return false;
		}

		if (len1 < len2 || d1 < d2) {
			d1.swap(d2);
			return true;
		}
		return false;
	}

	string getAdd(string& add1, string& add2) {
		unsigned int len1, len2, i;
		int acc, sum;
		stringstream ss;

		len1 = add1.size();
		len2 = add2.size();
		//cout << add1 << endl << add2 << endl;

		i = 0;
		acc = 0;
		ss.clear();
		ss.str("");
		while (i < len1 && i < len2) {
			sum = (add1[i] - '0') + (add2[i] - '0') + acc;
			acc = sum / 10;
			sum %= 10;
			ss << sum;
			++i;
		}

		while (i < len1) {
			sum = (add1[i] - '0') + acc;
			acc = sum / 10;
			sum %= 10;
			ss << sum;
			++i;
		}

		while (i < len2) {
			sum = (add2[i] - '0') + acc;
			acc = sum / 10;
			sum %= 10;
			ss << sum;
			++i;
		}

		if (acc == 1) {
			ss << 1;
		}

		return ss.str();
	}

	string getSub(string& sub1, string& sub2) {
		unsigned int len1, len2, i;
		int acc, sum;
		stringstream ss;

		len1 = sub1.size();
		len2 = sub2.size();
		//cout << sub1 << endl << sub2 << endl;

		i = 0;
		acc = 0;
		ss.clear();
		ss.str("");
		while (i < len1 && i < len2) {
			sum = (sub1[i] - '0') - acc - (sub2[i] - '0');
			if (sum < 0) {
				acc = 1;
				sum += 10;
			}
			else {
				acc = 0;
			}
			ss << sum;
			++i;
		}

		while (i < len1) {
			sum = (sub1[i] - '0') - acc;
			if (sum < 0) {
				acc = 1;
				sum += 10;
			}
			else {
				acc = 0;
			}
			ss << sum;
			++i;
		}

		while (i < len2) {
			sum = (sub2[i] - '0') - acc;
			if (sum < 0) {
				acc = 1;
				sum += 10;
			}
			else {
				acc = 0;
			}
			ss << sum;
			++i;
		}

		return ss.str();
	}

	string calculate(string& data1, string& data2) {
		string ans;

		ans = getSub(data1, data2);
		while (true) {
			auto it = ans.rbegin();
			if (ans.size() == 1 || *it != '0') {
				break;
			}
			ans.pop_back();
		}
		return ans;
	}

	string getMul(string& mul1, string& mul2) {
		unsigned int len1, len2;
		int acc, sum, base;
		stringstream ss;
		string curSum;

		len1 = mul1.size();
		len2 = mul2.size();
		//cout << mul1 << endl << mul2 << endl;

		curSum = "";
		for (unsigned int i = 0; i < len2; ++i) {
			string temp(""), res("");
			for (unsigned int k = 0; k < i; ++k) {
				temp += "0";
			}
			base = mul2[i] - '0';
			acc = 0;
			ss.clear();
			ss.str("");
			for (unsigned int j = 0; j < len1; ++j) {
				sum = base * (mul1[j] - '0') + acc;
				acc = sum / 10;
				sum %= 10;
				ss << sum;
			}
			if (acc != 0) {
				ss << acc;
			}
			res = temp + ss.str();
			//cout << "res=" << res << endl;
			curSum = getAdd(curSum, res);
			//cout << "curSum=" << curSum << endl;
		}

		return curSum;
	}
};



int main(void) {

	ios::sync_with_stdio(false);
	cin.tie(NULL);
	cout.tie(NULL);

	BigData data1, data2;

#ifdef  InputOutputOperatorOverload
	cin >> data1 >> data2;

	//cout << "data1=" << data1 << endl << "data2=" << data2 << endl;
	//cout << data1 + data2 << endl;
	//cout << data1 - data2 << endl;
	//cout << data1 * data2 << endl;
#else
	string d1, d2;
	cin >> d1 >> d2;
	data1.setValue(d1);
	data2.setValue(d2);

	//cout << "data1=" << data1.getValue() << endl << "data2=" << data2.getValue() << endl;
	//cout << (data1 + data2).getValue() << endl;
	//cout << (data1 - data2).getValue() << endl;
	cout << (data1 * data2).getValue() << endl;
#endif

	return 0;
}
accuracy: 1
time_ms: 50
memory_kb: 3504
final_rank: 9

code_snippet: #define _USE_MATH_DEFINES
#include <bits/stdc++.h>
using namespace std;

//template
#define rep(i,a,b) for(int i=(int)(a);i<(int)(b);i++)
#define ALL(v) (v).begin(),(v).end()
typedef long long int ll;
const int inf = 0x3fffffff; const ll INF = 0x1fffffffffffffff; const double eps=1e-12;
template<typename T>inline bool chmax(T& a,T b){if(a<b){a=b;return 1;}return 0;}
template<typename T>inline bool chmin(T& a,T b){if(a>b){a=b;return 1;}return 0;}
//end

template<typename T>struct FFT{
   struct C{
      T x,y;
      C(T _x=0,T _y=0):x(_x),y(_y){}
      C operator~()const{return {x,-y};}
      C operator+(const C& c)const{return {x+c.x,y+c.y};}
      C operator-(const C& c)const{return {x-c.x,y-c.y};}
      C operator*(const C& c)const{return {x*c.x-y*c.y,x*c.y+y*c.x};}
   };
   vector<C> rt;
   FFT(int lg=20){
      rt.resize(1<<lg,1);
      rep(k,1,lg){
         int d=1<<k;
         rep(i,0,d){
            if(i&1)rt[d+i]=C(cos(2*M_PI*i/d),sin(2*M_PI*i/d));
            else rt[d+i]=rt[(d+i)>>1];
         }
      }
   }
   void fft(vector<C>& a,bool inv=0){
      int n=a.size(); assert((n&(n-1))==0);
      if(inv){
         for(int i=1;i<n;i<<=1)for(int j=0;j<n;j+=i*2)for(int k=0;k<i;k++){
            a[i+j+k]=a[i+j+k]*~rt[i*2+k]; C tmp=a[j+k]-a[i+j+k];
            a[j+k]=a[j+k]+a[i+j+k]; a[i+j+k]=tmp;
         } rep(i,0,n)a[i].x/=n,a[i].y/=n;
      }
      else{
         for(int i=n>>1;i;i>>=1)for(int j=0;j<n;j+=i*2)for(int k=0;k<i;k++){
            C tmp=a[j+k]-a[i+j+k];
            a[j+k]=a[j+k]+a[i+j+k]; a[i+j+k]=tmp*rt[i*2+k];
         }
      }
      for(int i=0,j=1;j<n-1;j++){
         for(int k=n>>1;k>(i^=k);k>>=1);
         if(j<i)swap(a[i],a[j]);
      }
   }
   vector<ll> conv(vector<ll> a,vector<ll> b){
      if(a.empty() or b.empty())return vector<ll>();
      int n=a.size()+b.size()-1,m=1; vector<ll> res(n); while(m<n)m<<=1;
      vector<C> c(m); rep(i,0,a.size())c[i].x=a[i]; rep(i,0,b.size())c[i].y=b[i];
      fft(c); C rad(0,-0.25/m);
      for(int i=0,j=0;i<=m/2;i++,j=(m-i)&(m-1)){
         C z=(c[j]*c[j]-~(c[i]*c[i]))*rad;
         if(i!=j)c[j]=(c[i]*c[i]-~(c[j]*c[j]))*rad;
         c[i]=z;
      } fft(c); rep(i,0,n)res[i]=c[i].x+0.5; return res;
   }
};

FFT<double> fft;
template<int D=4>struct bigint{
   int B,sign; vector<ll> v;
   bigint(ll x=0){
      B=1; rep(_,0,D)B*=10; sign=1;
      if(x<0)x*=-1,sign=0;
      do{v.push_back(x%B); x/=B;
      }while(x);
   }
   bigint(string s){
      B=1; rep(_,0,D)B*=10; sign=1;
      if(s[0]=='-')s.erase(s.begin()),sign=0;
      int add=0,cnt=0,base=1;
      while(s.size()){
         if(cnt==D){
            v.push_back(add);
            cnt=0; add=0; base=1;
         }
         add=(s.back()-'0')*base+add;
         cnt++; base*=10;
         s.pop_back();
      }
      if(add)v.push_back(add);
   }
   bigint operator-()const{
      bigint res=*this;
      res.sign^=1; return res;
   }
   bigint abs()const{
      bigint res=*this;
      res.sign=1; return res;
   }
   ll& operator[](const int i){return v[i];}
   int size()const{return v.size();}
   void norm(){
      rep(i,0,v.size()-1){
         if(v[i]>=0){v[i+1]+=v[i]/B; v[i]%=B;}
         else{
            int c=(-v[i]+B-1)/B;
            v[i]+=c*B; v[i+1]-=c;
         }
      }
      while(!v.empty() and v.back()>=B){
         int c=v.back()/B;
         v.back()%=B; v.push_back(c);
      }
      while(v.size()>1 and v.back()==0)v.pop_back();
   }
   friend istream& operator>>(istream& is,bigint<D>& x){
      string tmp; is>>tmp;
      x=bigint(tmp); return is;
   }
   friend ostream& operator<<(ostream& os,bigint<D> x){
      if(x.v.empty() or ((int)x.size()==1 and x[0]==0))os<<"0";
      else{
         if(!x.sign)os<<"-";
         string res=to_string(x.v.back());
         for(int i=x.size()-2;i>=0;i--){
            string add; int w=x[i];
            rep(_,0,D){
               add+=('0'+(w%10)); w/=10;
            } reverse(ALL(add)); res+=add;
         } os<<res;
      }
      return os;
   }
   bigint& operator+=(const bigint& x){
      if(sign!=x.sign){*this-=(-x); return *this;}
      if((int)v.size()<(int)x.size())v.resize(x.size(),0);
      rep(i,0,x.size())v[i]+=x.v[i];
      norm(); return *this;
   }
   bigint& operator-=(const bigint& x){
      if(sign!=x.sign){*this+=(-x); return *this;}
      if(abs()<x.abs()){*this=x-(*this); sign^=1; return *this;}
      rep(i,0,x.size())v[i]-=x.v[i];
      norm(); return *this;
   }
   bigint& operator*=(const bigint& x){
      if(!x.sign)sign^=1; v=fft.conv(v,x.v);
      norm(); return *this;
   } /*
   bigint& operator/=(const bigint& x){
      
   } */
   bigint operator+(const bigint& x)const{return bigint(*this)+=x;}
   bigint operator-(const bigint& x)const{return bigint(*this)-=x;}
   bigint operator*(const bigint& x)const{return bigint(*this)*=x;}
   bigint operator/(const bigint& x)const{return bigint(*this)/=x;}
   bool operator<(const bigint& x)const{
      if(sign!=x.sign)return sign<x.sign;
      if((int)v.size()!=(int)x.size())return (int)v.size()*sign<(int)x.size()*x.sign;
      for(int i=v.size()-1;i>=0;i--)if(v[i]!=x.v[i])return v[i]*sign<x.v[i]*x.sign;
      return false;
   }
   bool operator>(const bigint& x)const{return x<*this;}
   bool operator<=(const bigint& x)const{return !(x>*this);}
   bool operator>=(const bigint& x)const{return !(x<*this);}
};
typedef bigint<4> Bigint;

int main(){
   Bigint x,y;
   cin>>x>>y;
   cout<<x*y<<endl;
   return 0;
}
accuracy: 1
time_ms: 20
memory_kb: 19040
final_rank: 10

code_snippet: #define _USE_MATH_DEFINES
#include <bits/stdc++.h>
using namespace std;

//template
#define rep(i,a,b) for(int i=(int)(a);i<(int)(b);i++)
#define ALL(v) (v).begin(),(v).end()
typedef long long int ll;
const int inf = 0x3fffffff; const ll INF = 0x1fffffffffffffff; const double eps=1e-12;
template<typename T>inline bool chmax(T& a,T b){if(a<b){a=b;return 1;}return 0;}
template<typename T>inline bool chmin(T& a,T b){if(a>b){a=b;return 1;}return 0;}
//end

template<typename T>struct FFT{
   struct C{
      T x,y;
      C(T _x=0,T _y=0):x(_x),y(_y){}
      C operator~()const{return {x,-y};}
      C operator+(const C& c)const{return {x+c.x,y+c.y};}
      C operator-(const C& c)const{return {x-c.x,y-c.y};}
      C operator*(const C& c)const{return {x*c.x-y*c.y,x*c.y+y*c.x};}
   };
   vector<C> rt;
   FFT(int lg=20){
      rt.resize(1<<lg,1);
      rep(k,1,lg){
         int d=1<<k;
         rep(i,0,d){
            if(i&1)rt[d+i]=C(cos(2*M_PI*i/d),sin(2*M_PI*i/d));
            else rt[d+i]=rt[(d+i)>>1];
         }
      }
   }
   void fft(vector<C>& a,bool inv=0){
      int n=a.size(); assert((n&(n-1))==0);
      if(inv){
         for(int i=1;i<n;i<<=1)for(int j=0;j<n;j+=i*2)for(int k=0;k<i;k++){
            a[i+j+k]=a[i+j+k]*~rt[i*2+k]; C tmp=a[j+k]-a[i+j+k];
            a[j+k]=a[j+k]+a[i+j+k]; a[i+j+k]=tmp;
         } rep(i,0,n)a[i].x/=n,a[i].y/=n;
      }
      else{
         for(int i=n>>1;i;i>>=1)for(int j=0;j<n;j+=i*2)for(int k=0;k<i;k++){
            C tmp=a[j+k]-a[i+j+k];
            a[j+k]=a[j+k]+a[i+j+k]; a[i+j+k]=tmp*rt[i*2+k];
         }
      }
      for(int i=0,j=1;j<n-1;j++){
         for(int k=n>>1;k>(i^=k);k>>=1);
         if(j<i)swap(a[i],a[j]);
      }
   }
   vector<int> conv(vector<int> a,vector<int> b){
      if(a.empty() or b.empty())return vector<int>();
      int n=a.size()+b.size()-1,m=1; vector<int> res(n); while(m<n)m<<=1;
      vector<C> c(m); rep(i,0,a.size())c[i].x=a[i]; rep(i,0,b.size())c[i].y=b[i];
      fft(c); C rad(0,-0.25/m);
      for(int i=0,j=0;i<=m/2;i++,j=(m-i)&(m-1)){
         C z=(c[j]*c[j]-~(c[i]*c[i]))*rad;
         if(i!=j)c[j]=(c[i]*c[i]-~(c[j]*c[j]))*rad;
         c[i]=z;
      } fft(c); rep(i,0,n)res[i]=c[i].x+0.5; return res;
   }
};

FFT<double> fft;
template<int D=4>struct bigint{
   int B,sign; vector<int> v;
   bigint(ll x=0){
      B=1; rep(_,0,D)B*=10; sign=1;
      if(x<0)x*=-1,sign=0;
      do{v.push_back(x%B); x/=B;
      }while(x);
   }
   bigint(string s){
      B=1; rep(_,0,D)B*=10; sign=1;
      if(s[0]=='-')s.erase(s.begin()),sign=0;
      int add=0,cnt=0,base=1;
      while(s.size()){
         if(cnt==D){
            v.push_back(add);
            cnt=0; add=0; base=1;
         }
         add=(s.back()-'0')*base+add;
         cnt++; base*=10;
         s.pop_back();
      }
      if(add)v.push_back(add);
   }
   bigint operator-()const{
      bigint res=*this;
      res.sign^=1; return res;
   }
   bigint abs()const{
      bigint res=*this;
      res.sign=1; return res;
   }
   int& operator[](const int i){return v[i];}
   int size()const{return v.size();}
   void norm(){
      rep(i,0,v.size()-1){
         if(v[i]>=0){v[i+1]+=v[i]/B; v[i]%=B;}
         else{
            int c=(-v[i]+B-1)/B;
            v[i]+=c*B; v[i+1]-=c;
         }
      }
      if(!v.empty() and v.back()>=B){
         int c=v.back()/B;
         v.back()%=B; v.push_back(c);
      }
      while(v.size()>1 and v.back()==0)v.pop_back();
   }
   friend istream& operator>>(istream& is,bigint<D>& x){
      string tmp; is>>tmp;
      x=bigint(tmp); return is;
   }
   friend ostream& operator<<(ostream& os,bigint<D> x){
      if(x.v.empty() or ((int)x.size()==1 and x[0]==0))os<<"0";
      else{
         if(!x.sign)os<<"-";
         string res=to_string(x.v.back());
         for(int i=x.size()-2;i>=0;i--){
            string add; int w=x[i];
            rep(_,0,D){
               add+=('0'+(w%10)); w/=10;
            } reverse(ALL(add)); res+=add;
         } os<<res;
      }
      return os;
   }
   bigint& operator+=(const bigint& x){
      if(sign!=x.sign){*this-=(-x); return *this;}
      if((int)v.size()<(int)x.size())v.resize(x.size(),0);
      rep(i,0,x.size())v[i]+=x.v[i];
      norm(); return *this;
   }
   bigint& operator-=(const bigint& x){
      if(sign!=x.sign){*this+=(-x); return *this;}
      if(abs()<x.abs()){*this=x-(*this); sign^=1; return *this;}
      rep(i,0,x.size())v[i]-=x.v[i];
      norm(); return *this;
   }
   bigint& operator*=(const bigint& x){
      if(!x.sign)sign^=1; v=fft.conv(v,x.v);
      norm(); return *this;
   } /*
   bigint& operator/=(const bigint& x){
      
   } */
   bigint operator+(const bigint& x)const{return bigint(*this)+=x;}
   bigint operator-(const bigint& x)const{return bigint(*this)-=x;}
   bigint operator*(const bigint& x)const{return bigint(*this)*=x;}
   bigint operator/(const bigint& x)const{return bigint(*this)/=x;}
   bool operator<(const bigint& x)const{
      if(sign!=x.sign)return sign<x.sign;
      if((int)v.size()!=(int)x.size())return (int)v.size()*sign<(int)x.size()*x.sign;
      for(int i=v.size()-1;i>=0;i--)if(v[i]!=x.v[i])return v[i]*sign<x.v[i]*x.sign;
      return false;
   }
   bool operator>(const bigint& x)const{return x<*this;}
   bool operator<=(const bigint& x)const{return !(x>*this);}
   bool operator>=(const bigint& x)const{return !(x<*this);}
};
typedef bigint<4> Bigint;

int main(){
   Bigint x,y;
   cin>>x>>y;
   cout<<x*y<<endl;
   return 0;
}
accuracy: 0.64
time_ms: 20
memory_kb: 19040
final_rank: 18

code_snippet: #define _USE_MATH_DEFINES
#include <bits/stdc++.h>
using namespace std;

//template
#define rep(i,a,b) for(int i=(int)(a);i<(int)(b);i++)
#define ALL(v) (v).begin(),(v).end()
typedef long long int ll;
const int inf = 0x3fffffff; const ll INF = 0x1fffffffffffffff; const double eps=1e-12;
template<typename T>inline bool chmax(T& a,T b){if(a<b){a=b;return 1;}return 0;}
template<typename T>inline bool chmin(T& a,T b){if(a>b){a=b;return 1;}return 0;}
//end

template<typename T>struct FFT{
   struct C{
      T x,y;
      C(T _x=0,T _y=0):x(_x),y(_y){}
      C operator~()const{return {x,-y};}
      C operator+(const C& c)const{return {x+c.x,y+c.y};}
      C operator-(const C& c)const{return {x-c.x,y-c.y};}
      C operator*(const C& c)const{return {x*c.x-y*c.y,x*c.y+y*c.x};}
   };
   vector<C> rt;
   FFT(int lg=20){
      rt.resize(1<<lg,1);
      rep(k,1,lg){
         int d=1<<k;
         rep(i,0,d){
            if(i&1)rt[d+i]=C(cos(2*M_PI*i/d),sin(2*M_PI*i/d));
            else rt[d+i]=rt[(d+i)>>1];
         }
      }
   }
   void fft(vector<C>& a,bool inv=0){
      int n=a.size(); assert((n&(n-1))==0);
      if(inv){
         for(int i=1;i<n;i<<=1)for(int j=0;j<n;j+=i*2)for(int k=0;k<i;k++){
            a[i+j+k]=a[i+j+k]*~rt[i*2+k]; C tmp=a[j+k]-a[i+j+k];
            a[j+k]=a[j+k]+a[i+j+k]; a[i+j+k]=tmp;
         } rep(i,0,n)a[i].x/=n,a[i].y/=n;
      }
      else{
         for(int i=n>>1;i;i>>=1)for(int j=0;j<n;j+=i*2)for(int k=0;k<i;k++){
            C tmp=a[j+k]-a[i+j+k];
            a[j+k]=a[j+k]+a[i+j+k]; a[i+j+k]=tmp*rt[i*2+k];
         }
      }
      for(int i=0,j=1;j<n-1;j++){
         for(int k=n>>1;k>(i^=k);k>>=1);
         if(j<i)swap(a[i],a[j]);
      }
   }
   vector<int> conv(vector<int> a,vector<int> b){
      int n=a.size()+b.size()-1,m=1; vector<int> res(n); while(m<n)m<<=1;
      vector<C> c(m); rep(i,0,a.size())c[i].x=a[i]; rep(i,0,b.size())c[i].y=b[i];
      fft(c); C rad(0,-0.25/m);
      for(int i=0,j=0;i<=m/2;i++,j=(m-i)&(m-1)){
         C z=(c[j]*c[j]-~(c[i]*c[i]))*rad;
         if(i!=j)c[j]=(c[i]*c[i]-~(c[j]*c[j]))*rad;
         c[i]=z;
      } fft(c); rep(i,0,n)res[i]=c[i].x+0.5; return res;
   }
};

FFT<double> fft;
template<int D=4>struct bigint{
   int B,sign; vector<int> v;
   bigint(ll x=0){
      B=1; rep(_,0,D)B*=10; sign=1;
      if(x<0)x*=-1,sign=0;
      do{v.push_back(x%B); x/=B;
      }while(x);
   }
   bigint(string s){
      B=1; rep(_,0,D)B*=10; sign=1;
      if(s[0]=='-')s.erase(s.begin()),sign=0;
      int add=0,cnt=0,base=1;
      while(s.size()){
         if(cnt==D){
            v.push_back(add);
            cnt=0; add=0; base=1;
         }
         add=(s.back()-'0')*base+add;
         cnt++; base*=10;
         s.pop_back();
      }
      if(add)v.push_back(add);
   }
   bigint operator-()const{
      bigint res=*this;
      res.sign^=1; return res;
   }
   bigint abs()const{
      bigint res=*this;
      res.sign=1; return res;
   }
   int& operator[](const int i){return v[i];}
   int size()const{return v.size();}
   void norm(){
      rep(i,0,v.size()-1){
         if(v[i]>=0){v[i+1]+=v[i]/B; v[i]%=B;}
         else{
            int c=(-v[i]+B-1)/B;
            v[i]+=c*B; v[i+1]-=c;
         }
      }
      if(!v.empty() and v.back()>=B){
         int c=v.back()/B;
         v.back()%=B; v.push_back(c);
      }
      while(v.size()>1 and v.back()==0)v.pop_back();
   }
   friend istream& operator>>(istream& is,bigint<D>& x){
      string tmp; is>>tmp;
      x=bigint(tmp); return is;
   }
   friend ostream& operator<<(ostream& os,bigint<D> x){
      if(x.v.empty() or ((int)x.size()==1 and x[0]==0))os<<"0";
      else{
         if(!x.sign)os<<"-";
         string res=to_string(x.v.back());
         for(int i=x.size()-2;i>=0;i--){
            string add; int w=x[i];
            rep(_,0,D){
               add+=('0'+(w%10)); w/=10;
            } reverse(ALL(add)); res+=add;
         } os<<res;
      }
      return os;
   }
   bigint& operator+=(const bigint& x){
      if(sign!=x.sign){*this-=(-x); return *this;}
      if((int)v.size()<(int)x.size())v.resize(x.size(),0);
      rep(i,0,x.size())v[i]+=x.v[i];
      norm(); return *this;
   }
   bigint& operator-=(const bigint& x){
      if(sign!=x.sign){*this+=(-x); return *this;}
      if(abs()<x.abs()){*this=x-(*this); sign^=1; return *this;}
      rep(i,0,x.size())v[i]-=x.v[i];
      norm(); return *this;
   }
   bigint& operator*=(const bigint& x){
      if(!x.sign)sign^=1; v=fft.conv(v,x.v);
      norm(); return *this;
   } /*
   bigint& operator/=(const bigint& x){
      
   } */
   bigint operator+(const bigint& x)const{return bigint(*this)+=x;}
   bigint operator-(const bigint& x)const{return bigint(*this)-=x;}
   bigint operator*(const bigint& x)const{return bigint(*this)*=x;}
   bigint operator/(const bigint& x)const{return bigint(*this)/=x;}
   bool operator<(const bigint& x)const{
      if(sign!=x.sign)return sign<x.sign;
      if((int)v.size()!=(int)x.size())return (int)v.size()*sign<(int)x.size()*x.sign;
      for(int i=v.size()-1;i>=0;i--)if(v[i]!=x.v[i])return v[i]*sign<x.v[i]*x.sign;
      return false;
   }
   bool operator>(const bigint& x)const{return x<*this;}
   bool operator<=(const bigint& x)const{return !(x>*this);}
   bool operator>=(const bigint& x)const{return !(x<*this);}
};
typedef bigint<4> Bigint;

int main(){
   Bigint x,y;
   cin>>x>>y;
   cout<<x*y<<endl;
   return 0;
}
accuracy: 0.08
time_ms: 20
memory_kb: 19008
final_rank: 19

code_snippet: #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;

class Karatsuba{
	int base = 10; // 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({z0.size(), z1.size()+b, 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];
		}
		
		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');
		}
		
		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;
}
accuracy: 1
time_ms: 20
memory_kb: 3304
final_rank: 5

code_snippet: #include<bits/stdc++.h>
using namespace std;

vector<int> stoa(string const& s){
  vector<int> a(s.size());
  for(int i=(s[0]=='-'?1:0);i<s.size();++i){
    a[i] = s[i]-'0';
  }
  return a;
}
string atos(vector<int> const& a){
  string s;
  for(auto ai:a)s+=(ai+'0');
  return s;
}

string product(string const& lhs,string const& rhs){
  if(lhs=="0"||rhs=="0")return "0";
  string sign = (lhs[0]=='-'^rhs[0]=='-'?"-":"");
  auto a = stoa(lhs);
  reverse(a.begin(),a.end());
  auto b = stoa(rhs);
  reverse(b.begin(),b.end());
  int n = a.size();
  int m = b.size();
  vector<vector<int>> tmp(m,vector<int>(n+m));
  for(int i=0;i<n;++i){
    for(int j=0;j<m;++j){
      tmp[j][i+j] += a[i]*b[j]%10;
      tmp[j][i+j+1] += a[i]*b[j]/10;
    }
  }
  vector<int> res(n+m+1);
  for(int i=0;i<n+m;++i){
    for(int j=0;j<m;++j){
      res[i] += tmp[j][i];
      res[i+1] += res[i]/10;
      res[i] %= 10;
    }
  }
  while(res.size()>1&&res.back()==0)res.pop_back();
  reverse(res.begin(),res.end());
  return sign+atos(res);
}

signed main(){

  string a,b;
  cin>>a>>b;

  cout<<product(a,b)<<endl;

}
accuracy: 1
time_ms: 10
memory_kb: 10796
final_rank: 8

code_snippet: #include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define rep(i,n) for(long long i=0; i<(n); i++)
template<class T> inline bool chmin(T& a, T b) { if (a > b) { a = b; return true; } return false; }
template<class T> inline bool chmax(T& a, T b) { if (a < b) { a = b; return true; } return false; }

bool compare(string a, string b) {
    if (a.size() > b.size()) return true;
    else if (a.size() < b.size()) return false;
    else {
        for (long long i = 0; i < a.size(); i++) {
            if (a[i] > b[i]) return true;
            else if (a[i] < b[i]) return false;
        }
    }
    return true;
}


string add(string a, string b) {
    bool x = false, y = false;
    if (a[0] == '-') x = true;
    if (b[0] == '-') y = true;

    if (x && y) return '-' + add(a.substr(1, a.size()-1), b.substr(1, b.size()-1));
    else if (x) return add(b, a);
    // 'a - b' or 'a + b'

    if (y) b = b.substr(1, b.size()-1);
    if (y && !compare(a, b)) {
        return '-' + add(b, '-' + a);
    }

    reverse(a.begin(), a.end());
    reverse(b.begin(), b.end());

    string res = "";
    long long up = 0;

    for (long long i = 0; i < max(a.size(), b.size()); i++) {
        long long tmp = up;
        if (i < a.size()) {
            tmp += (a[i] - '0');
        }
        if (i < b.size() && b[i] != '-') {
            if (y) tmp -= (b[i] - '0');
            else tmp += (b[i] - '0');
        }

        if (tmp < 0) {
            res.push_back((10 + tmp) + '0');
            up = -1;
        }
        else if (tmp > 9) {
            res.push_back((tmp - 10) + '0');
            up = 1;
        }
        else {
            res.push_back(tmp + '0');
            up = 0;
        }
    }

    if (up > 0) res.push_back(up + '0');

    reverse(res.begin(), res.end());

    long long begin = 0;
    while (res[begin] == '0') begin++;
    
    if (res.size() == begin) return "0";
    else return res.substr(begin, res.size() - begin);
}

string mult(string a, string b) {
    if (a == "0" || b == "0") return "0";
    string res = "0";
    bool ifminus = false;
    if (a[0] == '-' && b[0] == '-') return mult(a.substr(1, a.size()-1), b.substr(1, b.size()-1));
    else if (a[0] == '-') return '-' + mult(a.substr(1, a.size()-1), b);
    else if (b[0] == '-') return '-' + mult(a, b.substr(1, b.size()-1));

    reverse(b.begin(), b.end());

    for (long long i = 0; i < b.size(); i++) {
        string tmp = "0";
        for (long long j = 0; j < (b[i] - '0'); j++) {
            tmp = add(tmp, a);
        }
        for (long long j = 0; j < i; j++) {
            tmp = tmp + '0';
        }
        res = add(res, tmp);
    }

    return res;
}


int main(){
    string a, b;
    cin >> a >> b;
    cout << mult(a, b) << endl;
    return 0;
}
accuracy: 1
time_ms: 80
memory_kb: 3220
final_rank: 12

code_snippet: #include<iostream>
#include<string>
using namespace std;

string fixedNum( string a )
{
    if( a.size() == 1 )
        return a;
    for( int i = 0; i < a.size(); i++ )
        if( '1'<= a[i] && a[i] <= '9' )
            return a.substr( i, a.size() );
    return "0";
}

string calcAddition( string a, string b )
{
    a = fixedNum(a); b = fixedNum(b);
    int as = a.size(), bs = b.size(), d = as > bs ? as - bs : bs - as;
    string s = "0", t = "0";
    for( int i = 0; i < d; i++ )
        as > bs ? t += "0" : s += "0";
    s += a; t += b;

    for( int i = s.size() - 1; i >= 1; i-- )
    {
        s[i] += t[i] - '0';
        if( s[i] > '9' )
        {
            s[i] -= 10;
            s[i-1]++;
        }
    }

    return s[0] == '0' ? s.substr( 1, s.size() ) : s;
}

string calcMultiplication( string a, string b )
{
    a = fixedNum(a); b = fixedNum(b);
    int as = a.size(), bs = b.size(), d = as > bs ? as - bs : bs - as;
    string s = "0", t = "0", x = "", sum = "", zero = "", digit = "";
    for( int i = 0; i < d; i++ )
        as > bs ? t += "0" : s += "0";
    s += a; t += b;

    for( int i = 0; i < s.size(); i++ )
        zero += "0";
    
    x = zero;
    sum = zero;

    for( int i = s.size() - 1; i >= 1; i-- )
    {
        for( int j = s.size() - 1; j >= 1; j-- )
            x[j] = ( t[i] - '0' ) * ( s[j] - '0' );
        for( int j = s.size() - 1; j >= 1; j-- )
        {
            int f = x[j] / 10;
            x[j-1] += f;
            x[j] = x[j] - 10 * f + '0';
        }
        x += digit;
        sum = calcAddition( x, sum );
        digit += "0";
        x = zero;
    }
    return sum;
}

int main()
{
    string a, b;

    cin >> a >> b;

    int as = a.size(), bs = b.size();
    string s = a.substr( 1, as ), t = b.substr( 1, bs );

    if( a[0] == '-' && b[0] == '-' )
        cout << calcMultiplication( s, t ) << endl;
    else if( a[0] >= '0' && b[0] >= '0' )
        cout << calcMultiplication( a, b ) << endl;
    else
    {
        if( a == "0" || b == "0" )
            cout << "0" << endl;
        else if( a[0] == '-' )
            cout << '-' << calcMultiplication( s, b ) << endl;
        else
            cout << '-' << calcMultiplication( a, t ) << endl;
    }
    return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 3228
final_rank: 1

code_snippet: // includes
#include <bits/stdc++.h>

// macros
#define ll long long int
#define pb emplace_back
#define mk make_pair
#define pq priority_queue
#define FOR(i, a, b) for(int i=(a);i<(b);++i)
#define rep(i, n) FOR(i, 0, n)
#define rrep(i, n) for(int i=((int)(n)-1);i>=0;i--)
#define irep(itr, st) for(auto itr = (st).begin(); itr != (st).end(); ++itr)
#define irrep(itr, st) for(auto itr = (st).rbegin(); itr != (st).rend(); ++itr)
#define vrep(v, i) for(int i = 0; i < (v).size(); i++)
#define all(x) (x).begin(),(x).end()
#define sz(x) ((int)(x).size())
#define UNIQUE(v) v.erase(unique(v.begin(), v.end()), v.end())
#define FI first
#define SE second
#define dump(a, n) for(int i = 0; i < n; i++)cout << a[i] << "\n "[i + 1 != n];
#define dump2(a, n, m) for(int i = 0; i < n; i++)for(int j = 0; j < m; j++)cout << a[i][j] << "\n "[j + 1 != m];
#define bit(n) (1LL<<(n))
#define INT(n) int n; cin >> n;
#define LL(n) ll n; cin >> n;
#define DOUBLE(n) double n; cin >> n;
using namespace std;

//  types
typedef pair<int, int> P;
typedef pair<ll, int> Pl;
typedef pair<ll, ll> Pll;
typedef pair<double, double> Pd;
typedef complex<double> cd;
 
// constants
const int inf = 1e9;
const ll linf = 1LL << 50;
const double EPS = 1e-10;
const int mod = 1e9 + 7;
const int dx[4] = {-1, 0, 1, 0};
const int dy[4] = {0, -1, 0, 1};

// solve
template <class T>bool chmax(T &a, const T &b){if(a < b){a = b; return 1;} return 0;}
template <class T>bool chmin(T &a, const T &b){if(a > b){a = b; return 1;} return 0;}
template <typename T> istream &operator>>(istream &is, vector<T> &vec){for(auto &v: vec)is >> v; return is;}
template <typename T> ostream &operator<<(ostream &os, const vector<T>& vec){for(int i = 0; i < vec.size(); i++){ os << vec[i]; if(i + 1 != vec.size())os << " ";} return os;}
template <typename T> ostream &operator<<(ostream &os, const set<T>& st){for(auto itr = st.begin(); itr != st.end(); ++itr){ os << *itr; auto titr = itr; if(++titr != st.end())os << " ";} return os;}
template <typename T> ostream &operator<<(ostream &os, const unordered_set<T>& st){for(auto itr = st.begin(); itr != st.end(); ++itr){ os << *itr; auto titr = itr; if(++titr != st.end())os << " ";} return os;}
template <typename T> ostream &operator<<(ostream &os, const multiset<T>& st){for(auto itr = st.begin(); itr != st.end(); ++itr){ os << *itr; auto titr = itr; if(++titr != st.end())os << " ";} return os;}
template <typename T> ostream &operator<<(ostream &os, const unordered_multiset<T>& st){for(auto itr = st.begin(); itr != st.end(); ++itr){ os << *itr; auto titr = itr; if(++titr != st.end())os << " ";} return os;}
template <typename T1, typename T2> ostream &operator<<(ostream &os, const pair<T1, T2> &p){os << p.first << " " << p.second; return os;}
template <typename T1, typename T2> ostream &operator<<(ostream &os, const map<T1, T2> &mp){for(auto itr = mp.begin(); itr != mp.end(); ++itr){ os << itr->first << ":" << itr->second; auto titr = itr; if(++titr != mp.end())os << " "; } return os;}
template <typename T1, typename T2> ostream &operator<<(ostream &os, const unordered_map<T1, T2> &mp){for(auto itr = mp.begin(); itr != mp.end(); ++itr){ os << itr->first << ":" << itr->second; auto titr = itr; if(++titr != mp.end())os << " "; } return os;}

template <typename T>
T power(T a, T n, T mod) {
  T res = 1;
  T tmp = n;
  T curr = a;
  while(tmp){
    if(tmp % 2 == 1){
      res = (T)((ll)res * curr % mod);
    }
    curr = (T)((ll)curr * curr % mod);
    tmp >>= 1;
  }
  return res;
}

template<typename T>
T extgcd(T a, T b, T &x, T &y){
  T d = a;
  if(b != 0){
    d = extgcd(b, a % b, y, x);
    y -= (a / b) * x;
  }else{
    x = 1, y = 0;
  }
  return d;
}

template <typename T>
T modinv(T a, T m){
  long long x = 0, y = 0;
  extgcd<long long>(a, m, x, y);
  x %= m;
  if(x < 0)x += m;
  return x;
}

template <typename T>
long long garner(vector<T> b, vector<T> m, T MOD){
  m.emplace_back(MOD);
  vector<long long> coef(m.size(), 1);
  vector<long long> consts(m.size(), 0);
  for(int i = 0; i < b.size(); i++){
    long long t = ((b[i] - consts[i]) % m[i]) * modinv<long long>(coef[i], m[i]) % m[i];
    for(int j = i + 1; j < m.size(); j++){
      consts[j] = (consts[j] + t * coef[j] % m[j]) % m[j];
      coef[j] = coef[j] * m[i] % m[j];
    }
  }
  return consts.back();
}

template <int MOD, int g>
struct NTT{
  int get_mod(){
    return MOD;
  }
  void _ntt(vector<long long> &f, bool inv=false){
    int n = f.size(), mask = n - 1;
    int h = power<long long>(g, (MOD - 1) / n, MOD);
    if(inv)h = modinv(h, MOD);
    vector<long long> tmp(n);
    for(int i = n >> 1; i >= 1; i >>= 1){
      long long zeta = power<long long>(h, i, MOD);
      long long w = 1;
      for(int j = 0; j < n; j += i){
        for(int k = 0; k < i; k++){
          tmp[j+k] = (f[((j<<1)&mask)+k] + w * f[(((j<<1)+i)&mask)+k] % MOD) % MOD;
        }
        w = w * zeta % MOD;
      }
      swap(f, tmp);
    }
  }
  void ntt(vector<long long> &f){
    _ntt(f, false);
  }
  void intt(vector<long long> &f){
    _ntt(f, true);
    int n = f.size();
    int ni = modinv(n, MOD);
    for(int i = 0; i < n; i++)f[i] = f[i] * ni % MOD;
  }
  vector<long long> convolution(vector<long long> f, vector<long long> h){
    int n = 1;
    while(n < int(f.size() + h.size()))n *= 2;
    f.resize(n, 0); h.resize(n, 0);
    ntt(f);
    ntt(h);
    for(int i = 0; i < n; i++)f[i] = f[i] * h[i] % MOD;
    intt(f);
    return f;
  }
};

using NTT1 = NTT<167772161, 3>;
using NTT2 = NTT<469762049, 3>;
using NTT3 = NTT<1224736769, 3>;

vector<long long> arbitrary_mod_convolution(vector<long long> f, vector<long long> g, long long MOD){
  for(size_t i = 0; i < f.size(); i++)f[i] %= MOD;
  for(size_t i = 0; i < g.size(); i++)g[i] %= MOD;
  NTT1 ntt1;
  NTT2 ntt2;
  NTT3 ntt3;
  auto x1 = ntt1.convolution(f, g);
  auto x2 = ntt2.convolution(f, g);
  auto x3 = ntt3.convolution(f, g);

  vector<long long> res(x1.size());
  vector<long long> b(3), m(3);
  m[0] = ntt1.get_mod();
  m[1] = ntt2.get_mod();
  m[2] = ntt3.get_mod();
  for(size_t i = 0; i < x1.size(); i++){
    b[0] = x1[i];
    b[1] = x2[i];
    b[2] = x3[i];
    res[i] = garner<long long>(b, m, MOD);
  }
  return res;
}

const ll B = 10000;
const int BW = 4;
struct BigInt{
  vector<ll> digit;
  BigInt(ll a = 0){
    digit.emplace_back(a);
    normalize();
  }
  BigInt(const string &s){
    from_string(s);
  }
  void from_string(const string &s){
    digit.clear();
    int i;
    for(i = (int)s.size() - BW; i >= 0; i-=BW){
      digit.emplace_back(stol(s.substr(i, BW)));
    }
    i += BW;
    if(i > 0)digit.emplace_back(stol(s.substr(0, i)));
  }
  void normalize(){
    ll c = 0;
    for(int i = 0; i < digit.size(); i++){
      while(digit[i] < 0){
        if(i + 1 == digit.size())digit.emplace_back(0);
        digit[i+1]--;
        digit[i] += B;
      }
      ll a = digit[i] + c;
      digit[i] = a % B;
      c = a / B;
    }
    while(c){
      digit.emplace_back(c % B);
      c /= B;
    }
    for(int i = (int)digit.size() - 1; i >= 1; i--){
      if(digit[i] == 0){
        digit.pop_back();
      }else{
        break;
      }
    }
  }
  size_t size(){
    return digit.size();
  }
  BigInt& operator=(ll a){
    digit.resize(1, a);
    normalize();
    return *this;
  }
  BigInt& operator=(const string &s){
    from_string(s);
    return *this;
  }
} ZERO(0), ONE(1);

ostream &operator<<(ostream &os, const BigInt &b){
  os << b.digit[b.digit.size() - 1];
  for(int i = (int)b.digit.size() - 2; i >= 0; i--){
    os << setw(BW) << setfill('0') << b.digit[i];
  }
  return os;
}

istream & operator>>(istream &is, BigInt &b){
  string s;
  is >> s;
  b.from_string(s);
  return is;
}

bool operator<(const BigInt &x, const BigInt &y){
  if(x.digit.size() != y.digit.size())return x.digit.size() < y.digit.size();
  for(int i = x.digit.size() - 1; i >= 0; i--){
    if(x.digit[i] != y.digit[i])return x.digit[i] < y.digit[i];
  }
  return false;
}

bool operator>(const BigInt &x, const BigInt y){
  return y < x;
}

bool operator<=(const BigInt &x, const BigInt &y){
  return !(y < x);
}

bool operator>=(const BigInt &x, const BigInt &y){
  return !(x < y);
}

bool operator!=(const BigInt &x, const BigInt &y){
  return x < y || y < x;
}

bool operator==(const BigInt &x, const BigInt &y){
  return !(x < y) && !(y < x);
}

BigInt operator+(const BigInt &x, ll a){
  BigInt res = x;
  res.digit[0] += a;
  res.normalize();
  return res;
}

BigInt operator+(const BigInt &x, const BigInt &y){
  BigInt res = x;
  while(res.digit.size() < y.digit.size())res.digit.emplace_back(0);
  for(int i = 0; i < y.digit.size(); i++)res.digit[i] += y.digit[i];
  res.normalize();
  return res;
}

BigInt operator-(const BigInt &x, const BigInt &y){
  BigInt res = x;
  assert(res.digit.size() >= y.digit.size());
  for(int i = 0; i < y.digit.size(); i++)res.digit[i] -= y.digit[i];
  res.normalize();
  return res;
}

BigInt operator*(const BigInt &x, const BigInt &y){
  BigInt z;
  //NTT3 ntt;
  vector<long long> xc = x.digit, yc = y.digit;
  /*z.digit.assign(x.digit.size() + y.digit.size(), 0);
    for(int i = 0; i < x.digit.size(); i++){
    for(int j = 0; j < y.digit.size(); j++){
    z.digit[i+j] += x.digit[i] * y.digit[j];
    }
    }*/
  //z.digit = ntt.convolution(xc, yc);
  z.digit = arbitrary_mod_convolution(xc, yc, (ll)mod * 10);
  z.normalize();
  return z;
}

BigInt operator*(const BigInt &x, ll a){
  BigInt res = x;
  for(int i = 0; i < res.digit.size(); i++)res.digit[i] *= a;
  res.normalize();
  return res;
}

pair<BigInt, ll> divmod(const BigInt &x, ll a){
  ll c = 0;
  BigInt res = x;
  for(int i = (int)res.digit.size() - 1; i >= 0; i--){
    ll t = B * c + res.digit[i];
    res.digit[i] = t / a;
    c = t % a;
  }
  res.normalize();
  return make_pair(res, c);
}

BigInt operator/(const BigInt &x, ll a){
  return divmod(x, a).first;
}

BigInt operator%(const BigInt &x, ll a){
  return divmod(x, a).second;
}

pair<BigInt, BigInt> divmod(const BigInt &x, const BigInt &y){
  BigInt rx = x, ry = y;
  if(x.digit.size() < y.digit.size())return make_pair(ZERO, x);
  int F = B / (y.digit[y.digit.size() - 1] + 1);
  rx = rx * F; ry = ry * F;
  BigInt z;
  z.digit.assign(rx.digit.size() - ry.digit.size() + 1, 0);
  for(int k = (int)z.digit.size() - 1, i = (int)rx.digit.size() - 1; k >= 0; k--, i--){
    z.digit[k] = (i + 1 < rx.digit.size() ? rx.digit[i+1]: 0) * B + rx.digit[i];
    z.digit[k] /= ry.digit[ry.digit.size() - 1];
    BigInt t;
    t.digit.assign(k + ry.digit.size(), 0);
    for(int m = 0; m < ry.digit.size(); m++){
      t.digit[k+m] = z.digit[k] * ry.digit[m];
    }
    t.normalize();
    while(rx < t){
      z.digit[k] -= 1;
      for(int m = 0; m < ry.digit.size(); m++){
        t.digit[k+m] -= ry.digit[m];
      }
      t.normalize();
    }
    rx = rx - t;
  }
  z.normalize();
  return make_pair(z, rx / F);
}

BigInt operator/(const BigInt &x, const BigInt &y){
  return divmod(x, y).first;
}

BigInt operator%(const BigInt &x, const BigInt &y){
  return divmod(x, y).second;
}

BigInt& operator+=(BigInt &x, ll a){
  x = x + a;
  return x;
}

BigInt &operator+=(BigInt &x, const BigInt &y){
  x = x + y;
  return x;
}

BigInt &operator-=(BigInt &x, const BigInt &y){
  x = x - y;
  return x;
}

BigInt& operator*=(BigInt &x, const BigInt &y){
  x = x * y;
  return x;
}

BigInt& operator/=(BigInt &x, const BigInt &y){
  x = x / y;
  return x;
}

BigInt& operator%=(BigInt &x, const BigInt &y){
  x = x % y;
  return x;
}

BigInt& operator/=(BigInt &x, ll a){
  x = x / a;
  return x;
}

BigInt& operator%=(BigInt &x, ll a){
  x = x % a;
  return x;
}

BigInt sqrt(const BigInt &x){
  BigInt l = 1;
  BigInt r = x;
  while(r - l > BigInt(1)){
    BigInt m = (r + l) / 2;
    if(m * m > x)r = m;
    else l = m;
  }
  return l;
}

struct SBigInt{
  bool neg = false;
  BigInt b = 0;
  SBigInt(){}
  SBigInt(ll a): b(BigInt(abs(a))){
    if(a < 0)neg = true;
  }
  SBigInt(const string &s){
    string t = s;
    if(t[0] == '-'){
      neg = true;
      t = t.substr(1, t.size() - 1);
    }
    b = BigInt(t);
  }
  void check_zero(){
    if(b == ZERO)neg = false;
  }
  bool operator==(const SBigInt &r) const{
    return (neg == r.neg) && (b == r.b);
  }
  bool operator!=(const SBigInt &r) const{
    return (neg != r.neg) || (b != r.b);
  }
  SBigInt operator-() const{
    SBigInt res = *this;
    res.neg = !res.neg;
    res.check_zero();
    return res;
  }
};

SBigInt operator+(const SBigInt &x, const SBigInt &y){
  SBigInt res;
  if(x.neg == y.neg){
    res.b = x.b + y.b;
    res.neg = x.neg;
  }else{
    if(x.b > y.b){
      res.b = x.b - y.b;
      res.neg = x.neg;
    }else{
      res.b = y.b - x.b;
      res.neg = y.neg;
    }
  }
  res.check_zero();
  return res;
}

SBigInt operator-(const SBigInt &x, const SBigInt &y){
  SBigInt res = x + (- y);
  res.check_zero();
  return res;
}

SBigInt operator*(const SBigInt &x, const SBigInt &y){
  SBigInt res;
  res.neg = !(x.neg == y.neg);
  res.b = x.b * y.b;
  res.check_zero();
  return res;
}

SBigInt operator/(const SBigInt &x, const SBigInt &y){
  SBigInt res;
  res.neg = !(x.neg == y.neg);
  res.b = x.b / y.b;
  res.check_zero();
  return res;
}

ostream &operator<<(ostream &os, const SBigInt &b){
  if(b.neg)os << "-";
  os << b.b;
  return os;
}

int main(int argc, char const* argv[])
{
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  cout << fixed << setprecision(20);
  string a, b;
  cin >> a >> b;
  SBigInt A(a), B(b);
  cout << A * B << endl;
  return 0;
}
accuracy: 0.64
time_ms: 20
memory_kb: 3308
final_rank: 17