#pragma region HEADER #include #include #include #include #include #include #include #include #include using namespace std; // === TYPE & CONST === // using INT128 = __int128_t; using INT = long long int; const INT INF = 1LL << 60LL; using FLOAT = long double; using INT2 = std::array; using INT3 = std::array; using INT4 = std::array; using INT5 = std::array; using INT6 = std::array; using INT7 = std::array; using INT8 = std::array; using FLOAT2 = std::array; using FLOAT3 = std::array; using FLOAT4 = std::array; using FLOAT5 = std::array; // col and row axis enum class DIR4 : INT { DOWN, RIGHT, UP, LEFT }; const INT2 dxdy[4] = { {1,0}, {0,1}, {-1,0}, {0,-1} }; const INT2 dxdy4[4] = { {1,0}, {0,1}, {-1,0}, {0,-1} }; // 8 direction enum class DIR8 : INT { DOWN, RIGHT, UP, LEFT, DR, UR, UL, DL }; const INT2 dxdy8[8] = { {1,0}, {0,1}, {-1,0}, {0,-1}, {1,1}, {-1,1}, {-1,-1}, {1,-1} }; // 4 direction with diagonal enum class DIR4D : INT { DR, UR, UL, DL }; const INT2 ppmm[4] = { {1,1}, {-1,1}, {-1,-1}, {1,-1} }; template< typename T > using vector2d = std::vector< std::vector >; template< typename T > using vector3d = std::vector< vector2d >; template< typename T > using vector4d = std::vector< vector3d >; // SCOPE-BREAK Macro #define SCOPE( STATEMENT ) [&](){ STATEMENT; }(); #define BREAK return; // [0,N) #define REP(i, N) for ( INT i = 0; i < (N); i++ ) #define REP2(i, j, N) for ( INT i = 0; i < (N); i++ ) REP(j, N) #define REP3(i, j, k, N) for ( INT i = 0; i < (N); i++ ) REP2(j, k, N) #define RREP(i, N) for (INT i = ((N)-1LL); i >= 0; i--) // FOR #define FOR(i, str, end) for ( INT i = str; i < end; i++ ) #define RFOR(i, str, end) for ( INT i = end-1LL; i >= str; i-- ) // Combinated For #define COMB_FOR(i, N) for( INT i = 0; i < (N); i++ ) #define COMB_FOR2(i, j, N) COMB_FOR(i, N) for( INT j = i+1LL; j < (N); j++ ) #define COMB_FOR3(i, j, k, N) COMB_FOR2(i, j, N) for( INT k = j+1LL; k < (N); k++ ) // Yes or No void YESNO(bool b){ if(b){cout<<"YES"< bool chmax( T& lhs, const T& rhs){ if( lhs < rhs ){ lhs = rhs; return true; } else { return false; } } template< class T > bool chmin( T& lhs, const T& rhs){ if( lhs > rhs ){ lhs = rhs; return true; } else { return false; } } // modpow | a^n % mod を計算する template< class T > T modpow(T a, T n, T mod) { T res = 1; while (n > 0) { if (n & 1) res = res * a % mod; a = a * a % mod; n >>= 1; } return res; } // 拡張ユークリッドの互除法 template< class T > T gcdExtended(T a, T b, T& x, T& y) { if (a == 0) { x = 0; y = 1; return b; } T x1, y1; // 仮変数 T gcd = gcdExtended(b % a, a, x1, y1); // 更新 x と y x = y1 - (b / a) * x1; y = x1; return gcd; } // 任意のModにおける逆元を求める関数 template< class T > T modinv(T a, T mod) { T x, y; T g = gcdExtended(a, mod, x, y); if (g != 1) { #ifdef __DEBUG__ throw std::invalid_argument("逆元は存在しません。"); #endif return -1; } // m が負の場合を考慮 T res = (x % mod + mod) % mod; return res; } // range_check bool range_check(INT idx, INT N ){ return (0 <= idx) && (idx < N); } bool range_check2d(INT idx1, INT idx2, INT N, INT M){ return (0 <= idx1) && (idx1 < N) && ( 0 <= idx2) && (idx2 < M); } // safe_get template< class T, class T2 > T safe_get ( const std::vector& v, INT idx, T2 def = -1LL ){ return range_check( idx, v.size() ) ? v[idx] : def; } template< class T, class T2 > T safe_get2d ( const vector2d& vv, INT idx1, INT idx2, T2 def = -1LL ){ return range_check( idx1, vv.size() ) ? safe_get( vv[idx1], idx2, def) : def; } // VECTOR array constructors template< typename T > std::vector VECTOR(INT N, const T& INIT_VALUE = T() ){ return std::vector(N, INIT_VALUE); } template< typename T > vector2d VECTOR2D(INT N, INT N2, const T& INIT_VALUE = T() ){ return vector2d(N, VECTOR(N2, INIT_VALUE)); } template< typename T > vector3d VECTOR3D(INT N, INT N2, INT N3, const T& INIT_VALUE = T() ){ return vector3d(N, VECTOR2D(N2, N3, INIT_VALUE) ); } template< typename T > vector4d VECTOR4D(INT N, INT N2, INT N3, INT N4, const T& INIT_VALUE = T() ){ return vector4d(N, VECTOR3D(N2, N3, N4, INIT_VALUE)); } // sort template< typename T > vector& sort_vector_less( vector& v ){ std::sort( RANGE(v), [](auto l, auto r){ return l < r; } ); return v; } template< typename T > vector& sort_vector_greater( vector& v){ std::sort( RANGE(v), [](auto l, auto r){ return l > r; } ); return v; } template< typename T > vector& sort_vector2d_less( vector& v, INT index=0 ){ std::sort( RANGE(v), [index](auto l, auto r){ return l[index] < r[index]; } ); return v; } template< typename T > vector& sort_vector2d_greater( vector& v, INT index=0 ){ std::sort( RANGE(v), [index](auto l, auto r){ return l[index] > r[index]; } ); return v; } // === cin >> vector/array === // template< class T, std::size_t N> std::istream& operator>> ( std::istream& lhs, std::array& rhs){ for( auto& elem: rhs ){ lhs >> elem; } return lhs; } template< class T > std::istream& operator>> ( std::istream& lhs, std::vector& rhs){ for( auto& elem: rhs ){ lhs >> elem; } return lhs; } template< class T, std::size_t N> std::istream& operator>> ( std::istream& lhs, std::vector>& rhs){ for( auto& elem: rhs ){ lhs >> elem; } return lhs; } template< class T > std::istream& operator>> ( std::istream& lhs, std::vector>& rhs){ for( auto& elem: rhs ){ lhs >> elem; } return lhs; } // ======================== DEBUG ======================== // const int __SETW__ = 5; #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wunused-variable" #pragma GCC diagnostic ignored "-Wunused-parameter" class DebugOutput : public std::ostream { public: DebugOutput( std::ostream& origin ) : std::ostream( origin.rdbuf() ) {} // to ignore "debug << endl" DebugOutput& operator<< (basic_ostream& (*pf)(basic_ostream&)){ #ifdef __DEBUG__ pf(*this); #endif return *this; } } debug(std::cerr); #ifdef __DEBUG__ # include "debug.hpp" #else template DebugOutput& operator<< ( DebugOutput& lhs, const T& rhs ){ // *(static_cast(&lhs)) << rhs; // NOP // return lhs; } template DebugOutput& operator<< ( DebugOutput& lhs, basic_ostream& endl ){ // *(static_cast(&lhs)) << rhs; // NOP // return lhs; } #define debug(x) #endif #pragma GCC diagnostic pop #pragma endregion HEADER #pragma region OPTIONAL_LIBS // STL =========================== // //#include #include // queue, priority_queue #include // stack #include // map #include // set // #include // #include // #include // #include // #include // #include // #include // #include // #include // #include // std::chrono::system_clock::time_point START_TIME = std::chrono::system_clock::now(); // INT spent_ms = std::chrono::duration_cast(std::chrono::system_clock::now() - START_TIME).count(); // ATCODER LIBRARY =========================== // // https://atcoder.github.io/ac-library/document_ja/index.html // // #include // #include // #include // #include // #include // #include // #include // #include // #include // #include // #include // #include #pragma endregion OPTIONAL_LIBS // =========================== MAIN =========================== // // SNIPETS // LINK : https://www.notion.so/g-domain/C-1b6dbde0ac3949e3b6d44fbaf31f7c03?pvs=4 int main(){ INT i, j; cin >> i >> j; if( i == 0 && j == 0 ){ cout << "0" << endl; } else if( false || abs(i) == abs(j) || i == 0 || j == 0 ){ cout << "1" << endl; } else { cout << "2" << endl; } return 0; }