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






Example

Input

5 8


Output

13
#include <vector>
#include <algorithm>
#include <iostream>
#include <cmath>
#include <cassert>
#include <utility>
//!===============================================================!//
//!   88888888b            dP       .88888.   a88888b. 888888ba   !//
//!   88                   88      d8'   '88 d8'   '88 88    '8b  !//
//!  a88aaaa    dP.  .dP d8888P    88        88        88     88  !//
//!   88         '8bd8'    88      88   YP88 88        88     88  !//
//!   88         .d88b.    88      Y8.   .88 Y8.   .88 88    .8P  !//
//!   88888888P dP'  'dP   dP       '88888'   Y88888P' 8888888P   !//
//!===============================================================!//
template <typename T>
constexpr std::pair<T, T> extgcd(const T a, const T b)
{
    if (b == 0) { return std::pair<T, T>{1, 0}; }
    const auto p = extgcd(b, a % b);
    return {p.second, p.first - p.second * (a / b)};
}
template <typename T>
constexpr T inverse(const T a, const T mod) { return (mod + extgcd((mod + a % mod) % mod, mod).first % mod) % mod; }
using uint = unsigned int;
using ll = long long;
using ull = unsigned long long;
//!========================================================!//
//!  8888ba.88ba                 dP    dP            dP    !//
//!  88  '8b  '8b                88    88            88    !//
//!  88   88   88 .d8888b. .d888b88    88 88d888b. d8888P  !//
//!  88   88   88 88'  '88 88'  '88    88 88'  '88   88    !//
//!  88   88   88 88.  .88 88.  .88    88 88    88   88    !//
//!  dP   dP   dP '88888P' '88888P8    dP dP    dP   dP    !//
//!========================================================!//
template <uint mod>
class ModInt
{
private:
    uint v;
    static uint norm(const uint& x) { return x < mod ? x : x - mod; }
    static ModInt make(const uint& x)
    {
        ModInt m;
        return m.v = x, m;
    }
    static ModInt power(ModInt x, ll n)
    {
        ModInt ans = 1;
        for (; n; n >>= 1, x *= x) {
            if (n & 1) { ans *= x; }
        }
        return ans;
    }
    static ModInt inv(const ModInt& x) { return ModInt{inverse((ll)x.v, (ll)mod)}; }

public:
    ModInt() : v{0} {}
    ModInt(const ll val) : v{norm(uint(val % (ll)mod + (ll)mod))} {}
    ModInt(const ModInt<mod>& n) : v{n()} {}
    explicit operator bool() const { return v != 0; }
    ModInt<mod>& operator=(const ModInt<mod>& n) { return v = n(), (*this); }
    ModInt<mod>& operator=(const ll val) { return v = norm(uint(val % (ll)mod + (ll)mod)), (*this); }
    ModInt<mod> operator+() const { return *this; }
    ModInt<mod> operator-() const { return make(norm(mod - v)); }
    ModInt<mod> operator+(const ModInt<mod>& val) const { return make(norm(v + val())); }
    ModInt<mod> operator-(const ModInt<mod>& val) const { return make(norm(v + mod - val())); }
    ModInt<mod> operator*(const ModInt<mod>& val) const { return make((uint)((ll)v * val() % (ll)mod)); }
    ModInt<mod> operator/(const ModInt<mod>& val) const { return *this * inv(val()); }
    ModInt<mod>& operator+=(const ModInt<mod>& val) { return *this = *this + val; }
    ModInt<mod>& operator-=(const ModInt<mod>& val) { return *this = *this - val; }
    ModInt<mod>& operator*=(const ModInt<mod>& val) { return *this = *this * val; }
    ModInt<mod>& operator/=(const ModInt<mod>& val) { return *this = *this / val; }
    ModInt<mod> operator+(const ll val) const { return ModInt{v + val}; }
    ModInt<mod> operator-(const ll val) const { return ModInt{v - val}; }
    ModInt<mod> operator*(const ll val) const { return ModInt{(ll)v * (val % mod)}; }
    ModInt<mod> operator/(const ll val) const { return ModInt{(ll)v * inv(val)}; }
    template <typename I>
    ModInt<mod> operator^(const I n) const { return power(v, n); }
    ModInt<mod>& operator+=(const ll val) { return *this = *this + val; }
    ModInt<mod>& operator-=(const ll val) { return *this = *this - val; }
    ModInt<mod>& operator*=(const ll val) { return *this = *this * val; }
    ModInt<mod>& operator/=(const ll val) { return *this = *this / val; }
    template <typename I>
    ModInt<mod>& operator^=(const I n) { return (*this) = ((*this) ^ n); }
    bool operator==(const ModInt<mod>& val) const { return v == val.v; }
    bool operator!=(const ModInt<mod>& val) const { return not(*this == val); }
    bool operator==(const ll val) const { return v == norm(uint((ll)mod + val % (ll)mod)); }
    bool operator!=(const ll val) const { return not(*this == val); }
    uint operator()() const { return v; }
};
template <uint mod>
inline ModInt<mod> operator+(const ll val, const ModInt<mod>& n) { return n + val; }
template <uint mod>
inline ModInt<mod> operator-(const ll val, const ModInt<mod>& n) { return ModInt<mod>{val - (ll)n()}; }
template <uint mod>
inline ModInt<mod> operator*(const ll val, const ModInt<mod>& n) { return n * val; }
template <uint mod>
inline ModInt<mod> operator/(const ll val, const ModInt<mod>& n) { return ModInt<mod>(val) / n; }
template <uint mod>
inline bool operator==(const ll val, const ModInt<mod>& n) { return n == val; }
template <uint mod>
inline bool operator!=(const ll val, const ModInt<mod>& n) { return not(val == n); }
template <uint mod>
inline std::istream& operator>>(std::istream& is, ModInt<mod>& n)
{
    uint v;
    return is >> v, n = v, is;
}
template <uint mod>
std::ostream& operator<<(std::ostream& os, const ModInt<mod>& n) { return (os << n()); }
template <typename T>
constexpr T popCount(const T u)
{
#ifdef __has_builtin
    return u == 0 ? T(0) : (T)__builtin_popcountll(u);
#else
    unsigned long long v = static_cast<unsigned long long>(u);
    return v = (v & 0x5555555555555555ULL) + (v >> 1 & 0x5555555555555555ULL), v = (v & 0x3333333333333333ULL) + (v >> 2 & 0x3333333333333333ULL), v = (v + (v >> 4)) & 0x0F0F0F0F0F0F0F0FULL, static_cast<T>(v * 0x0101010101010101ULL >> 56 & 0x7f);
#endif
}
template <typename T>
constexpr T log2p1(const T u)
{
#ifdef __has_builtin
    return u == 0 ? T(0) : T(64 - __builtin_clzll(u));
#else
    unsigned long long v = static_cast<unsigned long long>(u);
    return v = static_cast<unsigned long long>(v), v |= (v >> 1), v |= (v >> 2), v |= (v >> 4), v |= (v >> 8), v |= (v >> 16), v |= (v >> 32), popCount(v);
#endif
}
template <typename T>
constexpr T clog(const T v) { return v == 0 ? T(0) : log2p1(v - 1); }
template <typename T>
constexpr T msbp1(const T v) { return log2p1(v); }
template <typename T>
constexpr T lsbp1(const T v)
{
#ifdef __has_builtin
    return __builtin_ffsll(v);
#else
    return v == 0 ? T(0) : popCount((v & (-v)) - T(1)) + T(1);
#endif
}
template <typename T>
constexpr bool ispow2(const T v) { return popCount(v) == 1; }
template <typename T>
constexpr T ceil2(const T v) { return v == 0 ? T(1) : T(1) << log2p1(v - 1); }
template <typename T>
constexpr T floor2(const T v) { return v == 0 ? T(0) : T(1) << (log2p1(v) - 1); }
template <typename F>
constexpr F PI = static_cast<F>(3.1415926535897932385);
template <typename F>
struct Complex
{
    F x, y;
    Complex() : x(0), y(0) {}
    Complex(const F& s) : x(std::cos(s)), y(std::sin(s)) {}
    Complex(const F x, const F y) : x(x), y(y) {}
    Complex operator-() const { return Complex(-x, -y); }
    Complex operator+(const Complex& c) const { return Complex{x + c.x, y + c.y}; }
    Complex operator-(const Complex& c) const { return Complex{x - c.x, y - c.y}; }
    Complex operator*(const Complex& c) const { return Complex{x * c.x - y * c.y, x * c.y + y * c.x}; }
    Complex operator*(const F& r) const { return Complex{x * r, y * r}; }
    Complex& operator+=(const Complex& c) { return this->x += c.x, this->y += c.y, *this; }
    Complex& operator-=(const Complex& c) { return this->x -= c.x, this->y -= c.y, *this; }
    Complex& operator*=(const Complex& c) { return *this = *this * c; }
    Complex& operator*=(const F& r) { return this->x *= r, this->y *= r, *this; }
    Complex conj() const { return Complex{x, -y}; }
};
//!==================================!//
//!   88888888b  88888888b d888888P  !//
//!   88         88           88     !//
//!  a88aaaa    a88aaaa       88     !//
//!   88         88           88     !//
//!   88         88           88     !//
//!   dP         dP           dP     !//
//!==================================!//
template <typename F = double>
class FFT
{
private:
    static constexpr std::size_t L = 30;

public:
    FFT() = delete;
    static void fft(std::vector<Complex<F>>& a, const std::size_t lg, const bool rev)
    {
        static std::vector<Complex<F>> root[L];
        const std::size_t N = a.size();
        assert((1UL << lg) == N);
        if (root[lg].empty()) {
            root[lg].reserve(N), root[lg].resize(N);
            for (std::size_t i = 0; i < N; i++) { root[lg][i] = Complex<F>(PI<F> * F(2 * i) / F(N)); }
        }
        std::vector<Complex<F>> tmp(N);
        for (std::size_t w = (N >> 1); w > 0; w >>= 1) {
            for (std::size_t y = 0; y < (N >> 1); y += w) {
                const Complex<F> r = rev ? root[lg][y].conj() : root[lg][y];
                for (std::size_t x = 0; x < w; x++) {
                    const auto u = a[y << 1 | x], v = a[y << 1 | x | w] * r;
                    tmp[y | x] = u + v, tmp[y | x | (N >> 1)] = u - v;
                }
            }
            std::swap(tmp, a);
        }
    }
    template <typename T = ll>
    static std::vector<T> simpleConvolute(const std::vector<int>& a, const std::vector<int>& b)
    {
        const std::size_t need = a.size() + b.size() - 1, lg = clog(need), N = 1UL << lg;
        std::vector<Complex<F>> A(N), B(N);
        for (std::size_t i = 0; i < a.size(); i++) { A[i] = Complex<F>{F(a[i]), 0}; }
        for (std::size_t i = 0; i < b.size(); i++) { B[i] = Complex<F>{F(b[i]), 0}; }
        fft(A, lg, false), fft(B, lg, false);
        for (std::size_t i = 0; i < N; i++) { A[i] *= B[i] * ((F)1 / (F)N); }
        fft(A, lg, true);
        std::vector<T> ans(need);
        for (std::size_t i = 0; i < need; i++) { ans[i] = T(std::round(A[i].x)); }
        return ans;
    }
    template <typename T = ll, std::size_t K = 2, typename I = int>
    static std::vector<T> convolute(const std::vector<I>& a, const std::vector<I>& b)
    {
        constexpr std::size_t V = 30;
        constexpr std::size_t S = (V + K - 1) / K;
        const std::size_t need = a.size() + b.size() - 1, lg = clog(need), N = 1UL << lg;
        std::vector<Complex<F>> A[K], B[K], tmp(N);
        for (std::size_t i = 0; i < K; i++) {
            A[i].reserve(N), A[i].resize(N), B[i].reserve(N), B[i].resize(N);
            std::fill(tmp.begin() + std::min(a.size(), b.size()), tmp.end(), Complex<F>{});
            for (std::size_t j = 0; j < a.size(); j++) { tmp[j].x = F((a[j] >> (S * i)) & ((1 << S) - 1)); }
            for (std::size_t j = 0; j < b.size(); j++) { tmp[j].y = F((b[j] >> (S * i)) & ((1 << S) - 1)); }
            fft(tmp, lg, false);
            for (std::size_t j = 0; j < N; j++) { tmp[j] *= F(0.5); }
            for (std::size_t j = 0; j < N; j++) {
                const std::size_t k = j == 0 ? 0UL : N - j;
                A[i][j] = Complex<F>{tmp[j].x + tmp[k].x, tmp[j].y - tmp[k].y}, B[i][j] = Complex<F>{tmp[j].y + tmp[k].y, -tmp[j].x + tmp[k].x};
            }
        }
        std::vector<Complex<F>> Z[K];
        for (std::size_t i = 0; i < K; i++) { Z[i].reserve(N), Z[i].resize(N); }
        for (std::size_t a = 0; a < K; a++) {
            for (std::size_t b = 0; b < K; b++) {
                for (std::size_t i = 0; i < N; i++) {
                    if (a + b < K) {
                        Z[a + b][i] += A[a][i] * B[b][i];
                    } else {
                        Z[a + b - K][i] += A[a][i] * B[b][i] * Complex<F>(0, 1);
                    }
                }
            }
        }
        for (std::size_t i = 0; i < K; i++) { fft(Z[i], lg, true); }
        std::vector<T> ans(need);
        T base = 1;
        for (std::size_t k = 0; k < 2 * K - 1; k++, base *= (1LL << S)) {
            for (std::size_t i = 0; i < need; i++) {
                if (k < K) {
                    ans[i] += base * ll(std::round(Z[k][i].x / F(N)));
                } else {
                    ans[i] += base * ll(std::round(Z[k - K][i].y / F(N)));
                }
            }
        }
        return ans;
    }
    template <uint mod, std::size_t K = 2>
    static std::vector<ModInt<mod>> convolute(const std::vector<ModInt<mod>>& a, const std::vector<ModInt<mod>>& b)
    {
        constexpr std::size_t V = 30;
        constexpr std::size_t S = (V + K - 1) / K;
        const std::size_t need = a.size() + b.size() - 1, lg = clog(need), N = 1UL << lg;
        std::vector<Complex<F>> A[K], B[K], tmp(N);
        for (std::size_t i = 0; i < K; i++) {
            A[i].reserve(N), A[i].resize(N), B[i].reserve(N), B[i].resize(N);
            std::fill(tmp.begin() + std::min(a.size(), b.size()), tmp.end(), Complex<F>{});
            for (std::size_t j = 0; j < a.size(); j++) { tmp[j].x = F((a[j]() >> (S * i)) & ((1 << S) - 1)); }
            for (std::size_t j = 0; j < b.size(); j++) { tmp[j].y = F((b[j]() >> (S * i)) & ((1 << S) - 1)); }
            fft(tmp, lg, false);
            for (std::size_t j = 0; j < N; j++) { tmp[j] *= F(0.5); }
            for (std::size_t j = 0; j < N; j++) {
                const std::size_t k = j == 0 ? 0UL : N - j;
                A[i][j] = Complex<F>{tmp[j].x + tmp[k].x, tmp[j].y - tmp[k].y}, B[i][j] = Complex<F>{tmp[j].y + tmp[k].y, -tmp[j].x + tmp[k].x};
            }
        }
        std::vector<Complex<F>> Z[K];
        for (std::size_t i = 0; i < K; i++) { Z[i].reserve(N), Z[i].resize(N); }
        for (std::size_t a = 0; a < K; a++) {
            for (std::size_t b = 0; b < K; b++) {
                for (std::size_t i = 0; i < N; i++) {
                    if (a + b < K) {
                        Z[a + b][i] += A[a][i] * B[b][i];
                    } else {
                        Z[a + b - K][i] += A[a][i] * B[b][i] * Complex<F>(0, 1);
                    }
                }
            }
        }
        for (std::size_t i = 0; i < K; i++) { fft(Z[i], lg, true); }
        std::vector<ModInt<mod>> ans(need);
        ModInt<mod> base = 1;
        for (std::size_t k = 0; k < 2 * K - 1; k++, base *= (1LL << S)) {
            for (std::size_t i = 0; i < need; i++) {
                if (k < K) {
                    ans[i] += int((base * ll(std::round(Z[k][i].x / F(N))))());
                } else {
                    ans[i] += int((base * ll(std::round(Z[k - K][i].y / F(N))))());
                }
            }
        }
        return ans;
    }
};
//!=============================================!//
//!   888888ba  oo          dP            dP    !//
//!   88    '8b             88            88    !//
//!  a88aaaa8P' dP .d8888b. 88 88d888b. d8888P  !//
//!   88   '8b. 88 88'  '88 88 88'  '88   88    !//
//!   88    .88 88 88.  .88 88 88    88   88    !//
//!   88888888P dP '8888P88 dP dP    dP   dP    !//
//!                     .88                     !//
//!                 d8888P                      !//
//!=============================================!//

