#include <bits/stdc++.h>

using namespace std;

struct Initializer {
  Initializer() {
    cin.tie(0);
    ios::sync_with_stdio(0);
    cout << fixed << setprecision(15);
  }
} initializer;

template<typename Edge> class Graph {
public:
  using EdgeType = Edge;
  virtual int size() const = 0;
  template<typename... Args> void addEdge(int from, int to, Args...) {}
  template<typename... Args> void addUndirectedEdge(int from, int to, Args...) {}

  vector<pair<int, Edge>> getAllEdges() const {
    vector<pair<int, Edge>> res;
    for (int i = 0; i < size(); ++i) {
      for (const auto& edge : getEdges(i)) {
        res.emplace_back(i, edge);
      }
    }
    return res;
  }

  virtual vector<Edge> getEdges(int from) const = 0;
  virtual vector<Edge> getEdges(int from, int to) const = 0;
  virtual int getDegree(int v) const = 0;

  vector<int> getIndegree() const {
    vector<int> degree(size());
    for (const auto& edge : getAllEdges()) ++degree[edge.second.to];
    return degree;
  }
};

template<typename Edge> class AdjacencyList : public Graph<Edge> {
protected:
  vector<vector<Edge>> graph;

public:
  AdjacencyList(int n) : graph(n) {}

  int size() const {
    return graph.size();
  }
  
  template<typename... Args> void addEdge(int from, int to, Args... args) {
    graph[from].emplace_back(to, args...);
  }

  template<typename... Args> void addUndirectedEdge(int from, int to, Args... args) {
    addEdge(from, to, args...);
    addEdge(to, from, args...);
  }

  vector<Edge> getEdges(int from) const {
    return graph[from];
  }

  vector<Edge> getEdges(int from, int to) const {
    vector<Edge> res;
    for (const auto& edge : graph[from]) {
      if (edge.to == to) res.emplace_back(edge);
    }
    return res;
  }

  int getDegree(int v) const {
    return graph[v].size();
  }

  vector<Edge>& operator[](int v) {
    return graph[v];
  }
};

struct Edge {
  using CostType = int;
  const static int cost = 1;
  int to;
  Edge(int to) : to(to) {};
};

template<typename Cost> struct WeightedEdge : public Edge {
  using CostType = Cost;
  Cost cost;
  WeightedEdge(int to, Cost cost = 0) : Edge(to), cost(cost) {}
};

template<typename Capacity> struct ResidualEdge : public Edge {
  using CapacityType = Capacity;
  Capacity cap;
  int rev;
  ResidualEdge(int to, Capacity cap) : Edge(to), cap(cap) {}
  ResidualEdge reverse(int from) const {return ResidualEdge(from, 0);}
};

template<typename Capacity, typename Cost> struct WeightedResidualEdge : public ResidualEdge<Capacity> {
  Cost cost;
  WeightedResidualEdge(int to, Capacity cap, Cost cost) : ResidualEdge<Capacity>(to, cap), cost(cost) {}
  WeightedResidualEdge reverse(int from) const {return WeightedResidualEdge(from, 0, -cost);}
};

template<typename Graph, typename State> class Search {
protected:
  using Edge = typename Graph::EdgeType;

  const Graph graph;
  vector<bool> visited;

  virtual void push(const State&) = 0;
  virtual State next() = 0;
  virtual bool isRunning() = 0;

  virtual void visit(const State&) {}

public:
  Search(const Graph& graph) : graph(graph), visited(graph.size(), false) {}

  void solve(vector<int> from) {
    for (int i : from) push(State(i));
    while (isRunning()) {
      State now = next();
      int pos = now.getPos();
      if (visited[pos]) continue;
      visited[pos] = true;
      visit(now);
      for (const Edge& edge : graph.getEdges(pos)) {
        State nextState = now.next(pos, edge);
        if (visited[nextState.getPos()]) continue;
        push(nextState);
      }
    }
  }

  void solve(int from) {solve(vector<int>({from}));}

  bool isReachable(int v) {return visited[v];}
};

