#ifndef CLASS_MODINT
#define CLASS_MODINT

#include <cassert>
#include <cstdint>

template <std::uint32_t mod>
class modint {
private:
	std::uint32_t n;
public:
	modint() noexcept : n(0) {};
	modint(std::int64_t n_) noexcept : n((n_ >= 0 ? n_ : mod - (-n_) % mod) % mod) {};
	static constexpr std::uint32_t get_mod() noexcept { return mod; }
	std::uint32_t get() const noexcept { return n; }
	bool operator==(const modint& m) const noexcept { return n == m.n; }
	bool operator!=(const modint& m) const noexcept { return n != m.n; }
	modint& operator+=(const modint& m) noexcept { n += m.n; n = (n < mod ? n : n - mod); return *this; }
	modint& operator-=(const modint& m) noexcept { n += mod - m.n; n = (n < mod ? n : n - mod); return *this; }
	modint& operator*=(const modint& m) noexcept { n = std::uint64_t(n) * m.n % mod; return *this; }
	modint operator+(const modint& m) const noexcept { return modint(*this) += m; }
	modint operator-(const modint& m) const noexcept { return modint(*this) -= m; }
	modint operator*(const modint& m) const noexcept { return modint(*this) *= m; }
	modint inv() const {
		assert(n != 0);
		return pow(mod - 2);
	}
	modint pow(std::uint64_t b) const noexcept {
		modint ans = 1, m = modint(*this);
		while (b) {
			if (b & 1) ans *= m;
			m *= m;
			b >>= 1;
		}
		return ans;
	}
};

#endif // CLASS_MODINT

#ifndef CLASS_POLYNOMIAL_NTT
#define CLASS_POLYNOMIAL_NTT

#include <vector>
#include <algorithm>

template<std::uint32_t mod, std::uint32_t depth, std::uint32_t primroot>
class polynomial_ntt {
public:
	using modulo = modint<mod>;
	static void fourier_transform(std::vector<modulo> &v, bool inverse) {
		std::size_t s = v.size();
		for (std::size_t i = 0, j = 1; j < s - 1; ++j) {
			for (std::size_t k = s >> 1; k > (i ^= k); k >>= 1);
			if (i < j) std::swap(v[i], v[j]);
		}
		std::size_t sc = 0, sz = 1;
		while (sz < s) sz *= 2, ++sc;
		modulo root = modulo(primroot).pow((mod - 1) >> sc);
		std::vector<modulo> pw(s + 1); pw[0] = 1;
		for (std::size_t i = 1; i <= s; i++) pw[i] = pw[i - 1] * root;
		std::size_t qs = s;
		for (std::size_t b = 1; b < s; b <<= 1) {
			qs >>= 1;
			for (std::size_t i = 0; i < s; i += b * 2) {
				for (std::size_t j = i; j < i + b; ++j) {
					modulo delta = pw[(inverse ? b * 2 - j + i : j - i) * qs] * v[j + b];
					v[j + b] = v[j] - delta;
					v[j] += delta;
				}
			}
		}
		if (!inverse) return;
		modulo powinv = modulo((mod + 1) / 2).pow(sc);
		for (std::size_t i = 0; i < s; ++i) {
			v[i] = v[i] * powinv;
		}
	}
	static std::vector<modulo> convolve(std::vector<modulo> v1, std::vector<modulo> v2) {
		if(v1.empty() || v2.empty()) {
			return std::vector<modulo>();
		}
		if(v1.size() < v2.size()) {
			swap(v1, v2);
		}
		std::size_t fsize = v1.size() + v2.size() - 1;
		std::size_t step = v2.size();
		while(step & (step - 1)) {
			step += step & (-step); // step to become minimum 2^k >= v2.size()
		}
		v1.resize((v1.size() + step - 1) / step * step); // change v1.size() to multiple of step
		v2.resize(step * 2);
		std::vector<modulo> ans(fsize);
		std::vector<modulo> pv1(step * 2);
		fourier_transform(v2, false);
		for(std::size_t i = 0; i < v1.size(); i += step) {
			std::copy(v1.begin() + i, v1.begin() + i + step, pv1.begin());
			std::fill(pv1.begin() + step, pv1.end(), modulo(0));
			fourier_transform(pv1, false);
			for(std::size_t j = 0; j < step * 2; ++j) {
				pv1[j] *= v2[j];
			}
			fourier_transform(pv1, true);
			for(std::size_t j = 0; j < step * 2 && i + j < fsize; ++j) {
				ans[j + i] += pv1[j];
			}
		}
		return ans;
	}
};

#endif // CLASS_POLYNOMIAL_NTT

#ifndef CLASS_BASICINT
#define CLASS_BASICINT

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

