#include<iostream>
#include<queue>
#include<map>
#include<stdlib.h>
using namespace std;
queue<int>q;
map<int,int>m;
long long end1;//目标状态(一维形式)
int end[3][3];//目标状态(二维形式)
int ini[3][3];//状态(二维形式)
void bfs();//广搜
void init();//初始化
int canmoveto(int,int);
int moveto(int,int);
int main()
{
int i,j;
end1=0;
for(i=0;i<=2;i++)
{
for(j=0;j<=2;j++)
{
cin>>end[i][j];
end1=end1*10+end[i][j];
}
}
init();
bfs();
return(0);
}
void bfs()
{
int u,v;
int flag=0;
int i;
while(!q.empty())
{
u=q.front();
q.pop();
for(i=0;i<=3;i++)//i=0,1,2,3分别代表左下右上四个方向
{
if(canmoveto(u,i))//判合法
{
v=moveto(u,i);
if(v==end1)//判目标
{
cout<<m[u]+1<<endl;
exit(1);
}
else
{
if(m.count(v)==0)//判价值
{
q.push(v);
m[v]=m[u]+1;
}
}
}
}
}
if(flag==0)
{
cout<<-1<<endl;
}
}
void init()
{
q.push(123456780);
m[123456780]=0;
}
int canmoveto(int u, int i)
{
int row,col; //空格所在行,列
int j,k;
for(j=2;j>=0;j--)//一维转化到二维
{
for(k=2;k>=0;k--)
{
ini[j][k]=u%10;
u=u/10;
if(ini[j][k]==0)
{
row=j;
col=k;
}
}
}
if(i==0&&col-1>=0)
{
return(1);
}
else if(i==1&&row+1<=2)
{
return(1);
}
else if(i==2&&col+1<=2)
{
return(1);
}
else if(i==3&&row-1>=0)
{
return(1);
}
return(0);
}
int moveto(int u,int i)
{
int row,col; //空格所在行,列
int j,k;
for(j=2;j>=0;j--)//一维转化到二维
{
for(k=2;k>=0;k--)
{
ini[j][k]=u%10;
u=u/10;
if(ini[j][k]==0)
{
row=j;
col=k;
}
}
}
int temp;
if(i==0&&col-1>=0)
{
temp=ini[row][col];
ini[row][col]=ini[row][col-1];
ini[row][col-1]=temp;
}
else if(i==1&&row+1<=2)
{
temp=ini[row][col];
ini[row][col]=ini[row+1][col];
ini[row+1][col]=temp;
}
else if(i==2&&col+1<=2)
{
temp=ini[row][col];
ini[row][col]=ini[row][col+1];
ini[row][col+1]=temp;
}
else if(i==3&&row-1>=0)
{
temp=ini[row][col];
ini[row][col]=ini[row-1][col];
ini[row-1][col]=temp;
}
int v=0;
for(j=0;j<=2;j++)
{
for(k=0;k<=2;k++)
{
v=v*10+ini[j][k];
}
}
return(v);
}