#include <iostream>
#include <string>
#include <algorithm>
#include <map>
#include <fstream>
#include <queue>
#include <vector>
#include <time.h>
#define PSIZE 3
#define PPSIZE PSIZE * PSIZE
#define NOTMOVED "NOTMOVED"
#define SPACE '0'

using namespace std;

string GOAL = "123456780";
int dist_table[PPSIZE][PPSIZE];

typedef enum Move {
    UP,
    DOWN,
    LEFT,
    RIGHT,
    NOMOVE
} Move;

typedef struct State State;
struct State {
    int depth;
    int dist;
    string puzzle;
    State* parent;
};

struct comp {
    bool operator()(const State* s1, const State* s2) {
        return (s1->depth + s1->dist) > (s2->depth + s2->dist);
    }
};

State* createState(int depth, int dist, string puzzle, State* parent);
int findSpace(string puzzle);
string movePuzzle(string puzzle, Move move);
int mdist(string p1);
void createDistTable();
void printDistTable();
void printPath(State* state);

int solve(string start_puzzle) {
    int dist;
    string moved = "";
    State* curr_state = NULL;
    State* next_state = NULL;

    map<string, int> puzzle_table;
    priority_queue<State*, vector<State*>, comp> pqueue;

    curr_state = createState(0, 0, start_puzzle, NULL);
    pqueue.push(curr_state);
    puzzle_table[start_puzzle] = 0;
    
    while (!pqueue.empty()) {
        curr_state = pqueue.top();
        pqueue.pop();
        
        if (mdist(curr_state->puzzle) == 0) break;
        
        for (int mi = 0; mi <= NOMOVE; mi++) {
            Move move = (Move)mi;
            moved = movePuzzle(curr_state->puzzle, move);
            if (moved == NOTMOVED) continue;
            if (puzzle_table.find(moved) != puzzle_table.end() && puzzle_table[moved] < curr_state->depth+1) continue;
            puzzle_table[moved] = curr_state->depth+1;
            dist = mdist(moved);
            next_state = createState(curr_state->depth+1, dist, moved, curr_state);
            pqueue.push(next_state);
        }
    }
  
    //printPath(curr_state);

    return curr_state->depth;

}

int main() {

    createDistTable();
    //printDistTable();


    int out;
    string line, puzzle;
    for (int i = 0; i < PSIZE; i++) {
        getline(cin, line);
        puzzle += line[0];
        puzzle += line[2];
        puzzle += line[4];
    }

    out = solve(puzzle);

    cout << out << endl;

    return 0;
}

State* createState(int depth, int dist, string puzzle, State* parent) {
    State* state = new State;
    state->depth = depth;
    state->dist = dist;
    state->puzzle = puzzle;
    state->parent = parent;
    return state;
}

int mdist(string p1) {
    int dist = 0;
    int pi;
    for (int i = 0; i < PPSIZE; i++) {
        if (p1[i] == '0') continue;
        pi = p1[i] - '1';
        dist += dist_table[pi][i];
    }
    return dist;
}

int findSpace(string puzzle) {
    size_t found = puzzle.find(SPACE);
    if (found == string::npos) return -1;
    return (int)found;
}

string movePuzzle(string puzzle, Move move) {
    int si = findSpace(puzzle);
    if (si == -1) return NOTMOVED;
   
    string moved = puzzle;
    if (move == UP) {
        if (si < PSIZE) return NOTMOVED;
        swap(moved[si], moved[si-3]);
    } else if (move == DOWN) {
        if (si >= PSIZE*(PSIZE-1)) return NOTMOVED;
        swap(moved[si], moved[si+3]);
    } else if (move == LEFT) {
        if (si % PSIZE == 0) return NOTMOVED;
        swap(moved[si], moved[si-1]);
    } else if (move == RIGHT) {
        if (si % PSIZE == PSIZE-1) return NOTMOVED;
        swap(moved[si], moved[si+1]);
    } else {
        return NOTMOVED;
    }
    return moved;
}

void createDistTable() {
    for (int i = 0; i < PPSIZE; i++) {
        for (int j = 0; j < PPSIZE; j++) {
            dist_table[i][j] = abs(i / PSIZE - j / PSIZE) + abs(i % PSIZE - j % PSIZE);
        }
    }
}

void printDistTable() {
    for (int i = 0; i < PPSIZE; i++) {
        for (int j = 0; j < PPSIZE; j++) {
            cout << dist_table[i][j];
        }
        cout << endl;
    }
}

void printPuzzle(string puzzle) {
    cout << "---" << endl;
    for (int i = 0; i < PSIZE; i++) {
        for (int j = 0; j < PSIZE; j++) {
            cout << puzzle[i*PSIZE+j];
        }
        cout << endl;
    }
    cout << "---" << endl;
}

void printPath(State* state) {
    while (state != NULL) {
        printPuzzle(state->puzzle);
        state = state->parent;
    }
}


Measured memory_bytes: 5604