Problem:
Addition of Big Integers
Given two integers $A$ and $B$, compute the sum, $A + B$.
Input
Two integers $A$ and $B$ separated by a space character are given in a line.
Output
Print the sum in a line.
Constraints
$-1 \times 10^{100000} \leq A, B \leq 10^{100000}$
Sample Input 1
5 8
Sample Output 1
13
Sample Input 2
100 25
Sample Output 2
125
Sample Input 3
-1 1
Sample Output 3
0
Sample Input 4
12 -3
Sample Output 4
9

Submitted solutions:

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 ld PI = acos( -1.0 );

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

template <typename T>
void print_arr( vector<T> v ){
    if( v.size() == 0 ) return;
    for( int i = 0 ; i < v.size() ; i++ )
        cout << v[i];
    cout << endl;
}

struct BigInteger{

    bool minus;
    int digit;
    vector<ll> arr;

    BigInteger( string val = "", bool m = false ){

        minus = m;
        while( val.length() > 4 ){
            arr.push_back( stoll( val.substr( val.length() - 4 ) ) );
            val = val.substr( 0, val.length() - 4 );
        }
        if( val.length() != 0 )
            arr.push_back( stoll( val ) );
        set_digit();

    }

    void shift_l(){

        ll up = 0;
        for( int i = 0 ; i < digit ; i++ ){
            ll next_up = arr[i] / 1000;
            arr[i] = ( arr[i] % 1000 ) * 10 + up;  
            up = next_up;
        }
        arr.push_back( up );
        set_digit();

    }

    void shift_r(){

        ll down = 0;
        for( int i = digit - 1 ; i >= 0 ; i-- ){
            ll next_down = arr[i] % 10;
            arr[i] = 1000 * down + arr[i] / 10;
            down = next_down;
        }
        set_digit();

    }

    bool zero(){

        return digit == 1 && arr[0] == 0;

    }

    void set_digit(){

        while( arr.size() > 1 && arr[arr.size()-1] == 0 )
            arr.pop_back();
        digit = arr.size();

    }

    void print(){

        if( zero() ){
            cout << 0 << endl;
            return;
        }
        if( minus )
            cout << "-";
        cout << arr[digit - 1];
        for( int i = digit - 2 ; i >= 0 ; i-- )
            cout << setfill( '0' ) << std::setw( 4 ) << arr[i];
        cout << endl;

    }

};

BigInteger add( BigInteger bi1, BigInteger bi2 );
BigInteger sub( BigInteger bi1, BigInteger bi2 );
BigInteger mul( BigInteger bi1, BigInteger bi2 );
BigInteger div( BigInteger bi1, BigInteger bi2 );
bool operator<( const BigInteger bi1, const BigInteger bi2 );
bool operator>( const BigInteger bi1, const BigInteger bi2 );
bool operator<=( const BigInteger bi1, const BigInteger bi2 );
bool operator>=( const BigInteger bi1, const BigInteger bi2 );
bool operator==( const BigInteger bi1, const BigInteger bi2 );
bool operator!=( const BigInteger bi1, const BigInteger bi2 );

BigInteger add( BigInteger bi1, BigInteger bi2 ){

    if( !bi1.minus && bi2.minus ){
        bi2.minus = false;
        return sub( bi1, bi2 );
    }
    else if( bi1.minus && !bi2.minus ){
        bi1.minus = false;
        return sub( bi2, bi1 );
    }
    else if( bi1.minus && bi2.minus ){
        bi1.minus = false;
        bi2.minus = false;
        BigInteger res = add( bi1, bi2 );
        res.minus = true;
        return res;
    }

    BigInteger res;
    ll up = 0;
    for( int i = 0 ; i < max( bi1.digit, bi2.digit ) ; i++ ){
        ll val1 = 0, val2 = 0;
        if( i < bi1.digit )
            val1 = bi1.arr[i];
        if( i < bi2.digit )
            val2 = bi2.arr[i];
        res.arr.push_back( ( val1 + val2 + up ) % 10000 );   
        up = ( val1 + val2 + up ) / 10000;
    }
    res.arr.push_back( up );
    res.set_digit();
    return res;

}

BigInteger sub( BigInteger bi1, BigInteger bi2 ){

    if( !bi1.minus && bi2.minus ){
        bi2.minus = false;
        return add( bi1, bi2 );
    }
    else if( bi1.minus && !bi2.minus ){
        bi1.minus = false;
        BigInteger res = add( bi1, bi2 );
        res.minus = true;
        return res;
    }
    else if( bi1.minus && bi2.minus ){
        bi1.minus = false;
        bi2.minus = false;
        BigInteger res = sub( bi2, bi1 );
        return res;
    }

    if( bi1.digit < bi2.digit ){
        BigInteger res = sub( bi2, bi1 );
        res.minus = true;
        return res;
    }
    else if( bi1.digit == bi2.digit ){
        for( int i = bi1.digit-1 ; i >= 0 ; i-- ){
            if( bi1.arr[i] > bi2.arr[i] )
                break;
            else if( bi1.arr[i] < bi2.arr[i] ){
                BigInteger res = sub( bi2, bi1 );
                res.minus = true;
                return res;
            }
        }
    }
    
    BigInteger res;
    ll down = 0;
    for( int i = 0 ; i < bi1.digit ; i++ ){
        ll val1 = 0, val2 = 0;
        if( i < bi1.digit )
            val1 = bi1.arr[i] - down;
        if( i < bi2.digit )
            val2 = bi2.arr[i];
        if( val1 < val2 ){
            down = 1;
            val1 += 10000;
        }
        else    
            down = 0;
        res.arr.push_back( val1 - val2 );
    }
    res.set_digit();
    return res;

}

BigInteger mul( BigInteger bi1, BigInteger bi2 ){

    BigInteger res;
    res.minus = ( bi1.minus != bi2.minus );
    for( int i = 0 ; i < bi1.digit + bi2.digit ; i++ )
        res.arr.push_back( 0 );
    for( int i = 0 ; i < bi1.digit ; i++ ){
        for( int j = 0 ; j < bi2.digit ; j++ )
            res.arr[i+j] += bi1.arr[i] * bi2.arr[j];
    }
    ll up = 0;
    for( int i = 0 ; i < bi1.digit + bi2.digit ; i++ ){
        ll next_up = ( res.arr[i] + up ) / 10000;
        res.arr[i] = ( res.arr[i] + up ) % 10000;
        up = next_up;
    }
    res.set_digit();
    return res;

}

BigInteger div( BigInteger bi1, BigInteger bi2 ){

    string num = "";
    bool m = ( bi1.minus != bi2.minus );
    bi1.minus = bi2.minus = false;
    BigInteger org = bi2;
    if( bi1 < bi2 ){
        BigInteger zero( "0", false );
        return zero;
    }
    while( bi1.digit > bi2.digit ){
        bi2.arr.insert( bi2.arr.begin(), 0 );
        bi2.digit++;
    }
    while( to_string( bi1.arr[bi1.digit-1] ).length() > to_string( bi2.arr[bi2.digit-1] ).length() )
        bi2.shift_l();
    while( to_string( bi1.arr[bi1.digit-1] ).length() < to_string( bi2.arr[bi2.digit-1] ).length() )
        bi2.shift_r();
    while( bi2 >= org ){ 
        int i;
        for( i = 0 ; i <= 9 ; i++ ){
            BigInteger tmp = sub( bi1, bi2 );
            tmp.print();
            if( !tmp.zero() && tmp.minus )
                break;
            bi1 = tmp;
        } 
        num += to_string( i );
        bi2.shift_r();
    }
    BigInteger res( num, m );
    return res;

}

bool operator<( const BigInteger bi1, const BigInteger bi2 ){

    BigInteger tmp = sub( bi1, bi2 );
    return tmp.minus && !tmp.zero();

}

bool operator>( const BigInteger bi1, const BigInteger bi2 ){
 
    BigInteger tmp = sub( bi1, bi2 );
    return !tmp.minus && !tmp.zero();

}

bool operator<=( const BigInteger bi1, const BigInteger bi2 ){
    
    BigInteger tmp = sub( bi1, bi2 );
    return tmp.minus || tmp.zero();

}

bool operator>=( const BigInteger bi1, const BigInteger bi2 ){
    
    BigInteger tmp = sub( bi1, bi2 );
    return !tmp.minus || tmp.zero();

}

bool operator==( const BigInteger bi1, const BigInteger bi2 ){
    
    BigInteger tmp = sub( bi1, bi2 );
    return tmp.zero();

}

bool operator!=( const BigInteger bi1, const BigInteger bi2 ){
    
    BigInteger tmp = sub( bi1, bi2 );
    return !tmp.zero();

}

int main(){

    string val1, val2;
    bool minus;
    
    cin >> val1;
    if( val1[0] == '-' ){
        minus = true;
        val1 = val1.substr( 1 );
    }
    else
        minus = false;
    BigInteger bi1( val1, minus );

    cin >> val2;
    if( val2[0] == '-' ){
        minus = true;
        val2 = val2.substr( 1 );
    }
    else
        minus = false;
    BigInteger bi2( val2, minus );
    
    BigInteger res = add( bi1, bi2 );
    res.print();

}
accuracy: 1
time_ms: 50
memory_kb: 5368
final_rank: 2

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 ld PI = acos( -1.0 );

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

template <typename T>
void print_arr( vector<T> v ){
    if( v.size() == 0 ) return;
    for( int i = 0 ; i < v.size() ; i++ )
        cout << v[i];
    cout << endl;
}

struct BigInteger{

    bool minus;
    int digit;
    vector<ll> arr;

    BigInteger( string val = "", bool m = false ){

        minus = m;
        while( val.length() > 4 ){
            arr.push_back( stoll( val.substr( val.length() - 4 ) ) );
            val = val.substr( 0, val.length() - 4 );
        }
        if( val.length() != 0 )
            arr.push_back( stoll( val ) );
        set_digit();

    }

    void shift_l(){

        ll up = 0;
        for( int i = 0 ; i < digit ; i++ ){
            ll next_up = arr[i] / 1000;
            arr[i] = ( arr[i] % 1000 ) * 10 + up;  
            up = next_up;
        }
        arr.push_back( up );
        set_digit();

    }

    void shift_r(){

        ll down = 0;
        for( int i = digit - 1 ; i >= 0 ; i-- ){
            ll next_down = arr[i] % 10;
            arr[i] = 1000 * down + arr[i] / 10;
            down = next_down;
        }
        set_digit();

    }

    bool zero(){

        return digit == 1 && arr[0] == 0;

    }

    void set_digit(){

        while( arr.size() > 1 && arr[arr.size()-1] == 0 )
            arr.pop_back();
        digit = arr.size();

    }

    void print(){

        if( zero() ){
            cout << 0 << endl;
            return;
        }
        if( minus )
            cout << "-";
        cout << arr[digit - 1];
        for( int i = digit - 2 ; i >= 0 ; i-- )
            cout << setfill( '0' ) << std::setw( 4 ) << arr[i];
        cout << endl;

    }

};

BigInteger add( BigInteger bi1, BigInteger bi2 );
BigInteger sub( BigInteger bi1, BigInteger bi2 );
BigInteger mul( BigInteger bi1, BigInteger bi2 );
BigInteger div( BigInteger bi1, BigInteger bi2 );
bool operator<( const BigInteger bi1, const BigInteger bi2 );
bool operator>( const BigInteger bi1, const BigInteger bi2 );
bool operator<=( const BigInteger bi1, const BigInteger bi2 );
bool operator>=( const BigInteger bi1, const BigInteger bi2 );
bool operator==( const BigInteger bi1, const BigInteger bi2 );
bool operator!=( const BigInteger bi1, const BigInteger bi2 );

BigInteger add( BigInteger bi1, BigInteger bi2 ){

    if( !bi1.minus && bi2.minus ){
        bi2.minus = false;
        return sub( bi1, bi2 );
    }
    else if( bi1.minus && !bi2.minus ){
        bi1.minus = false;
        return sub( bi2, bi1 );
    }
    else if( bi1.minus && bi2.minus ){
        bi1.minus = false;
        bi2.minus = false;
        BigInteger res = add( bi1, bi2 );
        res.minus = true;
        return res;
    }

    BigInteger res;
    ll up = 0;
    for( int i = 0 ; i < max( bi1.digit, bi2.digit ) ; i++ ){
        ll val1 = 0, val2 = 0;
        if( i < bi1.digit )
            val1 = bi1.arr[i];
        if( i < bi2.digit )
            val2 = bi2.arr[i];
        res.arr.push_back( ( val1 + val2 + up ) % 10000 );   
        up = ( val1 + val2 + up ) / 10000;
    }
    res.arr.push_back( up );
    res.set_digit();
    return res;

}

BigInteger sub( BigInteger bi1, BigInteger bi2 ){

    if( !bi1.minus && bi2.minus ){
        bi2.minus = false;
        return add( bi1, bi2 );
    }
    else if( bi1.minus && !bi2.minus ){
        bi1.minus = false;
        BigInteger res = add( bi1, bi2 );
        res.minus = true;
        return res;
    }
    else if( bi1.minus && bi2.minus ){
        bi1.minus = false;
        bi2.minus = false;
        BigInteger res = sub( bi2, bi1 );
        return res;
    }

    if( bi1.digit < bi2.digit ){
        BigInteger res = sub( bi2, bi1 );
        res.minus = true;
        return res;
    }
    else if( bi1.digit == bi2.digit ){
        for( int i = bi1.digit-1 ; i >= 0 ; i++ ){
            if( bi1.arr[i] > bi2.arr[i] )
                break;
            else if( bi1.arr[i] < bi2.arr[i] ){
                BigInteger res = sub( bi2, bi1 );
                res.minus = true;
                return res;
            }
        }
    }
    
    BigInteger res;
    ll down = 0;
    for( int i = 0 ; i < bi1.digit ; i++ ){
        ll val1 = 0, val2 = 0;
        if( i < bi1.digit )
            val1 = bi1.arr[i] - down;
        if( i < bi2.digit )
            val2 = bi2.arr[i];
        if( val1 < val2 ){
            down = 1;
            val1 += 10000;
        }
        else    
            down = 0;
        res.arr.push_back( val1 - val2 );
    }
    res.set_digit();
    return res;

}

BigInteger mul( BigInteger bi1, BigInteger bi2 ){

    BigInteger res;
    res.minus = ( bi1.minus != bi2.minus );
    for( int i = 0 ; i < bi1.digit + bi2.digit ; i++ )
        res.arr.push_back( 0 );
    for( int i = 0 ; i < bi1.digit ; i++ ){
        for( int j = 0 ; j < bi2.digit ; j++ )
            res.arr[i+j] += bi1.arr[i] * bi2.arr[j];
    }
    ll up = 0;
    for( int i = 0 ; i < bi1.digit + bi2.digit ; i++ ){
        ll next_up = ( res.arr[i] + up ) / 10000;
        res.arr[i] = ( res.arr[i] + up ) % 10000;
        up = next_up;
    }
    res.set_digit();
    return res;

}

