#include<stdio.h>
#define N 3
#define N2 9
#define L 3628800//キューの長さ//めっちゃでかくする！


typedef struct{
  int m[N][N];
  int space;//左上0として空白のいちを示す(0=8)
  
  int changetime;
}MAS;


int head=0, tail=0;//head=tailで初期化出来る(空に出来る)////////////
int all_tail=0;
MAS Q[L];
int All[L];//そこにすでにあったら1
int way[4];//次に進む方向　上右下左
//==================================
void Swap(int *a,int *b){
  int c=*a;
  *a=*b;
  *b=c;
}

//Que==================================
int isEmpty(){//1なら空
  if(head==tail)return 1;
  return 0;
}


void Enqueue(MAS x){
  Q[tail]=x;
  tail=(tail+1)%L;
}

MAS Dequeue(){
  MAS x=Q[head];
  head=(head+1)%L;
  return x;
}
//========================================
int Judge(MAS A,MAS B){//成功していたら1 失敗していたら0//２つの並びが同じか確かめる
 
  int i,j;
  for(i=0;i<N;i++){
    for(j=0;j<N;j++){
      if(A.m[i][j]!=B.m[i][j])return 0;
    }
  }
  return 1;
}

int Allcal(MAS child){
  return child.m[0][0]*L/9+child.m[0][1]*L/9/8+child.m[0][2]*L/9/8/7+child.m[1][0]*L/9/8/7/6+child.m[1][1]*L/9/8/7/6/5+child.m[1][2]*L/9/8/7/6/5/4+child.m[2][0]*L/9/8/7/6/5/4/3+child.m[2][1]*L/9/8/7/6/5/4/3/2+child.m[2][2];
}



  
void  Way(MAS u){//次に進める方向を教える　進めない方向は0　すすめるのは1
  int i;
  
  for(i=0;i<4;i++)way[i]=1;//初期化;

  if(u.space==0||u.space==1||u.space==2)way[0]--;//上
  if(u.space==2||u.space==5||u.space==8)way[1]--;//右
  if(u.space==6||u.space==7||u.space==8)way[2]--;//下
  if(u.space%3==0)way[3]--;//左
    
  // printf("%d%d%d%d\n",way[0],way[1],way[2],way[3]);
}


int  BFS(MAS Input){//何回で解けたか返す
  MAS u;
  MAS child;
  MAS ans={1,2,3,4,5,6,7,8,0,0,0};
  int count=0;
  int i;
  int haba=1;
  int l=0;

  if(Judge(ans,Input)==1)return child.changetime;
  Enqueue(Input);
  All[Allcal(Input)]=1;
   


  while(!isEmpty()){
    u=Dequeue();
    Way(u);
    
    child=u;
    if(way[0]==1){
      Swap(&child.m[child.space/N][child.space%N],&child.m[child.space/N-1][child.space%N]);
      child.space-=N;
      child.changetime++;
      if(Judge(ans,child)==1)return child.changetime;

    
    
      
      if(!All[Allcal(child)]){
	Enqueue(child);
	All[Allcal(child)]=1;
      }
      //printf("up ");
    }   
      
    child=u;	
    if(way[1]==1){
      Swap(&child.m[child.space/N][child.space%N],&child.m[child.space/N][child.space%N+1]);
      child.space++;
      child.changetime++;
      if(Judge(ans,child)==1)return child.changetime;
    
    
      
      if(!All[Allcal(child)]){
	Enqueue(child);
	All[Allcal(child)]=1;
      }
      //printf("right ");
    }
    
    child=u;	
    if(way[2]==1){
      Swap(&child.m[child.space/N][child.space%N],&child.m[child.space/N+1][child.space%N]);      child.changetime++;
      child.space+=N;
      if(Judge(ans,child)==1)return child.changetime;
    
    
      
      if(!All[Allcal(child)]){
	Enqueue(child);
	All[Allcal(child)]=1;
      }//printf("down ");
    }
    
    child=u;	
    if(way[3]==1){
      Swap(&child.m[child.space/N][child.space%N],&child.m[child.space/N][child.space%N-1]);      child.changetime++;
      child.space--;
      if(Judge(ans,child)==1)return child.changetime;
    
    
      
       if(!All[Allcal(child)]){
	Enqueue(child);
	All[Allcal(child)]=1;
      }
    }
    
    //printf("%d     \n",child.changetime);
    // printf("\nchild.changetime %d\n================\n",child.changetime);
    //long=Max(long,)
  }
  // printf("long%d\n",long);
  return -2;//失敗
 
}
		     




    


int main(){
  int i,j;
  MAS Input={0,0,0,0,0,0,0,0,0,0,0};
  
  for(i=0;i<N;i++){
    for(j=0;j<N;j++){
      scanf("%d",&Input.m[i][j]);
      if(Input.m[i][j]==0)Input.space=i*N+j;
    }
  }

  // printf("A.space=%d\n",A.space);
  
  printf("%d\n",BFS(Input));
  return 0;
}



Measured memory_bytes: 20796