template<std::uint32_t base>
class basic_int {
	// 2 <= base < max(base_type)^(2/3) = 2,642,245
protected:
	using base_type = std::uint32_t; // base type
	using base_type_d = std::uint64_t; // double of base type
	std::size_t capacity;
	std::vector<base_type> digit;
	void resize(std::size_t capacity_) {
		if (capacity != capacity_) {
			assert(capacity_ >= 1);
			capacity = capacity_;
			digit.resize(capacity_);
		}
	}
	void minimize() {
		std::size_t d = digits();
		while (d & (d - 1)) {
			d += d & (-d);
		}
		resize(d);
	}
	std::size_t digits() const {
		for (std::size_t i = capacity - 1; i >= 1; --i) {
			if (digit[i] != 0) {
				return i + 1;
			}
		}
		return 1;
	}
public:
	// ----- #1. Costructors ----- //
	explicit basic_int() : capacity(1), digit(1, base_type(0)) {};
	explicit basic_int(std::vector<base_type> digit_) : digit(digit_) {
		assert(!digit.empty());
		for (base_type i : digit) {
			assert(0 <= i && i < base);
		}
		capacity = 1;
		while (capacity < digit.size()) {
			capacity <<= 1;
		}
		digit.resize(capacity, 0);
	};

	// ----- #2. Comparing Operators ----- //
	bool operator==(const basic_int& b) const noexcept {
		return digit == b.digit;
	}
	bool operator!=(const basic_int& b) const noexcept {
		return digit != b.digit;
	}
	bool operator<(const basic_int& b) const noexcept {
		if (capacity != b.capacity) {
			return capacity < b.capacity;
		}
		for (std::size_t i = capacity - 1; i >= 1; --i) {
			if (digit[i] != b.digit[i]) {
				return digit[i] < b.digit[i];
			}
		}
		return digit[0] < b.digit[0];
	}
	bool operator>(const basic_int& b) const noexcept {
		if (capacity != b.capacity) {
			return capacity > b.capacity;
		}
		for (std::size_t i = capacity - 1; i >= 1; --i) {
			if (digit[i] != b.digit[i]) {
				return digit[i] > b.digit[i];
			}
		}
		return digit[0] > b.digit[0];
	}
	bool operator<=(const basic_int& b) const noexcept {
		return basic_int(*this) < b || basic_int(*this) == b;
	}
	bool operator>=(const basic_int& b) const noexcept {
		return basic_int(*this) > b || basic_int(*this) == b;
	}

	// ----- #3. Shifting ----- //
	basic_int& operator<<=(std::size_t s) noexcept {
		std::size_t d = digits();
		if (d + s > capacity) {
			std::size_t nxtcap = d + s;
			while (nxtcap & (nxtcap - 1)) {
				nxtcap += nxtcap & (-nxtcap);
			}
			resize(nxtcap);
		}
		for (std::size_t i = d - 1; i != std::size_t(-1); --i) {
			digit[i + s] = digit[i];
		}
		std::fill(digit.begin(), digit.begin() + s, 0);
		return *this;
	}
	basic_int& operator>>=(std::size_t s) noexcept {
		std::size_t d = digits();
		if (d <= s) {
			(*this) = basic_int();
		}
		else {
			for (std::size_t i = 0; i < d - s; ++i) {
				digit[i] = digit[i + s];
			}
			std::fill(digit.begin() + d - s, digit.begin() + d, 0);
			minimize();
		}
		return *this;
	}

	// ----- #4. Addition ----- //
	basic_int& operator+=(const basic_int& b) {
		resize(std::max(capacity, b.capacity));
		bool carry = false;
		for (std::uint32_t i = 0; i < b.capacity; ++i) {
			digit[i] += b.digit[i] + (carry ? 1 : 0);
			carry = (digit[i] >= base);
			if (carry) digit[i] -= base;
		}
		for (std::uint32_t i = b.capacity; i < capacity; ++i) {
			digit[i] += (carry ? 1 : 0);
			carry = (digit[i] >= base);
			if (carry) digit[i] -= base;
		}
		if (carry) {
			resize(capacity << 1);
			digit[capacity >> 1] = 1;
		}
		return *this;
	}

	// ----- #5. Subtraction ----- //
	basic_int& operator-=(const basic_int& b) {
		bool carry = false;
		for (std::uint32_t i = 0; i < b.capacity; ++i) {
			digit[i] += base - b.digit[i] - (carry ? 1 : 0);
			carry = (digit[i] < base);
			if (!carry) digit[i] -= base;
		}
		for (std::uint32_t i = b.capacity; i < capacity; ++i) {
			digit[i] += base - (carry ? 1 : 0);
			carry = (digit[i] < base);
			if (!carry) digit[i] -= base;
		}
		// assert(!carry) // noexcept
		minimize();
		return *this;
	}