BigInteger div( BigInteger bi1, BigInteger bi2 ){

    string num = "";
    bool m = ( bi1.minus != bi2.minus );
    bi1.minus = bi2.minus = false;
    BigInteger org = bi2;
    if( bi1 < bi2 ){
        BigInteger zero( "0", false );
        return zero;
    }
    while( bi1.digit > bi2.digit ){
        bi2.arr.insert( bi2.arr.begin(), 0 );
        bi2.digit++;
    }
    while( to_string( bi1.arr[bi1.digit-1] ).length() > to_string( bi2.arr[bi2.digit-1] ).length() )
        bi2.shift_l();
    while( to_string( bi1.arr[bi1.digit-1] ).length() < to_string( bi2.arr[bi2.digit-1] ).length() )
        bi2.shift_r();
    while( bi2 >= org ){ 
        int i;
        for( i = 0 ; i <= 9 ; i++ ){
            BigInteger tmp = sub( bi1, bi2 );
            tmp.print();
            if( !tmp.zero() && tmp.minus )
                break;
            bi1 = tmp;
        } 
        num += to_string( i );
        bi2.shift_r();
    }
    BigInteger res( num, m );
    return res;

}

bool operator<( const BigInteger bi1, const BigInteger bi2 ){

    BigInteger tmp = sub( bi1, bi2 );
    return tmp.minus && !tmp.zero();

}

bool operator>( const BigInteger bi1, const BigInteger bi2 ){
 
    BigInteger tmp = sub( bi1, bi2 );
    return !tmp.minus && !tmp.zero();

}

bool operator<=( const BigInteger bi1, const BigInteger bi2 ){
    
    BigInteger tmp = sub( bi1, bi2 );
    return tmp.minus || tmp.zero();

}

bool operator>=( const BigInteger bi1, const BigInteger bi2 ){
    
    BigInteger tmp = sub( bi1, bi2 );
    return !tmp.minus || tmp.zero();

}

bool operator==( const BigInteger bi1, const BigInteger bi2 ){
    
    BigInteger tmp = sub( bi1, bi2 );
    return tmp.zero();

}

bool operator!=( const BigInteger bi1, const BigInteger bi2 ){
    
    BigInteger tmp = sub( bi1, bi2 );
    return !tmp.zero();

}

int main(){

    string val1, val2;
    bool minus;
    
    cin >> val1;
    if( val1[0] == '-' ){
        minus = true;
        val1 = val1.substr( 1 );
    }
    else
        minus = false;
    BigInteger bi1( val1, minus );

    cin >> val2;
    if( val2[0] == '-' ){
        minus = true;
        val2 = val2.substr( 1 );
    }
    else
        minus = false;
    BigInteger bi2( val2, minus );
    
    BigInteger res = add( bi1, bi2 );
    res.print();

}
accuracy: 1
time_ms: 50
memory_kb: 5420
final_rank: 3

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 ld PI = acos( -1.0 );

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

template <typename T>
void print_arr( vector<T> v ){
    if( v.size() == 0 ) return;
    for( int i = 0 ; i < v.size() ; i++ )
        cout << v[i];
    cout << endl;
}

struct BigInteger{

    bool minus;
    int digit;
    vector<ll> arr;

    BigInteger( string val = "", bool m = false ){

        minus = m;
        while( val.length() > 4 ){
            arr.push_back( stoll( val.substr( val.length() - 4 ) ) );
            val = val.substr( 0, val.length() - 4 );
        }
        if( val.length() != 0 )
            arr.push_back( stoll( val ) );
        set_digit();

    }

    bool zero(){

        return arr.size() == 1 && arr[0] == 0;

    }

    void set_digit(){

        while( arr.size() > 1 && arr[arr.size()-1] == 0 ){
            arr.pop_back();
        }
        digit = arr.size();

    }

    void print(){

        if( zero() ){
            cout << 0 << endl;
            return;
        }
        if( minus )
            cout << "-";
        cout << arr[digit - 1];
        for( int i = digit - 2 ; i >= 0 ; i-- )
            cout << setfill( '0' ) << std::setw( 4 ) << arr[i];
        cout << endl;

    }

};

BigInteger add( BigInteger bi1, BigInteger bi2 );
BigInteger sub( BigInteger bi1, BigInteger bi2 );

BigInteger add( BigInteger bi1, BigInteger bi2 ){

    if( !bi1.minus && bi2.minus ){
        bi2.minus = false;
        return sub( bi1, bi2 );
    }
    else if( bi1.minus && !bi2.minus ){
        bi1.minus = false;
        return sub( bi2, bi1 );
    }
    else if( bi1.minus && bi2.minus ){
        bi1.minus = false;
        bi2.minus = false;
        BigInteger res = add( bi1, bi2 );
        res.minus = true;
        return res;
    }

    BigInteger res;
    ll up = 0;
    for( int i = 0 ; i < max( bi1.digit, bi2.digit ) ; i++ ){
        ll val1 = 0, val2 = 0;
        if( i < bi1.digit )
            val1 = bi1.arr[i];
        if( i < bi2.digit )
            val2 = bi2.arr[i];
        res.arr.push_back( ( val1 + val2 + up ) % 10000 );   
        up = ( val1 + val2 + up ) / 10000;
    }
    res.arr.push_back( up );
    res.set_digit();
    return res;

}

BigInteger sub( BigInteger bi1, BigInteger bi2 ){

    if( !bi1.minus && bi2.minus ){
        bi2.minus = false;
        return add( bi1, bi2 );
    }
    else if( bi1.minus && !bi2.minus ){
        bi1.minus = false;
        BigInteger res = add( bi1, bi2 );
        res.minus = true;
        return res;
    }
    else if( bi1.minus && bi2.minus ){
        bi1.minus = false;
        bi2.minus = false;
        BigInteger res = sub( bi2, bi1 );
        return res;
    }

    if( bi1.digit < bi2.digit ){
        BigInteger res = sub( bi2, bi1 );
        res.minus = true;
        return res;
    }
    else if( bi1.digit == bi2.digit ){
        if( bi1.arr[bi1.digit-1] < bi2.arr[bi2.digit-1] ){
            BigInteger res = sub( bi2, bi1 );
            res.minus = true;
            return res;
        }
    }
    
    BigInteger res;
    ll down = 0;
    for( int i = 0 ; i < bi1.digit ; i++ ){
        ll val1 = 0, val2 = 0;
        if( i < bi1.digit )
            val1 = bi1.arr[i] - down;
        if( i < bi2.digit )
            val2 = bi2.arr[i];
        if( val1 < val2 ){
            down = 1;
            val1 += 10000;
        }
        else    
            down = 0;
        res.arr.push_back( val1 - val2 );
    }
    res.set_digit();
    return res;

}

int main(){

    string val1, val2;
    bool minus;
    
    cin >> val1;
    if( val1[0] == '-' ){
        minus = true;
        val1 = val1.substr( 1 );
    }
    else
        minus = false;
    BigInteger bi1( val1, minus );

    cin >> val2;
    if( val2[0] == '-' ){
        minus = true;
        val2 = val2.substr( 1 );
    }
    else
        minus = false;
    BigInteger bi2( val2, minus );
    
    BigInteger res = add( bi1, bi2 );
    res.print();

}
accuracy: 1
time_ms: 50
memory_kb: 5448
final_rank: 4

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;

    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(_digit.size() == 1 && _digit[0] == 0) _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;
        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: 110
memory_kb: 5252
final_rank: 6

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

int main() {
    boost::multiprecision::cpp_int a, b;
    cin >> a >> b;
    cout << a+b << '\n';
}
accuracy: 1
time_ms: 700
memory_kb: 3432
final_rank: 14

code_snippet: #include <iostream>

#include "boost/multiprecision/cpp_int.hpp"

int main() {
    boost::multiprecision::cpp_int a, b;
    std::cin >> a >> b;
    std::cout << a + b << std::endl;
    return 0;
}
accuracy: 1
time_ms: 700
memory_kb: 3424
final_rank: 12

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


int main() {
    std::string rawA, rawB;
    std::cin >> rawA >> rawB;

    int fa = 1, fb = 1;
    std::string A = rawA, B = rawB;
    if (A[0] == '-') {
        fa = -1;
        A.erase(0, 1);
    }
    if (B[0] == '-') {
        fb = -1;
        B.erase(0, 1);
    }
    // std::cout << A << " , " << B << std::endl;

    bool is_swap = A.size() < B.size();
    if (A.size() == B.size()) {
        for (int i = 0; i < A.size(); i++) {
            if (A[i] == B[i]) {
                continue;
            }
            is_swap = A[i] < B[i];
            break;
        }
    }

    if (is_swap) {
        std::swap(A, B);
        std::swap(fa, fb);
        std::swap(rawA, rawB);
    }

    int diff = (A.size() - B.size());
    for (int i = 0; i < diff; i++) {
        B = '0' + B;
    }

    int f = fa * fb;
    int next = 0;
    std::string s = "";
    // std::cout << A << std::endl;
    // std::cout << B << std::endl;
    for (int i = 1; i <= A.size(); i++) {
        int val = A[A.size() - i] - '0' + f * (B[B.size() - i] - '0') + next;
        if (val > 9) {
            next = 1;
            val -= 10;
        } else if (val < 0) {
            next = -1;
            val += 10;
        } else {
            next = 0;
        }
        s = std::to_string(val) + s;
    }
    if (next != 0) {
        s = "1" + s;
    }

    while (s.size() > 1 && s[0] == '0') {
        s.erase(0, 1);
    }

    if (s != "0" && fa < 0) {
        s = "-" + s;
    }

    std::cout << s << std::endl;
}
accuracy: 1
time_ms: 260
memory_kb: 4196
final_rank: 8

code_snippet: #include <algorithm>
#include <cstdio>
#include <cstring>
#include <ctime>
#include <iomanip>
#include <iostream>

using namespace std;

typedef unsigned long long u64;
typedef __uint128_t u128;

struct bignum {
  u64 a[30005];
  int n;

  int ctz() const {
    for (int i = 0;; i++) {
      if (a[i]) {
        return i << 6 | __builtin_ctzll(a[i]);
      }
    }
  }

  int lg() const {
    return n << 6 | __lg(a[n]);
  }

  bool operator<(const bignum &b) const {
    if (n != b.n) {
      return n < b.n;
    }
    for (int i = n; i != -1; i--) {
      if (a[i] < b.a[i]) {
        return 1;
      }
      if (a[i] > b.a[i]) {
        return 0;
      }
    }
    return 0;
  }

  bool operator>(const bignum &b) const {
    return b < *this;
  }

  bool operator<=(const bignum &b) const {
    return !(b < *this);
  }

  bool operator>=(const bignum &b) const {
    return !(*this < b);
  }

  bool operator==(const bignum &b) const {
    if (n != b.n) {
      return 0;
    }
    for (int i = 0; i <= n; i++) {
      if (a[i] != b.a[i]) {
        return 0;
      }
    }
    return 1;
  }

  bool operator!=(const bignum &b) const {
    return !(*this == b);
  }

  bignum operator+(u64 x) const {
    bignum c = *this;
    int l = c.n;

    c.a[0] += x;

    bool o = c.a[0] < a[0];
    if (o) {
      for (int i = 1; i <= l; i++) {
        if (a[i] == (u64)-1) {
          c.a[i] = 0;
        } else {
          c.a[i]++;
          o = 0;
          break;
        }
      }

      if (o) {
        c.a[++l] = 1;
      }
    }
    c.n = l;
    return c;
  }

  bignum operator-(u64 x) const {
    bignum c = *this;
    int l = c.n;

    c.a[0] -= x;

    bool o = c.a[0] > a[0];
    if (o) {
      for (int i = 1; i <= l; i++) {
        if (!a[i]) {
          c.a[i] = -1;
        } else {
          c.a[i]--;
          break;
        }
      }
      while (l && !c.a[l]) {
        l--;
        c.n--;
      }
    }
    return c;
  }

  bignum operator*(u64 x) const {
    bignum c;
    memset(&c, 0, sizeof c);

    int l = n;
    u128 ad = 0;

    for (int i = 0; i <= l; i++) {
      ad += (u128)a[i] * x;
      c.a[i] = ad, ad >>= 64;
    }

    if (ad) {
      c.a[++l] = ad;
    }
    c.n = l;

    return c;
  }

  bignum operator/(int m) const {
    if (m == 1) {
      return *this;
    }

    bignum c;
    memset(&c, 0, sizeof c);

    u64 b = ((u128)1 << 64) / m, rr = ((u128)1 << 64) % m;

    int l = n;
    int r = 0;

    for (int i = l; i != -1; i--) {
      u128 v = (u128)r * rr + a[i];
      u64 q = (v * b) >> 64;
      int gu = v - (u128)q * m;
      if (gu >= m) {
        gu -= m, q++;
      }

      c.a[i] = r * b + q, r = gu;
    }

    while (l && !c.a[l]) {
      l--;
    }
    c.n = l;

    return c;
  }

  int operator%(int m) const {
    if (m == 1) {
      return 0;
    }

    u64 b = ((u128)1 << 64) / m, rr = ((u128)1 << 64) % m;
    int r = 0;

    for (int i = n; i != -1; i--) {
      u128 v = (u128)r * rr + a[i];
      u64 q = (v * b) >> 64;
      r = v - q * m;
      if (r >= m) {
        r -= m;
      }
    }

    return r;
  }

  bignum operator+(const bignum &b) const {
    bignum c;
    memset(&c, 0, sizeof c);

    bool o = 0;
    int l = max(n, b.n);
    for (int i = 0; i <= l; i++) {
      c.a[i] = a[i] + b.a[i] + o;
      o = (c.a[i] < a[i]) || (b.a[i] == (u64)-1 && o);
    }
    if (o) {
      c.a[++l] = 1;
    }
    c.n = l;

    return c;
  }

  bignum operator-(const bignum &b) const {
    bignum c;
    memset(&c, 0, sizeof c);

    bool o = 0;
    int l = n;
    for (int i = 0; i <= l; i++) {
      c.a[i] = a[i] - b.a[i] - o;
      o = (c.a[i] > a[i]) || (b.a[i] == (u64)-1 && o);
    }
    while (l && !c.a[l]) {
      l--;
    }
    c.n = l;

    return c;
  }

  bignum operator*(const bignum &b) const {
    bignum c;
    memset(&c, 0, sizeof c);

    u128 r = 0;
    int l = n + b.n;
    for (int i = 0; i <= n + b.n; i++) {
      u128 h = 0;

      for (int j = max(0, i - b.n); j <= min(i, n); j++) {
        u128 tp = (u128)a[j] * b.a[i - j];
        r += tp & ((u64)-1), h += tp >> 64;
      }

      c.a[i] = r;
      r = h + (r >> 64);
    }
    if (r) {
      c.a[++l] = r;
    }
    c.n = l;

    return c;
  }

  bignum operator/(const bignum &b) const {
    bignum c;
    memset(&c, 0, sizeof c);

    int n = lg(), m = b.lg();
    if (n < m) {
      return c;
    }

    bignum tp = *this, qwq = b << (n - m);
    int l = 0;
    for (int i = n - m; i != -1; i--, qwq >>= 1) {
      if (tp >= qwq) {
        tp -= qwq;
        c.a[i >> 6] |= 1ull << (i & 63);
        if (!l) {
          l = i;
        }
      }
    }

    c.n = l >> 6;
    return c;
  }

  bignum operator%(const bignum &b) const {
    bignum c = *this;

    int n = lg(), m = b.lg();
    if (n < m) {
      return c;
    }

    bignum tp = b << (n - m);
    for (int i = n; i >= m; i--, tp >>= 1) {
      if (c >= tp) {
        c -= tp;
      }
    }

    return c;
  }

  bignum operator+=(u64 x) {
    u64 tp = a[0];
    a[0] += x;
    bool o = a[0] < tp;

    if (o) {
      for (int i = 1; i <= n; i++) {
        if (a[i] == (u64)-1) {
          a[i] = 0;
        } else {
          a[i]++;
          o = 0;
          break;
        }
      }

      if (o) {
        a[++n] = 1;
      }
    }
    return *this;
  }

