#include<stdio.h>

#define N 3
#define MAXQ 3628800

int bfs(int [N][N]);
int check_save (int [N][N]);
//hash
long long h1(long long);
long long  h2(long long);

#define RIGHT -1
#define LEFT -2
#define ABOVE -3
#define UNDER -4

int Z[362880][N][N];
int num=0;

int hash[MAXQ];

int main(){
  int i,j;
  int depth;
  int P[N][N];
  
  for(i=0;i<N;i++){
    for(j=0;j<N;j++){
      scanf("%d",&P[i][j]);
    }
  }
  
  for(i=0;i<MAXQ;i++) hash[i] = 0;

  /* for(i=0;i<N;i++){
     for(j=0;j<N;j++){
     if(j) printf(" ");
     printf("%d",P[i][j]);
     }
     printf("\n");

     }
  */

  depth = bfs(P);

  printf("%d\n",depth);
  
  return 0;
}
int Q[MAXQ][N][N];
int Qd[MAXQ];

int bfs(int A[N][N]){

  int head=0,tail=0;
  int depth;
  int i,j,puzzle[N][N],tp[N][N];
  int x,y;
  int temp;
  int direction = 0;
  //int depth_limit = 32;
  //int min = depth_limit;
  int result;


  for(i=0;i<N;i++){
    for(j=0;j<N;j++){
      Q[tail][i][j] = A[i][j];
      Qd[tail]=0;
    }
  }
  tail++;
  //if(tail >= MAXQ) tail = 0;
  

  while(head != tail){
    //printf("%d:%d\n",head,tail);
    for(i=0;i<N;i++){
      for(j=0;j<N;j++){
        puzzle[i][j] = Q[head][i][j];
        if(puzzle[i][j] == 0) {
          x = i;
          y = j;
        }    
      }
    }
    depth=Qd[head];
    head++;
    if(head >= MAXQ) head = 0;
  
    //finish
    if(puzzle[0][0] == 1 &&
       puzzle[0][1] == 2 &&
       puzzle[0][2] == 3 &&
       puzzle[1][0] == 4 &&
       puzzle[1][1] == 5 &&
       puzzle[1][2] == 6 &&
       puzzle[2][0] == 7 &&
       puzzle[2][1] == 8 && puzzle[2][2] == 0) return depth;

    /*
      result = check_save(puzzle);

      if(result == 1) continue;
    */
  

    //0の位置は(x,y)

    //0 can swap above
    if(y != 0){
      for(i=0;i<N;i++){
        for(j=0;j<N;j++){
          tp[i][j] = puzzle[i][j];
        }
      }
      //swaping pazzle
      temp = tp[x][y-1];
      tp[x][y-1] = tp[x][y];
      tp[x][y] = temp;

      result = check_save(tp);

      if(result == 0) {

	for(i=0;i<N;i++){
	  for(j=0;j<N;j++){       
	    Q[tail][i][j] = tp[i][j];     
	  }     
	}
	Qd[tail] = depth + 1;
	tail++;
	if(tail >= MAXQ) tail = 0;
      }
    }

    

    //0 can swap under
    if(y != 2) {
      for(i=0;i<N;i++){
        for(j=0;j<N;j++){
          tp[i][j] = puzzle[i][j];
        }
      }

      temp = tp[x][y+1];
      tp[x][y+1] = tp[x][y];
      tp[x][y] = temp;

      result = check_save(tp);

      if(result == 0) {

	for(i=0;i<N;i++){
	  for(j=0;j<N;j++){       
	    Q[tail][i][j] = tp[i][j];     
	  }     
	}
	Qd[tail] = depth + 1;
	tail++;
	if(tail >= MAXQ) tail = 0;
      }

    }

    //0 can swap right
    if(x != 2){
      for(i=0;i<N;i++){
        for(j=0;j<N;j++){
          tp[i][j] = puzzle[i][j];
        }
      }

      temp = tp[x+1][y];
      tp[x+1][y] = tp[x][y];
      tp[x][y] = temp;

      result = check_save(tp);

      if(result == 0) {


      
	for(i=0;i<N;i++){
	  for(j=0;j<N;j++){       
	    Q[tail][i][j] = tp[i][j];     
	  }     
	}
	Qd[tail] = depth + 1;
	tail++;
	if(tail >= MAXQ) tail = 0;
      }
    }

    //0 can swap left
    if(x != 0){
      for(i=0;i<N;i++){
        for(j=0;j<N;j++){
          tp[i][j] = puzzle[i][j];
        }
      }

      temp = tp[x-1][y];
      tp[x-1][y] = tp[x][y];
      tp[x][y] = temp;

      result = check_save(tp);

      if(result == 0) {
	
	for(i=0;i<N;i++){
	  for(j=0;j<N;j++){       
	    Q[tail][i][j] = tp[i][j];     
	  }     
	}
	Qd[tail] = depth + 1;
	tail++;
	if(tail >= MAXQ) tail = 0;
      }
    }
  }
  return -1;
}





int check_save(int A[3][3]){
  int i,j;
  int sum=0;
  int value;
  
  //存在すれば １
  
  for(i=0;i<3;i++){
    for(j=0;j<3;j++){
      sum += A[i][j];
      if(i != 2 || j != 2) sum *=10;
    }
  }

  //printf("sum = %d\n",sum);


  i = 0; 
  while(1){
    
    value = (h1(sum) + i * h2(sum)) % MAXQ;
  
    if(hash[value] != 0) {
      if(hash[value] == sum) {
	//printf("%d already exists!!\n", value);
	return 1;

      }
      else{
	//printf("CONFLICT!!\n");
	i++;
      }
    }
  
    else{
      hash[value] = sum;
      break;
    }
  }

  return 0;
}

long long h1(long long key){
  return key % MAXQ;
}

long long h2(long long key){
  return 1 + (key % (MAXQ-1));
}
  



Measured memory_bytes: 23988