using System;
using System.Collections.Generic;
using System.Linq;
class Program
{
static string InputPattern = "InputX";
static List<string> GetInputList()
{
var WillReturn = new List<string>();
if (InputPattern == "Input1") {
WillReturn.Add("11 2");
//3
}
else if (InputPattern == "Input2") {
WillReturn.Add("0 4");
//4
}
else if (InputPattern == "Input3") {
WillReturn.Add("112 20210213");
//20210436
}
else if (InputPattern == "Input4") {
WillReturn.Add("-211 1000000000000000000");
//1000000000000000422
}
else {
string wkStr;
while ((wkStr = Console.ReadLine()) != null) WillReturn.Add(wkStr);
}
return WillReturn;
}
static void Main()
{
List<string> InputList = GetInputList();
long[] wkArr = InputList[0].Split(' ').Select(pX => long.Parse(pX)).ToArray();
long B = wkArr[0];
long C = wkArr[1];
long Result = Solve(B, C);
Console.WriteLine(Result);
}
static void Debugger()
{
//long Result1 = Solve(-2, 4);
//long Result2 = SolveDFS(-2, 4);
//if (Result1 != Result2) {
// Console.WriteLine("■■■差異あり■■■");
// Console.WriteLine("Solve={0}", Result1);
// Console.WriteLine("SolveDFS={0}", Result2);
//}
var InsRandom = new Random();
for (int I = 1; I <= 30; I++) {
long RandB = InsRandom.Next(-99, 99);
long RandC = InsRandom.Next(5, 100);
long Result1 = Solve(RandB, RandC);
long Result2 = SolveDFS(RandB, RandC);
if (Result1 != Result2) {
Console.WriteLine("差異あり");
Console.WriteLine("B={0},C={1}", RandB, RandC);
Console.WriteLine("Solve={0}", Result1);
Console.WriteLine("SolveDFS={0}", Result2);
}
}
}
static long Solve(long pB, long pC)
{
// コーナーケース回避で、Cが100以下だったら、DFSで解く
if (pC <= 100) {
return SolveDFS(pB, pC);
}
// 場合1 Bが0以上の場合
if (pB >= 0) {
return SolvePlus(pB, pC);
}
// 場合2 Bが負の場合
return SolveMinus(pB, pC);
}
// 閉区間の定義
class RangeInfoDef
{
internal long Sta;
internal long End;
}
// Bが正の場合
static long SolvePlus(long pB, long pC)
{
var RangeInfoList = new List<RangeInfoDef>();
// 閉区間1 ひたすら1を引く
RangeInfoDef Range1 = new RangeInfoDef();
Range1.Sta = pB;
Range1.End = pB - pC / 2;
RangeInfoList.Add(Range1);
// 閉区間2 閉区間1の-1倍で到達可能な数値の区間
RangeInfoDef Range2 = new RangeInfoDef();
Range2.Sta = Range1.Sta;
Range2.End = Range1.End;
long RestC = pC % 2;
if (RestC == 0) {
Range2.End++;
}
Range2.Sta *= -1;
Range2.End *= -1;
RangeInfoList.Add(Range2);
// 閉区間3 -1倍してから、ひたすら1を引く
RangeInfoDef Range3 = new RangeInfoDef();
Range3.Sta = -pB;
Range3.End = -pB - (pC - 1) / 2;
RangeInfoList.Add(Range3);
// 閉区間4 閉区間3の-1倍で到達可能な数値の区間
RangeInfoDef Range4 = new RangeInfoDef();
Range4.Sta = Range3.Sta;
Range4.End = Range3.End;
RestC = (pC - 1) % 2;
if (RestC == 0) {
Range4.End++;
}
Range4.Sta *= -1;
Range4.End *= -1;
RangeInfoList.Add(Range4);
return DeriveUniqNumCnt(RangeInfoList);
}
// Bが負の場合
static long SolveMinus(long pB, long pC)
{
var RangeInfoList = new List<RangeInfoDef>();
// 閉区間1 ひたすら1を引く
RangeInfoDef Range1 = new RangeInfoDef();
Range1.Sta = pB;
Range1.End = pB - pC / 2;
RangeInfoList.Add(Range1);
// 閉区間2 閉区間1に-1倍で到達可能な数値の区間
RangeInfoDef Range2 = new RangeInfoDef();
Range2.Sta = Range1.Sta;
Range2.End = Range1.End;
long RestC = pC % 2;
if (RestC == 0) {
Range2.End++;
}
Range2.Sta *= -1;
Range2.End *= -1;
RangeInfoList.Add(Range2);
// 閉区間3 -1倍してから、ひたすら1を引く
RangeInfoDef Range3 = new RangeInfoDef();
Range3.Sta = -pB;
Range3.End = -pB - (pC - 1) / 2;
RangeInfoList.Add(Range3);
// 閉区間4 閉区間3の-1倍で到達可能な数値の区間
RangeInfoDef Range4 = new RangeInfoDef();
Range4.Sta = Range3.Sta;
Range4.End = Range3.End;
RestC = (pC - 1) % 2;
if (RestC == 0) {
Range4.End++;
}
Range4.Sta *= -1;
Range4.End *= -1;
RangeInfoList.Add(Range4);
return DeriveUniqNumCnt(RangeInfoList);
}
// 閉区間のListを引数として、何通りの数があるかを返す
static long DeriveUniqNumCnt(List<RangeInfoDef> pRangeInfoList)
{
// 開始 <= 終了 にする
for (int I = 0; I <= pRangeInfoList.Count - 1; I++) {
long Sta = pRangeInfoList[I].Sta;
long End = pRangeInfoList[I].End;
if (Sta > End) {
pRangeInfoList[I].Sta = End;
pRangeInfoList[I].End = Sta;
}
}
//Console.WriteLine("マージ前の区間");
//foreach (RangeInfoDef EachRangeInfo in pRangeInfoList) {
// Console.WriteLine("区間開始{0} 区間終了{1}", EachRangeInfo.Sta, EachRangeInfo.End);
//}
for (int I = pRangeInfoList.Count - 1; 1 <= I; I--) {
long CurrSta = pRangeInfoList[I].Sta;
long CurrEnd = pRangeInfoList[I].End;
for (int J = I - 1; 0 <= J; J--) {
long PrevSta = pRangeInfoList[J].Sta;
long PrevEnd = pRangeInfoList[J].End;
// OverLapしてたら、マージしてから、Remove
if (PrevSta <= CurrEnd && CurrSta <= PrevEnd) {
pRangeInfoList[J].Sta = Math.Min(CurrSta, PrevSta);
pRangeInfoList[J].End = Math.Max(CurrEnd, PrevEnd);
pRangeInfoList.RemoveAt(I);
break;
}
}
}
//Console.WriteLine("マージ後の区間");
//foreach (RangeInfoDef EachRangeInfo in pRangeInfoList) {
// Console.WriteLine("区間開始{0} 区間終了{1}", EachRangeInfo.Sta, EachRangeInfo.End);
//}
return pRangeInfoList.Sum(pX => pX.End - pX.Sta + 1);
}
struct JyoutaiDef
{
internal long CurrPos;
internal long RevCnt;
internal long Cost;
}
static long SolveDFS(long pB, long pC)
{
var Stk = new Stack<JyoutaiDef>();
JyoutaiDef WillPush;
WillPush.CurrPos = pB;
WillPush.RevCnt = 0;
WillPush.Cost = 0;
Stk.Push(WillPush);
var MinCostDict = new Dictionary<long, long>();
MinCostDict[pB] = 0;
while (Stk.Count > 0) {
JyoutaiDef Popped = Stk.Pop();
var PushKouhoList = new List<JyoutaiDef>();
// -1倍する場合
if (Popped.RevCnt < 3) {
WillPush.CurrPos = Popped.CurrPos * (-1);
WillPush.RevCnt = Popped.RevCnt + 1;
WillPush.Cost = Popped.Cost + 1;
PushKouhoList.Add(WillPush);
}
// -1する場合
WillPush.CurrPos = Popped.CurrPos - 1;
WillPush.RevCnt = Popped.RevCnt;
WillPush.Cost = Popped.Cost + 2;
PushKouhoList.Add(WillPush);
foreach (JyoutaiDef EachPushKouho in PushKouhoList) {
if (EachPushKouho.Cost > pC) continue;
if (MinCostDict.ContainsKey(EachPushKouho.CurrPos)) {
if (MinCostDict[EachPushKouho.CurrPos] <= EachPushKouho.Cost) {
continue;
}
}
MinCostDict[EachPushKouho.CurrPos] = EachPushKouho.Cost;
Stk.Push(EachPushKouho);
}
}
//foreach (var EachPair in MinCostDict) {
// Console.WriteLine("MinCostDict[{0}]={1}", EachPair.Key, EachPair.Value);
//}
return MinCostDict.Count;
}
}