Problem:
Problem B:
Lattice Practices
Once upon a time, there was a king who loved beautiful costumes very much. The king had a special cocoon bed to make excellent cloth of silk. The cocoon bed had 16 small square rooms, forming a 4 × 4 lattice, for 16 silkworms. The cocoon bed can be depicted as follows:
The cocoon bed can be divided into 10 rectangular boards, each of which has 5 slits:
Note that, except for the slit depth, there is no difference between the left side and the right side of the board (or, between the front and the back); thus, we cannot distinguish a symmetric board from its rotated image as is shown in the following:
Slits have two kinds of depth, either shallow or deep. The cocoon bed should be constructed by fitting five of the boards vertically and the others horizontally, matching a shallow slit with a deep slit.
Your job is to write a program that calculates the number of possible configurations to make the lattice. You may assume that there is no pair of identical boards. Notice that we are interested in the number of essentially different configurations and therefore you should not count mirror image configurations and rotated configurations separately as different configurations.
The following is an example of mirror image and rotated configurations, showing vertical and horizontal boards separately, where shallow and deep slits are denoted by '1' and '0' respectively.
Notice that a rotation may exchange position of a vertical board and a horizontal board.
Input
The input consists of multiple data sets, each in a line. A data set gives the patterns of slits of 10 boards used to construct the lattice. The format of a data set is as follows:
XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX
Each x is either '0' or '1'. '0' means a deep slit, and '1' a shallow slit. A block of five slit descriptions corresponds to a board. There are 10 blocks of slit descriptions in a line. Two adjacent blocks are separated by a space.
For example, the first data set in the Sample Input means the set of the following 10 boards:
The end of the input is indicated by a line consisting solely of three characters "END".
Output
For each data set, the number of possible configurations to make the lattice from the given 10 boards should be output, each in a separate line.
Sample Input
10000 01000 00100 11000 01100 11111 01110 11100 10110 11110
10101 01000 00000 11001 01100 11101 01110 11100 10110 11010
END
Output for the Sample Input
40
6

Submitted solutions:

code_snippet: #include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define FOR(i,l,r) for(ll i=l;i<r;i++)
#define REP(i,n) FOR(i,0,n)
#define ALL(A) A.begin(),A.end()
#define LB(A,x) (lower_bound(ALL(A),x)-A.begin())
#define UB(A,x) (upper_bound(ALL(A),x)-A.begin())
int main(){
    while(1){
        vector<string>S(10);
        REP(i,10)cin>>S[i];
        vector<string>revS=S;
        REP(i,10)reverse(ALL(revS[i]));
        if(S[0]=="END")return 0;
        ll ans=0;
        REP(i,9)REP(j,9)if(i!=j)REP(k,9)if(k!=i&&k!=j)REP(l,9)if(l!=i&&l!=j&&l!=k)REP(m,i)if(m!=i&&m!=j&&m!=k&&m!=l){
            vector<string>T,revT,U={S[i],S[j],S[k],S[l],S[m]},revU={revS[i],revS[j],revS[k],revS[l],revS[m]};
            REP(n,10)if(n!=i&&n!=j&&n!=k&&n!=l&&n!=m){
                T.emplace_back(S[n]);
                revT.emplace_back(revS[n]);
            }
            REP(n,32){
                bool ok=1;
                REP(o,5)if((n>>o)%2&&U[o]==revU[o]){ok=0;break;}
                if(!ok)continue;
                vector<bool>K(5);
                REP(o,5){
                    string t;
                    REP(p,5){
                        if((n>>p)%2)t+=revU[p][o];
                        else t+=U[p][o];
                    }
                    REP(p,5)t[p]='1'+'0'-t[p];
                    ll a=0;
                    while(a<5&&T[a]!=t&&revT[a]!=t)a++;
                    if(a==5||K[a]){ok=0;break;}
                    K[a]=1;
                }
                if(ok){
                    //cout<<S[i]<<endl<<S[j]<<endl<<S[k]<<endl<<S[l]<<endl<<S[m]<<endl;
                    ans++;
                }
            }
        }
        ans/=2;
        cout<<ans<<endl;
    }
    return 0;
}
accuracy: 1
time_ms: 100
memory_kb: 3132
final_rank: 7

code_snippet: #include <iostream>
#include<vector>
#include<algorithm>
#include<utility>
#include<math.h>
#include<iomanip>
#include<string>
#include <cassert>
#include <complex>
#include<bits/stdc++.h>

#define rep(s,i,n) for(int i = s;i < n;i++)
 
using namespace std;
 
typedef long long ll; //10e18くらい
typedef long double ld;
typedef __int128_t lll;
typedef pair<ll, ll> pll;
 
const int dx[] = { 0,1,0,-1 };
const int dy[] = { 1,0,-1,0 };
const ll LongINF = 1e13 + 7;
const int INF = 1e9 + 7;
const ll LL_MAX = 9223372036854775807;
const ll LL_MIN = -9223372036854775807;
const double pi = 3.141592653589793;


int dsp[3] = {-1,0,1};

// int keta(ll i){

//   int keta = 0;
//   do{
//     keta++;
//   }while(i /= 10);

//   return keta;
// }
//素因数分解　O(√n)
// vector<pair<ll,ll>> pfactor(ll n){
//   vector<pair<ll,ll>> factor;
//    ll ex; //指数
//    for(ll a = 2; a * a <= n; a++){
//      if(n % a != 0)continue;

//      ll ex = 0;

//      while(n % a == 0){
//        n /= a;
//        ex++;
//      }

//      factor.push_back({a,ex});
//    }

//    if(n != 1) factor.push_back({n,1});

//   return factor; 
// }

string s[10];
string srev[10];
string H[5];
string W[5];
bool symm[10];//ブロックのスリットに対称性があるかどうか
//噛み合うかどうか確認する
bool check(int idx){
    rep(0,i,5){
        if(W[idx][i] == H[i][idx]) return false;
    }
    return true;
}

int solve(int idx,int S){
    if(S == (1<<10) - 1){
        return 1;
    }

    int res = 0;

    rep(0,i,10){
        //使ったブロックを、もう一度使うことは出来ない
        if( (S >> i) & 1)continue;
        //初めは縦に置く(idx < 5まで　＝ 初めの五回)
        if(idx < 5){
            H[idx] = s[i];
            //S i番目のブロックを使ったらsのiビット目が1になる
            res += solve(idx + 1,S| 1 << i);
            //対称性がないなら同じところに逆向きにおいてみる
            if(!symm[i]){
                H[idx] = srev[i];
                res += solve(idx + 1, S | (1 << i));
            }
        //縦に置き終わったら、横においていく
        }else{
            W[idx - 5] = s[i];
            if(check(idx - 5)){
                res += solve(idx + 1,S | (1 << i));
            }
            if(!symm[i]){
                W[idx - 5] = srev[i];
                if(check(idx - 5)){
                    res += solve(idx + 1,S | (1 << i));
                }
            }

        }
    }
    
    return res;
}




int main(void){

    
  while(cin >> s[0],s[0] != "END"){
      memset(symm,false,sizeof(symm));
      srev[0] = s[0];
      reverse(srev[0].begin(),srev[0].end());
      symm[0] = (s[0] == srev[0]);

      rep(0,i,9){
          cin >> s[i + 1];
          srev[i + 1] = s[i + 1];
          reverse(srev[i + 1].begin(),srev[i + 1].end());
          symm[i + 1] = (s[i + 1] == srev[i + 1]);//sとsrevが同じなら対称性がある
      }
      cout << solve(0,0)/8 << endl;

    // rep(0,i,10){
    //     cout << s[i] << ":" ;

    //     cout << srev[i] << endl;
    // }
    
  }  
  
  
  return 0;

}
accuracy: 1
time_ms: 1580
memory_kb: 3180
final_rank: 10

