#include <iostream>
#include <string>
using namespace std;

struct config {
  int empty[2];			// Location of empty tile, row(0)-column(1)
  char pos[5][5];		// Either 0 or 1
};

/* Impose an arbitrary ordering on config's.
   This is needed if you want to create a set of configs */
bool operator< (const config& c1, const config& c2) {
  if (c1.empty[0] < c2.empty[0])
    return true;
  if (c1.empty[0] > c2.empty[0])
    return false;
  if (c1.empty[1] < c2.empty[1])
    return true;
  if (c1.empty[1] > c2.empty[1])
    return false;
  for (int r = 0; r < 5; ++r)
    for (int c = 0; c < 5; ++c) {
      if (c1.empty[0] == r && c1.empty[1] == c)
	continue;
      if (c1.pos[r][c] < c2.pos[r][c])
	return true;
      if (c1.pos[r][c] > c2.pos[r][c])
	return false;
    }
  return false;
}

config default_config = {
  empty : { 2, 2 },		// Location (2,2) is empty
  pos : { { 1, 1, 1, 1, 1 },	// All black knights
	  { 0, 1, 1, 1, 1 },
	  { 0, 0, 0, 1, 1 },	// Empty is represented by 0
	  { 0, 0, 0, 0, 1 },
	  { 0, 0, 0, 0, 0 } }	// All white knights
};

void read_config(config &conf) {
  string s;
  for (int r = 0; r < 5; ++r) {
    getline(cin, s);
    for (int c = 0; c < 5; ++c) {
      if (s[c] == ' ') {
	conf.empty[0] = r;
	conf.empty[1] = c;
      } else {
	conf.pos[r][c] = s[c] - '0';
      }
    }
  }
}

struct {
  int delta[2];
} moves [] = {
  { { -2, 1 } },
  { { -1, 2 } },
  { { 1, 2 } },
  { { 2, 1 } },
  { { 2, -1 } },
  { { 1, -2 } },
  { { -1, -2 } },
  { { -2, -1 } },
};

bool make_move(const config &c1, config &c2, int move_num) {
  c2 = c1;
  c2.empty[0] += moves[move_num].delta[0];
  c2.empty[1] += moves[move_num].delta[1];
  if (c2.empty[0] < 0 || c2.empty[0] > 4)
    return false;
  if (c2.empty[1] < 0 || c2.empty[1] > 4)
    return false;
  char orig = c2.pos[c2.empty[0]][c2.empty[1]];
  c2.pos[c2.empty[0]][c2.empty[1]] = 0;
  c2.pos[c1.empty[0]][c1.empty[1]] = orig;
  return true;
}

/* You probably want to create a set of configurations to avoid repeated
   states.  To do that, #include the <set> header.  Then you can create a
   variable of type set<config>, like

	set<config> closed;

   insert config (say conf) into it using

        closed.insert(conf);

   erase a config using

        closed.erase(conf);

   erase all configs using

	closed.clear();

   find whether a config is in it using

	closed.find(conf);

   which returns closed.end() if not found, and an "iterator" to the element
   if found.  You can also iterate through the set:

	set<config>::iterator iter;
	iter = close.begin();
	while (iter != close.end()) {
		/* the element */
		++iter;
	}

   but don't modify the set when you are still iterating through it.


   You might also want to create a queue of config's.  It is essentially
   the same as creating a set, replacing the word "set" with the word
   "queue".  The useful operations are push, pop and top:

	queue<config> fringe;
	fringe.push(conf);
	conf = fringe.top();
	fringe.pop();

   */