  bignum operator-=(u64 x) {
    u64 tp = a[0];
    a[0] -= x;
    bool o = a[0] > tp;

    if (o) {
      for (int i = 1; i <= n; i++) {
        if (!a[i]) {
          a[i] = -1;
        } else {
          a[i]--;
          break;
        }
      }
      while (n && !a[n]) {
        n--;
      }
    }
    return *this;
  }

  bignum operator*=(u64 x) {
    u128 ad = 0;

    for (int i = 0; i <= n; i++) {
      ad += (u128)a[i] * x;
      a[i] = ad, ad >>= 64;
    }

    if (ad) {
      a[++n] = ad;
    }

    return *this;
  }

  bignum operator/=(int m) {
    if (m == 1) {
      return *this;
    }

    u64 b = ((u128)1 << 64) / m, rr = ((u128)1 << 64) % m;

    int r = 0;

    for (int i = n; i != -1; i--) {
      u128 v = (u128)r * rr + a[i];
      u64 q = (v * b) >> 64;
      int gu = v - (u128)q * m;
      if (gu >= m) {
        gu -= m, q++;
      }

      a[i] = r * b + q, r = gu;
    }

    while (n && !a[n]) {
      n--;
    }

    return *this;
  }

  bignum operator+=(const bignum &b) {
    bool o = 0;
    int l = max(n, b.n);
    for (int i = 0; i <= l; i++) {
      u64 tp = a[i];
      a[i] += b.a[i] + o;
      o = (a[i] < tp) || (b.a[i] == (u64)-1 && o);
    }
    if (o) {
      a[++l] = 1;
    }
    n = l;

    return *this;
  }

  bignum operator-=(const bignum &b) {
    bool o = 0;
    int l = n;
    for (int i = 0; i <= l; i++) {
      u64 tp = a[i];
      a[i] -= b.a[i] + o;
      o = (a[i] > tp) || (b.a[i] == (u64)-1 && o);
    }
    while (l && !a[l]) {
      l--;
    }
    n = l;

    return *this;
  }

  bignum operator*=(const bignum &b) {
    return *this = *this * b;
  }

  bignum operator/=(const bignum &b) {
    return *this = *this / b;
  }

  bignum operator%=(const bignum &b) {
    return *this = *this % b;
  }

  bignum operator<<(int k) const {
    bignum c;
    memset(&c, 0, sizeof c);

    int t = k >> 6;
    memcpy(c.a + t, a, (n + 1) << 3);
    int l = n + t;

    t = k & 63;
    if (t) {
      for (int i = l + 1; i; i--) {
        c.a[i] = (c.a[i] << t) | (c.a[i - 1] >> (64 - t));
      }
      c.a[0] <<= t;

      if (c.a[l + 1]) {
        l++;
      }
    }
    c.n = l;

    return c;
  }

  bignum operator>>(int k) const {
    bignum c;
    memset(&c, 0, sizeof c);

    int t = k >> 6;
    if (t > n) {
      return c;
    }

    memcpy(c.a, a + t, (n - t + 1) << 3);

    int l = n - t;
    t = k & 63;

    if (t) {
      for (int i = 0; i <= l; i++) {
        c.a[i] = (c.a[i] >> t) | (c.a[i + 1] << (64 - t));
      }
    }

    while (l && !c.a[l]) {
      l--;
    }
    c.n = l;

    return c;
  }

  bignum operator&(const bignum &b) const {
    bignum c = *this;

    for (int i = 0; i <= b.n; i++) {
      c.a[i] &= b.a[i];
    }
    for (int i = b.n + 1; i <= c.n; i++) {
      c.a[i] = 0;
    }

    int l = c.n;
    while (l && !c.a[l]) {
      l--;
    }
    c.n = l;

    return c;
  }

  bignum operator|(const bignum &b) const {
    bignum c = *this;

    for (int i = 0; i <= b.n; i++) {
      c.a[i] |= b.a[i];
    }
    c.n = max(c.n, b.n);

    return c;
  }

  bignum operator^(const bignum &b) const {
    bignum c = *this;

    for (int i = 0; i <= b.n; i++) {
      c.a[i] ^= b.a[i];
    }

    int l = max(c.n, b.n);
    while (l && !c.a[l]) {
      l--;
    }
    c.n = l;

    return c;
  }

  bignum operator<<=(int k) {
    int t = k >> 6;

    if (t) {
      for (int i = n; i != -1; i--) {
        a[i + t] = a[i];
      }
      memset(a, 0, t << 3);
    }
    n += t;

    t = k & 63;

    if (t) {
      for (int i = n + 1; i; i--) {
        a[i] = (a[i] << t) | (a[i - 1] >> (64 - t));
      }
      a[0] <<= t;
    }

    if (a[n + 1]) {
      n++;
    }

    return *this;
  }

  bignum operator>>=(int k) {
    int t = k >> 6;

    if (t > n) {
      memset(a, 0, (n + 1) << 3);
      n = 0;
      return *this;
    }

    for (int i = t; i <= n; i++) {
      a[i - t] = a[i];
    }
    memset(a + n - t + 1, 0, t << 3);
    n -= t;

    t = k & 63;

    if (t) {
      for (int i = 0; i <= n; i++) {
        a[i] = (a[i] >> t) | (a[i + 1] << (64 - t));
      }
    }
    while (n && !a[n]) {
      n--;
    }

    return *this;
  }

  bignum operator&=(const bignum &b) {
    for (int i = 0; i <= b.n; i++) {
      a[i] &= b.a[i];
    }
    for (int i = b.n + 1; i <= n; i++) {
      a[i] = 0;
    }

    while (n && !a[n]) {
      n--;
    }

    return *this;
  }

  bignum operator|=(const bignum &b) {
    for (int i = 0; i <= b.n; i++) {
      a[i] |= b.a[i];
    }
    n = max(n, b.n);

    return *this;
  }

  bignum operator^=(const bignum &b) {
    n = max(n, b.n);
    for (int i = 0; i <= b.n; i++) {
      a[i] ^= b.a[i];
    }

    while (n && !a[n]) {
      n--;
    }

    return *this;
  }
};

bool oa, ob;

bignum read_bignum(bool &o) {
  static char str[100005];
  static u64 a[10005];
  static u64 bs = 1000000000000000000ll;

  cin >> str;
  int n = strlen(str);
  if (str[0] == '-') {
    o = 1;
    n--;
    for (int i = 0; i != n; i++) {
      str[i] = str[i + 1];
    }
  }
  reverse(str, str + n);

  for (int i = 0; i <= (n - 1) / 18; i++) {
    u64 v = 0;
    for (int j = min(n, (i + 1) * 18) - 1; j >= i * 18; j--) {
      v = v * 10 + str[j] - '0';
    }
    a[i] = v;
  }
  n = (n - 1) / 18;

  bignum c;
  memset(&c, 0, sizeof c);
  int m = 0;

  for (int i = n; i != -1; i--) {
    u128 ad = 0;
    for (int j = 0; j <= m; j++) {
      ad += (u128)c.a[j] * bs;
      c.a[j] = ad, ad >>= 64;
    }

    while (ad) {
      c.a[++m] = ad, ad >>= 64;
    }
    c.n = m;

    c += a[i], m = c.n;
  }

  return c;
}

void output(bignum a) {
  static u64 v[30005];
  const u64 bs = 1000000000000000000ll;

  int n = a.n, m = 0;

  for (int i = n; i != -1; i--) {
    u128 ad = 0;
    for (int j = 0; j <= m; j++) {
      ad += (u128)v[j] << 64;
      u128 gu = ad / bs;
      v[j] = ad - gu * bs, ad = gu;
    }

    while (ad) {
      u128 gu = ad / bs;
      v[++m] = ad - gu * bs, ad = gu;
    }

    ad = a.a[i];
    for (int j = 0; j <= m && ad; j++) {
      ad += v[j];
      u128 gu = ad / bs;
      v[j] = ad - gu * bs, ad = gu;
    }
    while (ad) {
      u128 gu = ad / bs;
      v[++m] = ad - gu * bs, ad = gu;
    }
  }

  cout << v[m];
  for (int i = m - 1; i != -1; i--) {
    cout << setw(18) << setfill('0') << v[i];
  }
  memset(v, 0, sizeof v);
}

bignum updiv(bignum &a, int m) {
  static bignum c;
  memset(&c, 0, sizeof c);

  if (m == 1) {
    return a;
  }

  u64 b = ((u128)1 << 64) / m, rr = ((u128)1 << 64) % m;

  int l = a.n;
  int r = 0;

  for (int i = l; i != -1; i--) {
    u128 v = (u128)r * rr + a.a[i];
    u64 q = (v * b) >> 64;
    int gu = v - (u128)q * m;
    if (gu >= m) {
      gu -= m, q++;
    }

    c.a[i] = r * b + q, r = gu;
  }

  while (l && !c.a[l]) {
    l--;
  }
  c.n = l;

  if (r) {
    bool o = 1;
    for (int i = 0; i <= l; i++) {
      if (c.a[i] == (u64)-1) {
        c.a[i] = 0;
      } else {
        c.a[i]++;
        o = 0;
        break;
      }
    }

    if (o) {
      c.a[++l] = 1;
    }
  }

  c.n = l;

  return c;
}

bignum gcd(bignum a, bignum b) {
  if (a > b) {
    swap(a, b);
  }

  if (a.n == 0 && !a.a[0]) {
    return b;
  }

  int l = min(a.ctz(), b.ctz());
  a >>= a.ctz(), b >>= b.ctz();

  while (1) {
    if (a.n == 0 && !a.a[0]) {
      return b << l;
    }

    if (!(a.a[0] & 1)) {
      a >>= 1;
    } else if (!(b.a[0] & 1)) {
      b >>= 1;
    } else {
      if (a < b) {
        swap(a, b);
      }
      a -= b;
    }
  }
}

int main() {
  ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);

  bignum a = read_bignum(oa), b = read_bignum(ob);
  if (oa && ob) {
    cout << '-';
    oa = ob = 0;
  }

  if (oa == 0 && ob == 0) {
    output(a + b);
    cout << endl;
    return 0;
  }

  if (oa) {
    swap(a, b);
  }

  if (a >= b) {
    output(a - b);
    cout << endl;
  } else {
    cout << '-';
    output(b - a);
    cout << endl;
  }
}
accuracy: 1
time_ms: 320
memory_kb: 4732
final_rank: 9

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

#include <boost/multiprecision/cpp_int.hpp>

signed main() {
    boost::multiprecision::cpp_int A, B;
    cin >> A >> B;
    cout << A + B << endl;
}
accuracy: 1
time_ms: 700
memory_kb: 3384
final_rank: 10

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 = "";
    int n1 = a.size();
    int n2 = b.size();
    if(n1 > n2) forr(i,1,n1 - n2) b = "0" + b;
    if(n1 < n2)
    {
        forr(i,1,n2 - n1) a = "0" + a;
        n1 = n2;
    }
    int nho = 0;
    forw(i,n1 - 1,0)
    {
        int res = a[i] - '0' + b[i] - '0' + nho;
        if(res > 9) nho = 1;
        else nho = 0;
        c = char(res%10 + 48) + c;
    }
    if(nho == 1) c = "1" + c;
    return c;
}

string h(string a,string b)
{
    string c = "";
    int n1 = a.size();
    int n2 = b.size();
    if(n2 < n1) forr(i,1,n1 - n2) b = "0" + b;
    int nho = 0;
    forw(i,n1 - 1,0)
    {
        int res = a[i] - '0' - (b[i] - '0') - nho;
        if(res < 0) nho = 1;
        else nho = 0;
        if(res < 0) c = char(res + 10 + 48) + c;
        else c = char(res + 48) + c;
    }
    while(c.size() > 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] == '-')
    {
        if(b[0] == '-')
        {
            a.erase(0,1);
            b.erase(0,1);
            cout << "-" << t(a,b) << "\n";
            return 0;
        }
        a.erase(0,1);
        if(b.size() > a.size() || (b.size() == a.size() && b >= a))
        {
            cout << h(b,a) << "\n";
            return 0;
        }
        else
        {
            cout << "-" << h(a,b) << "\n";
            return 0;
        }
    }
    else
    {
        if(b[0] == '-')
        {
            b.erase(0,1);
            if(b.size() < a.size() || (b.size() == a.size() && b <= a))
            {
                cout << h(a,b) << "\n";
                return 0;
            }
            else
            {
                cout << "-" << h(b,a) << "\n";
                return 0;
            }
        }
        else cout << t(a,b) << "\n";
        //cout << "Vandeeptry";
    }
    return 0;
}
accuracy: 1
time_ms: 250
memory_kb: 3988
final_rank: 7

code_snippet: #line 2 "nachia\\math-modulo\\modulo-primitive-root.hpp"
#include <vector>
#include <utility>

namespace nachia{

template<unsigned int MOD>
struct PrimitiveRoot{
    using u64 = unsigned long long;
    static constexpr u64 powm(u64 a, u64 i) {
        u64 res = 1, aa = a;
        while(i){
            if(i & 1) res = res * aa % MOD;
            aa = aa * aa % MOD;
            i /= 2;
        }
        return res;
    }
    static constexpr bool ExamineVal(unsigned int g){
        unsigned int t = MOD - 1;
        for(u64 d=2; d*d<=t; d++) if(t % d == 0){
            if(powm(g, (MOD - 1) / d) == 1) return false;
            while(t % d == 0) t /= d;
        }
        if(t != 1) if(powm(g, (MOD - 1) / t) == 1) return false;
        return true;
    }
    static constexpr unsigned int GetVal(){
        for(unsigned int x=2; x<MOD; x++) if(ExamineVal(x)) return x;
        return 0;
    }
    static const unsigned int val = GetVal();
};

} // namespace nachia
#line 1 "nachia\\fps\\ntt-interface.hpp"
#include <algorithm>

namespace nachia {

template<class mint>
struct NttInterface{

template<class Iter>
void Butterfly(Iter, int) const {}

template<class Iter>
void IButterfly(Iter, int) const {}

template<class Iter>
void BitReversal(Iter a, int N) const {
    for(int i=0, j=0; j<N; j++){
        if(i < j) std::swap(a[i], a[j]);
        for(int k = N>>1; k > (i^=k); k>>=1);
    }
}

};

} // namespace nachia
#line 4 "nachia\\misc\\bit-operations.hpp"

namespace nachia{

int Popcount(unsigned long long c) noexcept {
#ifdef __GNUC__
    return __builtin_popcountll(c);
#else
    c = (c & (~0ull/3)) + ((c >> 1) & (~0ull/3));
    c = (c & (~0ull/5)) + ((c >> 2) & (~0ull/5));
    c = (c & (~0ull/17)) + ((c >> 4) & (~0ull/17));
    c = (c * (~0ull/257)) >> 56;
    return c;
#endif
}

// please ensure x != 0
int MsbIndex(unsigned long long x) noexcept {
#ifdef __GNUC__
    return 63 - __builtin_clzll(x);
#else
    int res = 0;
    for(int d=32; d>0; d>>=1) if(x >> d){ res |= d; x >>= d; }
    return res;
#endif
}

// please ensure x != 0
int LsbIndex(unsigned long long x) noexcept {
#ifdef __GNUC__
    return __builtin_ctzll(x);
#else
    return MsbIndex(x & -x);
#endif
}

}

#line 5 "nachia\\bigint\\ntt.hpp"
#include <iterator>
#include <cassert>
#line 8 "nachia\\bigint\\ntt.hpp"
#include <array>

