#include <iostream.h>

int term1[256];
int term2[256];
int level[256];
int stack[15][256];
int size[15];
int total;

void assign(int val,int t1,int t2,int lev) {
 if (level[val] == 20) {
   term1[val]=t1;
   term2[val]=t2;
   level[val]=lev;
   stack[lev][size[lev]] = val;
   size[lev]++;
   total++;
 }
}

void init(void) {
 for (int lcv=0;lcv<15;lcv++) {
   size[lcv]=0;
 }
 for (int lcv=0;lcv<256;lcv++) {
   level[lcv]=20;
 }
 assign(0,0,0,0);
 assign(255,0,0,0);
 assign(15,0,0,0);
 assign(51,0,0,0);
 assign(85,0,0,0);
 assign(252,0,0,0);
 assign(250,0,0,0);
 assign(238,0,0,0);
 total = 5;
}

int nand(int n1,int n2) {
  return( ~(n1 & n2) & 0xFF );
}

void pline(int num) {
  if (level[num] != 0) {
    cout << num << " = (";
    pline(term1[num]);
    cout << ",";
    pline(term2[num]);
    cout << ")";
  } else {
    cout << num;
  }
}

void print(void) {
 for (int lcv=0;lcv<256;lcv++) {
   cout << lcv << " " << term1[lcv] << " " << term2[lcv] << " " <<
     level[lcv] << "\n";
   pline(lcv);
   cout << "\n";
 }
 for (int lcv=0;lcv<15;lcv++) {
   cout << lcv << " gates --> ";
   for (int clc=0;clc<size[lcv];clc++) 
     cout << " " << stack[lcv][clc];
   cout << "\n";
 }
}

void main(void) {
 init();
 for (int lv=1;lv<15;lv++) {
  for (int li=0;li<(lv+1)/2;li++) {
    int lj=lv-li-1;
   //cout << " li " << li << "  lj " << lj << " ";
   //cout << "sli " << size[li] << " slj " << size[lj] << "\n";
   for (int m1=0;m1<size[li];m1++) for (int m2=0;m2<size[lj];m2++) {
    assign(nand(stack[li][m1],stack[lj][m2]),stack[li][m1],stack[lj][m2],lv);
   }
  }
 }
 print();
 cout << "total " << total << "\n";
}