code_snippet: #include <bits/stdc++.h>
using namespace std;

const int N=10;

string slit[N+N];
int choose[N],used[N];


int check(int n) {
    int k=n/2;
    for (int i=n-1; i>=0; i-=2) {
        if (slit[choose[i]][k]+slit[choose[n]][i/2]!='0'+'1') return 0;
    }
    return 1;
}

int search(int n) {
    if (n==N) return 1;

    int cnt=0;
    for (int i=0; i<N; i++) {
        if (used[i]) continue;
        used[i]=1;

        choose[n]=i;
        if (check(n)) cnt+=search(n+1);

        if (!slit[N+i].empty()) {
            choose[n]=N+i;
            if (check(n)) cnt+=search(n+1);
        }

        used[i]=0;
    }
    return cnt;
}

int solve() {
    cin>>slit[0];
    if (slit[0]=="END") return 0;
    for (int i=1; i<N; i++) cin>>slit[i];

    for (int i=0; i<N; i++) {
        string rev(rbegin(slit[i]),rend(slit[i]));
        slit[N+i]=(rev!=slit[i] ? rev : "");
    }

    memset(used,0,sizeof(used));
    cout<<search(0)/8<<'\n';

    return 1;
}

int main() {
    while (solve());
    return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 3288
final_rank: 5

code_snippet: #include <cmath>
#include <vector>
#include <iostream>
#include <algorithm>
#include <set>
#include <iomanip>
#include <queue>
#include <string>
#include <map>
#include <fstream>
#include <cassert>
#include <stack>
#include <climits>
#include <array>
#include <unordered_set>
#include <unordered_map>
#include <memory>
#include <functional>
#include <cfloat>
#include <numeric>
#include <random>
#include <sstream>
#include <bitset>
using namespace std;
int reverse(int n) {
	int result{ 0 };
	for (auto i = 0; i < 5; ++i) {
		result <<= 1;
		result += n & 1;
		n >>= 1;
	}
	return result;
}
template<typename B>
void iterate(const std::vector<int>& a, const int current, const int count, const B& block, std::vector<int> &use, std::vector<int>& not_use) {
	if (current == a.size()) {
		return block(use, not_use);
	}
	if (a.size() > current + count) {
		not_use.push_back(a[current]);
		iterate(a, current + 1, count, block, use, not_use);
		not_use.pop_back();
	}
	if (count > 0) {
		use.push_back(a[current]);
		iterate(a, current + 1, count - 1, block, use, not_use);
		use.pop_back();
	}
}
template<typename B>
void iterate(const std::vector<int> &a, const B& block) {
	std::vector<int> use, not_use; use.reserve(5); not_use.reserve(5);
	use.push_back(a[0]);
	iterate(a, 1, 4, block, use, not_use);
}

int solve(std::vector<int> boards) {
	for (auto& a : boards) {
		if (a > reverse(a)) a = reverse(a);
	}
	std::sort(boards.begin(), boards.end());
	int count{ 0 };
	const auto block = [&count](std::vector<int> horizontal, std::vector<int> vertical) {
		std::vector<int> index(5), actual(5); std::iota(index.begin(), index.end(), 0);
		int mask{ 0 }, c{ 0 };
		for (auto i = 0; i < 5; ++i) {
			if (horizontal[i] == reverse(horizontal[i])) mask += 1 << i;
		}
		do {
			if (index[0] > index[4]) continue;
			for (auto pattern = 0; pattern < 32; ++pattern) {
				if ((mask & pattern) != 0) continue;
				for (auto i = 0; i < 5; ++i) {
					actual[i] = (pattern >> index[i] & 1) == 0 ? horizontal[index[i]] : reverse(horizontal[index[i]]);
				}
				for (auto i = 0; i < 5; ++i) {
					int target{ 0 };
					for (auto j = 0; j < 5; ++j) {
						target += (((actual[j] >> i) & 1) ^ 1) << j;
					}
					auto find = std::find(vertical.begin() + i, vertical.end(), target);
					if (find == vertical.end()) {
						find = std::find(vertical.begin() + i, vertical.end(), reverse(target));
					}
					if (find == vertical.end()) {
						--c;
						break;
					}
					else {
						std::swap(vertical[i], *find);
					}
				}
				++c;
			}
		} while (std::next_permutation(index.begin(), index.end()));
		count += c;
	};
	iterate(boards, block);
	return count >> 1;
}

int main() {
	while (true) {
		std::string first; std::cin >> first;
		if (first == "END") break;
		std::vector<int> boards(10);
		boards[0] = std::stoi(first, nullptr, 2);
		for (auto i = 1; i < 10; ++i) {
			std::cin >> first;
			boards[i] = std::stoi(first, nullptr, 2);
		}
		std::cout << solve(boards) << '\n';
	}
}
accuracy: 1
time_ms: 30
memory_kb: 3296
final_rank: 6

code_snippet: #include <stdio.h>
#include <cmath>
#include <algorithm>
#include <cfloat>
#include <stack>
#include <queue>
#include <vector>
#include <string>
#include <iostream>
#include <set>
#include <map>
#include <time.h>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;

char table[20][6];

int ans;

void recursive(bool used[20],int yoko[5],int yoko_index,int tate[5],int tate_index,bool is_pre_yoko){

	if(is_pre_yoko == false && tate_index == 5){
		ans++;
		return;
	}

	if(is_pre_yoko == false){

		switch(yoko_index){
		case 0:
			for(int i = 0; i < 20; i++){
				if(used[i] == false){
					int next_yoko[5];
					next_yoko[0] = i;
					bool next_used[20];
					for(int k = 0; k < 20; k++)next_used[k] = used[k];
					next_used[i] = true;
					if(i <= 9)next_used[i+10] = true;
					else{
						next_used[i-10] = true;
					}
					recursive(next_used,next_yoko,yoko_index+1,tate,tate_index,true);
				}
			}
			break;
		case 1:
			for(int i = 0; i < 20; i++){
				if(used[i] == false && abs(table[tate[0]][1]-table[i][0]) == 1){
					int next_yoko[5];
					for(int k = 0; k < 1; k++)next_yoko[k] = yoko[k];
					next_yoko[1] = i;
					bool next_used[20];
					for(int k = 0; k < 20; k++)next_used[k] = used[k];
					next_used[i] = true;
					if(i <= 9)next_used[i+10] = true;
					else{
						next_used[i-10] = true;
					}
					recursive(next_used,next_yoko,yoko_index+1,tate,tate_index,true);
				}
			}
			break;
		case 2:
			for(int i = 0; i < 20; i++){
				if(used[i] == false && abs(table[tate[0]][2]-table[i][0]) == 1 &&  abs(table[tate[1]][2]-table[i][1]) == 1){
					int next_yoko[5];
					for(int k = 0; k < 2; k++)next_yoko[k] = yoko[k];
					next_yoko[2] = i;
					bool next_used[20];
					for(int k = 0; k < 20; k++)next_used[k] = used[k];
					next_used[i] = true;
					if(i <= 9)next_used[i+10] = true;
					else{
						next_used[i-10] = true;
					}
					recursive(next_used,next_yoko,yoko_index+1,tate,tate_index,true);
				}
			}
			break;
		case 3:
			for(int i = 0; i < 20; i++){
				if(used[i] == false && abs(table[tate[0]][3]-table[i][0]) == 1 &&  abs(table[tate[1]][3]-table[i][1]) == 1 &&
						abs(table[tate[2]][3]-table[i][2]) == 1 ){
					int next_yoko[5];
					for(int k = 0; k < 3; k++)next_yoko[k] = yoko[k];
					next_yoko[3] = i;
					bool next_used[20];
					for(int k = 0; k < 20; k++)next_used[k] = used[k];
					next_used[i] = true;
					if(i <= 9)next_used[i+10] = true;
					else{
						next_used[i-10] = true;
					}
					recursive(next_used,next_yoko,yoko_index+1,tate,tate_index,true);
				}
			}
			break;
		case 4:
			for(int i = 0; i < 20; i++){
				if(used[i] == false && abs(table[tate[0]][4]-table[i][0]) == 1 &&  abs(table[tate[1]][4]-table[i][1]) == 1 &&
						abs(table[tate[2]][4]-table[i][2]) == 1 && abs(table[tate[3]][4]-table[i][3]) == 1){
					int next_yoko[5];
					for(int k = 0; k < 4; k++)next_yoko[k] = yoko[k];
					next_yoko[4] = i;
					bool next_used[20];
					for(int k = 0; k < 20; k++)next_used[k] = used[k];
					next_used[i] = true;
					if(i <= 9)next_used[i+10] = true;
					else{
						next_used[i-10] = true;
					}
					recursive(next_used,next_yoko,yoko_index+1,tate,tate_index,true);
				}
			}
			break;
		}

	}else{

		switch(tate_index){
		case 0:
			for(int i = 0; i < 20; i++){
				if(used[i] == false && abs(table[yoko[0]][0] - table[i][0]) == 1){
					int next_tate[5];
					next_tate[0] = i;
					bool next_used[20];
					for(int k = 0; k < 20; k++)next_used[k] = used[k];
					next_used[i] = true;
					if(i <= 9)next_used[i+10] = true;
					else{
						next_used[i-10] = true;
					}
					recursive(next_used,yoko,yoko_index,next_tate,tate_index+1,false);
				}
			}
			break;
		case 1:
			for(int i = 0; i < 20; i++){
				if(used[i] == false && abs(table[yoko[0]][1] - table[i][0]) == 1 && abs(table[yoko[1]][1]-table[i][1]) == 1){
					int next_tate[5];
					for(int k = 0; k < 1; k++)next_tate[k] = tate[k];
					next_tate[1] = i;
					bool next_used[20];
					for(int k = 0; k < 20; k++)next_used[k] = used[k];
					next_used[i] = true;
					if(i <= 9)next_used[i+10] = true;
					else{
						next_used[i-10] = true;
					}
					recursive(next_used,yoko,yoko_index,next_tate,tate_index+1,false);
				}
			}
			break;
		case 2:
			for(int i = 0; i < 20; i++){
				if(used[i] == false && abs(table[yoko[0]][2] - table[i][0]) == 1 && abs(table[yoko[1]][2]-table[i][1]) == 1 &&
						abs(table[yoko[2]][2]-table[i][2]) == 1){
					int next_tate[5];
					for(int k = 0; k < 2; k++)next_tate[k] = tate[k];
					next_tate[2] = i;
					bool next_used[20];
					for(int k = 0; k < 20; k++)next_used[k] = used[k];
					next_used[i] = true;
					if(i <= 9)next_used[i+10] = true;
					else{
						next_used[i-10] = true;
					}
					recursive(next_used,yoko,yoko_index,next_tate,tate_index+1,false);
				}
			}
			break;
		case 3:
			for(int i = 0; i < 20; i++){
				if(used[i] == false && abs(table[yoko[0]][3] - table[i][0]) == 1 && abs(table[yoko[1]][3]-table[i][1]) == 1 &&
						abs(table[yoko[2]][3]-table[i][2]) == 1 && abs(table[yoko[3]][3]-table[i][3]) == 1){
					int next_tate[5];
					for(int k = 0; k < 3; k++)next_tate[k] = tate[k];
					next_tate[3] = i;
					bool next_used[20];
					for(int k = 0; k < 20; k++)next_used[k] = used[k];
					next_used[i] = true;
					if(i <= 9)next_used[i+10] = true;
					else{
						next_used[i-10] = true;
					}
					recursive(next_used,yoko,yoko_index,next_tate,tate_index+1,false);
				}
			}
			break;
		case 4:
			for(int i = 0; i < 20; i++){
				if(used[i] == false && abs(table[yoko[0]][4] - table[i][0]) == 1 && abs(table[yoko[1]][4]-table[i][1]) == 1 &&
						abs(table[yoko[2]][4]-table[i][2]) == 1 && abs(table[yoko[3]][4]-table[i][3]) == 1 && abs(table[yoko[4]][4]-table[i][4]) == 1){
					int next_tate[5];
					for(int k = 0; k < 4; k++)next_tate[k] = tate[k];
					next_tate[4] = i;
					bool next_used[20];
					for(int k = 0; k < 20; k++)next_used[k] = used[k];
					next_used[i] = true;
					if(i <= 9)next_used[i+10] = true;
					else{
						next_used[i-10] = true;
					}
					recursive(next_used,yoko,yoko_index,next_tate,tate_index+1,false);
				}
			}
			break;
		}
	}
}

void func(){

	for(int i = 1; i <= 9; i++)scanf("%s",table[i]);

	bool first_used[20];
	for(int i = 0; i < 20; i++)first_used[i] = false;

	for(int i = 0; i < 10; i++){
		for(int k = 0; k < 5; k++)table[i+10][k] = table[i][4-k];

		if(table[i][0] == table[i][4] && table[i][1] == table[i][3]){
			first_used[i+10] = true;
		}
	}

	ans = 0;

	int first_yoko[5],first_tate[5];

	recursive(first_used,first_yoko,0,first_tate,0,false);

	printf("%d\n",ans/8);
}

int main(){

	while(true){
		scanf("%s",table[0]);
		if(table[0][0] == 'E')break;

		func();
	}

	return 0;
}
accuracy: 1
time_ms: 20
memory_kb: 3168
final_rank: 4

code_snippet: #include <bits/stdc++.h>
#define int long long
#define N 100010
using namespace std;
typedef unsigned long long ull;
const int INF = 1LL<<55;
const int mod = (1e9)+7;
const double EPS = 1e-8;
const double PI = 6.0 * asin(0.5);
template<class T> T Max(T &a,T b){return a=max(a,b);}
template<class T> T Min(T &a,T b){return a=min(a,b);}
vector<vector<int> > AB,A,B;
int Aidx[5],Bidx[5];

set<ull> S;
ull VtoH(const vector<vector<int> > &v){
  const ull B = 1777771;
  ull res = 0;
  for(int i=0;i<5;i++)
    for(int j=0;j<5;j++) res = res * B + (v[i][j]+'0');
  return res;
}

vector<int> rev(vector<int> a){reverse(a.begin(),a.end());return a;}
void mirror(vector<vector<int> > &res){for(int i=0;i<5;i++) res[i] = rev(res[i]);}

vector<vector<int> > rot(const vector<vector<int> > &a){
  vector<vector<int> > res(5,vector<int>(5));
  for(int i=0;i<5;i++)
    for(int j=0;j<5;j++) res[i][j] = a[4-j][i];
  return res;
}

void insert(vector<vector<int> > &v){
  S.insert(VtoH(v));
  v = rot(v) , v = rot(v), S.insert(VtoH(v));
  mirror(v), S.insert(VtoH(v));
  v = rot(v) , v = rot(v), S.insert(VtoH(v));
}

bool canPut(int idx,int j){
  int a = 1, b = 1;
  for(int i=0;i<5;i++) if(A[i][j] == B[idx][i]) a = 0;
  for(int i=0;i<5;i++) if(A[i][j] == B[idx][4-i]) b = 0;
  return a || b;
}

bool can(){
  int used = 0;
  for(int i=0;i<5;i++){
    for(int nx=0;nx<5;nx++){
      if((used>>nx&1) || !canPut(nx,i)) continue;
      Bidx[i] = nx;
      used |= (1<<nx);
      break;
    }
  }
  return used == (1<<5)-1;
}

int solve(){
  S.clear();
  int res = 0;
  for(int i=0;i<5;i++) Aidx[i] = i;
  for(int bit=0;bit<(1<<10);bit++){
    if(__builtin_popcount(bit) != 5) continue;    
    A.clear();B.clear();
    for(int i=0;i<10;i++) (bit>>i&1)? A.push_back(AB[i]):B.push_back(AB[i]);
    vector<vector<int> > tmp = A;
    do{
      for(int a=0;a<(1<<5);a++){
        for(int i=0;i<5;i++) A[Aidx[i]] = (a>>i&1)? rev(tmp[i]):tmp[i];
        if(!can() || S.count(VtoH(A))) continue;
        insert(A);
        res++;
      }
    } while(next_permutation(Aidx,Aidx+5));
  }
  return res/2;
}

signed main(){
  while(1){
    AB.clear();
    for(int i=0;i<10;i++){
      string str;
      cin>>str;
      if(str == "END") return 0;
      vector<int> tmp(5);
      for(int j=0;j<5;j++) tmp[j] = str[j] - '0';
      AB.push_back(tmp);
    }
    cout<<solve()<<endl;
  }
  return 0;
}
accuracy: 1
time_ms: 2750
memory_kb: 3200
final_rank: 16

code_snippet: #include <bits/stdc++.h>
#define int long long
#define N 100010
using namespace std;
typedef unsigned long long ull;
const int INF = 1LL<<55;
const int mod = (1e9)+7;
const double EPS = 1e-8;
const double PI = 6.0 * asin(0.5);
template<class T> T Max(T &a,T b){return a=max(a,b);}
template<class T> T Min(T &a,T b){return a=min(a,b);}
vector<vector<int> > AB,A,B;
int Aidx[5],Bidx[5];

unordered_set<ull> S;
ull VtoH(const vector<vector<int> > &v){
  const ull B = 1777771;
  ull res = 0;
  for(int i=0;i<5;i++)
    for(int j=0;j<5;j++) res = res * B + (v[i][j]+'0');
  return res;
}

vector<int> rev(vector<int> a){reverse(a.begin(),a.end());return a;}
void mirror(vector<vector<int> > &res){for(int i=0;i<5;i++) res[i] = rev(res[i]);}

vector<vector<int> > rot(const vector<vector<int> > &a){
  vector<vector<int> > res(5,vector<int>(5));
  for(int i=0;i<5;i++)
    for(int j=0;j<5;j++) res[i][j] = a[4-j][i];
  return res;
}

void insert(vector<vector<int> > &v){
  S.insert(VtoH(v));
  v = rot(v) , v = rot(v), S.insert(VtoH(v));
  mirror(v), S.insert(VtoH(v));
  v = rot(v) , v = rot(v), S.insert(VtoH(v));
}

bool canPut(int idx,int j){
  int a = 1, b = 1;
  for(int i=0;i<5;i++) if(A[i][j] == B[idx][i]) a = 0;
  for(int i=0;i<5;i++) if(A[i][j] == B[idx][4-i]) b = 0;
  return a || b;
}

bool can(){
  int used = 0;
  for(int i=0;i<5;i++){
    for(int nx=0;nx<5;nx++){
      if((used>>nx&1) || !canPut(nx,i)) continue;
      Bidx[i] = nx;
      used |= (1<<nx);
      break;
    }
  }
  return used == (1<<5)-1;
}

int solve(){
  S.clear();
  int res = 0;
  for(int i=0;i<5;i++) Aidx[i] = i;
  for(int bit=0;bit<(1<<10);bit++){
    if(__builtin_popcount(bit) != 5) continue;    
    A.clear();B.clear();
    for(int i=0;i<10;i++) (bit>>i&1)? A.push_back(AB[i]):B.push_back(AB[i]);
    vector<vector<int> > tmp = A;
    do{
      for(int a=0;a<(1<<5);a++){
        for(int i=0;i<5;i++) A[Aidx[i]] = (a>>i&1)? rev(tmp[i]):tmp[i];
        if(!can() || S.count(VtoH(A))) continue;
        insert(A);
        res++;
      }
    } while(next_permutation(Aidx,Aidx+5));
  }
  return res/2;
}

signed main(){
  while(1){
    AB.clear();
    for(int i=0;i<10;i++){
      string str;
      cin>>str;
      if(str == "END") return 0;
      vector<int> tmp(5);
      for(int j=0;j<5;j++) tmp[j] = str[j] - '0';
      AB.push_back(tmp);
    }
    cout<<solve()<<endl;
  }
  return 0;
}
accuracy: 1
time_ms: 2760
memory_kb: 3196
final_rank: 17

code_snippet: #include <bits/stdc++.h>
#define int long long
#define N 100010
using namespace std;
typedef unsigned long long ull;
const int INF = 1LL<<55;
const int mod = (1e9)+7;
const double EPS = 1e-8;
const double PI = 6.0 * asin(0.5);
template<class T> T Max(T &a,T b){return a=max(a,b);}
template<class T> T Min(T &a,T b){return a=min(a,b);}
vector<vector<int> > AB,A,B;
int Aidx[5],Bidx[5];

unordered_set<ull> S;
ull VtoH(const vector<vector<int> > &v){
  const ull B = 1777771;
  ull res = 0;
  for(int i=0;i<5;i++)
    for(int j=0;j<5;j++) res = res * B + (v[i][j]+'0');
  return res;
}

vector<int> rev(vector<int> a){reverse(a.begin(),a.end());return a;}
void mirror(vector<vector<int> > &res){for(int i=0;i<5;i++) res[i] = rev(res[i]);}

vector<vector<int> > rot(const vector<vector<int> > &a){
  vector<vector<int> > res(5,vector<int>(5));
  for(int i=0;i<5;i++)
    for(int j=0;j<5;j++) res[i][j] = a[4-j][i];
  return res;
}

void insert(vector<vector<int> > v){
  S.insert(VtoH(v));
  v = rot(v) , v = rot(v), S.insert(VtoH(v));
  mirror(v), S.insert(VtoH(v));
  v = rot(v) , v = rot(v), S.insert(VtoH(v));
}

bool canPut(int idx,int j){
  int a = 1, b = 1;
  for(int i=0;i<5;i++) if(A[i][j] == B[idx][i]) a = 0;
  for(int i=0;i<5;i++) if(A[i][j] == B[idx][4-i]) b = 0;
  return a || b;
}

bool can(){
  int used = 0;
  for(int i=0;i<5;i++){
    for(int nx=0;nx<5;nx++){
      if((used>>nx&1) || !canPut(nx,i)) continue;
      Bidx[i] = nx;
      used |= (1<<nx);
      break;
    }
  }
  return used == (1<<5)-1;
}

int solve(){
  S.clear();
  int res = 0;
  for(int i=0;i<5;i++) Aidx[i] = i;
  for(int bit=0;bit<(1<<10);bit++){
    if(__builtin_popcount(bit) != 5) continue;    
    A.clear();B.clear();
    for(int i=0;i<10;i++) (bit>>i&1)? A.push_back(AB[i]):B.push_back(AB[i]);
    vector<vector<int> > tmp = A;
    do{
      for(int a=0;a<(1<<5);a++){
        for(int i=0;i<5;i++) A[Aidx[i]] = (a>>i&1)? rev(tmp[i]):tmp[i];
        if(!can() || S.count(VtoH(A))) continue;
        insert(A);
        res++;
      }
    } while(next_permutation(Aidx,Aidx+5));
  }
  return res/2;
}

signed main(){
  while(1){
    AB.clear();
    for(int i=0;i<10;i++){
      string str;
      cin>>str;
      if(str == "END") return 0;
      vector<int> tmp(5);
      for(int j=0;j<5;j++) tmp[j] = str[j] - '0';
      AB.push_back(tmp);
    }
    cout<<solve()<<endl;
  }
  return 0;
}
accuracy: 1
time_ms: 2730
memory_kb: 3184
final_rank: 15

code_snippet: #include <bits/stdc++.h>
#define int long long
#define N 100010
using namespace std;
typedef unsigned long long ull;
const int INF = 1LL<<55;
const int mod = (1e9)+7;
const double EPS = 1e-8;
const double PI = 6.0 * asin(0.5);
template<class T> T Max(T &a,T b){return a=max(a,b);}
template<class T> T Min(T &a,T b){return a=min(a,b);}
vector<vector<int> > AB,A,B;
int Aidx[5],Bidx[5];

unordered_set<ull> S;
ull VtoH(const vector<vector<int> > &v){
  const ull B = 1777771;
  ull res = 0;
  for(int i=0;i<5;i++)
    for(int j=0;j<5;j++) res = res * B + (v[i][j]+'0');
  return res;
}

vector<int> rev(vector<int> a){reverse(a.begin(),a.end());return a;}
void mirror(vector<vector<int> > &res){for(int i=0;i<5;i++) res[i] = rev(res[i]);}

vector<vector<int> > rot(const vector<vector<int> > &a){
  vector<vector<int> > res(5,vector<int>(5));
  for(int i=0;i<5;i++)
    for(int j=0;j<5;j++) res[i][j] = a[4-j][i];
  return res;
}

void insert(vector<vector<int> > v){
  S.insert(VtoH(v));
  v = rot(v) , v = rot(v), S.insert(VtoH(v));
  mirror(v), S.insert(VtoH(v));
  v = rot(v) , v = rot(v), S.insert(VtoH(v));
}

bool canPut(int idx,int j){
  int a = 1, b = 1;
  for(int i=0;i<5;i++) if(A[i][j] == B[idx][i]) a = 0;
  for(int i=0;i<5;i++) if(A[i][j] == B[idx][4-i]) b = 0;
  return a || b;
}

bool can(){
  int used = 0;
  for(int i=0;i<5;i++){
    for(int nx=0;nx<5;nx++){
      if((used>>nx&1) || !canPut(nx,i)) continue;
      Bidx[i] = nx;
      used |= (1<<nx);
      break;
    }
  }
  return used == (1<<5)-1;
}

int solve(){
  S.clear();
  int res = 0;
  for(int i=0;i<5;i++) Aidx[i] = i;
  for(int bit=0;bit<(1<<10);bit++){
    if(__builtin_popcount(bit) != 5) continue;    
    A.clear();B.clear();
    for(int i=0;i<10;i++) (bit>>i&1)? A.push_back(AB[i]):B.push_back(AB[i]);
    vector<vector<int> > tmp = A;
    do{
      for(int a=0;a<(1<<5);a++){
        for(int i=0;i<5;i++) A[Aidx[i]] = (a>>i&1)? rev(tmp[i]):tmp[i];
        if(S.count(VtoH(A)) || !can()) continue;
        insert(A);
        res++;
      }
    } while(next_permutation(Aidx,Aidx+5));
  }
  return res/2;
}

signed main(){
  while(1){
    AB.clear();
    for(int i=0;i<10;i++){
      string str;
      cin>>str;
      if(str == "END") return 0;
      vector<int> tmp(5);
      for(int j=0;j<5;j++) tmp[j] = str[j] - '0';
      AB.push_back(tmp);
    }
    cout<<solve()<<endl;
  }
  return 0;
}
accuracy: 1
time_ms: 3160
memory_kb: 3184
final_rank: 18

code_snippet: #include <bits/stdc++.h>
#define r(i,n) for(int i=0;i<n;i++)
using namespace std;
int ans;
string s[10],r[10];
string t1[5],t2[5];
bool b[11];
bool check(int p){
  r(i,5)if(t1[i][p]==t2[p][i])return 0;
  return 1;
}
void dfs2(int d){
  if(d==5)ans++;
  else{
    r(i,10)if(!b[i]){
      b[i]=1;
      t2[d]=s[i];
      if(check(d))dfs2(d+1);
      t2[d]=r[i];
      if(check(d))dfs2(d+1);
      b[i]=0;
    }
  }
}
void dfs(int d){
  if(d==5)dfs2(0);
  else{
    r(i,10)if(!b[i]){
      b[i]=1;
      t1[d]=s[i];
      dfs(d+1);
      t1[d]=r[i];
      dfs(d+1);
      b[i]=0;
    }
  }
}
main(){
  while(cin>>s[0],s[0]!="END"){
    memset(b,0,sizeof(b));
    ans=0;
    r[0]=s[0];
    reverse(r[0].begin(),r[0].end());
    r(i,9){
      cin>>s[i+1];
      r[i+1]=s[i+1];
      reverse(r[i+1].begin(),r[i+1].end());
    }
    int p=0;
    r(i,10)if(s[i]==r[i])p++;
    dfs(0);
    cout<<ans/(pow(2,p)*8)<<endl;
  }
}
accuracy: 1
time_ms: 5080
memory_kb: 3404
final_rank: 19

code_snippet: #include<bits/stdc++.h>
using namespace std;
#define int long long
string s[10];
set<int> si,us,cu;
vector<int> v;
int x,y;
int calc(const int a[5][5]){
  int res=0;
  for(int i=0;i<5;i++)
    for(int j=0;j<5;j++)
      res+=(1LL<<(i*5+j))*a[i][j];
  return res;
}
int calc2(const int a[5][5]){
  int res=0;
  for(int i=0;i<5;i++)
    for(int j=0;j<5;j++)
      res+=(1LL<<(i*5+j))*a[i][4-j];
  return res;
}
string t[5];
bool check(){
  map<string,int> ms;
  for(int i=0;i<10;i++){
    if(cu.count(i)) continue;
    string tmp=s[i];
    ms[tmp]++;
    reverse(tmp.begin(),tmp.end());
    ms[tmp]++;
  }
  for(int i=0;i<5;i++){
    string tmp=t[i];
    ms[tmp]--;
    reverse(tmp.begin(),tmp.end());
    ms[tmp]--;
    if(ms[t[i]]<0) return false;
  }
  return true;
}
set<int> memo[6];
void dfs(int d){
  if(memo[d].count(x)) return;
  memo[d].insert(x);
  if(d==5){
    if(si.count(x)) return;
    if(!check()) return;
    si.insert(x);
    return;
  }
  for(int i=0;i<20;i++){
    if(cu.count(i%10)) continue;
    cu.insert(i%10);
    if(i>=10) reverse(s[i%10].begin(),s[i%10].end());
    v.push_back(i%10);
    for(int j=0;j<5;j++){
      t[j]+=(s[i%10][j]=='1'?'0':'1');
      x+=(1LL<<(d*5+j))*(s[i%10][j]=='1');
    }
    dfs(d+1);
    v.pop_back();
    for(int j=0;j<5;j++){
      t[j].pop_back();
      x-=(1LL<<(d*5+j))*(s[i%10][j]=='1');
    }
    if(i>=10) reverse(s[i%10].begin(),s[i%10].end());
    cu.erase(i%10);
  }
}
signed main(){
  while(cin>>s[0],s[0]!="END"){
    for(int i=1;i<10;i++) cin>>s[i];
    si.clear();
    us.clear();
    for(int i=0;i<6;i++) memo[i].clear();
    x=y=0;
    dfs(0);
    int a[5][5];
    int c[5][5];
    int ans=0;
    for(int b:si){
      if(us.count(b)) continue;
      for(int i=0;i<5;i++)
	for(int j=0;j<5;j++)
	  a[i][j]=(b>>(i*5+j))&1;
      us.insert(calc(a));
      us.insert(calc2(a));
      for(int i=0;i<5;i++)
	for(int j=0;j<5;j++)
	  c[i][j]=a[4-j][i];
      us.insert(calc(c));
      us.insert(calc2(c));
      for(int i=0;i<5;i++)
	for(int j=0;j<5;j++)
	  c[i][j]=a[j][4-i];
      us.insert(calc(c));
      us.insert(calc2(c));
      for(int i=0;i<5;i++)
	for(int j=0;j<5;j++)
	  c[i][j]=a[4-i][4-j];
      us.insert(calc(c));
      us.insert(calc2(c));
      ans++;
    }
    //cout<<si.size()<<endl<<us.size()<<endl;
    cout<<ans/2<<endl;
  }
  return 0;
}
accuracy: 1
time_ms: 7710
memory_kb: 30904
final_rank: 20

code_snippet: #include "bits/stdc++.h"
#include<unordered_map>
#include<unordered_set>
#pragma warning(disable:4996)
using namespace std;
using ld = long double;
const ld eps = 1e-9;

//// < "d:\d_download\visual studio 2015\projects\programing_contest_c++\debug\a.txt" > "d:\d_download\visual studio 2015\projects\programing_contest_c++\debug\b.txt"

int getnum(vector<int>&used, const vector<vector<int>>&walls, vector<vector<int>>&decided,int now) {
	int sum = 0;
	if (now == 10)return 1;
	else 	if (now < 5) {
		const int y = now;
		for (int i = 0; i < 10; ++i) {
			if (used[i])continue;
			else {
				used[i] = true;
				for (int rev = 0; rev < 2; ++rev) {
					if (rev&&walls[i][0] == walls[i][4] && walls[i][1] == walls[i][3])continue;
					for (int x = 0; x < 5; ++x) {
						decided[y][rev?4-x:x] = walls[i][x];
					}
					sum += getnum(used, walls, decided, now + 1);
					for (int x = 0; x < 5; ++x) {
						decided[y][rev ? 4 - x : x] = -1;
					}
				}
				used[i] = false;
				
			}
		}
		
	}
	else {
		const int x = now-5;
		for (int i = 0; i < 10; ++i) {
			if (used[i])continue;
			else {
				used[i] = true;
				for (int rev = 0; rev < 2; ++rev) {
					if (rev&&walls[i][0] == walls[i][4] && walls[i][1] == walls[i][3])continue;

					bool ok = true;
					for (int y = 0; y < 5; ++y) {
						if (decided[rev ? 4 - y : y][x] == walls[i][y])ok = false;
					}
					if (!ok)continue;
					
					sum += getnum(used, walls, decided, now + 1);

				}
				used[i] = false;

			}
		}

	}
	return sum;
}

int main() {
	while (1) {
		vector<vector<int>>walls (10);
		for (int i = 0; i < 10; ++i) {
			string st; cin >> st;
			if (st == "END")return 0;
			else {
				for (int j = 0; j< 5; ++j) {
					walls[i].push_back(st[j] == '1');
				}
			}
		}
		vector<int>used(10, false);
		vector<vector<int>>decided(5, vector<int>(5, -1));
		int ans = getnum(used, walls, decided, 0);
		cout << ans/8<< endl;
	}
	return 0;
}
accuracy: 1
time_ms: 460
memory_kb: 3120
final_rank: 9

code_snippet: #include <iostream>
#include <cstdio>
#include <cstdlib>
#include <string>
#include <vector>
#include <deque>
#include <list>
#include <algorithm>
#include <numeric>
#include <functional>
#include <cmath>
#include <cstring>
#include <cctype>
#include <sstream>
#include <set>
#include <map>
#include <stack>
#include <queue>
#include <complex>
using namespace std;
#define REP(i,n) for(int i = 0; i < (int)n; i++)
#define FOR(i,a,b) for(int i = a; i < (int)b; i++)
#define pb push_back
#define mp make_pair
typedef vector<int> vi;
typedef pair<int, int> pi;
typedef long long ll;
const int INF = 1<<28;
const ll MOD = 1000000007;

int cnt;
string s[2][10];
bool same[10];

bool chk(string &a, string &b, int &pnt) {
	REP(i, 5) {
		if(a[i*5 + pnt - 5] == b[i])
			return false;
	}
	return true;
}

void dfs(int pnt, string done, bool b[2][10]) {
	if(pnt == 10) {
		/*
		//debug
		REP(i, 10) {
			REP(j, 5) {
				cout << done[i*5 + j] << ' ';
			}
			cout << endl;
			if(i == 4) cout << "-----" << endl;
		}
		cout << endl;
		*/
		cnt++;
		return;
	}
	if(pnt < 5) {
		REP(i, 2) REP(j, 10) {
			if(!b[i][j]) {
				b[0][j] = true;
				b[1][j] = true;
				dfs(pnt+1, done + s[i][j], b);
				b[0][j] = false;
				if(!same[j]) b[1][j] = false;
			}
		}
	}
	else {
		REP(i, 2) REP(j, 10) {
			if(!b[i][j] && chk(done, s[i][j], pnt)) {
				b[0][j] = true;
				b[1][j] = true;
				dfs(pnt+1, done + s[i][j], b);
				b[0][j] = false;
				if(!same[j]) b[1][j] = false;
			}
		}
	}
	return;
}

int main() {
	string in;
	while(cin >> in, in != "END") {
		bool b[2][10] = {};
		REP(i, 10) {
			if(i)
				cin >> in;
			s[0][i] = in;
			reverse(in.begin(), in.end());
			s[1][i] = in;
			same[i] = s[0][i] == s[1][i] ? true:false;
		}
		cnt = 0;
		dfs(0, "", b);
		cout << cnt / 8 << endl;
	}
	return 0;
}
accuracy: 1
time_ms: 870
memory_kb: 1200
final_rank: 8

code_snippet: #include<bits/stdc++.h>
using namespace std;

/*
string cocoon[10];
char area[5][5];
int ans;

bool check(bool used[]){
	bool flag = false;



	return flag;
}

void dfs(bool used[], depth){
	if (depth == 5){

	}


	return;
}


int main(){
	while (cin >> cocoon[0] && cocoon[0][0] != 'E'){
		for (int i = 1; i < 10; i++){
			cin >> cocoon[i];
		}

		ans = 0;
		bool used[10] = { false };

		cout << ans / 8 << endl;
	}
	return 0;


}

*/

int cocoon[10][5];
int area[5][5];
vector<int> bita, bitb;
int ans;

bool used[10];

void check(int depth){
	int ret = 0;

	if (depth == 10){
		ans++;
		return;
	}
	else if (depth >= 5){
		for (int i = 0; i < 5; i++){
			int num = bitb[i];
			if (used[num]) continue;
			used[num] = true;
			bool flag1 = true, flag2 = true;

			for (int j = 0; j < 5; j++){
				if (area[j][depth - 5] == cocoon[num][j]) flag1 = false;
				if (area[j][depth - 5] == cocoon[num][4 - j]) flag2 = false;
			}

			if (flag1 || flag2) check(depth + 1);
			
			used[num] = false;
		}
	}
	else{
		for (int i = 0; i < 5; i++){
			int num = bita[i];
			if (used[num]) continue;
			used[num] = true;

			for (int j = 0; j < 5; j++){
				area[depth][j] = cocoon[num][j];
			}
			check(depth + 1);

			if (cocoon[num][0] == cocoon[num][4] && cocoon[num][1] == cocoon[num][3]){
				used[num] = false;
				continue;
			}

			for (int j = 0; j < 5; j++){
				area[depth][j] = cocoon[num][4 - j];
			}
			check(depth + 1);

			used[num] = false;
		}
	}

	return;
}


int main(void){

	char in[50];

	while (cin >> in){
		if (in[0] == 'E') break;

		for (int j = 0; j < 5; j++){
			cocoon[0][j] = in[j] - '0';
		}

		for (int i = 1; i <= 9; i++){
			cin >> in;
			for (int j = 0; j < 5; j++){
				cocoon[i][j] = in[j] - '0';
			}
		}
		
		ans = 0;

		for (int i = 0; i < 512; i++){
			
			bita.clear();
			bitb.clear();
			int num = i;
			for (int j = 0; j <= 9; j++){
				if (num % 2 != 0) bita.push_back(j);
				else bitb.push_back(j);

				num = num / 2;
			}

			if (bita.size() != 5) continue;

			check(0);

		}

		cout << ans / 4 << endl;

	}

	return 0;
}



/*

void check(vector<int> a, vector<int> b){

	if (!a.empty()){
		int count = a.size();
		for (int i = 0; i < count; i++){
			vector<int> aa(a);
			int num = a[i];
			aa.erase(aa.begin() + i);
			for (int j = 0; j < 5; j++){
				area[5 - count][j] = cocoon[num][j];
			}
			check(aa, b);
			for (int j = 0; j < 5; j++){
				area[5 - count][j] = cocoon[num][4 - j];
			}
			check(aa, b);
		}
	}
	else if (!b.empty()){
		int count = b.size();
		for (int i = 0; i < count; i++){
			vector<int> bb(b);
			int num = b[i];
			bool flag1 = true, flag2 = true;
			for (int j = 0; j < 5; j++){
				if (area[j][5 - count] == cocoon[num][j]) flag1 = false;
				if (area[j][5 - count] == cocoon[num][4 - j]) flag2 = false;
			}

			bb.erase(bb.begin() + i);

			if (flag1) check(a, bb);
			if (flag2) check(a, bb);
		}
	}
	else{
		ans++;
		return;
	}


	return;
}


int main(void){

	char in[50];
	char end[] = "END";

	while (cin >> in){
		if (in[0] == 'E') break;

		for (int j = 0; j < 5; j++){
			cocoon[0][j] = in[j] - '0';
		}

		for (int i = 1; i <= 9; i++){
			cin >> in;
			for (int j = 0; j < 5; j++){
				cocoon[i][j] = in[j] - '0';
			}
		}

		ans = 0;

		for (int i = 0; i < 512; i++){
			vector<int> bita, bitb;
			int bits = 0;
			int num = i;
			for (int j = 0; j <= 9; j++){
				if (num % 2 != 0) bita.push_back(j);
				else bitb.push_back(j);

				num = num / 2;
			}

			if (bita.size() != 5) continue;

			check(bita, bitb);

		}

		cout << ans / 32 << endl;

	}

	return 0;
}
*/
accuracy: 1
time_ms: 110
memory_kb: 1196
final_rank: 1

code_snippet: #include <bits/stdc++.h>
 
using namespace std;
 
string s[10],srev[10];
string H[5],W[5];
bool eq[10];
 
bool valid(int idx){
    for(int i = 0 ; i < 5 ; i++){
	if(W[idx][i] == H[i][idx]){
	    return false;
	}
    }
    return true;
}
 
int solve(int idx,int S){
    if(S == (1<<10)-1){
	return 1;
    }
    int res = 0;
    for(int i = 0 ; i < 10 ; i++){
	if((S >> i) & 1) continue;
	if(idx < 5){
	    H[idx] = s[i];
	    res += solve(idx+1,S|(1<<i));
	    if(!eq[i]){
		H[idx] = srev[i];
		res += solve(idx+1,S|(1<<i));
	    }
	}else{
	    W[idx-5] = s[i];
	    if(valid(idx-5)){
		res += solve(idx+1,S|(1<<i));
	    }
	    if(!eq[i]){
		W[idx-5] = srev[i];
		if(valid(idx-5)){
		    res += solve(idx+1,S|(1<<i));
		}
	    }
	}
    }
    return res;
}
 
int main(){ 
    while(cin >> s[0], s[0] != "END"){
	memset(eq,false,sizeof(eq));
	string tmp = s[0];
	reverse(tmp.begin(),tmp.end());
	srev[0] = tmp;
	eq[0] = s[0] == srev[0];
	for(int i = 0 ; i < 9 ; i++){
	    cin >> s[i+1];
	    tmp = s[i+1];
	    reverse(tmp.begin(),tmp.end());
	    srev[i+1] = tmp;
	    eq[i+1] = s[i+1] == srev[i+1];
	}
	cout << solve(0,0)/8 << endl;
    }
    return 0;
}
accuracy: 1
time_ms: 1580
memory_kb: 3200
final_rank: 11

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

#define EACH(i,c) for(__typeof((c).begin()) i=(c).begin(); i!=(c).end(); ++i)
#define ALL(x) (x).begin(),(x).end() 
using namespace std; 
typedef long long ll;
const double eps = 1e-10;

bool check(const vector<string> &l, const vector<string> &u, int bit){
    vector<string> v;
    for(int i = 0; i < 5; ++i){
        v.push_back(l[i]);
        if(bit >> i & 1){
            reverse(ALL(v[i]));
            if(v[i] == l[i]) return false;
        }
        // cout << v[i] << " ";
    }
    // cout << endl;

    vector<int> used(5, -1);
    for(int j = 0; j < 5; ++j){
        string s = "";
        for(int i = 0; i < 5; ++i){
            if(v[i][j] == '0')
                s.push_back('1');
            else
                s.push_back('0');
        }
        string rs = s;
        reverse(ALL(rs));
        bool flag = false;
        for(int i = 0; i < 5; ++i){
            if(used[i] < 0 && (s == u[i] || rs == u[i])){
                used[i] = j;
                flag = true;
                break;
            }
        }
        if(!flag) return false;
    }
    /*
    for(int i = 0; i < 5; ++i){
        cout << v[i] << endl;
    }
    cout << endl;
    for(int i = 0; i < 5; ++i){
        cout << u[i] << " ";
    }
    cout << endl;
    for(int i = 0; i < 5; ++i) cout << used[i] << " ";
    cout << endl;
    */
    return true;
}
int main(){
    for(;;){
        vector<string> v(10);
        cin >> v[0];
        if(v[0] == "END") return 0;
        for(int i = 1; i < 10; ++i) cin >> v[i];
        sort(ALL(v));
        int cnt = 0;
        for(int s = 0; s < 1 << 10; ++s) if(__builtin_popcount(s) == 5 && s < (~s & 1023)){
            vector<string> lv, uv;
            for(int i = 0; i < 10; ++i)
                if(s >> i & 1)
                    lv.push_back(v[i]);
                else
                    uv.push_back(v[i]);
            do{
                for(int t = 0; t < 1 << 5; ++t){
                    bool res = check(lv, uv, t);
                    if(res){
                        ++cnt;
                    }
                }
            }while(next_permutation(ALL(lv)));
        }
        cout << cnt / 4 << endl;
    }
}
accuracy: 1
time_ms: 2450
memory_kb: 1208
final_rank: 13

code_snippet: #include<stdio.h>
#include<algorithm>
using namespace std;
char str[11][7];
int used[11];
int p[6][6];
int solve(int a){
	if(a==10){
		for(int i=0;i<5;i++)for(int j=0;j<5;j++)
			if(!p[i][j])return 0;
		return 1;
	}
	int ret=0;
	for(int i=0;i<10;i++){
		if(used[i])continue;
		used[i]=1;
		bool ok=true;
		if(a%2){
			for(int j=0;j<5;j++){
				p[a/2][j]+=str[i][j]-'0';
				if(p[a/2][j]==2)ok=false;
			}
		}else{
			for(int j=0;j<5;j++){
				p[j][a/2]+=str[i][j]-'0';
				if(p[j][a/2]==2)ok=false;
			}
		}
		if(ok)ret+=solve(a+1);
		used[i]=0;
		if(a%2){
			for(int j=0;j<5;j++){
				p[a/2][j]-=str[i][j]-'0';
			}
		}else{
			for(int j=0;j<5;j++){
				p[j][a/2]-=str[i][j]-'0';
			}
		}
	}
	for(int i=0;i<10;i++){
		if(used[i])continue;
		if(str[i][0]==str[i][4]&&str[i][1]==str[i][3])continue;
		used[i]=1;
		bool ok=true;
		if(a%2){
			for(int j=0;j<5;j++){
				p[a/2][j]+=str[i][4-j]-'0';
				if(p[a/2][j]==2)ok=false;
			}
		}else{
			for(int j=0;j<5;j++){
				p[j][a/2]+=str[i][4-j]-'0';
				if(p[j][a/2]==2)ok=false;
			}
		}
		if(ok)ret+=solve(a+1);
		used[i]=0;
		if(a%2){
			for(int j=0;j<5;j++){
				p[a/2][j]-=str[i][4-j]-'0';
			}
		}else{
			for(int j=0;j<5;j++){
				p[j][a/2]-=str[i][4-j]-'0';
			}
		}
	}
	return ret;
}
int main(){
	while(1){
		for(int i=0;i<5;i++)for(int j=0;j<5;j++)p[i][j]=0;
		scanf("%s",str[0]);
		for(int i=0;i<10;i++)used[i]=0;
		if(str[0][0]=='E')break;
		for(int i=1;i<10;i++)scanf("%s",str[i]);
		int ret=solve(0);
		printf("%d\n",ret/8);
	}
}
accuracy: 1
time_ms: 410
memory_kb: 964
final_rank: 3

code_snippet: #include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <cstring>
using namespace std;

int lat[5][5];

vector<vector<int>> bx = {
    {0, 1, 2, 3, 4},
    {0, 1, 2, 3, 4},
    {0, 1, 2, 3, 4},
    {0, 1, 2, 3, 4},
    {0, 1, 2, 3, 4},
    {0, 0, 0, 0, 0},
    {1, 1, 1, 1, 1},
    {2, 2, 2, 2, 2},
    {3, 3, 3, 3, 3},
    {4, 4, 4, 4, 4}
};

vector<vector<int>> by = {
    {0, 0, 0, 0, 0},
    {1, 1, 1, 1, 1},
    {2, 2, 2, 2, 2},
    {3, 3, 3, 3, 3},
    {4, 4, 4, 4, 4},
    {0, 1, 2, 3, 4},
    {0, 1, 2, 3, 4},
    {0, 1, 2, 3, 4},
    {0, 1, 2, 3, 4},
    {0, 1, 2, 3, 4}
};

string rev(string s) {
    reverse(s.begin(), s.end());
    return s;
}

int dfs(vector<string> &v, int k) {
    if (k == 10) {
        return 1;
    }
    vector<string> S(1, v[k]);
    if (v[k] != rev(v[k])) {
        S.push_back(rev(v[k]));
    }
    int ret = 0;
    for (string bloc : S) {
        for (int i=0; i<10; ++i) {
            bool ok = true;
            vector<int> t;
            for (int j=0; j<5; ++j) {
                if ((lat[by[i][j]][bx[i][j]] & 1 && bloc[j] - '0' == 0) ||
                    (lat[by[i][j]][bx[i][j]] & 2 && bloc[j] - '0' == 1)) {
                    ok = false;
                    break;
                }
                t.push_back(lat[by[i][j]][bx[i][j]]);
            }
            if (ok) {
                for (int j=0; j<5; ++j) {
                    lat[by[i][j]][bx[i][j]] |= (bloc[j] - '0' + 1);
                }
                ret += dfs(v, k+1);
                for (int j=0; j<5; ++j) {
                    lat[by[i][j]][bx[i][j]] = t[j];
                }
            }
        }
    }
    return ret;
}

int main() {
    vector<string> v(10);
    while (cin >> v[0], v[0] != "END") {
        for (int i=1; i<10; ++i) {
            cin >> v[i];
        }
        memset(lat, 0, sizeof lat);
        int ret = dfs(v, 0);
        cout << (ret == 0 ? 0 : ret / 8) << endl;
    }
    return 0;
}
accuracy: 1
time_ms: 290
memory_kb: 1220
final_rank: 2

code_snippet: #include <bits/stdc++.h>

using namespace std;

string s[10],srev[10];
string H[5],W[5];
bool eq[10];

bool valid(int idx){
  for(int i = 0 ; i < 5 ; i++){
    if(W[idx][i] == H[i][idx]){
      return false;
    }
  }
  return true;
}

int solve(int idx,int S){
  if(S == (1<<10)-1){
    return 1;
  }
  int res = 0;
  for(int i = 0 ; i < 10 ; i++){
    if((S >> i) & 1) continue;
    if(idx < 5){
      H[idx] = s[i];
      res += solve(idx+1,S|(1<<i));
      if(!eq[i]){
        H[idx] = srev[i];
        res += solve(idx+1,S|(1<<i));
      }
    }else{
      W[idx-5] = s[i];
      if(valid(idx-5)){
        res += solve(idx+1,S|(1<<i));
      }
      if(!eq[i]){
        W[idx-5] = srev[i];
        if(valid(idx-5)){
          res += solve(idx+1,S|(1<<i));
        }
      }
    }
  }
  return res;
}

int main(){ 
  while(cin >> s[0], s[0] != "END"){
    memset(eq,false,sizeof(eq));
    string tmp = s[0];
    reverse(tmp.begin(),tmp.end());
    srev[0] = tmp;
    eq[0] = s[0] == srev[0];
    for(int i = 0 ; i < 9 ; i++){
      cin >> s[i+1];
      tmp = s[i+1];
      reverse(tmp.begin(),tmp.end());
      srev[i+1] = tmp;
      eq[i+1] = s[i+1] == srev[i+1];
    }
    cout << solve(0,0)/8 << endl;
  }
  return 0;
}
accuracy: 1
time_ms: 2200
memory_kb: 1200
final_rank: 12

code_snippet: #include <bits/stdc++.h>
using namespace std;
int ans;
bool use[10];
string s[10],t[10];

bool check(int n) {
  bool ck=true;
  for(int i=0; i<5; i++) {
    if(t[n][i]==t[i][n-5]) ck=false;
  }
  return ck;
}

void dfs(int n) {
  if(n==10) {
    ans++;
    return;
  }
  
  for(int i=0; i<10; i++) {
    if(!use[i]) {
      use[i]=true;
      
      t[n]=s[i];
      if(n<5) dfs(n+1);
      else {
	if(check(n)) {
	  dfs(n+1);
	  use[i]=false;
	  return;
	}
      }

      reverse(s[i].begin(),s[i].end());
      t[n]=s[i];
      reverse(s[i].begin(),s[i].end());
      
      if(s[i]==t[n]) {
	use[i]=false;
	continue;
      }
      
      if(n<5) dfs(n+1);
      else {
	if(check(n)) {
	  dfs(n+1);
	  use[i]=false;
	  return;
	}
      }
      
      use[i]=false;
    }
  }
}

int main() {
  while(cin >> s[0]) {
    if(s[0]=="END") break;
    for(int i=1; i<10; i++) cin >> s[i];
    memset(use,false,sizeof(use));
    ans=0;
    dfs(0);
    cout << ans/8 << endl;
  }
  return 0;
}
accuracy: 1
time_ms: 2740
memory_kb: 1200
final_rank: 14