import std.algorithm, std.conv, std.range, std.stdio, std.string;
import std.container, std.math, std.typecons;

const auto n = 4;
const auto bits = 4;
const auto bitMask = (1UL << bits) - 1;

version(unittest) {} else
void main()
{
  auto b = 0UL;
  foreach (i; 0..n) {
    auto rd = readln.split.to!(int[]);
    foreach (j, d; rd)
      b = b.setDigit(i * n + j, d);
  }

  auto g = goal;

  auto vi = [b: true];

  auto qb = new blf[](4_000_000);
  qb[0] = blf(b, 0, b.sumMd);
  auto qi = qb.heapify!("a.f > b.f")(1);

  int insertQueue(blf q, size_t i, size_t j)
  {
    auto c = q.b.swapDigit(i, j), l = q.l + 1;
    if (c == g) {
      return l;
    } else if (c !in vi) {
      auto h = c.sumMd;
      if (h <= 45)
        qi.insert(blf(c, l, l + h));
    }
    return -1;
  }

  int loop()
  {
    while (!qi.empty) {
      auto q = qi.front; qi.removeFront;
      vi[q.b] = true;
      auto i = q.b.findZero;
      int r;
      if (i / n > 0     && (r = insertQueue(q, i, i - n)) >= 0) return r;
      if (i / n < n - 1 && (r = insertQueue(q, i, i + n)) >= 0) return r;
      if (i % n > 0     && (r = insertQueue(q, i, i - 1)) >= 0) return r;
      if (i % n < n - 1 && (r = insertQueue(q, i, i + 1)) >= 0) return r;
    }
    return -1;
  }

  writeln(b == g ? 0 : loop);
}

alias Tuple!(ulong, "b", int, "l", int, "f") blf;

ulong goal()
{
  auto r = 0UL;
  foreach (i; 0..n*n-1)
    r = r.setDigit(i, i + 1);
  return r;
}

ulong setDigit(ulong b, size_t i, int val)
{
  return b & (~(bitMask << i * bits)) | (val.to!ulong << i * bits);
}

int digit(ulong b, size_t i)
{
  return (b >> i * bits) & bitMask;
}

ulong swapDigit(ulong b, size_t i, size_t j)
{
  auto x = b.digit(i), y = b.digit(j);
  return b.setDigit(i, y).setDigit(j, x);
}

ptrdiff_t findZero(ulong b)
{
  foreach (i; 0..n*n)
    if (b.digit(i) == 0)
      return i;
  return -1;
}

const auto mdTable = [[6, 0, 1, 2, 3, 1, 2, 3, 4, 2, 3, 4, 5, 3, 4, 5],
                      [5, 1, 0, 1, 2, 2, 1, 2, 3, 3, 2, 3, 4, 4, 3, 4],
                      [4, 2, 1, 0, 1, 3, 2, 1, 2, 4, 3, 2, 3, 5, 4, 3],
                      [3, 3, 2, 1, 0, 4, 3, 2, 1, 5, 4, 3, 2, 6, 5, 4],
                      [5, 1, 2, 3, 4, 0, 1, 2, 3, 1, 2, 3, 4, 2, 3, 4],
                      [4, 2, 1, 2, 3, 1, 0, 1, 2, 2, 1, 2, 3, 3, 2, 3],
                      [3, 3, 2, 1, 2, 2, 1, 0, 1, 3, 2, 1, 2, 4, 3, 2],
                      [2, 4, 3, 2, 1, 3, 2, 1, 0, 4, 3, 2, 1, 5, 4, 3],
                      [4, 2, 3, 4, 5, 1, 2, 3, 4, 0, 1, 2, 3, 1, 2, 3],
                      [3, 3, 2, 3, 4, 2, 1, 2, 3, 1, 0, 1, 2, 2, 1, 2],
                      [2, 4, 3, 2, 3, 3, 2, 1, 2, 2, 1, 0, 1, 3, 2, 1],
                      [1, 5, 4, 3, 2, 4, 3, 2, 1, 3, 2, 1, 0, 4, 3, 2],
                      [3, 3, 4, 5, 6, 2, 3, 4, 5, 1, 2, 3, 4, 0, 1, 2],
                      [2, 4, 3, 4, 5, 3, 2, 3, 4, 2, 1, 2, 3, 1, 0, 1],
                      [1, 5, 4, 3, 4, 4, 3, 2, 3, 3, 2, 1, 2, 2, 1, 0],
                      [0, 6, 5, 4, 3, 5, 4, 3, 2, 4, 3, 2, 1, 3, 2, 1]];

int sumMd(ulong b)
{
  auto r = 0;
  foreach (i; 0..n*n)
    r += mdTable[i][b.digit(i)];
  return r;
}