# 2018多校第4场1010 && HDU6341 ProblemJ. Let Sudoku Rotate

#include <cstdio>
#include <cstring>
#include <string>
#include <algorithm>
using namespace std;

const int maxn = 20;
char s[maxn][maxn];
int a[maxn][maxn];
int b[10][10];
int row[maxn][maxn],col[maxn][maxn];
int ans;

inline int getc(char c){
if (isdigit(c)) return c-'0';
return c-'A'+10;
}

inline int Min(int x, int y) {return x<y?x:y;}

inline void add(int idx, int idy, int val) {
for (int i=idx<<2; i<(idx+1)<<2; ++i) {
for (int j=idy<<2; j<(idy+1)<<2; ++j)
row[i][a[i][j]] += val, col[j][a[i][j]] += val;
}
}

inline int Rotate(int idx, int idy) {
for (int i=idx<<2; i<(idx+1)<<2; ++i) {
for (int j=idy<<2; j<(idy+1)<<2; ++j) {
--row[i][a[i][j]]; --col[j][a[i][j]];
b[j-(idy<<2)][((idx+1)<<2)-i-1] = a[i][j];
}
}

int res = 1;
for (int i=idx<<2; i<(idx+1)<<2; ++i) {
for (int j=idy<<2; j<(idy+1)<<2; ++j) {
a[i][j] = b[i-(idx<<2)][j-(idy<<2)];
if ( (++row[i][a[i][j]]>1) || (++col[j][a[i][j]]>1) ) res = 0;
}
}
return res;
}

void dfs(int idx,int idy, int num){
if (idx>=4) {
ans = Min(ans,num);
return ;
}
if (num >= ans) return;
for (int i=1; i<=4; ++i) {
if (Rotate(idx,idy)) dfs(idy == 3?idx+1:idx,idy == 3?0:idy+1,num+i%4);
}
}

int main(){
int T; scanf("%d",&T);
register int i,j;
while (T--){
for (i=0; i<16; ++i) {
scanf("%s",s[i]);
for (j=0; j<16; ++j) a[i][j] = getc(s[i][j]);
}

/*for (i=0; i<16; ++i) {
for (j=0; j<16; ++j) printf("%d",a[i][j]); puts("");
}*/
memset(row,0,sizeof(row));
memset(col,0,sizeof(col));
ans = 1<<30;
dfs(0,0,0);
printf("%d\n",ans);
}
return 0;
}