//  Programa para armar sudokus
//  Eduardo Viruena Silva
//  Septiembre 17 de 2015
#include <iostream>
#include <cstdlib>

using namespace std;
int  tab[9][9];
bool f[9][10];
bool c[9][10];
bool s[9][10];

int sc(int i, int j)
{
   return 3*(i/3) + (j/3);
}

// ¿Puede colocarse d en la posición (i,j)?
bool SePuede(int i, int j, int d)
{
   return tab[i][j]==0 && !f[i][d] 
                       && !c[j][d] 
                       && !s[sc(i,j)][d];
}

// Poner d en la posición (i,j)
void Poner(int i, int j, int d)
{
   tab[i][j]= d;
   f[i][d]= true;
   c[j][d]= true;
   s[sc(i,j)][d]= true;
}

// Quitar d en la posición (i,j)
void Quitar(int i, int j, int d)
{
   tab[i][j]= 0;
   f[i][d]= false;
   c[j][d]= false;
   s[sc(i,j)][d]= false;
}

// Intento n-esimo
   
void intento(int n)
{
   if (n==81)
     // ya acabé, debemos imprimir
     {
      for (int i=0; i<9; i++)
         {
          for (int j=0; j<9; j++)
             {
              cout << tab[i][j] << ' ';
              if (j%3==2)
                 cout << ' ';
             }
          cout << endl;
          if (i%3==2)
             cout << endl;
         }
      cout << "-----------------------\n";
     }
   else
     {
      int i= n/9;
      int j= n%9;
      if (tab[i][j] != 0)     // condición fija del sudoku
         intento(n+1);
      else
         for (int d=1; d<=9; d++)
            {
             if (SePuede(i,j,d))
                {
                 Poner(i,j,d);
                 intento(n+1);
                 Quitar(i,j,d);
                }
            }
     }
}


int main(void)
{
   for (int i=0; i<9; i++)
    {
     for (int j=0; j<10; j++)
        f[i][j]= c[i][j]= s[i][j]= false;
     for (int j=0; j<9; j++)
        tab[i][j]= 0;
    }
   for (int i=0; i<9; i++)
     for (int j=0; j<9; j++)
       {
        int d;
        cin >> d;
        Poner(i,j,d);
       }
   intento(0);
   return EXIT_SUCCESS;
}















