#include<iostream>
#include<algorithm>
using namespace std;
#define REP(i,b,n) for(int i=b;i<n;i++)
#define rep(i,n)   REP(i,0,n)
const int r = 12,c=6;
const int dx[]={0,0,1,-1};
const int dy[]={1,-1,0,0};

char m[r][c];
bool vis[r][c];
bool willerase[r][c];
//fall down
void fall(){
  for(int i=r-1;i>=0;i--){
    rep(j,c){
      int now=i;
      if (m[now][j] == '.')continue;
      while(now+1 < r && m[now+1][j] == '.')swap(m[now+1][j],m[now][j]),now++;
    }
  }
}

//find ojama
void erase(int y,int x,char tar){
  if (vis[y][x])return;
  vis[y][x]=true;
  m[y][x]='.';
  rep(i,4){
    int ney=y+dy[i],nex=x+dx[i];
    if (ney == -1 || nex == -1 || ney == r || nex == c)continue;
    if (m[ney][nex] == 'O')m[ney][nex]='.';
    else if (m[ney][nex] == tar)erase(ney,nex,tar);
  }
}

//dousyoku4ko
void check(int y,int x,char tar,int &cnt){
  if (vis[y][x])return;
  vis[y][x]=true;
  cnt++;
  rep(i,4){
    int nex=x+dx[i],ney=y+dy[i];
    if (nex == -1 || ney == -1 || nex == c || ney == r || m[ney][nex] != tar)
      continue;
    check(ney,nex,tar,cnt);
  }
}

int solve(){
  int ret=0;
  while(true){
    bool isok=false;
    rep(i,r)rep(j,c)vis[i][j]=false,willerase[i][j]=false;
    rep(i,r){
      rep(j,c)if (!vis[i][j] && m[i][j] != '.' && m[i][j] != 'O'){
	int tmp=0;
	check(i,j,m[i][j],tmp);
	if (tmp >= 4)willerase[i][j]=true,isok=true;
      }
    }
    if (!isok)break;
    rep(i,r)rep(j,c)vis[i][j]=false;
    rep(i,r){
      rep(j,c)if (willerase[i][j])erase(i,j,m[i][j]);
    }
    fall();
    ret++;
  }
  return ret;
}

int main(){
  int te;
  cin>>te;
  while(te--){
    rep(i,r)cin>>m[i];
    cout << solve() << endl;
  }
  return false;
}