namespace nachia{
namespace bigint{

constexpr int bsf_constexpr(unsigned int n) {
	int x = 0;
	while (!(n & (1 << x))) x++;
	return x;
}

template <class mint>
struct NttFromAcl : NttInterface<mint> {

using u32 = unsigned int;
using u64 = unsigned long long;
    
static int ceil_pow2(int n) {
	int x = 0;
	while ((1U << x) < (u32)(n)) x++;
	return x;
}

struct fft_info {
	static constexpr u32 g = nachia::PrimitiveRoot<mint::GetMod()>::val;
	static constexpr int rank2 = bsf_constexpr(mint::GetMod()-1);
	std::array<mint, rank2+1> root;
	std::array<mint, rank2+1> iroot;

	std::array<mint, std::max(0, rank2-1)> rate2;
	std::array<mint, std::max(0, rank2-1)> irate2;

	std::array<mint, std::max(0, rank2-2)> rate3;
	std::array<mint, std::max(0, rank2-2)> irate3;

	fft_info(){
		root[rank2] = mint(g).pow((mint::GetMod() - 1) >> rank2);
		iroot[rank2] = root[rank2].inv();
		for(int i=rank2-1; i>=0; i--){
			root[i] = root[i+1] * root[i+1];
			iroot[i] = iroot[i+1] * iroot[i+1];
		}
		mint prod = 1u, iprod = 1u;
		for(int i=0; i<=rank2-2; i++){
			rate2[i] = root[i+2] * prod;
			irate2[i] = iroot[i+2] * iprod;
			prod *= iroot[i+2];
			iprod *= root[i+2];
		}
		prod = 1u; iprod = 1u;
		for(int i=0; i<=rank2-3; i++){
			rate3[i] = root[i+3] * prod;
			irate3[i] = iroot[i+3] * iprod;
			prod *= iroot[i+3];
			iprod *= root[i+3];
		}
	}
};

template<class RandomAccessIterator>
void Butterfly(RandomAccessIterator a, int n) const {
	int h = ceil_pow2(n);

	static const fft_info info;

	int len = 0;
	while(len < h){
		if(h-len == 1){
			int p = 1 << (h-len-1);
			mint rot = 1u;
			for(int s=0; s<(1<<len); s++){
				int offset = s << (h-len);
				for(int i=0; i<p; i++){
					auto l = a[i+offset];
					auto r = a[i+offset+p] * rot;
					a[i+offset] = l+r;
					a[i+offset+p] = l-r;
				}
				if(s+1 != (1<<len)) rot *= info.rate2[LsbIndex(~(u32)(s))];
			}
			len++;
		} else {
			int p = 1 << (h-len-2);
			mint rot = 1u, imag = info.root[2];
			for(int s=0; s<(1<<len); s++){
				mint rot2 = rot * rot;
				mint rot3 = rot2 * rot;
				int offset = s << (h-len);
				for(int i=0; i<p; i++){
					auto a0 = a[i+offset];
					auto a1 = a[i+offset+p] * rot;
					auto a2 = a[i+offset+2*p] * rot2;
					auto a3 = a[i+offset+3*p] * rot3;
					auto a0a2 = a0 + a2;
					auto a0b2 = a0 - a2;
					auto a1a3 = a1 + a3;
					auto a1na3imag = (a1 - a3) * imag;
					a[i+offset] = a0a2 + a1a3;
					a[i+offset+1*p] = a0a2 - a1a3;
					a[i+offset+2*p] = a0b2 + a1na3imag;
					a[i+offset+3*p] = a0b2 - a1na3imag;
				}
				if(s+1 != (1<<len)) rot *= info.rate3[LsbIndex(~(u32)(s))];
			}
			len += 2;
		}
	}
}

template<class RandomAccessIterator>
void IButterfly(RandomAccessIterator a, int n) const {
	int h = ceil_pow2(n);

	static const fft_info info;

	int len = h;
	while(len){
		if(len == 1){
			int p = 1 << (h-len);
			mint irot = 1u;
			for(int s=0; s<(1<<(len-1)); s++){
				int offset = s << (h-len+1);
				for(int i=0; i<p; i++){
					auto l = a[i+offset];
					auto r = a[i+offset+p];
					a[i+offset] = l+r;
					a[i+offset+p] = (l-r)*irot;
				}
				if(s+1 != (1<<(len-1))) irot *= info.irate2[LsbIndex(~(u32)(s))];
			}
			len--;
		} else {
			int p = 1 << (h-len);
			mint irot = 1u, iimag = info.iroot[2];
			for(int s=0; s<(1<<(len-2)); s++){
				mint irot2 = irot * irot;
				mint irot3 = irot2 * irot;
				int offset = s << (h-len+2);
				for(int i=0; i<p; i++){
					auto a0 = a[i+offset+0*p];
					auto a1 = a[i+offset+1*p];
					auto a2 = a[i+offset+2*p];
					auto a3 = a[i+offset+3*p];
					auto a0a1 = a0 + a1;
					auto a0b1 = a0 - a1;
					auto a2a3 = a2 + a3;
					auto a2na3iimag = (a2 - a3) * iimag;

					a[i+offset] = a0a1 + a2a3;
					a[i+offset+1*p] = (a0b1 + a2na3iimag) * irot;
					a[i+offset+2*p] = (a0a1 - a2a3) * irot2;
					a[i+offset+3*p] = (a0b1 - a2na3iimag) * irot3;
				}
				if(s+1 != (1<<(len-2))) irot *= info.irate3[LsbIndex(~(u32)(s))];
			}
			len -= 2;
		}
	}
}

};

} // namespace bigint
} // namespace nachia
#line 3 "nachia\\bigint\\static-p-modint.hpp"

namespace nachia{
namespace bigint{

template<unsigned int MxVal>
class Montgomery32Info{
public:
    using u32 = unsigned int;
    using u64 = unsigned long long;
    static constexpr u32 u32inverse(u32 x){
        u32 v = 1;
        for(int i=0; i<5; i++) v = v * ((u32)2 - v * x);
        return v;
    }
    static constexpr u32 getMy(u32 mx){ return (-mx) % mx; }
    static constexpr u32 powMod(u32 a, u32 i, u32 m){
        if(i == 0) return 1 % m;
        if(i % 2 == 0) return powMod((u64)a*a%m, i/2, m);
        return (u64)a*powMod((u64)a*a%m, i/2, m)%m;
    }
    static constexpr u32 Mx = MxVal;
    static constexpr u32 iMx = u32inverse(Mx);
    static constexpr u32 My1 = getMy(Mx);
    static constexpr u32 My2 = powMod(getMy(Mx), 2, Mx);
    static constexpr u32 My3 = powMod(getMy(Mx), 3, Mx);
    // return z
    //  +  z % Mx == x % Mx
    //  +  x <= max(x>>32, Mx-1)
    static constexpr u32 red(u64 x){
        u32 z1 = x >> 32;
        u32 z2 = ((u64)Mx * ((u32)x*iMx)) >> 32;
        return z1 - z2 + (z1 < z2 ? Mx : 0);
    }
};

template<unsigned int MOD>
class StaticPModint{
public:
    using u32 = unsigned int;
    using u64 = unsigned long long;
private:
    static constexpr u32 mod = MOD;
    using Tool = Montgomery32Info<MOD>;
    using MyType = StaticPModint;
    u32 _v;
    static MyType RAW(u32 v) { auto res = StaticPModint(); res._v = v; return res; }
public:
    StaticPModint() : _v(0) {}
    StaticPModint(u32 v) : _v(Tool::red((u64)v * Tool::My2)) {}
    StaticPModint(u64 v) : _v(Tool::red((u64)Tool::My3 * Tool::red(v))) {}
    u32 val() const { return Tool::red(_v); }
    u32 mrVal() const { return _v; }
    MyType& operator-=(MyType r) { _v = _v - r._v + (_v < r._v ? mod : 0); return *this; }
    MyType& operator+=(MyType r) { u32 t = mod - r._v; _v = _v - t + (_v < t ? mod : 0); return *this; }
    MyType& operator*=(MyType r) { _v = Tool::red((u64)_v * r._v); return *this; }
    MyType operator+(MyType r) const { auto v = *this; v += r; return v; }
    MyType operator-(MyType r) const { auto v = *this; v -= r; return v; }
    MyType operator*(MyType r) const { auto v = *this; v *= r; return v; }
    MyType operator-() const { return RAW(_v ? mod - _v : (u32)0); }
    MyType pow(unsigned long long i) const {
        MyType x = *this, r = RAW(Tool::My1);
        while(i){ if(i&1){ r *= x; } x*=x; i>>=1; }
        return r;
    }
    MyType inv() const { return pow(mod-2); }
    static constexpr u32 GetMod() { return mod; }
};

} // namespace bigint
} // namespace nachia
#line 2 "nachia\\bigint\\dynamic-p-modint.hpp"

namespace nachia{
namespace bigint{

class DynMontgomery32Info{
public:
    using u32 = unsigned int;
    using u64 = unsigned long long;
    static u32 u32inverse(u32 x) {
        u32 v = 1;
        for(int i=0; i<5; i++) v = v * ((u32)2 - v * x);
        return v;
    }
    static u32 getMy(u32 mx) { return (-mx) % mx; }
    static u32 powMod(u32 a, u32 i, u32 m) {
        if(i == 0) return 1 % m;
        if(i % 2 == 0) return powMod((u64)a*a%m, i/2, m);
        return (u64)a*powMod((u64)a*a%m, i/2, m)%m;
    }
    const u32 Mx;
    const u32 iMx;
    const u32 My1;
    const u32 My2;
    const u32 My3;
    DynMontgomery32Info(u32 newMod)
        : Mx(newMod)
        , iMx(u32inverse(Mx))
        , My1(getMy(Mx))
        , My2((u64)My1 * My1 % Mx)
        , My3((u64)My2 * My1 % Mx) {}

    // return z
    //  +  z % Mx == x % Mx
    //  +  x <= max(x>>32, Mx-1)
    u32 red(u64 x) const {
        u32 z1 = x >> 32;
        u32 z2 = ((u64)Mx * ((u32)x*iMx)) >> 32;
        return z1 - z2 + (z1 < z2 ? Mx : 0);
    }
    u32 add(u32 a, u32 b) const { b = Mx-b; return a - b + ((a < b) ? Mx : 0u); }
    u32 sub(u32 a, u32 b) const { return a - b + ((a < b) ? Mx : 0u); }
    u32 mul(u32 a, u32 b) const { return red((u64)a * b); }
    u32 pow(u32 a, u32 i) const {
        u32 x = a, r = My1;
        while(i){ if(i&1){ r=mul(r,x); } x=mul(x,x); i>>=1; }
        return r;
    }
    u32 inv(u32 a) const { return pow(a, Mx-2); }
    u32 input64(u64 a) const { return mul(red(a), My3); }
};

} // namespace bigint
} // namespace nachia
#line 5 "nachia\\bigint\\garner.hpp"

namespace nachia{
namespace bigint{

struct GarnerU96{
    using u32 = unsigned int;
    using u64 = unsigned long long;
    std::vector<u32> mods;
    std::vector<DynMontgomery32Info> dynmods;
    std::vector<std::vector<u32>> table_coeff;
    std::vector<u32> table_coeffinv;

    void precalc(std::vector<u32> new_mods){
        mods = std::move(new_mods);
        for(std::size_t i=0; i<mods.size(); i++) dynmods.emplace_back(mods[i]);
        int nmods = mods.size();
        table_coeff.assign(nmods+1, std::vector<u32>(nmods, 0));
        for(int k=0; k<nmods; k++) table_coeff[0][k] = dynmods[k].My2;
        for(int j=0; j<nmods; j++){
            for(int k=0; k<nmods; k++) table_coeff[j+1][k] = table_coeff[j][k];
            for(int k=j+1; k<nmods; k++) table_coeff[j+1][k] = dynmods[k].mul(table_coeff[j+1][k], dynmods[k].input64(mods[j]));
        }
        table_coeffinv.resize(nmods);
        for(int i=0; i<nmods; i++) table_coeffinv[i] = dynmods[i].inv(table_coeff[i][i]);
    }

    u64 calc(const std::vector<u32>& x){
        int nmods = mods.size();
        std::vector<u32> table_const(nmods);
        u64 res = 0;
        u64 res_coeff = 1;
        for(int j=0; j<nmods; j++){
            u32 t = dynmods[j].mul(dynmods[j].sub(x[j], table_const[j]), table_coeffinv[j]);
            for(int k=j+1; k<nmods; k++){
                table_const[k] = dynmods[k].add(dynmods[k].mul(t, table_coeff[j][k]), table_const[k]);
            }
            res += res_coeff * u64(t);
            res_coeff *= mods[j];
        }
        return res;
    }

    std::pair<std::vector<u32>, std::vector<u64>> calc(std::vector<std::vector<u32>> x){
        int n = x[0].size(), m = x.size();
        std::vector<u64> resl(n);
        std::vector<u32> resh(n);
        std::vector<u32> buf(m);
        u32 inv64 = dynmods[0].inv(dynmods[0].mul(dynmods[0].My3, dynmods[0].My2));
        for(int i=0; i<n; i++){
            for(int j=0; j<m; j++) buf[j] = x[j][i];
            resl[i] = calc(buf);
            resh[i] = dynmods[0].mul(dynmods[0].sub(buf[0], dynmods[0].input64(resl[i])), inv64);
        }
        return std::make_pair(std::move(resh), std::move(resl));
    }
};

} // namespace bigint
} // namespace nachia
#line 5 "nachia\\bigint\\convolution.hpp"

namespace nachia{
namespace bigint{

struct MultiplySupply {
    using u32 = unsigned int;
    using u64 = unsigned long long;
    static constexpr u32 MODCNT = 3;
    static constexpr u32 MOD[3] = { 3892314113, 3489660929, 3221225473 };
    
    GarnerU96 garner;

    MultiplySupply(){
        garner.precalc(std::vector<u32>(MOD, MOD + MODCNT));
    }
    
    template<unsigned int P>
    static std::vector<u32> SubConvolution(
        const std::vector<u32>& a,
        const std::vector<u32>& b
    ) {
        using Elem = StaticPModint<P>;
        static NttFromAcl<Elem> ntt;
        int z = a.size() + b.size() - 1;
        int N = 1; while(N < z) N *= 2;
        std::vector<Elem> A(N), B(N);
        for(std::size_t i=0; i<a.size(); i++) A[i] = a[i];
        for(std::size_t i=0; i<b.size(); i++) B[i] = b[i];
        Elem iN = Elem((u32)N).inv();
        ntt.Butterfly(A.begin(), N);
        ntt.Butterfly(B.begin(), N);
        for(int i=0; i<N; i++) A[i] = A[i] * B[i] * iN;
        ntt.IButterfly(A.begin(), N);
        std::vector<u32> res(z);
        for(int i=0; i<z; i++) res[i] = A[i].mrVal();
        return res;
    }
    
    std::vector<u32> multiplyBin(
        const std::vector<u32>& a,
        const std::vector<u32>& b
    ){
        if(a.empty() || b.empty()) return {};
        std::vector<std::vector<u32>> cx(MODCNT);
        cx[0] = SubConvolution<MOD[0]>(a, b);
        cx[1] = SubConvolution<MOD[1]>(a, b);
        cx[2] = SubConvolution<MOD[2]>(a, b);
        auto q = garner.calc(std::move(cx));
        int n = q.first.size();
        std::vector<u32> res(n + 2);
        for(int i=0; i<n; i++) res[i] = q.second[i];
        u64 c = 0;
        for(int i=0; i<n; i++){ res[i+1] = c += (u64)res[i+1] + (q.second[i] >> 32); c >>= 32; }
        res[n+1] = c; c = 0;
        for(int i=0; i<n; i++){ res[i+2] = c += (u64)res[i+2] + q.first[i]; c >>= 32; }
        while(res.size() && res.back() == 0) res.pop_back();
        return res;
    }
    
