import std.stdio;
import std.conv;
import std.algorithm;
import std.range;
import std.string;
import std.typecons;
import std.math;
import std.random;
import std.range;
import std.functional;
import std.container;
struct Puzzle
{
    int[9] panel;
    size_t toHash() const @safe pure nothrow
    {
        size_t hash = 0;
        foreach (i; panel)
        {
            hash *= 10;
            hash += i;
        }
        return hash;
    }
    bool opEquals(ref const Puzzle s) const @safe pure nothrow
    {
        return equal(panel[0..$], s.panel[0..$]);
    }
    int c;
}
int[] dx = [-1, 0, 1, 0];
int[] dy = [0, -1, 0, 1];
void main()
{
    bool[Puzzle] set;
    auto queue = DList!Puzzle();
    Puzzle initial;
    foreach (i; 0..9)
    {
        scanf("%d", &initial.panel[i]);
    }
    set[initial] = true;
    queue.insertBack(initial);
    while (!queue.empty)
    {
        auto u = queue.front;
        queue.removeFront;
        if (u.panel[0..$].equal([1, 2, 3, 4, 5, 6, 7, 8, 0]))
        {
            writeln(u.c);
            break;
        }
        auto sp = u.panel[0..$].countUntil(0);
        auto sx = sp % 3;
        auto sy = sp / 3;
        foreach (r; 0..4)
        {
            auto tx = sx + dx[r];
            auto ty = sy + dy[r];
            if (tx < 0 || tx >= 3 || ty < 0 || ty >= 3)
                continue;
            auto temp = u;
            temp.panel[sp].swap(temp.panel[tx + ty * 3]);
            if (temp !in set)
            {
                set[temp] = true;
                temp.c++;
                queue.insertBack(temp);
            }
        }
    }
}