	// ----- #6. Multiplication ----- //
	basic_int& operator*=(const basic_int& b) {
		using ntt1 = polynomial_ntt<2013265921, 27, 31>;
		using ntt2 = polynomial_ntt<1811939329, 26, 13>;
		const ntt2::modulo magic_mult = ntt2::modulo(ntt1::modulo::get_mod()).inv();
		std::size_t nxtcap = std::max(capacity, b.capacity) * 2;
		std::vector<ntt1::modulo> nxtdigit1 = ntt1::convolve(std::vector<ntt1::modulo>(digit.begin(), digit.end()), std::vector<ntt1::modulo>(b.digit.begin(), b.digit.end())); nxtdigit1.resize(nxtcap);
		std::vector<ntt2::modulo> nxtdigit2 = ntt2::convolve(std::vector<ntt2::modulo>(digit.begin(), digit.end()), std::vector<ntt2::modulo>(b.digit.begin(), b.digit.end())); nxtdigit2.resize(nxtcap);
		capacity = nxtcap;
		digit = std::vector<std::uint32_t>(capacity, 0);
		std::uint64_t carry = 0;
		for (std::uint32_t i = 0; i < capacity; ++i) {
			std::uint64_t nxtdigit = std::uint64_t(ntt1::modulo::get_mod()) * ((nxtdigit2[i] - nxtdigit1[i].get()) * magic_mult).get() + nxtdigit1[i].get();
			nxtdigit += carry;
			carry = nxtdigit / base;
			digit[i] = nxtdigit - carry * base;
		}
		minimize();
		return *this;
	}

	// ----- #7. Division ----- //
	basic_int& operator/=(const basic_int& b) {
		assert(b != basic_int());
		if ((*this) < b) {
			(*this) = basic_int();
		}
		else {
			std::size_t digit_a = digits();
			std::size_t digit_b = b.digits();
			std::size_t req_precis = digit_a - digit_b + 2;
			std::size_t set_precis = 1;
			while (set_precis < req_precis) set_precis <<= 1;
			// Find the inverse!
			std::uint64_t gen = (digit_b == 1 ? std::uint64_t(b.digit[0]) * base : std::uint64_t(b.digit[digit_b - 1]) * base + b.digit[digit_b - 2]);
			std::uint64_t gen_inv = std::uint64_t(base) * base * base / (gen + 1);
			std::size_t current_precis = 2;
			basic_int inv({ std::uint32_t(gen_inv % base), std::uint32_t(gen_inv / base) });
			while (current_precis < set_precis) {
				std::size_t digit_nb = std::min(digit_b, current_precis * 2);
				basic_int nb = (digit_b == digit_nb ? b : b >> (digit_b - digit_nb));
				inv = (((basic_int({ 2 }) << (current_precis + digit_nb - 1)) - inv * nb - basic_int({ 1 })) * inv) >> (digit_nb - 1);
				current_precis *= 2;
			}
			while (true) {
				basic_int next_inv = (((basic_int({ 2 }) << (current_precis + digit_b - 1)) - inv * b - basic_int({ 1 })) * inv) >> (set_precis + digit_b - 1);
				if (inv == next_inv) break;
				inv = next_inv;
			}
			basic_int val = (basic_int(*this) * inv) >> (set_precis + digit_b - 1);
			while (b * (val + basic_int({ 1 })) <= (*this)) {
				val += basic_int({ 1 });
			}
			(*this) = val;
		}
		return *this;
	}

	// ----- #8. Operators ----- //
	basic_int operator<<(std::size_t s) const { return basic_int(*this) <<= s; }
	basic_int operator>>(std::size_t s) const { return basic_int(*this) >>= s; }
	basic_int operator+(const basic_int& b) const { return basic_int(*this) += b; }
	basic_int operator-(const basic_int& b) const { return basic_int(*this) -= b; }
	basic_int operator*(const basic_int& b) const { return basic_int(*this) *= b; }
	basic_int operator/(const basic_int& b) const { return basic_int(*this) /= b; }
};

#endif // CLASS_BASICINT

#ifndef CLASS_BIGINT
#define CLASS_BIGINT

#include <string>
#include <iostream>

// (digit / base_digit) * base_number^2 <= 1811939329 * 2013265921 = 3647915701995307009
// (digit / base_digit) < min(2^27, 2^26) = 67108864
// ---> max_digit = min(1823957850, 335544320) = 335544320

constexpr std::size_t base_digit = 5;
constexpr std::uint32_t base_number = 100000;

