#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
const int N(9);
int W[N][N]={
{6,6,6,6,6,6,6,6,6},
{6,7,7,7,7,7,7,7,6},
{6,7,8,8,8,8,8,7,6},
{6,7,8,9,9,9,8,7,6},
{6,7,8,9,10,9,8,7,6},
{6,7,8,9,9,9,8,7,6},
{6,7,8,8,8,8,8,7,6},
{6,7,7,7,7,7,7,7,6},
{6,6,6,6,6,6,6,6,6}
};
int B[N][N]={
{0,0,0,1,1,1,2,2,2},
{0,0,0,1,1,1,2,2,2},
{0,0,0,1,1,1,2,2,2},
{3,3,3,4,4,4,5,5,5},
{3,3,3,4,4,4,5,5,5},
{3,3,3,4,4,4,5,5,5},
{6,6,6,7,7,7,8,8,8},
{6,6,6,7,7,7,8,8,8},
{6,6,6,7,7,7,8,8,8},
};
unsigned int row[N]={0},col[N]={0},blk[N]={0},pos[257]={0};
int ans=-1;
struct Sudoku{
struct node{
short x,y,opt;
inline node():x(0),y(0),opt(0) {}
};
short Su[N][N]; int blank;
inline Sudoku(){ memset(Su,0,sizeof(Su)); blank=81; }
inline void init(){
for(int i=0;i<9;i++)
for(int j=0;j<9;j++)
{
scanf("%d",&(Su[i][j]));
int num=Su[i][j];
if(Su[i][j]) set(i,j,num-1);
}
}
inline void set(const int &x,const int &y,const int &k){
Su[x][y]=k+1;blank--;
row[x]&=~(1<<k);col[y]&=~(1<<k);blk[B[x][y]]&=~(1<<k);
}
inline void un_set(const int &x,const int &y,const int &k){
Su[x][y]=0;blank++;
row[x]|=(1<<k);col[y]|=(1<<k);blk[B[x][y]]|=(1<<k);
}
inline void cal(){
int sum=0;
for(int i=0;i<N;i++)
for(int j=0;j<N;j++)
sum+=Su[i][j]*W[i][j];
ans=ans>sum?ans:sum;
}
inline node get_min(){
int min=81,opt; node P;
for(int i=0;i<9;i++)
for(int j=0;j<9;j++)
if(!Su[i][j])
{
opt=count(row[i]&col[j]&blk[B[i][j]]);
if(opt<min)
{
min=opt;
P.x=i,P.y=j,P.opt=min;
if(!min) return P;
}
}
return P;
}
inline int count(unsigned int x)
{
x=(x&0x55555555)+(x>>1&0x55555555);
x=(x&0x33333333)+(x>>2&0x33333333);
x=(x&0x0F0F0F0F)+(x>>4&0x0F0F0F0F);
x=(x&0x00FF00FF)+(x>>8&0x00FF00FF);
x=(x&0x0000FFFF)+(x>>16&0x0000FFFF);
return x;
}
inline bool valid(const int &x,const int &y,const int &k){
return (row[x]&col[y]&blk[B[x][y]])>>k&1;
}
}Sudo;
inline void init()
{
for(int i=0;i<N;i++) row[0]+=(1<<i);
for(int i=0;i<N;i++) row[i]=col[i]=blk[i]=row[0];
for(int i=0;i<N;i++) pos[1<<i]=i;
Sudo.init();
}
void dfs(Sudoku &Sudo)
{
if(!Sudo.blank){
Sudo.cal();
return;
}
Sudoku::node P=Sudo.get_min(); if(!P.opt) return;
int x=P.x,y=P.y;
unsigned int k=row[x]&col[y]&blk[B[x][y]],p;
while(k)
{
p=k&(~k+1); k-=p;
Sudo.set(x,y,pos[p]);
dfs(Sudo);
Sudo.un_set(x,y,pos[p]);
}
}
int main()
{
init();
dfs(Sudo);
printf("%d\n",ans);
return 0;
}
/**************************************************************
Problem: 2291
User: admin
Language: C++
Result: Accepted
Time:811 ms
Memory:1148 kb
****************************************************************/