#include <iostream>
#include <algorithm>
#include <string>
#include <vector>
#include <set>
#include <map>
#include <cstring>
using namespace std;

#define TOP     0
#define RIGHT   1
#define BOTTOM  2
#define LEFT    3

const char aToA = 'A' - 'a';

inline bool check( char a, char b )
{
    return a == b + aToA || a + aToA == b;
}

inline void rotate( string& piece )
{
    piece = piece.substr( 1, 3 ) + piece[0];
}

int main( void )
{
    int n;
    cin >> n;

    string pieces[9];

    for ( int lpc = 0; lpc < n; lpc++ )
    {
        for ( int i = 0; i < 9; i++ )
        {
            cin >> pieces[i];
        }

        map <string, int>   ID;
        set <string>        P;
        for ( int i = 0; i < 9; i++ )   
        {
            for ( int j = 0; j < 4; j++ )
            {
                P.insert( pieces[i] );
                ID[pieces[i]] = i;
                rotate( pieces[i] );
            }
        }

        int answer = 0;
        bool used[9];
        memset( used, false, sizeof( used ) );

        for ( set <string> ::iterator it_1 = P.begin(); it_1 != P.end(); it_1++ )
        {
            used[ID[*it_1]] = true;
            for ( set <string> ::iterator it_2 = P.begin(); it_2 != P.end(); it_2++ )
            {
                if ( used[ID[*it_2]] ) continue;
                if ( check( (*it_2)[LEFT], (*it_1)[RIGHT] ) == false ) continue;
                used[ID[*it_2]] = true;
                for ( set <string> ::iterator it_3 = P.begin(); it_3 != P.end(); it_3++ )
                {
                    if ( used[ID[*it_3]] ) continue;
                    if ( check( (*it_3)[LEFT], (*it_2)[RIGHT] ) == false ) continue;
                    used[ID[*it_3]] = true;
                    for ( set <string> ::iterator it_4 = P.begin(); it_4 != P.end(); it_4++ )
                    {
                        if ( used[ID[*it_4]] ) continue;
                        if ( check( (*it_4)[TOP], (*it_1)[BOTTOM] ) == false ) continue;
                        used[ID[*it_4]] = true;
                        for ( set <string> ::iterator it_5 = P.begin(); it_5 != P.end(); it_5++ )
                        {
                            if ( used[ID[*it_5]] ) continue;
                            if ( check( (*it_5)[TOP], (*it_2)[BOTTOM] ) == false || check( (*it_5)[LEFT], (*it_4)[RIGHT] ) == false ) continue;
                            used[ID[*it_5]] = true;
                            for ( set <string> ::iterator it_6 = P.begin(); it_6 != P.end(); it_6++ )
                            {
                                if ( used[ID[*it_6]] ) continue;
                                if ( check( (*it_6)[TOP], (*it_3)[BOTTOM] ) == false || check( (*it_6)[LEFT], (*it_5)[RIGHT] ) == false ) continue;
                                used[ID[*it_6]] = true;
                                for ( set <string> ::iterator it_7 = P.begin(); it_7 != P.end(); it_7++ )
                                {
                                    if ( used[ID[*it_7]] ) continue;
                                    if ( check( (*it_7)[TOP], (*it_4)[BOTTOM] ) == false ) continue;
                                    used[ID[*it_7]] = true;
                                    for ( set <string> ::iterator it_8 = P.begin(); it_8 != P.end(); it_8++ )
                                    {
                                        if ( used[ID[*it_8]] ) continue;
                                        if ( check( (*it_8)[TOP], (*it_5)[BOTTOM] ) == false || check( (*it_8)[LEFT], (*it_7)[RIGHT] ) == false ) continue;
                                        used[ID[*it_8]] = true;
                                        for ( set <string> ::iterator it_9 = P.begin(); it_9 != P.end(); it_9++ )
                                        {
                                            if ( used[ID[*it_9]] ) continue;
                                            if ( check( (*it_9)[TOP], (*it_6)[BOTTOM] ) == false || check( (*it_9)[LEFT], (*it_8)[RIGHT] ) == false ) continue;
                                            used[ID[*it_9]] = true;
                                            answer++;
                                            used[ID[*it_9]] = false;
                                        }
                                        used[ID[*it_8]] = false;
                                    }
                                    used[ID[*it_7]] = false;
                                }
                                used[ID[*it_6]] = false;
                            }
                            used[ID[*it_5]] = false;
                        }
                        used[ID[*it_4]] = false;
                    }
                    used[ID[*it_3]] = false;
                }
                used[ID[*it_2]] = false;
            }
            used[ID[*it_1]] = false;
        } // end of loop

        cout << answer << endl;
    }

    return 0;
}

Measured memory_bytes: 940