template<typename Edge> class Tree {
public:
  vector<Edge> parent;
  vector<vector<int>> children;
  vector<int> depth;

  Tree() {}

  Tree(int n) : children(n), depth(n, -1) {
    for (int i = 0; i < n; ++i) parent.emplace_back(i);
  }

  int size() const {
    return parent.size();
  }
  
  template<typename... Args> void addEdge(int from, int to, Args... args) {
    parent[from] = Edge(to, args...);
    children[to].emplace_back(from);
  }

  void addEdge(int from, const Edge& edge) {
    parent[from] = edge;
    children[edge.to].emplace_back(from);
  }

  int getDepth(int v) {
    if (depth[v] != -1) return depth[v];
    if (parent[v].to == v) return depth[v] = 0;
    return depth[v] = getDepth(parent[v].to) + 1;
  }

  vector<int> getPath(int v) {
    vector<int> res{v};
    while (v != parent[v].to) {
      v = parent[v].to;
      res.emplace_back(v);
    }
    return res;
  }
};

template<typename Edge> struct DijkstraState {
  using Cost = typename Edge::CostType;

  int from;
  Edge edge;
  Cost cost;

  DijkstraState(const int pos) : from(pos), edge(pos), cost(0) {}

  DijkstraState(const int from, const Edge& edge, const Cost cost) : from(from), edge(edge), cost(cost) {}

  DijkstraState next(const int from, const Edge& edge) const {return DijkstraState(from, edge, cost + edge.cost);}

  bool operator<(const DijkstraState& state) const {return cost > state.cost;}

  int getPos() const {return edge.to;}
};

template<typename Graph, bool Restoration = false, typename State = DijkstraState<typename Graph::EdgeType>> class Dijkstra : public Search<Graph, State> {
protected:
  using Edge = typename Graph::EdgeType;
  using Cost = typename Edge::CostType;

  constexpr static Cost INF = numeric_limits<Cost>::max();

  priority_queue<State> que;

  void push(const State& state) {
    if (dis[state.getPos()] <= state.cost) return;
    que.push(state);
    dis[state.getPos()] = state.cost;
  }

  State next() {
    State now = que.top();
    que.pop();
    return now;
  }

  bool isRunning() {return !que.empty();}

  void visit(const State& state) {
    if (Restoration) {
      int from = state.from, to = state.edge.to;
      if (from != to) {
        auto e = state.edge;
        e.to = from;
        shortestPathTree.addEdge(to, e);
      }
    }
  }

public:
  vector<Cost> dis;
  Tree<Edge> shortestPathTree;

  Dijkstra(const Graph& graph) : Search<Graph, State>(graph), dis(graph.size(), INF) {
    if (Restoration) shortestPathTree = Tree<Edge>(graph.size());
  }
};

template<typename Graph> Dijkstra<Graph> shortestPath(Graph& graph, int from) {
  Dijkstra<Graph> dijkstra(graph);
  dijkstra.solve(from);
  return dijkstra;
}

template<typename Graph> typename Graph::EdgeType::CostType shortestPath(Graph& graph, int from, int to) {
  return shortestPath(graph, from).dis[to];
}

template<typename Graph> Dijkstra<Graph, true> shortestPathTree(Graph& graph, int from) {
  Dijkstra<Graph, true> dijkstra(graph);
  dijkstra.solve(from);
  return dijkstra;
}

int main() {
  int x, y;
  cin >> x >> y;
  AdjacencyList<WeightedEdge<int>> g(4);
  g.addUndirectedEdge(0, 1, 1);
  g.addUndirectedEdge(2, 3, 1);
  int v[] = {abs(x), -abs(x), abs(y), -abs(y)};
  for (int i = 0; i < 4; ++i) {
    for (int j = 0; j < 4; ++j) {
      if (v[i] <= v[j]) g.addEdge(i, j, v[j] - v[i]);
    }
  }
  cout << shortestPath(g, x > 0 ? 0 : 1, y > 0 ? 2 : 3) << endl;
}


Measured memory_bytes: 256