    std::vector<u32> multiplyDec(
        std::vector<u32> a,
        std::vector<u32> b
    ){
        static constexpr u32 d = 1000000000;
        if(a.empty() || b.empty()) return {};
        std::vector<std::vector<u32>> cx(MODCNT);
        cx[0] = SubConvolution<MOD[0]>(a, b);
        cx[1] = SubConvolution<MOD[1]>(a, b);
        cx[2] = SubConvolution<MOD[2]>(a, b);
        auto q0 = garner.calc(std::move(cx));
        int n = q0.first.size();
        std::vector<u64> buf(n + 2);
        static constexpr u32 j11 = (1ull << 32) / d;
        static constexpr u32 j10 = (-d) % d;
        static constexpr u32 j22 = 1 + (0ull- 1ull * d * d) / d / d;
        static constexpr u32 j21 = (-1ull * j22 * d * d) / d;
        static constexpr u32 j20 = (0ull-d) % d;
        for(int i=0; i<n; i++) buf[i] = q0.second[i] & ((1ull << 32) - 1);
        for(int i=0; i<n; i++) buf[i] += 1ull * (q0.second[i] >> 32) * j10;
        for(int i=0; i<n; i++) buf[i+1] += 1ull * (q0.second[i] >> 32) * j11;
        for(int i=0; i<n; i++) buf[i] += 1ull * q0.first[i] * j20; // q0.first[i] is small enough
        for(int i=0; i<n; i++) buf[i+1] += 1ull * q0.first[i] * j21;
        for(int i=0; i<n; i++) buf[i+2] += 1ull * q0.first[i] * j22;
        std::vector<u32> res(n + 2);
        u64 c = 0;
        for(int i=0; i<n+2; i++){ c += buf[i]; res[i] = c % d; c /= d; }
        while(res.size() && res.back() == 0) res.pop_back();
        return res;
    }
};

} // namespace bigint
} // namespace nachia
#line 5 "nachia\\bigint\\base-operators.hpp"
#include <iostream>

namespace nachia {
namespace bigint {

class UIntDec {
public:
using u32 = unsigned int;
using u64 = unsigned long long;
std::vector<u32> x;
static constexpr u32 BASE = 1'000'000'000;

void Regularize(){ while(!x.empty() & !x.back()) x.pop_back(); }

UIntDec() = default;
UIntDec(std::vector<u32> _x) : x(std::move(_x)) {}
UIntDec& operator+=(const UIntDec& b){
    x.resize(std::max(x.size(), b.x.size()) + 1);
    u64 c = 0;
    for(std::size_t i=0; i<b.x.size(); i++){
        c += b.x[i]; c += x[i];
        if(c >= BASE){ x[i] = c - BASE; c = 1; }
        else{ x[i] = c; c = 0; }
    }
    for(int i=b.x.size(); c; i++){
        c += x[i];
        if(c >= BASE){
            x[i] = c - BASE;
            c = 1;
        } else {
            x[i] = c;
            c = 0;
            break;
        }
    }
    Regularize();
    return *this;
}
UIntDec operator*(const UIntDec& b) const { return MultiplySupply().multiplyDec(x, b.x); }

UIntDec Pow(u32 c) const {
    if(c == 0) return std::vector<u32>{1};
    if(c == 1) return *this;
    auto aa = Pow(c/2);
    aa = aa * aa;
    return (c&1) ? aa * (*this) : aa;
}
void mulU32(unsigned int cx) {
    u64 c = cx;
    for(std::size_t i=0; i<x.size(); i++){ c += (u64)x[i] << 32; x[i] = c % BASE; c /= BASE; }
    while(c){ x.push_back(c % BASE); c /= BASE; }
}

};

class UIntBin {
public:
using u32 = unsigned int;
using u64 = unsigned long long;
std::vector<u32> x;

void Regularize(){ while(!x.empty() & !x.back()) x.pop_back(); }

UIntBin() = default;
UIntBin(std::vector<u32> _x) : x(std::move(_x)) {}
UIntBin& operator+=(const UIntBin& b){
    x.resize(std::max(x.size(), b.x.size()) + 1);
    u64 c = 0;
    for(std::size_t i=0; i<b.x.size(); i++){
        c += b.x[i]; c += x[i];
        x[i] = c; c >>= 32;
    }
    for(int i=b.x.size(); c; i++){ x[i] = c += x[i]; c >>= 32; }
    Regularize();
    return *this;
}
UIntBin operator*(const UIntBin& b) const { return MultiplySupply().multiplyBin(x, b.x); }

UIntBin Pow(u32 c) const {
    if(c == 0) return std::vector<u32>{1};
    if(c == 1) return *this;
    auto aa = Pow(c/2);
    aa = aa * aa;
    return (c&1) ? aa * (*this) : aa;
}
void mulD(unsigned int d, unsigned int cx) {
    u64 c = cx;
    for(std::size_t i=0; i<x.size(); i++){ x[i] = (c += (u64)x[i] * d); c >>= 32; }
    if(c) x.push_back(c);
}

};

std::vector<unsigned int> DecToBin(std::string decstr){
    std::vector<UIntBin> pdec;
    auto dfs = [&](auto& dfs, int l, int r) -> UIntBin {
        if(r - l <= 308){
            UIntBin p;
            for(int j=l; j<l+(r-l)%9; j++) p.mulD(10, decstr[j] - '0');
            for(int j=l+(r-l)%9; j<r; j+=9) p.mulD(1000000000, std::stoi(decstr.substr(j, 9)));
            return p;
        }
        if(pdec.empty()) pdec.push_back(UIntBin({10}).Pow(308));
        int h = 0; while(((308*2)<<h) < r-l) h++;
        while((int)pdec.size() < h+1) pdec.push_back(pdec.back() * pdec.back());
        auto res = dfs(dfs, l, r-(308<<h)) * pdec[h];
        res += dfs(dfs, r-(308<<h), r);
        return res;
    };
    return std::move(dfs(dfs, 0, decstr.size()).x);
}

std::string BinToDec(std::vector<unsigned int> b){
    while(!b.empty() && !b.back()) b.pop_back();
    std::reverse(b.begin(), b.end());
    if(b.empty()) return "0";
    std::vector<UIntDec> pbin;
    auto dfs = [&](auto& dfs, int l, int r) -> UIntDec {
        if(r - l <= 29){
            UIntDec p;
            for(int j=l; j<r; j++) p.mulU32(b[j]);
            return p;
        }
        if(pbin.empty()) pbin.push_back(UIntDec({2}).Pow(32*29));
        int h = 0; while(((29*2)<<h) < r-l) h++;
        while((int)pbin.size() < h+1) pbin.push_back(pbin.back() * pbin.back());
        auto res = dfs(dfs, l, r-(29<<h)) * pbin[h];
        res += dfs(dfs, r-(29<<h), r);
        return res;
    };
    auto x = std::move(dfs(dfs, 0, b.size()).x);
    while(!x.empty() && !x.back()) x.pop_back();
    std::string res = std::to_string(x.back());
    res.resize(res.size() + 9 * (int)(x.size()-1), '0');
    for(int i=(int)x.size()-2; i>=0; i--){
        int o = res.size() - i*9 - 9;
        for(int j=o+8; j>=o; j--){ res[j] += x[i] % 10; x[i] /= 10; }
    }
    return res;
}

} // namespace bigint
} // namespace nachia
#line 4 "nachia\\bigint\\integer.hpp"

namespace nachia{

class UnsignedIntegerBin{
public:
    using MyType = UnsignedIntegerBin;
    friend class SignedIntegerBin;
private:
    using u32 = uint32_t;
    using u64 = uint64_t;
    std::vector<u32> x;
    static inline bool Cflag;
    static MyType FromVec(std::vector<u32> _x){ MyType res; res.x = std::move(_x); return res; }
public:
    UnsignedIntegerBin(){}
    MyType operator>>(int sh) const {
        int h = sh / 32, l = sh % 32;
        MyType res; res.memreserve(size() - h);
        for(int i=h; i<size(); i++) res[i-h] = x[i] >> l;
        if(l) for(int i=h+1; i<size(); i++) res[i-h-1] |= x[i] << (32-l);
        res.regularize();
        return res;
    }
    MyType operator<<(int sh) const {
        int h = sh / 32, l = sh % 32;
        MyType res; res.memreserve(size() + h + 1);
        for(int i=0; i<size(); i++) res[i+h] = x[i] << l;
        if(l) for(int i=0; i<size(); i++) res[i+h+1] |= x[i] >> (32-l);
        res.regularize();
        return res;
    }
    MyType& operator>>=(int sh) { return (*this) = operator>>(sh); }
    MyType& operator<<=(int sh) { return (*this) = operator<<(sh); }
    MyType& operator%=(const MyType& d) { divInternal(d); return *this; }
    MyType operator%(const MyType& d) const { auto p = *this; return p.divInternal(d); }
    MyType operator/(const MyType& d) const { auto p = *this; return p.divInternal(d); }
    MyType& operator/=(const MyType& d) { return (*this) = divInternal(d); }
    MyType& operator+=(const MyType& v){
        memreserve(std::max(size(), v.size()) + 1);
        u64 c = 0;
        for(int i=0; i<v.size(); i++){ x[i] = (c += (u64)x[i] + v[i]); c >>= 32; }
        for(int i=v.size(); c; i++){ x[i] = c += x[i]; c >>= 32; }
        regularize();
        return *this;
    }
    MyType& operator-=(const MyType& v){
        memreserve(std::max(size(), v.size()));
        u64 c = 0;
        for(int i=0; i<v.size(); i++){
            c += v[i];
            x[i] -= c;
            c = (c + x[i]) >> 32;
        }
        for(int i=v.size(); i<size() && c; i++){
            x[i] -= c;
            c = (c + x[i]) >> 32;
        }
        Cflag = c;
        if(c){ complement(); increment(); }
        regularize();
        return *this;
    }
    MyType operator*(const MyType& v) const {
        MyType res;
        res.x = bigint::MultiplySupply().multiplyBin(x, v.x);
        res.regularize();
        return res;
    }
    MyType& operator*=(const MyType& r) { return (*this) = operator*(r); }
    MyType operator+(const MyType& r) { auto p = *this; p += r; return p; }
    MyType operator-(const MyType& r) { auto p = *this; p -= r; return p; }
    bool operator<(const MyType& r) const {
        return (size() != r.size())
            ? (size() < r.size())
            : std::lexicographical_compare(x.rbegin(), x.rend(), r.x.rbegin(), r.x.rend());
    }
    bool operator>(const MyType& r) const { return r < (*this); }
    bool operator<=(const MyType& r) const { return !(r < (*this)); }
    bool operator>=(const MyType& r) const { return !operator<(r); }
    bool operator==(const MyType& r) const { return x == r.x; }
    bool operator!=(const MyType& r) const { return x != r.x; }
    bool operator!() const { return size(); }
    bool isZero() const { return size() == 0; }
    std::string toStringBin() const {
        std::string res;
        for(int i=size()-1; i>=0; i--) for(int j=31; j>=0; j--) res.push_back('0' + (x[i]>>j) % 2);
        return res;
    }
    std::string toStringDec() const {
        if(isZero()) return "0";
        
        //auto p = *this;
        //std::string s;
        //while(!p.isZero()) s.push_back('0' + p.div10());
        //std::reverse(s.begin(), s.end());
        //return s;
        
        return bigint::BinToDec(x);
    }
    static MyType FromStringDec(const std::string& s) {
        return FromVec(bigint::DecToBin(s));
    }
    int lsb() const { for(int i=0; i<size(); i++){ if(x[i]) return nachia::LsbIndex(x[i]) + i * 32; } return -1; }
    int msb() const { for(int i=size()-1; i>=0; i--){ if(x[i]) return nachia::MsbIndex(x[i]) + i * 32; } return -1; }
private:
    int size() const { return x.size(); }
    u32& operator[](int at) { return x[at]; }
    u32 operator[](int at) const { return x[at]; }
    void memreserve(int sz) { if((int)x.size() < sz) x.resize(sz); }
    void setBit(int at, bool val){ memreserve(at/32+1); x[at/32] |= (u32)(val?1:0) << (at%32); regularize(); }
    MyType divInternal(const MyType& d) {
        if(d.isZero()) throw 1;
        MyType res;
        for(int s=(size()-d.size())*32+31; s>=0; s--){
            MyType x = d << s;
            if(operator>=(x)){
                res.setBit(s, true); operator-=(x);
            }
        }
        res.regularize();
        return res;
    }
    void complement() { for(u32& y:x){ y = ~y; } }
    void increment() { if(isZero()){ x = {1}; return; } int i=0; while(i < size() && !~x[i]){ x[i++]++; } if(i>=size()){ x.push_back(1); } else x[i]++; }
    void decrement() { if(isZero()){ x = {1}; return; } int i=0; while(x[i]){ x[i++]--; } x[i]--; regularize(); }
    void regularize() { while(!x.empty() && 0 == x.back()) x.pop_back(); }
    int div10() {
        u64 c = 0;
        for(int i=size()-1; i>=0; i--){
            c = (c << 32) | x[i];
            x[i] = c / 10;
            c %= 10;
        }
        regularize();
        return c;
    }
    void mul10(int d) {
        u64 c = d;
        for(int i=0; i<size(); i++){ x[i] = (c += (u64)x[i] * 10); c >>= 32; }
        if(c) x.push_back(c);
    }
};

class SignedIntegerBin{
    using MyType = SignedIntegerBin;
    using UInt = UnsignedIntegerBin;
private:
    UInt u;
    int sign = 1;
    void regularize(){ u.regularize(); if(u.isZero()) sign = 1; }
    static MyType Raw(UInt u, int s){ MyType res; res.u = std::move(u); res.sign = s; res.regularize(); return res; }
public:
    bool isZero() const { return u.isZero(); }
    MyType& operator+=(const MyType& r) {
        if(sign == r.sign) u += r.u;
        else{ u -= r.u; if(u.Cflag){ sign = -sign; } }
        regularize();
        return *this;
    }
    MyType& operator-=(const MyType& r) {
        if(sign != r.sign) u += r.u;
        else{ u -= r.u; if(u.Cflag){ sign = -sign; } }
        regularize();
        return *this;
    }
    MyType operator*(const MyType& r) const { return Raw(u*r.u, sign*r.sign); }
    MyType& operator*=(const MyType& r) { return (*this) = operator*(r); }
    MyType operator+(const MyType& r) const { auto p = *this; p += r; return p; }
    MyType operator-(const MyType& r) const { auto p = *this; p -= r; return p; }
    MyType operator-() const { return Raw(u, -sign); }
    MyType& operator<<=(int sh) { u <<= sh; return *this; }
    MyType& operator>>=(int sh) { u >>= sh; return *this; }
    MyType operator<<(int sh) const { return Raw(u<<sh, sign); }
    MyType operator>>(int sh) const { return Raw(u<<sh, sign); }
    MyType operator/(const MyType& r) const { return Raw(u/r.u, sign*r.sign); }
    MyType& operator/=(const MyType& r) { return (*this) = operator/(r); }
    MyType operator%(const MyType& r) const { return Raw(u%r.u, sign*r.sign); }
    MyType& operator%=(const MyType& r) { return (*this) = operator%(r); }
    std::string toStringDec() const {
        if(isZero()) return "0";
        return (sign>0 ? "" : "-") + u.toStringDec();
    }
    static MyType FromStringDec(const std::string& s) {
        if(s.empty()) return MyType();
        if(s[0] == '+') return Raw(UInt::FromStringDec(s.substr(1)), 1);
        if(s[0] == '-') return Raw(UInt::FromStringDec(s.substr(1)), -1);
        return Raw(UInt::FromStringDec(s), 1);
    }
};

} // namespace nachia
#line 2 "Main.cpp"
#include <cstdint>
#line 5 "Main.cpp"
#include <string>
#line 7 "Main.cpp"