class bigint : private basic_int<base_number> {
private:
	bool sign; // positive/zero = false, negative = true
	bool is_number(std::string str) {
		if(str.empty() || str == "-" || !(('0' <= str[0] && str[0] <= '9') || str[0] == '-')) {
			return false;
		}
		for(std::uint64_t i = 1; i < str.size(); ++i) {
			if(!('0' <= str[i] && str[i] <= '9')) {
				return false;
			}
		}
		return true;
	}
	std::vector<std::uint32_t> to_basic_expression(std::uint64_t x) {
		std::vector<std::uint32_t> res;
		do {
			res.push_back(x % base_number);
			x /= base_number;
		} while(x != 0);
		return res;
	}
public:
	// ----- #1. Constructors / String Functions ----- //
	bigint() : basic_int(), sign(false) {};
	bigint(std::int64_t x) : basic_int(to_basic_expression(x >= 0 ? x : -x)), sign(x < 0) {};
	bigint(const std::string& str) {
		assert(is_number(str));
		sign = (str[0] == '-');
		std::size_t initial = (sign ? 1 : 0);
		while(initial + 1 != str.size() && str[initial] == '0') {
			++initial;
		}
		std::size_t str_digits = str.size() - initial;
		capacity = 1;
		while(capacity * base_digit < str_digits) {
			capacity *= 2;
		}
		digit = std::vector<std::uint32_t>(capacity, 0);
		for(std::size_t i = 0; (i + 1) * base_digit < str_digits; ++i) {
			digit[i] = std::stoi(str.substr(str.size() - i * base_digit - base_digit, base_digit));
		}
		digit[(str_digits - 1) / base_digit] = std::stoi(str.substr(initial, (str.size() - (str_digits - 1) / base_digit * base_digit) - initial));
	}
	std::string to_string() const {
		std::size_t d = digits();
		std::string res = (sign ? "-" : "") + std::to_string(digit[d - 1]);
		for(std::size_t i = d - 2; i != std::size_t(-1); --i) {
			std::string digit_str = std::to_string(digit[i]);
			res += std::string(base_digit - digit_str.size(), '0') + digit_str;
		}
		return res;
	}

	// ----- #2. Operators ----- //
	bool operator==(const bigint& b) const noexcept { return sign == b.sign && basic_int::operator==(b); }
	bool operator!=(const bigint& b) const noexcept { return sign != b.sign || basic_int::operator!=(b); }
	bool operator<(const bigint& b) const noexcept { return sign != b.sign ? sign : basic_int::operator<(b); }
	bool operator>(const bigint& b) const noexcept { return sign != b.sign ? !sign : basic_int::operator>(b); }
	bool operator<=(const bigint& b) const noexcept { return sign != b.sign ? sign : basic_int::operator<=(b); }
	bool operator>=(const bigint& b) const noexcept { return sign != b.sign ? !sign : basic_int::operator>=(b); }
	bigint& operator+=(const bigint& b) {
		if(sign == b.sign) {
			basic_int::operator+=(b);
		}
		else if(basic_int(*this) >= basic_int(b)) {
			basic_int::operator-=(b);
			if(sign && basic_int(*this) == basic_int()) sign = false;
		}
		else {
			sign = !sign;
			(*this) = b - (*this);
		}
		return *this;
	}
	bigint& operator-=(const bigint& b) {
		if(sign != b.sign) {
			basic_int::operator+=(b);
		}
		else if(basic_int(*this) >= basic_int(b)) {
			basic_int::operator-=(b);
			if(sign && basic_int(*this) == basic_int()) sign = false;
		}
		else {
			sign = !sign;
			(*this) += b;
			sign = !sign;
		}
		return *this;
	}
	bigint& operator*=(const bigint& b) {
		basic_int::operator*=(b);
		if(b.sign) sign = !sign;
		if(sign && basic_int(*this) == basic_int()) sign = false;
		return *this;
	}
	bigint& operator/=(const bigint& b) {
		basic_int::operator/=(b);
		if(b.sign) sign = !sign;
		if(sign && basic_int(*this) == basic_int()) sign = false;
		return *this;
	}
	bigint operator%=(const bigint& b) {
		bigint itself(*this);
		(*this) = itself - itself / b * b;
		return *this;
	}
	bigint operator+(const bigint& b) const { return bigint(*this) += b; }
	bigint operator-(const bigint& b) const { return bigint(*this) -= b; }
	bigint operator*(const bigint& b) const { return bigint(*this) *= b; }
	bigint operator/(const bigint& b) const { return bigint(*this) /= b; }
	bigint operator%(const bigint& b) const { return bigint(*this) %= b; }
	friend std::istream& operator>>(std::istream& is, bigint& x) { std::string s; is >> s; x = bigint(s); return is; }
	friend std::ostream& operator<<(std::ostream& os, const bigint& x) { os << x.to_string(); return os; }
};

#endif // CLASS_BIGINT

#include <iostream>
using namespace std;
int main() {
	bigint a, b;
	cin >> a >> b;
	cout << a % b << endl;
	return 0;
}


Measured memory_bytes: 3352