import std.stdio;
import std.bitmanip;
import std.c.stdio;
import std.range;
import std.array;
import std.functional;
import std.algorithm;
import std.conv;
import std.container;
import std.math;
import std.numeric;
import std.string;
import std.c.string;
import std.regex;
import std.typecons;

int L(int x) {
    return (x & 0xFFFFFFF8) >> 3;
}
int R(int x) {
    return x & 0x00000007;
}
int C(int x, int y) {
    return (x << 3) + y;
}
string format(int x) {
    return L(x).to!string ~ R(x).to!string;
}
bool valid(int x) {
    return (1 <= L(x) && L(x) <= 4 && 1 <= R(x) && R(x) <= 7);
}

int F[32];
void input() {
    F[] = 0;
    foreach (i; 0 .. 4) {
        foreach (j; 1 .. 8) {
            int x;
            scanf("%d", &x);
            F[i * 8 + j] = C(x / 10, x % 10);
        }
    }
}

void dump(int[32] X) {
    foreach (i; 0 .. 4) {
        foreach (j; 0 .. 8) {
            writef("%s ", format(X[i * 8 + j]));
        }
        writeln;
    }
}

bool check(in int[32] X) {
    foreach (i; 0 .. 4) {
        foreach (j; 0 .. 7) {
            int x = X[i * 8 + j];
            if (L(x) == i + 1 && R(x) == j + 1) continue;
            return false;
        }
    }
    return true;
}

struct S {
    int[32] F;
    int[40] M;
    int[] zpos;
    int t;
}

void solve() {
    alias int[32] key;
    auto used = new RedBlackTree!key;

    foreach (i; 0 .. 4) {
        foreach (j; 0 .. 8) {
            int x = F[i * 8 + j];
            if (R(x) == 1) {
                swap(F[i * 8 + j], F[ (L(x) - 1) * 8  ]);
            }
        }
    }
    int[40] M;
    int[] zpos;
    foreach (i; 0 .. 4) {
        foreach (j; 0 .. 8) {
            int x = F[i * 8 + j];
            if (x == 0) zpos ~= i * 8 + j;
            M[x] = (i << 3) + j;
        }
    }

    DList!S Q;
    Q.insert(S(F, M, zpos.dup, 0));
    used.insert(F);
    while (!Q.empty) {
        S cur = Q.front; Q.removeFront;
        //writeln("\t", cur.t);
        //dump(cur.F);
        //writeln;
        if (check(cur.F)) {
            writeln(cur.t);
            return;
        }
        foreach (pos; cur.zpos) {
            int x = cur.F[pos];
            if (x > 0) continue;
            int y = cur.F[pos - 1];
            int z = C(L(y), R(y) + 1);
            if (!z.valid) continue;
            auto N = cur.M;
            int p = N[z];
            swap(cur.F[ L(p) * 8 + R(p) ], cur.F[pos]);
            N[z] = pos;
            auto nzpos = setDifference(cur.zpos, [pos]).array ~ p;
            if (cur.F in used) {
                swap(cur.F[ L(p) * 8 + R(p) ], cur.F[pos]);
            } else {
                used.insert(cur.F);
                Q.insert(S(cur.F, N, nzpos, cur.t + 1));
                swap(cur.F[ L(p) * 8 + R(p) ], cur.F[pos]);
            }
        }
    }
    writeln(-1);
}

void main() {
    int T;
    scanf("%d\n", &T);
    foreach (t; 0 .. T) {
        input; solve;
    }
}