int main() {
    using Int = nachia::SignedIntegerBin;
    std::string s;
    std::cin >> s;
    Int a = Int::FromStringDec(s);
    std::cin >> s;
    Int b = Int::FromStringDec(s);
    Int c = a + b;
    std::cout << c.toStringDec() << '\n';
    return 0;
}
accuracy: 1
time_ms: 60
memory_kb: 4312
final_rank: 5

code_snippet: #line 2 "nachia\\math-modulo\\modulo-primitive-root.hpp"
#include <vector>
#include <utility>

namespace nachia{

template<unsigned int MOD>
struct PrimitiveRoot{
    using u64 = unsigned long long;
    static constexpr u64 powm(u64 a, u64 i) {
        u64 res = 1, aa = a;
        while(i){
            if(i & 1) res = res * aa % MOD;
            aa = aa * aa % MOD;
            i /= 2;
        }
        return res;
    }
    static constexpr bool ExamineVal(unsigned int g){
        unsigned int t = MOD - 1;
        for(u64 d=2; d*d<=t; d++) if(t % d == 0){
            if(powm(g, (MOD - 1) / d) == 1) return false;
            while(t % d == 0) t /= d;
        }
        if(t != 1) if(powm(g, (MOD - 1) / t) == 1) return false;
        return true;
    }
    static constexpr unsigned int GetVal(){
        for(unsigned int x=2; x<MOD; x++) if(ExamineVal(x)) return x;
        return 0;
    }
    static const unsigned int val = GetVal();
};

} // namespace nachia
#line 1 "nachia\\fps\\ntt-interface.hpp"
#include <algorithm>

namespace nachia {

template<class mint>
struct NttInterface{

template<class Iter>
void Butterfly(Iter, int) const {}

template<class Iter>
void IButterfly(Iter, int) const {}

template<class Iter>
void BitReversal(Iter a, int N) const {
    for(int i=0, j=0; j<N; j++){
        if(i < j) std::swap(a[i], a[j]);
        for(int k = N>>1; k > (i^=k); k>>=1);
    }
}

};

} // namespace nachia
#line 4 "nachia\\misc\\bit-operations.hpp"

namespace nachia{

int Popcount(unsigned long long c) noexcept {
#ifdef __GNUC__
    return __builtin_popcountll(c);
#else
    c = (c & (~0ull/3)) + ((c >> 1) & (~0ull/3));
    c = (c & (~0ull/5)) + ((c >> 2) & (~0ull/5));
    c = (c & (~0ull/17)) + ((c >> 4) & (~0ull/17));
    c = (c * (~0ull/257)) >> 56;
    return c;
#endif
}

// please ensure x != 0
int MsbIndex(unsigned long long x) noexcept {
#ifdef __GNUC__
    return 63 - __builtin_clzll(x);
#else
    int res = 0;
    for(int d=32; d>0; d>>=1) if(x >> d){ res |= d; x >>= d; }
    return res;
#endif
}

// please ensure x != 0
int LsbIndex(unsigned long long x) noexcept {
#ifdef __GNUC__
    return __builtin_ctzll(x);
#else
    return MsbIndex(x & -x);
#endif
}

}

#line 5 "nachia\\bigint\\ntt.hpp"
#include <iterator>
#include <cassert>
#line 8 "nachia\\bigint\\ntt.hpp"
#include <array>

namespace nachia{
namespace bigint{

constexpr int bsf_constexpr(unsigned int n) {
	int x = 0;
	while (!(n & (1 << x))) x++;
	return x;
}

template <class mint>
struct NttFromAcl : NttInterface<mint> {

using u32 = unsigned int;
using u64 = unsigned long long;
    
static int ceil_pow2(int n) {
	int x = 0;
	while ((1U << x) < (u32)(n)) x++;
	return x;
}

struct fft_info {
	static constexpr u32 g = nachia::PrimitiveRoot<mint::GetMod()>::val;
	static constexpr int rank2 = bsf_constexpr(mint::GetMod()-1);
	std::array<mint, rank2+1> root;
	std::array<mint, rank2+1> iroot;

	std::array<mint, std::max(0, rank2-1)> rate2;
	std::array<mint, std::max(0, rank2-1)> irate2;

	std::array<mint, std::max(0, rank2-2)> rate3;
	std::array<mint, std::max(0, rank2-2)> irate3;

	fft_info(){
		root[rank2] = mint(g).pow((mint::GetMod() - 1) >> rank2);
		iroot[rank2] = root[rank2].inv();
		for(int i=rank2-1; i>=0; i--){
			root[i] = root[i+1] * root[i+1];
			iroot[i] = iroot[i+1] * iroot[i+1];
		}
		mint prod = 1u, iprod = 1u;
		for(int i=0; i<=rank2-2; i++){
			rate2[i] = root[i+2] * prod;
			irate2[i] = iroot[i+2] * iprod;
			prod *= iroot[i+2];
			iprod *= root[i+2];
		}
		prod = 1u; iprod = 1u;
		for(int i=0; i<=rank2-3; i++){
			rate3[i] = root[i+3] * prod;
			irate3[i] = iroot[i+3] * iprod;
			prod *= iroot[i+3];
			iprod *= root[i+3];
		}
	}
};

template<class RandomAccessIterator>
void Butterfly(RandomAccessIterator a, int n) const {
	int h = ceil_pow2(n);

	static const fft_info info;

	int len = 0;
	while(len < h){
		if(h-len == 1){
			int p = 1 << (h-len-1);
			mint rot = 1u;
			for(int s=0; s<(1<<len); s++){
				int offset = s << (h-len);
				for(int i=0; i<p; i++){
					auto l = a[i+offset];
					auto r = a[i+offset+p] * rot;
					a[i+offset] = l+r;
					a[i+offset+p] = l-r;
				}
				if(s+1 != (1<<len)) rot *= info.rate2[LsbIndex(~(u32)(s))];
			}
			len++;
		} else {
			int p = 1 << (h-len-2);
			mint rot = 1u, imag = info.root[2];
			for(int s=0; s<(1<<len); s++){
				mint rot2 = rot * rot;
				mint rot3 = rot2 * rot;
				int offset = s << (h-len);
				for(int i=0; i<p; i++){
					auto a0 = a[i+offset];
					auto a1 = a[i+offset+p] * rot;
					auto a2 = a[i+offset+2*p] * rot2;
					auto a3 = a[i+offset+3*p] * rot3;
					auto a0a2 = a0 + a2;
					auto a0b2 = a0 - a2;
					auto a1a3 = a1 + a3;
					auto a1na3imag = (a1 - a3) * imag;
					a[i+offset] = a0a2 + a1a3;
					a[i+offset+1*p] = a0a2 - a1a3;
					a[i+offset+2*p] = a0b2 + a1na3imag;
					a[i+offset+3*p] = a0b2 - a1na3imag;
				}
				if(s+1 != (1<<len)) rot *= info.rate3[LsbIndex(~(u32)(s))];
			}
			len += 2;
		}
	}
}

template<class RandomAccessIterator>
void IButterfly(RandomAccessIterator a, int n) const {
	int h = ceil_pow2(n);

	static const fft_info info;

	int len = h;
	while(len){
		if(len == 1){
			int p = 1 << (h-len);
			mint irot = 1u;
			for(int s=0; s<(1<<(len-1)); s++){
				int offset = s << (h-len+1);
				for(int i=0; i<p; i++){
					auto l = a[i+offset];
					auto r = a[i+offset+p];
					a[i+offset] = l+r;
					a[i+offset+p] = (l-r)*irot;
				}
				if(s+1 != (1<<(len-1))) irot *= info.irate2[LsbIndex(~(u32)(s))];
			}
			len--;
		} else {
			int p = 1 << (h-len);
			mint irot = 1u, iimag = info.iroot[2];
			for(int s=0; s<(1<<(len-2)); s++){
				mint irot2 = irot * irot;
				mint irot3 = irot2 * irot;
				int offset = s << (h-len+2);
				for(int i=0; i<p; i++){
					auto a0 = a[i+offset+0*p];
					auto a1 = a[i+offset+1*p];
					auto a2 = a[i+offset+2*p];
					auto a3 = a[i+offset+3*p];
					auto a0a1 = a0 + a1;
					auto a0b1 = a0 - a1;
					auto a2a3 = a2 + a3;
					auto a2na3iimag = (a2 - a3) * iimag;

					a[i+offset] = a0a1 + a2a3;
					a[i+offset+1*p] = (a0b1 + a2na3iimag) * irot;
					a[i+offset+2*p] = (a0a1 - a2a3) * irot2;
					a[i+offset+3*p] = (a0b1 - a2na3iimag) * irot3;
				}
				if(s+1 != (1<<(len-2))) irot *= info.irate3[LsbIndex(~(u32)(s))];
			}
			len -= 2;
		}
	}
}

};

} // namespace bigint
} // namespace nachia
#line 3 "nachia\\bigint\\static-p-modint.hpp"

namespace nachia{
namespace bigint{

template<unsigned int MxVal>
class Montgomery32Info{
public:
    using u32 = unsigned int;
    using u64 = unsigned long long;
    static constexpr u32 u32inverse(u32 x){
        u32 v = 1;
        for(int i=0; i<5; i++) v = v * ((u32)2 - v * x);
        return v;
    }
    static constexpr u32 getMy(u32 mx){ return (-mx) % mx; }
    static constexpr u32 powMod(u32 a, u32 i, u32 m){
        if(i == 0) return 1 % m;
        if(i % 2 == 0) return powMod((u64)a*a%m, i/2, m);
        return (u64)a*powMod((u64)a*a%m, i/2, m)%m;
    }
    static constexpr u32 Mx = MxVal;
    static constexpr u32 iMx = u32inverse(Mx);
    static constexpr u32 My1 = getMy(Mx);
    static constexpr u32 My2 = powMod(getMy(Mx), 2, Mx);
    static constexpr u32 My3 = powMod(getMy(Mx), 3, Mx);
    // return z
    //  +  z % Mx == x % Mx
    //  +  x <= max(x>>32, Mx-1)
    static constexpr u32 red(u64 x){
        u32 z1 = x >> 32;
        u32 z2 = ((u64)Mx * ((u32)x*iMx)) >> 32;
        return z1 - z2 + (z1 < z2 ? Mx : 0);
    }
};

template<unsigned int MOD>
class StaticPModint{
public:
    using u32 = unsigned int;
    using u64 = unsigned long long;
private:
    static constexpr u32 mod = MOD;
    using Tool = Montgomery32Info<MOD>;
    using MyType = StaticPModint;
    u32 _v;
    static MyType RAW(u32 v) { auto res = StaticPModint(); res._v = v; return res; }
public:
    StaticPModint() : _v(0) {}
    StaticPModint(u32 v) : _v(Tool::red((u64)v * Tool::My2)) {}
    StaticPModint(u64 v) : _v(Tool::red((u64)Tool::My3 * Tool::red(v))) {}
    u32 val() const { return Tool::red(_v); }
    u32 mrVal() const { return _v; }
    MyType& operator-=(MyType r) { _v = _v - r._v + (_v < r._v ? mod : 0); return *this; }
    MyType& operator+=(MyType r) { u32 t = mod - r._v; _v = _v - t + (_v < t ? mod : 0); return *this; }
    MyType& operator*=(MyType r) { _v = Tool::red((u64)_v * r._v); return *this; }
    MyType operator+(MyType r) const { auto v = *this; v += r; return v; }
    MyType operator-(MyType r) const { auto v = *this; v -= r; return v; }
    MyType operator*(MyType r) const { auto v = *this; v *= r; return v; }
    MyType operator-() const { return RAW(_v ? mod - _v : (u32)0); }
    MyType pow(unsigned long long i) const {
        MyType x = *this, r = RAW(Tool::My1);
        while(i){ if(i&1){ r *= x; } x*=x; i>>=1; }
        return r;
    }
    MyType inv() const { return pow(mod-2); }
    static constexpr u32 GetMod() { return mod; }
};

} // namespace bigint
} // namespace nachia
#line 2 "nachia\\bigint\\dynamic-p-modint.hpp"

namespace nachia{
namespace bigint{

class DynMontgomery32Info{
public:
    using u32 = unsigned int;
    using u64 = unsigned long long;
    static u32 u32inverse(u32 x) {
        u32 v = 1;
        for(int i=0; i<5; i++) v = v * ((u32)2 - v * x);
        return v;
    }
    static u32 getMy(u32 mx) { return (-mx) % mx; }
    static u32 powMod(u32 a, u32 i, u32 m) {
        if(i == 0) return 1 % m;
        if(i % 2 == 0) return powMod((u64)a*a%m, i/2, m);
        return (u64)a*powMod((u64)a*a%m, i/2, m)%m;
    }
    const u32 Mx;
    const u32 iMx;
    const u32 My1;
    const u32 My2;
    const u32 My3;
    DynMontgomery32Info(u32 newMod)
        : Mx(newMod)
        , iMx(u32inverse(Mx))
        , My1(getMy(Mx))
        , My2((u64)My1 * My1 % Mx)
        , My3((u64)My2 * My1 % Mx) {}

    // return z
    //  +  z % Mx == x % Mx
    //  +  x <= max(x>>32, Mx-1)
    u32 red(u64 x) const {
        u32 z1 = x >> 32;
        u32 z2 = ((u64)Mx * ((u32)x*iMx)) >> 32;
        return z1 - z2 + (z1 < z2 ? Mx : 0);
    }
    u32 add(u32 a, u32 b) const { b = Mx-b; return a - b + ((a < b) ? Mx : 0u); }
    u32 sub(u32 a, u32 b) const { return a - b + ((a < b) ? Mx : 0u); }
    u32 mul(u32 a, u32 b) const { return red((u64)a * b); }
    u32 pow(u32 a, u32 i) const {
        u32 x = a, r = My1;
        while(i){ if(i&1){ r=mul(r,x); } x=mul(x,x); i>>=1; }
        return r;
    }
    u32 inv(u32 a) const { return pow(a, Mx-2); }
    u32 input64(u64 a) const { return mul(red(a), My3); }
};

} // namespace bigint
} // namespace nachia
#line 5 "nachia\\bigint\\garner.hpp"

namespace nachia{
namespace bigint{

struct GarnerU96{
    using u32 = unsigned int;
    using u64 = unsigned long long;
    std::vector<u32> mods;
    std::vector<DynMontgomery32Info> dynmods;
    std::vector<std::vector<u32>> table_coeff;
    std::vector<u32> table_coeffinv;

    void precalc(std::vector<u32> new_mods){
        mods = std::move(new_mods);
        for(std::size_t i=0; i<mods.size(); i++) dynmods.emplace_back(mods[i]);
        int nmods = mods.size();
        table_coeff.assign(nmods+1, std::vector<u32>(nmods, 0));
        for(int k=0; k<nmods; k++) table_coeff[0][k] = dynmods[k].My2;
        for(int j=0; j<nmods; j++){
            for(int k=0; k<nmods; k++) table_coeff[j+1][k] = table_coeff[j][k];
            for(int k=j+1; k<nmods; k++) table_coeff[j+1][k] = dynmods[k].mul(table_coeff[j+1][k], dynmods[k].input64(mods[j]));
        }
        table_coeffinv.resize(nmods);
        for(int i=0; i<nmods; i++) table_coeffinv[i] = dynmods[i].inv(table_coeff[i][i]);
    }

