class Puzzle
  attr_accessor :s, :cou, :direction
  def initialize(s, direction, cou=-1)
    @s = s
    @cou = cou
    @direction = direction
  end

  def calc
    nums = @s.dup
    @s.each_with_index do |x, i_x|
      @s[i_x..-1].each_with_index do |y, i_y|
        nums[i_x + i_y] -= 1 if y > x
      end
    end
    number = 0
    nums.each_with_index do |x, i_x|
      factorial = (nums.size - 1 - i_x).downto(1).inject(:*)
      number += factorial * x if factorial != nil
    end
    return number
  end

  def zero
    return @s.index(0)
  end
end

class Dic
  attr_reader :visit, :cou
  def initialize(num)
    @visit = Array.new(num, 1)
    @cou = Array.new(num, 0)
  end
  def visited?(id, direction)
    return @visit[id] != 1 && @visit[id] % direction == 0
  end
  def visit(puzzle)
    id = puzzle.calc
    direction = puzzle.direction
    cou = puzzle.cou
    @visit[id] *= direction
    @cou[id] += cou
  end

  def get(puzzle)
    return cou[puzzle.calc]
  end
end

move = [[1, 3],
        [0, 2, 4],
        [1, 5],
        [0, 4, 6],
        [1, 3, 5, 7],
        [2, 4, 8],
        [3, 7],
        [4, 6, 8],
        [5, 7]]

col = [1, 2, 3, 4, 5, 6, 7, 8, 0]

f = 2
b = 3

# main
init_s = []
3.times do
  init_s.concat(gets.chomp.split.map(&:to_i))
end

queue = []
init = Puzzle.new(init_s, f, 0)
goal = Puzzle.new(col, b, 0)
queue << init
queue << goal

dict = Dic.new(9.downto(1).inject(:*))
dict.visit(init)
dict.visit(goal)

while queue.size > 0 do
  puzzle = queue.shift
  id = puzzle.calc
  if dict.visited?(id, f) && dict.visited?(id, b) then
    puts dict.cou[id]
    break
  end

  zero = puzzle.zero
  swap = move[zero]

  swap.each{|swap_pos|
    new = Puzzle.new(puzzle.s.dup,puzzle.direction,puzzle.cou+1)
    new.s[zero], new.s[swap_pos] = new.s[swap_pos], new.s[zero]
    next if dict.visited?(new.calc, new.direction)
    queue << new
    dict.visit(new)
  }
end