template <std::size_t D = 9, typename T = long long>
class BigInt
{
public:
    BigInt() {}
    BigInt(const T x) : sign(x >= 0), d(x == 0 ? 0 : 1, x < 0 ? -x : x) { normalize(); }
    BigInt(const bool sign, const std::vector<T>& d) : sign(sign), d(d) { normalize(); }
    BigInt(const BigInt<D, T>& n) : sign(n.sign), d(n.d) {}
    BigInt(const std::string& S)
    {
        assert(not S.empty());
        sign = S[0] != '-';
        for (std::size_t i = 0; i < S.size(); i += D) {
            const std::size_t R = S.size() - i, L = (sign ? (R >= D ? R - D : 0) : (R > D ? R - D : 1));
            if (R > L) { d.push_back((T)std::stoll(S.substr(L, R - L))); }
        }
    }
    BigInt operator+() const { return *this; }
    BigInt operator-() const { return BigInt<D, T>(not sign, d); }
    operator bool() const { return not d.empty(); }
    operator long long() const { return to_ll(); }
    bool operator!() const noexcept { return not static_cast<bool>(*this); }
    friend BigInt<D, T> operator+(const BigInt<D, T>& m, const BigInt<D, T>& n)
    {
        if (m.sign == n.sign) {
            std::size_t L = std::max(m.d.size(), n.d.size());
            std::vector<T> v(L, 0);
            for (std::size_t i = 0; i < m.d.size(); i++) { v[i] += m.d[i]; }
            for (std::size_t i = 0; i < n.d.size(); i++) { v[i] += n.d[i]; }
            return BigInt<D, T>(m.sign, v);
        } else {
            std::size_t L = std::max(m.d.size(), n.d.size());
            std::vector<T> v(L, 0);
            if (absComp(m, n) == -1) {
                for (std::size_t i = 0; i < m.d.size(); i++) { v[i] -= m.d[i]; }
                for (std::size_t i = 0; i < n.d.size(); i++) { v[i] += n.d[i]; }
                return BigInt<D, T>(n.sign, v);
            } else {
                for (std::size_t i = 0; i < m.d.size(); i++) { v[i] += m.d[i]; }
                for (std::size_t i = 0; i < n.d.size(); i++) { v[i] -= n.d[i]; }
                return BigInt<D, T>(m.sign, v);
            }
        }
    }
    friend BigInt<D, T> operator-(const BigInt<D, T>& m, const BigInt<D, T>& n) { return m + (-n); }
    friend BigInt<D, T> operator*(const BigInt<D, T>& m, const BigInt<D, T>& n) { return BigInt<D, T>(not(m.sign ^ n.sign), FFT<>::convolute<ll, 2, ll>(m.d, n.d)); }
    friend BigInt<D, T> operator/(const BigInt<D, T>& m, const BigInt<D, T>& n) { return div(m, n).first; }
    friend BigInt<D, T> operator%(const BigInt<D, T>& m, const BigInt<D, T>& n) { return div(m, n).second; }
    template <typename I>
    friend BigInt<D, T> operator^(const BigInt<D, T>& m, const I n) { return n == 0 ? BigInt<D, T>(1) : n % 2 == 1 ? (m ^ (n - 1)) * m : (m * m) ^ (n / 2); }
    friend int comp(const BigInt<D, T>& m, const BigInt<D, T>& n)
    {
        if (m.sign != n.sign) {
            return m.sign ? 1 : -1;
        } else {
            return m.sign ? absComp(m, n) : -absComp(m, n);
        }
    }
    friend bool operator<(const BigInt<D, T>& m, const BigInt<D, T>& n) { return comp(m, n) == -1; }
    friend bool operator>(const BigInt<D, T>& m, const BigInt<D, T>& n) { return comp(m, n) == 1; }
    friend bool operator==(const BigInt<D, T>& m, const BigInt<D, T>& n) { return comp(m, n) == 0; }
    friend bool operator!=(const BigInt<D, T>& m, const BigInt<D, T>& n) { return not(m == n); }
    friend bool operator<=(const BigInt<D, T>& m, const BigInt<D, T>& n) { return not(m > n); }
    friend bool operator>=(const BigInt<D, T>& m, const BigInt<D, T>& n) { return not(m < n); }
    friend BigInt<D, T> operator<<(const BigInt<D, T>& m, const std::size_t n)  // *(B^n)
    {
        std::vector<T> ans(m.d.size() + n, 0);
        for (std::size_t i = 0; i < m.d.size(); i++) { ans[i + n] = m.d[i]; }
        return BigInt<D, T>(m.sign, ans);
    }
    friend BigInt<D, T> operator>>(const BigInt<D, T>& m, const std::size_t n)  // *(B^n)
    {
        if (m.d.size() <= n) { return 0; }
        std::vector<T> ans(m.d.size() - n, 0);
        for (std::size_t i = 0; i < m.d.size() - n; i++) { ans[i] = m.d[i + n]; }
        return BigInt<D, T>(m.sign, ans);
    }
    BigInt<D, T>& operator=(const BigInt<D, T>& n) { return sign = n.sign, d = n.d, *this; }
    BigInt<D, T>& operator=(const T n) { return *this = BigInt<D, T>(n); }
    friend BigInt<D, T>& operator+=(BigInt<D, T>& m, const BigInt<D, T>& n) { return m = m + n; }
    friend BigInt<D, T>& operator-=(BigInt<D, T>& m, const BigInt<D, T>& n) { return m = m - n; }
    friend BigInt<D, T>& operator*=(BigInt<D, T>& m, const BigInt<D, T>& n) { return m = m * n; }
    friend BigInt<D, T>& operator/=(BigInt<D, T>& m, const BigInt<D, T>& n) { return m = m / n; }
    friend BigInt<D, T>& operator%=(BigInt<D, T>& m, const BigInt<D, T>& n) { return m = m % n; }
    template <typename I>
    friend BigInt<D, T>& operator^=(BigInt<D, T> m, const I n) { return m = m ^ n; }
    friend BigInt<D, T>& operator<<=(BigInt<D, T>& m, const std::size_t n) { return m = m << n; }
    friend BigInt<D, T>& operator>>=(BigInt<D, T>& m, const std::size_t n) { return m = m >> n; }
    friend BigInt<D, T> operator+(const BigInt<D, T>& m, const T n) { return m + BigInt<D, T>(n); }
    friend BigInt<D, T> operator-(const BigInt<D, T>& m, const T n) { return m - BigInt<D, T>(n); }
    friend BigInt<D, T> operator*(const BigInt<D, T>& m, const T n) { return m * BigInt<D, T>(n); }
    friend BigInt<D, T> operator/(const BigInt<D, T>& m, const T n) { return m / BigInt<D, T>(n); }
    friend BigInt<D, T> operator%(const BigInt<D, T>& m, const T n) { return m % BigInt<D, T>(n); }
    friend bool operator<(const BigInt<D, T>& m, const T n) { return comp(m, BigInt<D, T>(n)) == -1; }
    friend bool operator>(const BigInt<D, T>& m, const T n) { return comp(m, BigInt<D, T>(n)) == 1; }
    friend bool operator==(const BigInt<D, T>& m, const T n) { return comp(m, BigInt<D, T>(n)) == 0; }
    friend bool operator!=(const BigInt<D, T>& m, const T n) { return not(m == n); }
    friend bool operator<=(const BigInt<D, T>& m, const T n) { return not(m > n); }
    friend bool operator>=(const BigInt<D, T>& m, const T n) { return not(m < n); }
    friend BigInt<D, T>& operator+=(const BigInt<D, T>& m, const T n) { return m += BigInt<D, T>(n); }
    friend BigInt<D, T>& operator-=(const BigInt<D, T>& m, const T n) { return m -= BigInt<D, T>(n); }
    friend BigInt<D, T>& operator*=(const BigInt<D, T>& m, const T n) { return m *= BigInt<D, T>(n); }
    friend BigInt<D, T>& operator/=(const BigInt<D, T>& m, const T n) { return m /= BigInt<D, T>(n); }
    friend BigInt<D, T>& operator%=(const BigInt<D, T>& m, const T n) { return m %= BigInt<D, T>(n); }
    friend BigInt<D, T> operator+(const T m, const BigInt<D, T>& n) { return BigInt<D, T>(m) + n; }
    friend BigInt<D, T> operator-(const T m, const BigInt<D, T>& n) { return BigInt<D, T>(m) - n; }
    friend BigInt<D, T> operator*(const T m, const BigInt<D, T>& n) { return BigInt<D, T>(m) * n; }
    friend BigInt<D, T> operator/(const T m, const BigInt<D, T>& n) { return BigInt<D, T>(m) / n; }
    friend BigInt<D, T> operator%(const T m, const BigInt<D, T>& n) { return BigInt<D, T>(m) % n; }
    friend bool operator<(const T m, const BigInt<D, T>& n) { return comp(BigInt<D, T>(m), n) == -1; }
    friend bool operator>(const T m, const BigInt<D, T>& n) { return comp(BigInt<D, T>(m), n) == 1; }
    friend bool operator==(const T m, const BigInt<D, T>& n) { return comp(BigInt<D, T>(m), n) == 0; }
    friend bool operator!=(const T m, const BigInt<D, T>& n) { return not(m == n); }
    friend bool operator<=(const T m, const BigInt<D, T>& n) { return not(m > n); }
    friend bool operator>=(const T m, const BigInt<D, T>& n) { return not(m < n); }
    BigInt<D, T>& operator++() { return *this += 1; }
    BigInt<D, T>& operator++(int)
    {
        const auto ans = *this;
        return *this += 1, ans;
    }
    BigInt<D, T>& operator--() { return *this -= 1; }
    BigInt<D, T>& operator--(int)
    {
        const auto ans = *this;
        return *this -= 1, ans;
    }
    friend BigInt<D, T> smallMul(const BigInt<D, T>& m, T n)
    {
        const bool s = n < 0 ? not m.sign : m.sign;
        n = n < 0 ? -n : n;
        assert(n < B);
        std::vector<T> ans(m.d.size());
        for (std::size_t i = 0; i < m.d.size(); i++) { ans[i] = m.d[i] * n; }
        return BigInt<D, T>(s, ans);
    }
    friend std::pair<BigInt<D, T>, T> smallDiv(const BigInt<D, T>& m, T n)
    {
        assert(n != 0);
        const bool s = n >= 0 ? m.sign : not m.sign;
        n = n < 0 ? -n : n;
        assert(n < B);
        std::vector<T> ans(m.d.size());
        T rem = 0;
        for (std::size_t i = 0; i < m.d.size(); i++) {
            const std::size_t ind = m.d.size() - i - 1;
            ans[ind] = (m.d[ind] + rem * B) / n, rem = (m.d[ind] + rem * B) - ans[ind] * n;
        }
        return std::pair<BigInt<D, T>, T>{BigInt<D, T>(s, ans), m.sign ? rem : -rem};
    }
    friend std::pair<BigInt<D, T>, BigInt<D, T>> div(BigInt<D, T> m, BigInt<D, T> n)
    {
        assert(not n.d.empty());
        if (absComp(m, n) == -1) { return {0, m}; }
        const bool ms = m.sign, ns = n.sign;
        m.sign = n.sign = true;
        const std::size_t S = m.d.size() - n.d.size();
        std::vector<T> sho(S + 1);
        for (std::size_t i = 0; i <= S; i++) {
            const std::size_t ind = S - i;
            const auto L = m >> ind;
            T inf = -1, sup = B;
            while (sup - inf > 1) {
                const T mid = (sup + inf) >> 1;
                (absComp(L, smallMul(n, mid)) == -1 ? sup : inf) = mid;
            }
            sho[ind] = inf, m -= (smallMul(n, inf) << ind);
        }
        return m.sign = ms, std::pair<BigInt<D, T>, BigInt<D, T>>{BigInt<D, T>(not(ms ^ ns), sho), m};
    }
    friend std::istream& operator>>(std::istream& is, BigInt<D, T>& n)
    {
        std::string S;
        is >> S;
        return n = BigInt<D, T>(S), is;
    }
    friend std::ostream& operator<<(std::ostream& os, const BigInt<D, T>& n)
    {
        if (n.d.empty()) { return os << '0'; }
        if (n.sign == false) { os << '-'; }
        const int N = n.d.size();
        for (std::size_t i = 0; i < N; i++) {
            if (i == 0) {
                os << n.d[N - i - 1];
            } else {
                std::size_t NZ = 0;
                for (T U = 1; n.d[N - i - 1] >= U; NZ++, U *= T(10)) {}
                for (std::size_t i = 0; i + NZ < D; i++) { os << '0'; }
                if (n.d[N - i - 1] != 0LL) { os << n.d[N - i - 1]; }
            }
        }
        return os;
    }
    friend std::size_t log10p1(const BigInt<D, T>& m)
    {
        if (m.d.empty()) { return 0; }
        assert(m.sign);
        return (m.d.size() - 1) * D + log10p1(m.d.back());
    }
    long long to_ll() const
    {
        long long ans = 0, base = 1;
        for (std::size_t i = 0; i < d.size(); i++, base *= B) { ans += base * d[i]; }
        return sign ? ans : -ans;
    }

private:
    static std::size_t log10p1(const T n)
    {
        std::size_t ans = 0;
        for (T base = 1; base <= n; base *= (T)10, ans++) {}
        return ans;
    }
    friend int absComp(const BigInt<D, T>& m, const BigInt<D, T>& n)  // m<n:-1  m=n:0  m>n:1
    {
        if (m.d.size() != n.d.size()) {
            return m.d.size() < n.d.size() ? -1 : 1;
        } else {
            for (std::size_t i = 0; i < m.d.size(); i++) {
                const auto M = m.d[m.d.size() - i - 1], N = n.d[n.d.size() - i - 1];
                if (M != N) { return M < N ? -1 : 1; }
            }
        }
        return 0;
    }
    void normalize()
    {
        for (std::size_t i = 0; i < d.size(); i++) {
            if (d[i] >= B) {
                if (i + 1 == d.size()) {
                    d.push_back(d[i] / B);
                } else {
                    d[i + 1] += d[i] / B;
                }
                d[i] %= B;
            } else if (d[i] < 0) {
                assert(i + 1 != d.size());
                while (d[i] < 0) { d[i + 1]--, d[i] += B; }
            }
        }
        for (; not d.empty() and d.back() == 0; d.pop_back()) {}
    }
    static constexpr T TEN(const std::size_t n) { return n == 0 ? T(1) : TEN(n - 1) * T(10); }
    static constexpr T B = TEN(D);
    bool sign = true;
    std::vector<T> d;
};
//!============================================!//
//!    8888ba.88ba             oo              !//
//!    88  '8b  '8b                            !//
//!    88   88   88  .d8888b.  dP  88d888b.    !//
//!    88   88   88  88'  '88  88  88'  '88    !//
//!    88   88   88  88.  .88  88  88    88    !//
//!    dP   dP   dP  '88888P8  dP  dP    dP    !//
//!============================================!//
int main()
{
    BigInt<18> A, B;
    std::cin >> A >> B;
    std::cout << A + B << std::endl;
    return 0;
}