    u64 calc(const std::vector<u32>& x){
        int nmods = mods.size();
        std::vector<u32> table_const(nmods);
        u64 res = 0;
        u64 res_coeff = 1;
        for(int j=0; j<nmods; j++){
            u32 t = dynmods[j].mul(dynmods[j].sub(x[j], table_const[j]), table_coeffinv[j]);
            for(int k=j+1; k<nmods; k++){
                table_const[k] = dynmods[k].add(dynmods[k].mul(t, table_coeff[j][k]), table_const[k]);
            }
            res += res_coeff * u64(t);
            res_coeff *= mods[j];
        }
        return res;
    }

    std::pair<std::vector<u32>, std::vector<u64>> calc(std::vector<std::vector<u32>> x){
        int n = x[0].size(), m = x.size();
        std::vector<u64> resl(n);
        std::vector<u32> resh(n);
        std::vector<u32> buf(m);
        u32 inv64 = dynmods[0].inv(dynmods[0].mul(dynmods[0].My3, dynmods[0].My2));
        for(int i=0; i<n; i++){
            for(int j=0; j<m; j++) buf[j] = x[j][i];
            resl[i] = calc(buf);
            resh[i] = dynmods[0].mul(dynmods[0].sub(buf[0], dynmods[0].input64(resl[i])), inv64);
        }
        return std::make_pair(std::move(resh), std::move(resl));
    }
};

} // namespace bigint
} // namespace nachia
#line 5 "nachia\\bigint\\convolution.hpp"

namespace nachia{
namespace bigint{

struct MultiplySupply {
    using u32 = unsigned int;
    using u64 = unsigned long long;
    static constexpr u32 MODCNT = 3;
    static constexpr u32 MOD[3] = { 3892314113, 3489660929, 3221225473 };
    
    GarnerU96 garner;

    MultiplySupply(){
        garner.precalc(std::vector<u32>(MOD, MOD + MODCNT));
    }
    
    template<unsigned int P>
    static std::vector<u32> SubConvolution(
        const std::vector<u32>& a,
        const std::vector<u32>& b
    ) {
        using Elem = StaticPModint<P>;
        static NttFromAcl<Elem> ntt;
        int z = a.size() + b.size() - 1;
        int N = 1; while(N < z) N *= 2;
        std::vector<Elem> A(N), B(N);
        for(std::size_t i=0; i<a.size(); i++) A[i] = a[i];
        for(std::size_t i=0; i<b.size(); i++) B[i] = b[i];
        Elem iN = Elem((u32)N).inv();
        ntt.Butterfly(A.begin(), N);
        ntt.Butterfly(B.begin(), N);
        for(int i=0; i<N; i++) A[i] = A[i] * B[i] * iN;
        ntt.IButterfly(A.begin(), N);
        std::vector<u32> res(z);
        for(int i=0; i<z; i++) res[i] = A[i].mrVal();
        return res;
    }
    
    std::vector<u32> multiplyBin(
        const std::vector<u32>& a,
        const std::vector<u32>& b
    ){
        if(a.empty() || b.empty()) return {};
        std::vector<std::vector<u32>> cx(MODCNT);
        cx[0] = SubConvolution<MOD[0]>(a, b);
        cx[1] = SubConvolution<MOD[1]>(a, b);
        cx[2] = SubConvolution<MOD[2]>(a, b);
        auto q = garner.calc(std::move(cx));
        int n = q.first.size();
        std::vector<u32> res(n + 2);
        for(int i=0; i<n; i++) res[i] = q.second[i];
        u64 c = 0;
        for(int i=0; i<n; i++){ res[i+1] = c += (u64)res[i+1] + (q.second[i] >> 32); c >>= 32; }
        res[n+1] = c; c = 0;
        for(int i=0; i<n; i++){ res[i+2] = c += (u64)res[i+2] + q.first[i]; c >>= 32; }
        while(res.size() && res.back() == 0) res.pop_back();
        return res;
    }
    
    std::vector<u32> multiplyDec(
        std::vector<u32> a,
        std::vector<u32> b
    ){
        static constexpr u32 d = 1000000000;
        if(a.empty() || b.empty()) return {};
        std::vector<std::vector<u32>> cx(MODCNT);
        cx[0] = SubConvolution<MOD[0]>(a, b);
        cx[1] = SubConvolution<MOD[1]>(a, b);
        cx[2] = SubConvolution<MOD[2]>(a, b);
        auto q0 = garner.calc(std::move(cx));
        int n = q0.first.size();
        std::vector<u64> buf(n + 2);
        static constexpr u32 j11 = (1ull << 32) / d;
        static constexpr u32 j10 = (-d) % d;
        static constexpr u32 j22 = 1 + (0ull- 1ull * d * d) / d / d;
        static constexpr u32 j21 = (-1ull * j22 * d * d) / d;
        static constexpr u32 j20 = (0ull-d) % d;
        for(int i=0; i<n; i++) buf[i] = q0.second[i] & ((1ull << 32) - 1);
        for(int i=0; i<n; i++) buf[i] += 1ull * (q0.second[i] >> 32) * j10;
        for(int i=0; i<n; i++) buf[i+1] += 1ull * (q0.second[i] >> 32) * j11;
        for(int i=0; i<n; i++) buf[i] += 1ull * q0.first[i] * j20; // q0.first[i] is small enough
        for(int i=0; i<n; i++) buf[i+1] += 1ull * q0.first[i] * j21;
        for(int i=0; i<n; i++) buf[i+2] += 1ull * q0.first[i] * j22;
        std::vector<u32> res(n + 2);
        u64 c = 0;
        for(int i=0; i<n+2; i++){ c += buf[i]; res[i] = c % d; c /= d; }
        while(res.size() && res.back() == 0) res.pop_back();
        return res;
    }
};

} // namespace bigint
} // namespace nachia
#line 5 "nachia\\bigint\\base-operators.hpp"
#include <iostream>

namespace nachia {
namespace bigint {

class UIntDec {
public:
using u32 = unsigned int;
using u64 = unsigned long long;
std::vector<u32> x;
static constexpr u32 BASE = 1'000'000'000;

void Regularize(){ while(!x.empty() & !x.back()) x.pop_back(); }

UIntDec() = default;
UIntDec(std::vector<u32> _x) : x(std::move(_x)) {}
UIntDec& operator+=(const UIntDec& b){
    x.resize(std::max(x.size(), b.x.size()) + 1);
    u64 c = 0;
    for(std::size_t i=0; i<b.x.size(); i++){
        c += b.x[i]; c += x[i];
        if(c >= BASE){ x[i] = c - BASE; c = 1; }
        else{ x[i] = c; c = 0; }
    }
    for(int i=b.x.size(); c; i++){
        x[i] = c += x[i];
        if(c < BASE) break;
        c = x[i] -= BASE;
    }
    Regularize();
    return *this;
}
UIntDec operator*(const UIntDec& b) const { return MultiplySupply().multiplyDec(x, b.x); }

UIntDec Pow(u32 c) const {
    if(c == 0) return std::vector<u32>{1};
    if(c == 1) return *this;
    auto aa = Pow(c/2);
    aa = aa * aa;
    return (c&1) ? aa * (*this) : aa;
}
void mulU32(unsigned int cx) {
    u64 c = cx;
    for(std::size_t i=0; i<x.size(); i++){ c += (u64)x[i] << 32; x[i] = c % BASE; c /= BASE; }
    while(c){ x.push_back(c % BASE); c /= BASE; }
}

};

class UIntBin {
public:
using u32 = unsigned int;
using u64 = unsigned long long;
std::vector<u32> x;

void Regularize(){ while(!x.empty() & !x.back()) x.pop_back(); }

UIntBin() = default;
UIntBin(std::vector<u32> _x) : x(std::move(_x)) {}
UIntBin& operator+=(const UIntBin& b){
    x.resize(std::max(x.size(), b.x.size()) + 1);
    u64 c = 0;
    for(std::size_t i=0; i<b.x.size(); i++){
        c += b.x[i]; c += x[i];
        x[i] = c; c >>= 32;
    }
    for(int i=b.x.size(); c; i++){ x[i] = c += x[i]; c >>= 32; }
    Regularize();
    return *this;
}
UIntBin operator*(const UIntBin& b) const { return MultiplySupply().multiplyBin(x, b.x); }

UIntBin Pow(u32 c) const {
    if(c == 0) return std::vector<u32>{1};
    if(c == 1) return *this;
    auto aa = Pow(c/2);
    aa = aa * aa;
    return (c&1) ? aa * (*this) : aa;
}
void mulD(unsigned int d, unsigned int cx) {
    u64 c = cx;
    for(std::size_t i=0; i<x.size(); i++){ x[i] = (c += (u64)x[i] * d); c >>= 32; }
    if(c) x.push_back(c);
}

};

std::vector<unsigned int> DecToBin(std::string decstr){
    std::vector<UIntBin> pdec;
    auto dfs = [&](auto& dfs, int l, int r) -> UIntBin {
        if(r - l <= 308){
            UIntBin p;
            for(int j=l; j<l+(r-l)%9; j++) p.mulD(10, decstr[j] - '0');
            for(int j=l+(r-l)%9; j<r; j+=9) p.mulD(1000000000, std::stoi(decstr.substr(j, 9)));
            return p;
        }
        if(pdec.empty()) pdec.push_back(UIntBin({10}).Pow(308));
        int h = 0; while(((308*2)<<h) < r-l) h++;
        while((int)pdec.size() < h+1) pdec.push_back(pdec.back() * pdec.back());
        auto res = dfs(dfs, l, r-(308<<h)) * pdec[h];
        res += dfs(dfs, r-(308<<h), r);
        return res;
    };
    return std::move(dfs(dfs, 0, decstr.size()).x);
}

std::string BinToDec(std::vector<unsigned int> b){
    while(!b.empty() && !b.back()) b.pop_back();
    std::reverse(b.begin(), b.end());
    if(b.empty()) return "0";
    std::vector<UIntDec> pbin;
    auto dfs = [&](auto& dfs, int l, int r) -> UIntDec {
        if(r - l <= 29){
            UIntDec p;
            for(int j=l; j<r; j++) p.mulU32(b[j]);
            return p;
        }
        if(pbin.empty()) pbin.push_back(UIntDec({2}).Pow(32*29));
        int h = 0; while(((29*2)<<h) < r-l) h++;
        while((int)pbin.size() < h+1) pbin.push_back(pbin.back() * pbin.back());
        auto res = dfs(dfs, l, r-(29<<h)) * pbin[h];
        res += dfs(dfs, r-(29<<h), r);
        return res;
    };
    auto x = std::move(dfs(dfs, 0, b.size()).x);
    while(!x.empty() && !x.back()) x.pop_back();
    std::string res = std::to_string(x.back());
    res.resize(res.size() + 9 * (int)(x.size()-1), '0');
    for(int i=(int)x.size()-2; i>=0; i--){
        int o = res.size() - i*9 - 9;
        for(int j=o+8; j>=o; j--){ res[j] += x[i] % 10; x[i] /= 10; }
    }
    return res;
}

} // namespace bigint
} // namespace nachia
#line 4 "nachia\\bigint\\integer.hpp"

namespace nachia{

class UnsignedIntegerBin{
public:
    using MyType = UnsignedIntegerBin;
    friend class SignedIntegerBin;
private:
    using u32 = uint32_t;
    using u64 = uint64_t;
    std::vector<u32> x;
    static inline bool Cflag;
    static MyType FromVec(std::vector<u32> _x){ MyType res; res.x = std::move(_x); return res; }
public:
    UnsignedIntegerBin(){}
    MyType operator>>(int sh) const {
        int h = sh / 32, l = sh % 32;
        MyType res; res.memreserve(size() - h);
        for(int i=h; i<size(); i++) res[i-h] = x[i] >> l;
        if(l) for(int i=h+1; i<size(); i++) res[i-h-1] |= x[i] << (32-l);
        res.regularize();
        return res;
    }
    MyType operator<<(int sh) const {
        int h = sh / 32, l = sh % 32;
        MyType res; res.memreserve(size() + h + 1);
        for(int i=0; i<size(); i++) res[i+h] = x[i] << l;
        if(l) for(int i=0; i<size(); i++) res[i+h+1] |= x[i] >> (32-l);
        res.regularize();
        return res;
    }
    MyType& operator>>=(int sh) { return (*this) = operator>>(sh); }
    MyType& operator<<=(int sh) { return (*this) = operator<<(sh); }
    MyType& operator%=(const MyType& d) { divInternal(d); return *this; }
    MyType operator%(const MyType& d) const { auto p = *this; return p.divInternal(d); }
    MyType operator/(const MyType& d) const { auto p = *this; return p.divInternal(d); }
    MyType& operator/=(const MyType& d) { return (*this) = divInternal(d); }
    MyType& operator+=(const MyType& v){
        memreserve(std::max(size(), v.size()) + 1);
        u64 c = 0;
        for(int i=0; i<v.size(); i++){ x[i] = (c += (u64)x[i] + v[i]); c >>= 32; }
        for(int i=v.size(); c; i++){ x[i] = c += x[i]; c >>= 32; }
        regularize();
        return *this;
    }
    MyType& operator-=(const MyType& v){
        memreserve(std::max(size(), v.size()));
        u64 c = 0;
        for(int i=0; i<v.size(); i++){
            c += v[i];
            x[i] -= c;
            c = (c + x[i]) >> 32;
        }
        for(int i=v.size(); i<size() && c; i++){
            x[i] -= c;
            c = (c + x[i]) >> 32;
        }
        Cflag = c;
        if(c){ complement(); increment(); }
        regularize();
        return *this;
    }
    MyType operator*(const MyType& v) const {
        MyType res;
        res.x = bigint::MultiplySupply().multiplyBin(x, v.x);
        res.regularize();
        return res;
    }
    MyType& operator*=(const MyType& r) { return (*this) = operator*(r); }
    MyType operator+(const MyType& r) { auto p = *this; p += r; return p; }
    MyType operator-(const MyType& r) { auto p = *this; p -= r; return p; }
    bool operator<(const MyType& r) const {
        return (size() != r.size())
            ? (size() < r.size())
            : std::lexicographical_compare(x.rbegin(), x.rend(), r.x.rbegin(), r.x.rend());
    }
    bool operator>(const MyType& r) const { return r < (*this); }
    bool operator<=(const MyType& r) const { return !(r < (*this)); }
    bool operator>=(const MyType& r) const { return !operator<(r); }
    bool operator==(const MyType& r) const { return x == r.x; }
    bool operator!=(const MyType& r) const { return x != r.x; }
    bool operator!() const { return size(); }
    bool isZero() const { return size() == 0; }
    std::string toStringBin() const {
        std::string res;
        for(int i=size()-1; i>=0; i--) for(int j=31; j>=0; j--) res.push_back('0' + (x[i]>>j) % 2);
        return res;
    }
    std::string toStringDec() const {
        if(isZero()) return "0";
        return bigint::BinToDec(x);
    }
    static MyType FromStringDec(const std::string& s) {
        return FromVec(bigint::DecToBin(s));
    }
    int lsb() const { for(int i=0; i<size(); i++){ if(x[i]) return nachia::LsbIndex(x[i]) + i * 32; } return -1; }
    int msb() const { for(int i=size()-1; i>=0; i--){ if(x[i]) return nachia::MsbIndex(x[i]) + i * 32; } return -1; }
private:
    int size() const { return x.size(); }
    u32& operator[](int at) { return x[at]; }
    u32 operator[](int at) const { return x[at]; }
    void memreserve(int sz) { if((int)x.size() < sz) x.resize(sz); }
    void setBit(int at, bool val){ memreserve(at/32+1); x[at/32] |= (u32)(val?1:0) << (at%32); regularize(); }
    MyType divInternal(const MyType& d) {
        if(d.isZero()) throw 1;
        MyType res;
        for(int s=(size()-d.size())*32+31; s>=0; s--){
            MyType x = d << s;
            if(operator>=(x)){
                res.setBit(s, true); operator-=(x);
            }
        }
        res.regularize();
        return res;
    }
    void complement() { for(u32& y:x){ y = ~y; } }
    void increment() { if(isZero()){ x = {1}; return; } int i=0; while(i < size() && !~x[i]){ x[i++]++; } if(i>=size()){ x.push_back(1); } else x[i]++; }
    void decrement() { if(isZero()){ x = {1}; return; } int i=0; while(x[i]){ x[i++]--; } x[i]--; regularize(); }
    void regularize() { while(!x.empty() && 0 == x.back()) x.pop_back(); }
    int div10() {
        u64 c = 0;
        for(int i=size()-1; i>=0; i--){
            c = (c << 32) | x[i];
            x[i] = c / 10;
            c %= 10;
        }
        regularize();
        return c;
    }
    void mul10(int d) {
        u64 c = d;
        for(int i=0; i<size(); i++){ x[i] = (c += (u64)x[i] * 10); c >>= 32; }
        if(c) x.push_back(c);
    }
};

class SignedIntegerBin{
    using MyType = SignedIntegerBin;
    using UInt = UnsignedIntegerBin;
private:
    UInt u;
    int sign = 1;
    void regularize(){ u.regularize(); if(u.isZero()) sign = 1; }
    static MyType Raw(UInt u, int s){ MyType res; res.u = std::move(u); res.sign = s; res.regularize(); return res; }
public:
    bool isZero() const { return u.isZero(); }
    MyType& operator+=(const MyType& r) {
        if(sign == r.sign) u += r.u;
        else{ u -= r.u; if(u.Cflag){ sign = -sign; } }
        regularize();
        return *this;
    }
    MyType& operator-=(const MyType& r) {
        if(sign != r.sign) u += r.u;
        else{ u -= r.u; if(u.Cflag){ sign = -sign; } }
        regularize();
        return *this;
    }
    MyType operator*(const MyType& r) const { return Raw(u*r.u, sign*r.sign); }
    MyType& operator*=(const MyType& r) { return (*this) = operator*(r); }
    MyType operator+(const MyType& r) const { auto p = *this; p += r; return p; }
    MyType operator-(const MyType& r) const { auto p = *this; p -= r; return p; }
    MyType operator-() const { return Raw(u, -sign); }
    MyType& operator<<=(int sh) { u <<= sh; return *this; }
    MyType& operator>>=(int sh) { u >>= sh; return *this; }
    MyType operator<<(int sh) const { return Raw(u<<sh, sign); }
    MyType operator>>(int sh) const { return Raw(u<<sh, sign); }
    MyType operator/(const MyType& r) const { return Raw(u/r.u, sign*r.sign); }
    MyType& operator/=(const MyType& r) { return (*this) = operator/(r); }
    MyType operator%(const MyType& r) const { return Raw(u%r.u, sign*r.sign); }
    MyType& operator%=(const MyType& r) { return (*this) = operator%(r); }
    std::string toStringDec() const {
        if(isZero()) return "0";
        return (sign>0 ? "" : "-") + u.toStringDec();
    }
    static MyType FromStringDec(const std::string& s) {
        if(s.empty()) return MyType();
        if(s[0] == '+') return Raw(UInt::FromStringDec(s.substr(1)), 1);
        if(s[0] == '-') return Raw(UInt::FromStringDec(s.substr(1)), -1);
        return Raw(UInt::FromStringDec(s), 1);
    }
};

} // namespace nachia
#line 2 "Main.cpp"
#include <cstdint>
#line 5 "Main.cpp"
#include <string>
#line 7 "Main.cpp"


