#include <iostream>
#include <assert.h>

using namespace std;

int omino[25];
int nplace[25];

int momino[25];
int mplace[25];

int rows[5];
int cols[5];
int blbs[5];
int sols;

void print() {
  cout << endl;
  for (int row=0;row<5;row++) {
    for (int col=0;col<5;col++) {
      cout << omino[row*5+col];
    }
    cout << "  ";
    for (int col=0;col<5;col++) {
      cout << nplace[row*5+col];
    }
    cout << endl;
  }
//  for (int i=0; i<5; i++) {
//    cout << rows[i] << " ";
//    cout << cols[i] << " ";
//    cout << blbs[i] << " ";
//    cout << "\n";
//  }
}

void mprint() {
  cout << endl;
  for (int row=0;row<5;row++) {
    for (int col=0;col<5;col++) {
      cout << momino[row*5+col];
    }
    cout << "  ";
    for (int col=0;col<5;col++) {
      cout << mplace[row*5+col];
    }
    cout << "\t";
  }
//  for (int i=0; i<5; i++) {
//    cout << rows[i] << " ";
//    cout << cols[i] << " ";
//    cout << blbs[i] << " ";
//    cout << "\n";
//  }
}

void backup() {
  for (int i=0;i<25;i++) {
    momino[i] = omino[i];
    mplace[i] = nplace[i];
  }
}

bool canplace(int val, int pos) {
  int mask = (1 << val);
  int row = pos / 5;
  if ((rows[row] & mask) != 0) return false;
  int col = pos % 5;
  if ((cols[col] & mask) != 0) return false;
  int blb = omino[pos] - 1;
  if ((blbs[blb] & mask) != 0) return false;
  return true;
}

void place(int val, int pos) {
  int mask = (1 << val);
  int row = pos / 5;
  rows[row] |= mask;
  int col = pos % 5;
  cols[col] |= mask;
  int blb = omino[pos] - 1;
  blbs[blb] |= mask;
  nplace[pos] = val;
}

void unplace(int val, int pos) {
  int mask = ~(1 << val);
  int row = pos / 5;
  rows[row] &= mask;
  int col = pos % 5;
  cols[col] &= mask;
  int blb = omino[pos] - 1;
  blbs[blb] &= mask;
  nplace[pos] = 0;
}

void srecurse(int pos) {
  if (sols > 1) return;
  if (pos == 25) {
    sols++;
    backup();
    if (sols > 1) return;
  } else for (int val=1;val<=5;val++) {
    if (canplace(val,pos)) {
      place(val,pos);
      srecurse(pos+1);
      if (sols > 1) return;
      unplace(val,pos);
    }
  }
}

void solve() {
  sols = 0;
  for (int i=0;i<5;i++) {
    rows[i] = 0;
    cols[i] = 0;
    blbs[i] = 0;
  }
  assert(canplace(1,0)); place(1,0);
  assert(canplace(2,1)); place(2,1);
  assert(canplace(3,2)); place(3,2);
  assert(canplace(4,3)); place(4,3);
  assert(canplace(5,4)); place(5,4);
  sols = 0;
  srecurse(5);
  if (sols == 1) {
    mprint();
  }
  unplace(1,0);
  unplace(2,1);
  unplace(3,2);
  unplace(4,3);
  unplace(5,4);
}

void recurse(short placed) {
  if (placed == 25) {
  //  print();
    solve();
  } else if (placed == 0) {
    omino[0] = 1;
    recurse(1);
    omino[0] = 0;
  } else if (placed % 5 == 0) {
    int val = placed / 5 + 1;
    int i = 0;
    while (omino[i] != 0) i++;
    omino[i] = val;
    recurse(placed+1);
    omino[i] = 0;
  } else {
    int val = placed / 5 + 1;
    for (int i=0;i<25;i++) {
      if (omino[i] != 0) continue;
      bool okay = false;
      if (i >= 5 && omino[i-5] == val) okay = true;
      if (i < 20 && omino[i+5] == val) okay = true;
      if (i % 5 != 0 && omino[i-1] == val) okay = true;
      if (i % 5 != 4 && omino[i+1] == val) okay = true;
      if (!okay) continue;
      omino[i] = val;
      recurse(placed+1);
      omino[i] = 0;
    }
  }
}

int main() {
  for (int i=0;i<25;i++) omino[i] = 0;
  for (int i=0;i<25;i++) nplace[i] = 0;

  recurse(0);
}
