#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <climits>
#include <cfloat>
#include <ctime>
#include <map>
#include <utility>
#include <set>
#include <iostream>
#include <memory>
#include <string>
#include <vector>
#include <algorithm>
#include <functional>
#include <sstream>
#include <complex>
#include <stack>
#include <queue>
#include <numeric>
#include <list>

using namespace std;

#ifdef _MSC_VER
#define __typeof__ decltype
template <class T> int __builtin_popcount(T n) { return n ? 1 + __builtin_popcount(n & (n - 1)) : 0; }
#endif

#define foreach(it, c) for (__typeof__((c).begin()) it=(c).begin(); it != (c).end(); ++it)
#define all(c) (c).begin(), (c).end()
#define rall(c) (c).rbegin(), (c).rend()
#define popcount __builtin_popcount
#define CLEAR(arr, val) memset(arr, val, sizeof(arr))

#define rep(i, n) for (int i = 0; i < n; ++i)

template <class T> void max_swap(T& a, const T& b) { a = max(a, b); }
template <class T> void min_swap(T& a, const T& b) { a = min(a, b); }

typedef long long ll;
typedef pair<int, int> pint;

const double PI = acos(-1.0);
const int dx[] = { 0, 1, 0, -1 };
const int dy[] = { 1, 0, -1, 0 };



template <class T>
string to_bin(T n, int digits)
{
	string res(digits, '0');
	for (int i = digits - 1; i >= 0; --i, n >>= 1)
		if (n & 1)
			res[i] = '1';
	return res;
}
void pr(const vector<int>& v)
{
	foreach (it, v)
		cout << to_bin(*it, 5) << endl;
	cout << endl;
}

template <class T>
T next_combination(T combi)
{
	T leastBit = combi & -combi;
	T mostBits = combi + leastBit;
	T leastSequentialBits = combi & ~mostBits;
	return mostBits | ((leastSequentialBits / leastBit) >> 1);
}
int rev(int n)
{
	int res = 0;
	for (int i = 0; i < 5; ++i)
		res = (res << 1) | (n >> i & 1);
	return res;
}
void p_ver(const vector<int>& ver)
{
	for (int i = 0; i < 5; ++i)
	{
		for (int j = 0; j < 5; ++j)
			printf("%d", ver[j] >> i & 1);
		puts("");
	}
}
bool can_construct(const vector<int>& ver, const vector<int>& hor)
{
	vector<int> v(5, 0);
	for (int i = 0; i < 5; ++i)
		for (int j = 0; j < 5; ++j)
			v[i] |= (ver[j] >> i & 1) << j;

	const int fit = (1 << 5) - 1;
	bool used[5];
	fill_n(used, 5, false);
	for (int i = 0; i < 5; ++i)
	{
		for (int j = 0; j < 5; ++j)
		{
			if (!used[j] && ((v[i] ^ hor[j]) == fit || (v[i] ^ rev(hor[j])) == fit))
			{
				used[j] = true;
				break;
			}
		}
	}


	return count(used, used + 5, true) == 5;
}
int main()
{
	while (true)
	{
		vector<int> block;
		for (int i = 0; i < 10; ++i)
		{
			char buf[16];
			scanf("%s", buf);
			if (*buf == 'E')
				return 0;
			int b = 0;
			for (int j = 0; j < 5; ++j)
				b = (b << 1) | (buf[j] == '1');
			block.push_back(b);
		}
		for (int i = 0; i < 9; ++i)
			if (block[i] != rev(block[i]))
				swap(block[i], block[9]);
		sort(block.begin(), block.begin() + 9);

		int res = 0;
		for (int i = 0; i < 3; ++i)
		{
			int r = 0;
			for (int j = (1 << 4) - 1; j < 1 << 9; j = next_combination(j))
			{
				vector<int> ver, hor;
				for (int k = 0, l = 0; k < 9; ++k)
				{
					if (j >> k & 1)
						ver.push_back(block[k]);
					else
						hor.push_back(block[k]);
				}

				do
				{
					for (int k = 0; k < 1 << 4; ++k)
					{
						bool any_synmetric = false;
						vector<int> v = ver;
						for (int l = 0; l < 4; ++l)
						{
							if (k >> l & 1)
							{
								if (v[l] == rev(v[l]))
								{
									any_synmetric = true;
									break;
								}
								v[l] = rev(v[l]);
							}
						}
						if (any_synmetric)
							continue;

						v.insert(v.begin() + i, block[9]);
						if (can_construct(v, hor))
							++r;
					}
				} while (next_permutation(all(ver)));
			}

			if (i == 2)
				r /= 2;
			res += r;
		}
		printf("%d\n", res);
	}
}