int main() {
    using Int = nachia::SignedIntegerBin;
    std::string s;
    std::cin >> s;
    Int a = Int::FromStringDec(s);
    std::cin >> s;
    Int b = Int::FromStringDec(s);
    Int c = a + b;
    std::cout << c.toStringDec() << '\n';
    return 0;
}
accuracy: 0.84
time_ms: 60
memory_kb: 4204
final_rank: 18

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 );

struct bigInt{

  bool minus;
  int size;
  vector< vector<int> > 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] = str[id++] - '0';
        }
      }
    }

  }

  // 初期化
  void Init(){

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

  }

  // 表示
  void print(){

    if( minus )
      cout << '-';
    int top = 0;
    int order = 1;
    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 ){
      int lVal = 0, rVal = 0;
      int order = 1;
      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 ){
      int lVal = 0, rVal = 0;
      int order = 1;
      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 );
    int up = 0; // 繰り上がり
    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 );
        int down = 0; // 繰り下がり
        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;

}

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

int main(){

  string strA, strB;
  cin >> strA >> strB;
  bigInt a( strA );
  bigInt b( strB );
  bigInt sum = a + b;
  sum.print();

}
accuracy: 1
time_ms: 80
memory_kb: 95404
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 );

struct bigInt{

  bool minus;
  int size;
  vector< vector<int> > 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] = str[id++] - '0';
        }
      }
    }

  }

  // 初期化
  void Init(){

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

  }

  // 表示
  void print(){

    if( minus )
      cout << '-';
    int top = 0;
    int order = 1;
    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;

  }

};

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

  if( l.minus ){
    if( !r.minus ) return true;
    if( l.size == r.size ){
      int lVal = 0, rVal = 0;
      int order = 1;
      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 ){
      int lVal = 0, rVal = 0;
      int order = 1;
      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 );
    int up = 0; // 繰り上がり
    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.size = ( up != 0 ? maxSize+1 : maxSize );
    res.minus = l.minus;
  }
  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 < r ){
      res = r - l;
      res.minus = true;
    }
    else{
      res.size = max( l.size, r.size );
      int down = 0; // 繰り下がり
      for( int i = 0 ; i <= res.size ; 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;
        }
      }
      if( res.dat[res.size][0] == 0 && res.dat[res.size][1] == 0 && res.dat[res.size][2] == 0 && res.dat[res.size][3] == 0 )
        res.size = max( res.size-1, 0 );
    }
  }
  return res;

}

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

int main(){

  string strA, strB;
  cin >> strA >> strB;
  bigInt a( strA );
  bigInt b( strB );
  bigInt sum = a + b;
  sum.print();

}
accuracy: 1
time_ms: 80
memory_kb: 95512
final_rank: 17

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 );

struct bigInt{

  bool minus;
  int size;
  vector< vector<int> > 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] = str[id++] - '0';
        }
      }
    }

  }

  // 初期化
  void Init(){

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

  }

  // 表示
  void print(){

    if( minus )
      cout << '-';
    int top = 0;
    int order = 1;
    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;

  }

};

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

  if( l.minus ){
    if( !r.minus ) return true;
    if( l.size == r.size ){
      int lVal = 0, rVal = 0;
      int order = 1;
      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 ){
      int lVal = 0, rVal = 0;
      int order = 1;
      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 );
    int up = 0; // 繰り上がり
    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.size = ( up != 0 ? maxSize+1 : maxSize );
    res.minus = l.minus;
  }
  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 < r ){
      res = r - l;
      res.minus = true;
    }
    else{
      res.size = max( l.size, r.size );
      int down = 0; // 繰り下がり
      for( int i = 0 ; i <= res.size ; 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;
        }
      }
      if( res.dat[res.size][0] == 0 && res.dat[res.size][1] == 0 && res.dat[res.size][2] == 0 && res.dat[res.size][3] == 0 )
        res.size--;
    }
  }
  return res;

}

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

int main(){

  string strA, strB;
  cin >> strA >> strB;
  bigInt a( strA );
  bigInt b( strB );
  bigInt sum = a + b;
  sum.print();

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

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 );

struct bigInt{

  bool minus;
  int size;
  vector< vector<int> > 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] = str[id++] - '0';
        }
      }
    }

  }

  // 初期化
  void Init(){

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

  }

  // 表示
  void print(){

    if( minus )
      cout << '-';
    int top = 0;
    int order = 1;
    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;

  }

};

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

  if( l.minus ){
    if( !r.minus ) return true;
    if( l.size == r.size ){
      int lVal = 0, rVal = 0;
      for( int i = 0 ; i < 4 ; i++ ){
        lVal += l.dat[l.size][i];
        lVal *= 10;
        rVal += r.dat[r.size][i];
        rVal *= 10;
      }
      return lVal > rVal;
    }
    return l.size > r.size;
  }
  else{
    if( r.minus ) return false;
    if( l.size == r.size ){
      int lVal = 0, rVal = 0;
      for( int i = 0 ; i < 4 ; i++ ){
        lVal += l.dat[l.size][i];
        lVal *= 10;
        rVal += r.dat[r.size][i];
        rVal *= 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 );
    int up = 0; // 繰り上がり
    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.size = ( up != 0 ? maxSize+1 : maxSize );
    res.minus = l.minus;
  }
  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 < r ){
      res = r - l;
      res.minus = true;
    }
    else{
      res.size = max( l.size, r.size );
      int down = 0; // 繰り下がり
      for( int i = 0 ; i <= res.size ; i++ ){
        if( i == res.size && down == 1 ){
          res.size--;
          break;
        }
        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;
          }
        }
      }
    }
  }
  return res;

}

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

int main(){

  string strA, strB;
  cin >> strA >> strB;
  bigInt a( strA );
  bigInt b( strB );
  bigInt sum = a + b;
  sum.print();

}
accuracy: 0.06
time_ms: 70
memory_kb: 95232
final_rank: 19

code_snippet: #include <bits/stdc++.h>
#include <boost/multiprecision/cpp_int.hpp>
using namespace std;
int main(){
    boost::multiprecision::cpp_int a,b;
    std::cin>>a>>b;
    std::cout<<a+b<<std::endl;
}
accuracy: 1
time_ms: 700
memory_kb: 3408
final_rank: 11

code_snippet: #include<bits/stdc++.h>
#include <boost/multiprecision/cpp_int.hpp>
using namespace std;
#define rep(i,n) for(int i=0;i<(n);i++)
typedef long long ll;
using namespace boost::multiprecision;

int main() {
    cpp_int a,b;cin>>a>>b;
    cpp_int ans=a+b;
    cout<<ans<<endl;
    return 0;



}
accuracy: 1
time_ms: 700
memory_kb: 3428
final_rank: 13

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

#include <boost/multiprecision/cpp_int.hpp>

using namespace std;

typedef long long ll;
typedef long double ld;

const int mod=1e9+7;

int32_t main()
{
    boost::multiprecision::cpp_int a, b;
    cin >> a >> b;
    
    cout << a+b << endl;
    
    return 0;
}
accuracy: 1
time_ms: 700
memory_kb: 3456
final_rank: 15

code_snippet: // 多倍長整数
//#include <atcoder/convolution>
#include <iostream>
#include <vector>
#include <algorithm>

struct multiprecision{
  private:
  const long long base=100;
  const int lg = 2;
  std::vector<long long> num;

  void adjust(){
    for(int i=0;i<num.size();i++){
      long long z=num[i]/base;
      num[i]%=base;
      if(num[i]<0){
        if(z!=0||i<num.size()-1){
          z--;
          num[i]+=base;
        }
      }
      if(z==0)continue;
      if(i==num.size()-1){
        num.emplace_back(z);
      }
      else{
        num[i+1]+=z;
      }
    }

    while(num.size()>0&&num[num.size()-1]==0)num.pop_back();
    if(num.size()==0)num.emplace_back(0);
    while(num[num.size()-1]==-1&&num.size()>1&&num[num.size()-2]!=0){
      num[num.size()-2]-=base;
      num.pop_back();
    }
  }

  public:
  multiprecision(long long val){
    if(val==0){
      num.emplace_back(0);
    }
    else{
      long long cpy=val;
      while(cpy!=0){
        num.emplace_back(cpy%base);
        cpy/=base;
      }
    }
    adjust();
  }

  multiprecision(std::vector<long long> val){
    num=val;
    adjust();
  }

  multiprecision(std::string s){
    reverse(s.begin(),s.end());
    bool neg=0;
    if(s[s.size()-1]=='-'){
      s[s.size()-1]='0';
      neg=1;
    }
    while(s.size()%lg!=0){
      s+='0';
    }

    for(int i=0;i<s.size()/lg;i++){
      std::string t="";
      for(int j=0;j<lg;j++){
        t+=s[i*lg+j];
      }
      reverse(t.begin(),t.end());
      num.emplace_back(std::stoll(t));
    }

    if(neg){
      multiprecision zero=multiprecision(0);
      zero-=*this;
      *this=zero;
    }

    adjust();
  }

  std::vector<long long> val(){
    return num;
  }

  std::string s_val(){
    bool flg=0;
    if(num[num.size()-1]<0){
      flg=1;
      for(int i=0;i<num.size();i++){
        num[i]*=-1;
      }
      adjust();
    }
    std::string res="";
    if(flg)res+='-';
    for(int i=num.size()-1;i>=0;i--){
      std::string t=std::to_string(num[i]);
      if(i==num.size()-1){
        res+=t;
        continue;
      }
      for(int j=0;j<lg-t.size();j++){
        res+='0';
      }
      res+=t;
    }

    if(flg){
      for(int i=0;i<num.size();i++){
        num[i]*=-1;
      }
      adjust();
    }

    return res;
  }

  multiprecision& operator =(const multiprecision& other){
    this->num=other.num;
    return *this;
  }

  multiprecision& operator +=(const multiprecision& other){
    for(int i=0;i<other.num.size();i++){
      if(i>=this->num.size()){
        this->num.emplace_back(other.num[i]);
      }
      else{
        this->num[i]+=other.num[i];
      }
    }
    this->adjust();
    return *this;
  }

  multiprecision& operator -=(const multiprecision& other){
    for(int i=0;i<other.num.size();i++){
      if(i>=this->num.size()){
        this->num.emplace_back(-other.num[i]);
      }
      else{
        this->num[i]-=other.num[i];
      }
    }
    this->adjust();
    return *this;
  }
};


#include <bits/stdc++.h>
using namespace std;
 
using ll = long long;
using ld = long double;
 
using vi = vector<int>;
using vvi = vector<vi>;
using vll = vector<ll>;
using vvll = vector<vll>;
using vld = vector<ld>;
using vvld = vector<vld>;
using vst = vector<string>;
using vvst = vector<vst>;
 
#define fi first
#define se second
#define pb push_back
#define eb emplace_back
#define pq_big(T) priority_queue<T,vector<T>,less<T>>
#define pq_small(T) priority_queue<T,vector<T>,greater<T>>
#define all(a) a.begin(),a.end()
#define rep(i,start,end) for(ll i=start;i<(ll)(end);i++)
#define per(i,start,end) for(ll i=start;i>=(ll)(end);i--)
#define uniq(a) sort(all(a));a.erase(unique(all(a)),a.end())

int main(){
  string a,b;
  cin>>a>>b;

  multiprecision mp1(a),mp2(b);
  mp1+=mp2;

  cout<<mp1.s_val()<<endl;
}
accuracy: 1
time_ms: 10
memory_kb: 5012
final_rank: 1