/*

     bool isperfect(unsigned __int64 Ne[], int N=-1, ...)

     Function isperfect returns boolean value 'true' if input graph is a perfect graph and 'false' otherwise.

     The input graph with N<=64 nodes, expressed as a bitwise neighbor node lists. Each set bit in Ne[n] indicates
     that the corresponding graph node is a neighbor. For example, if the ith bit of Ne[n] is set, graph node i is
     a neighbor of graph node n. The nth bit of Ne[n] cannot be set, i.e. Ne[0]&0x0001 = 0 and Ne[1]&0x0002 = 0.

     Ne must be 64-bit unsigned integers. The length of Ne, N, can be surmised by checking for zero termination
     (if input parameter N=0) or for connected graphs, by looking at the maximal neighbor index (if the input
     parameter N=-1 or N is blank).

     Copyright 2010 by Delbert Dueck <deldueck@gmail.com>, Columbia University Department of Computer Science

*/
bool isperfect(unsigned __int64 *Ne, int N=-1
/* parameters for internal use only */, int va=-1, unsigned __int64 v_=0, int vy=-1, int vz=-1, int vn=0) {
   unsigned __int64 ne, vs, vt;
   int n, v;

   if (N<=0) { /* first [outside] call of function; determine graph length, N */
      if (N==-1) {N=5; for (n=0,ne=0; nne) {ne=Ne[n]; ne>>=N; while (ne) {N++; ne>>=1;} ne=Ne[n];}} /* auto-detect array length */
      if (N==0) ffor (N=0; N<64 && Ne[N]; N++); /* zero-terminated array; useful for disconnected graphs */
      for (n=0; n<N; n++) Ne[n] &= (~((span class="keywordstyle">unsigned __int64)1<<n)); /* remove any self-links (invalid format) */
      if (!(isperfect(Ne,N,-1,0,-1,-1,0))) return (false); /* test graph */
      for (n=0; n<N; n++) Ne[n] ^= (0xffffffffffffffff>>(64-N)); /* complement graph (invalid format) */
      for (n=0; n<N; n++) Ne[n] &= (~((unsigned __int64)1<<n)); /* remove any self-links */
      if (!(isperfect(Ne,N,-1,0,-1,-1,0))) return (false); else return (true); /* test graph complement */
   }

   if (vn==1 && va==-1 && vy==-1 && vz!=-1) va=vz; /* quick fix for array indexing/labelling problem */
   if (vn==0) vs=(0xffffffffffffffff>>(64-N)); else vs=Ne[vz];
   for (v=0; v<N; v++) { if (!(((unsigned __int64)1<<v)&vs)) continue; /* enforce for v=vs loop */
      if (vn>=2) {if (v==vy) continue;} /* don't backtrack for path */
      if (vn>=3) {vt = (v_-((unsigned __int64)1<<va)-((unsigned __int64)1<<vz)); if (Ne[v] & vt) continue;} /* chord encountered */
      if (vn>=2) { /* chordless path at least three long encountered */
         if (Ne[v] & ((unsigned __int64)1<<va)) { /* hole or 3-clique encountered */
            if (vn+1>=5 && ((vn+1)&1)) return (false); /* odd hole encountered */
            continue;
         }
      }
      if (vn<=((N-1)|1)) if (!isperfect(Ne,N,va,(v_|((unsigned __int64)1<<v)),vz,v,vn+1)) return (false); /* recursion call */
   }
   return (true); /* no odd holes encountered */
}