/*
  Switches

  DESL: if set (default) consider 6x4-S-Box for DESL acc.to Poschmann's conditions.
  PRESENT: if set consider 4x4-S-Box for PRESENT.
  TESTDESL: if set (to an integer) then preset the S-Box with values TESTDESL..63 of Poschmann's DESL S-Box.
  TOPSQUARE: fix topmost levels to S-Box arguments 00,04,08,0C,10,14,18,1C,20,24,28,2C (as long as free and not too deep in tree).
  FIRSTHIT: if set run to first success else run through entire tree

  DEBUG: if set  print "Try..." for all levels.
  DEBUGX: if set dprintf prints stuff and set DEBUG.
  DEBUGTM: if set stop after at most 10000 backrack calls.
  DEBUGLVL: if set (to an integer) only descend DEBUGLVL levels.
  QUIET: Suppress many outputs, add status message every 2^20 backtrack calls.
  NOPRINT: if set nothing is printed. (only useful for timing)
*/



#include <stdio.h>
#include <stdlib.h>
#include <math.h>
void * memcpy ( void * destination, const void * source, size_t num );
#ifdef DEBUGX
#define DEBUG
#endif

#ifdef NOPRINT
#define printf(...) ;
#endif
#ifdef DEBUGX
#define dprintf(...) { printf(__VA_ARGS__); fflush(stdout); }
#else
#define dprintf(...) ;
#endif

//#define PRESENT
#ifndef PRESENT
#ifndef DESL
#define DESL
#endif
#endif


#define UNDEF -1

#ifdef DESL
#define KIN 6
#define KOUT 4
#define NUMIN 64
#define NUMOUT 16
#define SETMAXDIFF setmaxdiffDESL
#define SETMAXBIAS  setmaxbiasDESL
#endif
#ifdef PRESENT
#define KIN 4
#define KOUT 4
#define NUMIN 16
#define NUMOUT 16
#define SETMAXDIFF setmaxdiffPRESENT
#define SETMAXBIAS  setmaxbiasPRESENT
#endif

#ifdef NUMIN
#else
#error
#endif

#define TRUE 1
#define FALSE 0
typedef char bool;

// Type for an S-box
typedef int sbox[NUMIN];

// Type for a table (differential or linear)
typedef int tab[NUMIN][NUMOUT];

// Type for a table of penalties
typedef bool optionstab[NUMIN][NUMOUT];
typedef double penaltytab[NUMIN][NUMOUT];


struct poswithpenalty {
  int pos;
  double penalty;
};

#if NUMIN==64 
   sbox dess5 = {2,14,12,11,4,2,1,12,7,4,10,7,11,13,6,1,8,5,5,0,3,15,15,10,13,3,0,9,14,8,9,6,4,11,2,8,1,12,11,7,10,1,13,14,7,2,8,13,15,6,9,15,12,0,5,9,6,10,3,4,0,5,14,3};
   sbox desl = {14, 5, 5, 0, 7, 8, 2, 15, 11, 14, 8, 3, 1, 2, 15, 12, 0, 11, 10, 7, 9, 6, 4, 9, 6, 13, 13, 4, 12, 1, 3, 10, 4, 9, 9, 6, 2, 15, 14, 5, 8, 3, 7, 8, 13, 4, 0, 11, 10, 7, 12, 1, 15, 12, 1, 2, 5, 0, 11, 14, 3, 10, 6, 13};
#endif
#if NUMIN==16
  sbox present = { 12, 5, 6, 11, 9, 0, 10, 13, 3, 14, 15, 8, 4, 7, 1, 2 };
#endif

#ifdef DESL
#if TRUE
// These 9 partial S-boxes have been computed using MuPAD.
// Up to isomorphism they constitute the top four layers of the tree.
sbox sboxbranch[] =
  {
    { // 0356
      0,UNDEF,UNDEF,UNDEF,3,UNDEF,UNDEF,UNDEF,
      5,UNDEF,UNDEF,UNDEF,6,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
    },
    { // 0359
      0,UNDEF,UNDEF,UNDEF,3,UNDEF,UNDEF,UNDEF,
      5,UNDEF,UNDEF,UNDEF,9,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
    },
    { // 035A
      0,UNDEF,UNDEF,UNDEF,3,UNDEF,UNDEF,UNDEF,
      5,UNDEF,UNDEF,UNDEF,10,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
    },
    { // 035E
      0,UNDEF,UNDEF,UNDEF,3,UNDEF,UNDEF,UNDEF,
      5,UNDEF,UNDEF,UNDEF,14,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
    },
    { // 035F
      0,UNDEF,UNDEF,UNDEF,3,UNDEF,UNDEF,UNDEF,
      5,UNDEF,UNDEF,UNDEF,15,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
    },
    { // 03CF
      0,UNDEF,UNDEF,UNDEF,3,UNDEF,UNDEF,UNDEF,
      12,UNDEF,UNDEF,UNDEF,15,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
    },
    { // 03DE
      0,UNDEF,UNDEF,UNDEF,3,UNDEF,UNDEF,UNDEF,
      13,UNDEF,UNDEF,UNDEF,14,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
    },
    { // 03FC
      0,UNDEF,UNDEF,UNDEF,3,UNDEF,UNDEF,UNDEF,
      15,UNDEF,UNDEF,UNDEF,12,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
    },
    { // 07BC
      0,UNDEF,UNDEF,UNDEF,7,UNDEF,UNDEF,UNDEF,
      11,UNDEF,UNDEF,UNDEF,12,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
    }
  };
#else
// These 56 partial S-boxes have been computed using MuPAD.
// Up to isomorphism they constitute the top five layers of the tree.
sbox LONGsboxbranch[] =
  {
    {
      0,UNDEF,UNDEF,UNDEF,3,UNDEF,UNDEF,UNDEF,
      5,UNDEF,UNDEF,UNDEF,6,UNDEF,UNDEF,UNDEF,
      7,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
    },
    {
      0,UNDEF,UNDEF,UNDEF,3,UNDEF,UNDEF,UNDEF,
      5,UNDEF,UNDEF,UNDEF,6,UNDEF,UNDEF,UNDEF,
      9,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
    },
    {
      0,UNDEF,UNDEF,UNDEF,3,UNDEF,UNDEF,UNDEF,
      5,UNDEF,UNDEF,UNDEF,6,UNDEF,UNDEF,UNDEF,
      10,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
    },
    {
      0,UNDEF,UNDEF,UNDEF,3,UNDEF,UNDEF,UNDEF,
      5,UNDEF,UNDEF,UNDEF,6,UNDEF,UNDEF,UNDEF,
      11,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
    },
    {
      0,UNDEF,UNDEF,UNDEF,3,UNDEF,UNDEF,UNDEF,
      5,UNDEF,UNDEF,UNDEF,6,UNDEF,UNDEF,UNDEF,
      12,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
    },
    {
      0,UNDEF,UNDEF,UNDEF,3,UNDEF,UNDEF,UNDEF,
      5,UNDEF,UNDEF,UNDEF,6,UNDEF,UNDEF,UNDEF,
      13,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
    },
    {
      0,UNDEF,UNDEF,UNDEF,3,UNDEF,UNDEF,UNDEF,
      5,UNDEF,UNDEF,UNDEF,6,UNDEF,UNDEF,UNDEF,
      14,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
    },
    {
      0,UNDEF,UNDEF,UNDEF,3,UNDEF,UNDEF,UNDEF,
      5,UNDEF,UNDEF,UNDEF,6,UNDEF,UNDEF,UNDEF,
      15,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
    },
    {
      0,UNDEF,UNDEF,UNDEF,3,UNDEF,UNDEF,UNDEF,
      5,UNDEF,UNDEF,UNDEF,9,UNDEF,UNDEF,UNDEF,
      6,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
    },
    {
      0,UNDEF,UNDEF,UNDEF,3,UNDEF,UNDEF,UNDEF,
      5,UNDEF,UNDEF,UNDEF,9,UNDEF,UNDEF,UNDEF,
      7,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
    },
    {
      0,UNDEF,UNDEF,UNDEF,3,UNDEF,UNDEF,UNDEF,
      5,UNDEF,UNDEF,UNDEF,9,UNDEF,UNDEF,UNDEF,
      10,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
    },
    {
      0,UNDEF,UNDEF,UNDEF,3,UNDEF,UNDEF,UNDEF,
      5,UNDEF,UNDEF,UNDEF,9,UNDEF,UNDEF,UNDEF,
      11,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
    },
    {
      0,UNDEF,UNDEF,UNDEF,3,UNDEF,UNDEF,UNDEF,
      5,UNDEF,UNDEF,UNDEF,9,UNDEF,UNDEF,UNDEF,
      12,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
    },
    {
      0,UNDEF,UNDEF,UNDEF,3,UNDEF,UNDEF,UNDEF,
      5,UNDEF,UNDEF,UNDEF,9,UNDEF,UNDEF,UNDEF,
      13,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
    },
    {
      0,UNDEF,UNDEF,UNDEF,3,UNDEF,UNDEF,UNDEF,
      5,UNDEF,UNDEF,UNDEF,9,UNDEF,UNDEF,UNDEF,
      14,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
    },
    {
      0,UNDEF,UNDEF,UNDEF,3,UNDEF,UNDEF,UNDEF,
      5,UNDEF,UNDEF,UNDEF,9,UNDEF,UNDEF,UNDEF,
      15,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
    },
    {
      0,UNDEF,UNDEF,UNDEF,3,UNDEF,UNDEF,UNDEF,
      5,UNDEF,UNDEF,UNDEF,10,UNDEF,UNDEF,UNDEF,
      6,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
    },
    {
      0,UNDEF,UNDEF,UNDEF,3,UNDEF,UNDEF,UNDEF,
      5,UNDEF,UNDEF,UNDEF,10,UNDEF,UNDEF,UNDEF,
      7,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
    },
    {
      0,UNDEF,UNDEF,UNDEF,3,UNDEF,UNDEF,UNDEF,
      5,UNDEF,UNDEF,UNDEF,10,UNDEF,UNDEF,UNDEF,
      9,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
    },
    {
      0,UNDEF,UNDEF,UNDEF,3,UNDEF,UNDEF,UNDEF,
      5,UNDEF,UNDEF,UNDEF,10,UNDEF,UNDEF,UNDEF,
      11,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
    },
    {
      0,UNDEF,UNDEF,UNDEF,3,UNDEF,UNDEF,UNDEF,
      5,UNDEF,UNDEF,UNDEF,10,UNDEF,UNDEF,UNDEF,
      12,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
    },
    {
      0,UNDEF,UNDEF,UNDEF,3,UNDEF,UNDEF,UNDEF,
      5,UNDEF,UNDEF,UNDEF,10,UNDEF,UNDEF,UNDEF,
      13,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
    },
    {
      0,UNDEF,UNDEF,UNDEF,3,UNDEF,UNDEF,UNDEF,
      5,UNDEF,UNDEF,UNDEF,10,UNDEF,UNDEF,UNDEF,
      14,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
    },
    {
      0,UNDEF,UNDEF,UNDEF,3,UNDEF,UNDEF,UNDEF,
      5,UNDEF,UNDEF,UNDEF,10,UNDEF,UNDEF,UNDEF,
      15,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
    },
    {
      0,UNDEF,UNDEF,UNDEF,3,UNDEF,UNDEF,UNDEF,
      5,UNDEF,UNDEF,UNDEF,14,UNDEF,UNDEF,UNDEF,
      6,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
    },
    {
      0,UNDEF,UNDEF,UNDEF,3,UNDEF,UNDEF,UNDEF,
      5,UNDEF,UNDEF,UNDEF,14,UNDEF,UNDEF,UNDEF,
      7,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
    },
    {
      0,UNDEF,UNDEF,UNDEF,3,UNDEF,UNDEF,UNDEF,
      5,UNDEF,UNDEF,UNDEF,14,UNDEF,UNDEF,UNDEF,
      9,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
    },
    {
      0,UNDEF,UNDEF,UNDEF,3,UNDEF,UNDEF,UNDEF,
      5,UNDEF,UNDEF,UNDEF,14,UNDEF,UNDEF,UNDEF,
      10,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
    },
    {
      0,UNDEF,UNDEF,UNDEF,3,UNDEF,UNDEF,UNDEF,
      5,UNDEF,UNDEF,UNDEF,14,UNDEF,UNDEF,UNDEF,
      11,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
    },
    {
      0,UNDEF,UNDEF,UNDEF,3,UNDEF,UNDEF,UNDEF,
      5,UNDEF,UNDEF,UNDEF,14,UNDEF,UNDEF,UNDEF,
      12,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
    },
    {
      0,UNDEF,UNDEF,UNDEF,3,UNDEF,UNDEF,UNDEF,
      5,UNDEF,UNDEF,UNDEF,14,UNDEF,UNDEF,UNDEF,
      13,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
    },
    {
      0,UNDEF,UNDEF,UNDEF,3,UNDEF,UNDEF,UNDEF,
      5,UNDEF,UNDEF,UNDEF,14,UNDEF,UNDEF,UNDEF,
      15,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
    },
    {
      0,UNDEF,UNDEF,UNDEF,3,UNDEF,UNDEF,UNDEF,
      5,UNDEF,UNDEF,UNDEF,15,UNDEF,UNDEF,UNDEF,
      6,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
    },
    {
      0,UNDEF,UNDEF,UNDEF,3,UNDEF,UNDEF,UNDEF,
      5,UNDEF,UNDEF,UNDEF,15,UNDEF,UNDEF,UNDEF,
      7,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
    },
    {
      0,UNDEF,UNDEF,UNDEF,3,UNDEF,UNDEF,UNDEF,
      5,UNDEF,UNDEF,UNDEF,15,UNDEF,UNDEF,UNDEF,
      9,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
    },
    {
      0,UNDEF,UNDEF,UNDEF,3,UNDEF,UNDEF,UNDEF,
      5,UNDEF,UNDEF,UNDEF,15,UNDEF,UNDEF,UNDEF,
      10,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
    },
    {
      0,UNDEF,UNDEF,UNDEF,3,UNDEF,UNDEF,UNDEF,
      5,UNDEF,UNDEF,UNDEF,15,UNDEF,UNDEF,UNDEF,
      11,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
    },
    {
      0,UNDEF,UNDEF,UNDEF,3,UNDEF,UNDEF,UNDEF,
      5,UNDEF,UNDEF,UNDEF,15,UNDEF,UNDEF,UNDEF,
      12,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
    },
    {
      0,UNDEF,UNDEF,UNDEF,3,UNDEF,UNDEF,UNDEF,
      5,UNDEF,UNDEF,UNDEF,15,UNDEF,UNDEF,UNDEF,
      13,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
    },
    {
      0,UNDEF,UNDEF,UNDEF,3,UNDEF,UNDEF,UNDEF,
      5,UNDEF,UNDEF,UNDEF,15,UNDEF,UNDEF,UNDEF,
      14,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
    },
    {
      0,UNDEF,UNDEF,UNDEF,3,UNDEF,UNDEF,UNDEF,
      12,UNDEF,UNDEF,UNDEF,15,UNDEF,UNDEF,UNDEF,
      5,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
    },
    {
      0,UNDEF,UNDEF,UNDEF,3,UNDEF,UNDEF,UNDEF,
      13,UNDEF,UNDEF,UNDEF,14,UNDEF,UNDEF,UNDEF,
      5,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
    },
    {
      0,UNDEF,UNDEF,UNDEF,3,UNDEF,UNDEF,UNDEF,
      13,UNDEF,UNDEF,UNDEF,14,UNDEF,UNDEF,UNDEF,
      6,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
    },
    {
      0,UNDEF,UNDEF,UNDEF,3,UNDEF,UNDEF,UNDEF,
      13,UNDEF,UNDEF,UNDEF,14,UNDEF,UNDEF,UNDEF,
      7,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
    },
    {
      0,UNDEF,UNDEF,UNDEF,3,UNDEF,UNDEF,UNDEF,
      15,UNDEF,UNDEF,UNDEF,12,UNDEF,UNDEF,UNDEF,
      5,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
    },
    {
      0,UNDEF,UNDEF,UNDEF,7,UNDEF,UNDEF,UNDEF,
      11,UNDEF,UNDEF,UNDEF,12,UNDEF,UNDEF,UNDEF,
      5,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
    },
    {
      0,UNDEF,UNDEF,UNDEF,7,UNDEF,UNDEF,UNDEF,
      11,UNDEF,UNDEF,UNDEF,12,UNDEF,UNDEF,UNDEF,
      9,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
    },
    {
      0,UNDEF,UNDEF,UNDEF,7,UNDEF,UNDEF,UNDEF,
      11,UNDEF,UNDEF,UNDEF,12,UNDEF,UNDEF,UNDEF,
      13,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
    },
    {
      0,UNDEF,UNDEF,UNDEF,3,UNDEF,UNDEF,UNDEF,
      12,UNDEF,UNDEF,UNDEF,15,UNDEF,UNDEF,UNDEF,
      7,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
    },
    {
      0,UNDEF,UNDEF,UNDEF,3,UNDEF,UNDEF,UNDEF,
      12,UNDEF,UNDEF,UNDEF,15,UNDEF,UNDEF,UNDEF,
      13,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
    },
    {
      0,UNDEF,UNDEF,UNDEF,3,UNDEF,UNDEF,UNDEF,
      13,UNDEF,UNDEF,UNDEF,14,UNDEF,UNDEF,UNDEF,
      12,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
    },
    {
      0,UNDEF,UNDEF,UNDEF,3,UNDEF,UNDEF,UNDEF,
      13,UNDEF,UNDEF,UNDEF,14,UNDEF,UNDEF,UNDEF,
      15,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
    },
    {
      0,UNDEF,UNDEF,UNDEF,3,UNDEF,UNDEF,UNDEF,
      15,UNDEF,UNDEF,UNDEF,12,UNDEF,UNDEF,UNDEF,
      7,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
    },
    {
      0,UNDEF,UNDEF,UNDEF,3,UNDEF,UNDEF,UNDEF,
      15,UNDEF,UNDEF,UNDEF,12,UNDEF,UNDEF,UNDEF,
      13,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
    },
    {
      0,UNDEF,UNDEF,UNDEF,7,UNDEF,UNDEF,UNDEF,
      11,UNDEF,UNDEF,UNDEF,12,UNDEF,UNDEF,UNDEF,
      3,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
    },
    {
      0,UNDEF,UNDEF,UNDEF,7,UNDEF,UNDEF,UNDEF,
      11,UNDEF,UNDEF,UNDEF,12,UNDEF,UNDEF,UNDEF,
      15,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
      UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,UNDEF,
    }
  };
#endif
#endif

/******************************************************************
 Global variables
 ******************************************************************/
unsigned int seed;

tab maxdiff;
tab maxbias;

#ifdef FIRSTHIT
bool backtrackdone = 1;
#else
bool backtrackdone = 0;
#endif

/******************************************************************/
/* General helpers */
/******************************************************************/

// Computes the hamming weight of val
// Better: http://en.wikipedia.org/wiki/Hamming_weight
inline int hamming(int val) {
  int akt;
  int res;

  akt = val;
  res = 0;
  while(akt != 0) {
    res = res + (akt&1);
    akt >>= 1;
  }

  return(res);
}

// Computes the scalar product of v1 and v2
inline int sprod( register int v1, int v2 ) {
  register int val;
  val = v1 & v2;
#if KIN>32 || KOUT>32
  val ^= val>>32;
#endif
#if KIN>16 || KOUT>16
  val ^= val>>16;
#endif
#if KIN>8 || KOUT>8
  val ^= val>>8;
#endif
#if KIN>4 || KOUT>4
  val ^= val>>4;
#endif
  val ^= val>>2;
  val ^= val>>1;
  return(val & 1);
}

/******************************************************************/
/* S-BOX HELPER FUNCTIONS */
/******************************************************************/

// Initializes an S-box as everywhere undefined
void initmeresbox(sbox s) {
  int i;

  for(i = 0; i < NUMIN; i++) {
    s[i] = UNDEF;
  }
}

// Prints an S-box
void printsbox(sbox s) {
  int i;

  for(i = 0; i < NUMIN; i++) {
    if(s[i] == UNDEF) {
      printf("-");
    } else {
      printf("%1X", s[i]);
    }
    if(i%16==15) {
      printf(" ");
    } 
  }
  printf("\n");
  fflush(stdout);
}

// Copies s1 into s2
void Xsboxcopy(sbox s1, sbox s2) {
  int i;

  for(i = 0; i < NUMIN; i++) {
    s2[i] = s1[i];
  }
}

#define sboxcopy(s1,s2) memcpy( (void*)(s2), (void*)(s1), (size_t)sizeof(sbox) );

// Counts the number of undefined places in an S-box
inline int countUNDEF(sbox s) {
  int x;
  int res;

  res = 0;
  for(x = 0; x < NUMIN; x++) {
    if(s[x] == UNDEF) {
      res++;
    }
  }
  return(res);
}

/******************************************************************/
/* TABLE HELPER FUNCTIONS */
/******************************************************************/

// Initializes t componentwise with initval
void inittab(tab t, int initval) {
  int i, j;

  for(i = 0; i < NUMIN; i++) {
    for(j = 0; j < NUMOUT; j++) {
      t[i][j] = initval;
    }
  }
}

void initoptions(optionstab t, int initval) {
  int i, j;

  for(i = 0; i < NUMIN; i++) {
    for(j = 0; j < NUMOUT; j++) {
      t[i][j] = initval;
    }
  }
}

// Prints t
void printtab(tab t) {
  int i, j;

  printf("     ");
  for(j = 0; j < NUMOUT; j++) {
    printf(" %02X ", j);
  }
  printf("\n");
  for(i = 0; i < NUMIN; i++) {
    printf("%02X | ", i);
    for(j = 0; j < NUMOUT; j++) {
      printf("%+03d ", t[i][j]);
    }
    printf("\n");
  }  
  fflush(stdout);
}

// Checks if t1 is componentwise equal to t2
int tabeq(tab t1, tab t2) {
  int i, j;

  for(i = 0; i < NUMIN; i++) {
    for(j = 0; j < NUMOUT; j++) {
      if(t1[i][j] != t2[i][j]) {
	return(0);
      }
    }
  }

  return(1);
}

#if FALSE
// Copies t1 into t2
void Xtabcopy(tab t1, tab t2) {
  int i, j;

  for(i = 0; i < NUMIN; i++) {
    for(j = 0; j < NUMOUT; j++) {
      t2[i][j] = t1[i][j];
    }
  }
}
#endif

// using tabcopy instead of Xtabcopy makes it 3 times faster!!!
#define tabcopy(t1,t2) memcpy( (void*)t2, (void*)t1, (size_t)sizeof(tab) )
#define optcopy(t1,t2) memcpy( (void*)t2, (void*)t1, (size_t)sizeof(optionstab) )

// Checks if t1 is componentwise lower or equal to t2
int tableq(tab t1, tab t2) {
  int i, j;

  for(i = 0; i < NUMIN; i++) {
    for(j = 0; j < NUMOUT; j++) {
      if(t1[i][j] > t2[i][j]) {
	return(0);
      }
    }
  }
  return(1);
}
int tababsleq(tab t1, tab t2) {
  int i, j;

  for(i = 0; i < NUMIN; i++) {
    for(j = 0; j < NUMOUT; j++) {
      if(abs(t1[i][j]) > t2[i][j]) {
	return(0);
      }
    }
  }
  return(1);
}
int tababsmaxovershoot(tab t1, tab t2) {
  int m, c, i, j;

  m=-NUMOUT;
  for(i = 0; i < NUMIN; i++) {
    for(j = 0; j < NUMOUT; j++) {
      c = abs(t1[i][j]) - t2[i][j];
      if(c>m) m=c;
    }
  }
  return(m);
}
int istababsmaxovershoot(tab t1, tab t2, int lmt) {
  int  c, i, j;

  for(i = 0; i < NUMIN; i++) {
    for(j = 0; j < NUMOUT; j++) {
      if( abs(t1[i][j]) - t2[i][j] > lmt ) return(1);
    }
  }
  return(0);
}


/******************************************************************/
/* DIFFERENTIAL STUFF */
/******************************************************************/

// DUMBEST METHOD EVER = DEFINITION
void computediffDUMB(sbox s, tab res) {
  int dx, dy, x;

  for(dx = 0; dx < NUMIN; dx++) {
    for(dy = 0; dy < NUMOUT; dy++) {
      res[dx][dy] = 0;
      for(x = 0; x < NUMIN; x++) {
        if(s[x] != UNDEF && s[x^dx] != UNDEF) {
          if((s[x]^s[x^dx]) == dy) {
	    res[dx][dy]++;
	  }
	}
      }
    }
  }
}

// Computes the differential table for S-box s and stores the result in res
void computediff(sbox s, tab res) {
  int dx, dy, x;

  inittab(res,0);
  for(x = 0; x < NUMIN; x++) {
    for(dx = 0; dx < NUMIN; dx++) {
      if(s[x] != UNDEF && s[x^dx] != UNDEF) {
        res[dx][s[x]^s[x^dx]]++;
      }
    }
  }
}

// Computes the differential table for S-box s with additional value s[x0] = y0 
// given the differential table res for the S-box s and stores the result in res
void updatediff(int x0, int y0, sbox s, tab diff) {
  int dx,dy;

  diff[0][0]++;
  for(dx = 1; dx < NUMIN; dx++) {
    dy=s[x0^dx];
    if(dy != UNDEF)
      diff[dx][y0^dy] += 2;
  }
}

// Incorrect procedure that should undo the changes of updatediffum
void undoupdatediff(int x0, int y0, sbox s, tab diff) {
  int dx,dy;

  for(dx = 0; dx < NUMIN; dx++) {
    dy=s[x0^dx];
    if(dy != UNDEF)
      diff[dx][y0^dy] -= 2;
  }
}

// Stores the maximal admissible differential table in res
void setmaxdiffPRESENT(tab res) {
  int i,j;

  // diff_S(dx,dy) <= 4
  inittab(res, 4);

  // Trivial
  res[0][0] = NUMIN;
  for(j = 1; j < NUMOUT; j++) {
    res[0][j] = 0;
  }
  // Force injective
  for(i = 1; i < NUMIN; i++) {
    res[i][0] = 0;
  }

  // diff_S(dx,dy) = 0 for wt(dx) = wt(dy) = 1.
  for(i = 0; i < NUMIN; i++) {
    for(j = 0; j < NUMOUT; j++) {
      if(hamming(j) == 1) {
	if(hamming(i) == 1) {
	  res[i][j] = 0;
	}
      }
    }
  }
}

// Stores the maximal admissible differential table in res
void setmaxdiffDESL(tab res) {
  int i,j;

  /* S-7 */
  inittab(res, 16);

  /* Trivial */
  res[0][0] = 64;
  for(j = 1; j < NUMOUT; j++) {
    res[0][j] = 0;
  }

  /* S-3 */
  for(i = 1; i < 16; i++) {
    res[2*i][0] = 0;
  }

  for(i = 0; i < NUMIN; i++) {
    for(j = 0; j < NUMOUT; j++) {
      if(hamming(j) <= 1) {
	/* S-4 */
	if(hamming(i) == 1) {
	  res[i][j] = 0;
	}
	/* S-5 */
	if(i == 12) {
	  res[i][j] = 0;
	}
      }
    }
  }

  /* C1 */
  for(i = 0; i < 8; i++) {
    res[32+4*i][0] = 0;
  }
}

// Test whether adding x0->y0 to s still fits with t1<t2
inline bool is_nextdiff_leq_maxdiff(
       sbox s,
       tab actdiff,
       int x0,
       int y0
){
  int dx, dy;
  for(dx = 0; dx < NUMIN; dx++) {
    dy=s[x0^dx];
    if(dy == UNDEF) continue;
    dy^=y0;
    if (actdiff[dx][dy]+2 > maxdiff[dx][dy]) return(FALSE);
  }
  return(TRUE);
}

#if FALSE
// Computes the list and number of admissible options 
inline void OLDupdateoptionsat(
			   sbox s,
			   tab diff,
			   int x0,
			   bool* res,
			   int* num) {
  int c,y0;
  tab diffbak;

  c= 0;
  for(y0 = 0; y0 < NUMOUT; y0++) {
    tabcopy(diff, diffbak);
    updatediff( x0, y0, s, diffbak);
    if(tableq(diffbak, maxdiff)) {
      res[c++] = y0; }
    /*
      printf("x0=%d, y0=%d, leq=%d, next=%d\n",
	   x0, y0,
	   tableq(diffbak,maxdiff),
	   is_nextdiff_leq_maxdiff(s,diff,x0,y0)
	   );//*/
  }
  *num = c;
}
#endif
inline void updateoptionsat(
			   sbox s,
			   tab diff,
			   int x0,
			   bool* res,
			   int* num) {
  int c,y0;

  c= 0;
  for(y0 = 0; y0 < NUMOUT; y0++) {
    if (!res[y0]) continue;
    if (is_nextdiff_leq_maxdiff(s,diff,x0,y0))
      c++;
    else
      res[y0] = FALSE;
  }
  *num = c;
}
#ifdef FALSE
inline void updateotions(
			   sbox s,
			   tab diff,
			   optionstab res
			 ) {
  int c,x0;
  for (x0=0; x0<NUMIN; x0++)
    updateoptionsat( s, diff, x0, res[x0], &c );
}
#endif

/******************************************************************/
/* LINEAR STUFF */
/******************************************************************/

// Computes the linear table for S-box s and stores the result in res
void bias(sbox s, tab res) {
  int alpha, beta, x;
 
  for(alpha = 0; alpha < NUMIN; alpha++) {
    for(beta = 0; beta < NUMOUT; beta++) {
      res[alpha][beta] = 0;
      for(x = 0; x < NUMIN; x++) {
        if(s[x] != UNDEF) {
	  if((sprod(beta,s[x])) == ((sprod(alpha,x)))) {
	    res[alpha][beta]++;
	  } else {
	    res[alpha][beta]--;
	  }
	}
      }
    }
  }
}

#if FALSE
// Computes the linear table for S-box s with additional value s[x0] = y0 
// given the linear table res for the S-box s and stores the result in res
void Xupdatebias(int x0, int y0, sbox s, tab bias) {
  int alpha, beta, x;
 
  for(alpha = 0; alpha < NUMIN; alpha++) {
    for(beta = 0; beta < NUMOUT; beta++) {
      if((sprod(y0,beta)) == ((sprod(x0,alpha)))) {
	bias[alpha][beta]++;
      } else {
	bias[alpha][beta]--;
      }
    }
  }
}
#endif

void updatebias(int x0, int y0, sbox s, tab bias) {
  int alpha, beta, a, x;
  int A[NUMIN];
  int B[NUMOUT];
 
  for(alpha = 0; alpha < NUMIN; alpha++) A[alpha] = sprod(x0,alpha);
  for(beta = 0; beta < NUMOUT; beta++) B[beta] = sprod(y0,beta);
  for(alpha = 0; alpha < NUMIN; alpha++) {
    a = A[alpha];
    for(beta = 0; beta < NUMOUT; beta++) {
      if(B[beta] == a) {
	bias[alpha][beta]++;
      } else {
	bias[alpha][beta]--;
      }
    }
  }
}

#if FALSE
void Yupdatebias(int x0, int y0, sbox s, tab bias) {
  int alpha, beta, a, x;
  int A[NUMIN], *pA;
  int B[NUMOUT], *pB;
 
  for(alpha = 0; alpha < NUMIN; alpha++) A[alpha] = sprod(x0,alpha);
  for(beta = 0; beta < NUMOUT; beta++) B[beta] = sprod(y0,beta);
  for(alpha = 0, pA=(int*)A; alpha < NUMIN; alpha++, pA++) {
    a = *pA;
    for(beta = 0, pB=(int*)B; beta < NUMOUT; beta++, pB++) {
      if(*pB == a) {
	bias[alpha][beta]++;
      } else {
	bias[alpha][beta]--;
      }
    }
  }
}
#endif

#if FALSE
// Undo the computations in the linear table for S-box s with additional value s[x0] = y0 
// given the linear table res for the S-box s. Stores the result in res.
void lintabUnacc(sbox s, int x0, int y0, tab bias) {
  int alpha, beta, x;
 
  for(alpha = 0; alpha < NUMIN; alpha++) {
    for(beta = 0; beta < NUMOUT; beta++) {
      if((sprod(y0,beta)) == ((sprod(x0,alpha)))) {
	bias[alpha][beta]--;
      } else {
	bias[alpha][beta]++;
      }
    }
  }
}
#endif

// Stores the maximal admissible bias table in res
void setmaxbiasPRESENT(tab res) {
  int i,j;

  /* C2 */
  inittab(res, 8);

  /* bias_S(a,b) <= 1/4 for wt(a) = wt(b) = 1. */
  for(i = 0; i < NUMIN; i++) {
    for(j = 0; j < NUMOUT; j++) {
      if(hamming(i) == 1 && hamming(j) == 1) {
	res[i][j] = 4;
      }
    }
  }

  /* trivial */
  res[0][0] = NUMIN;
  for(i = 1; i < NUMIN; i++) {
    res[i][0] = 0;
  }
}

/* Stores the maximal admissible bias table in res */
void setmaxbiasDESL(tab res) {
  int i,j;

  /* C2 */
  inittab(res, 28);

  for(i = 0; i < NUMIN; i++) {
    for(j = 0; j < NUMOUT; j++) {
      /* C4 */
      if(hamming(i) <= 2 && hamming(j) <= 2) {
	res[i][j] = 16;
      }

      /* C3 */
      if(hamming(i) == 1 && hamming(j) == 1) {
	res[i][j] = 4;
      }
    }
  }

  /* C6 */
  for(j = 0; j < NUMOUT; j++) {
    if(hamming(j) == 1) {
      res[2][j] = 0;
      res[16][j] = 0;
    }
  }

  /* C8 */
  //res[4][4] = 0; // removed this condition, need symmetric variant!

  /* trivial */
  res[0][0] = 64;

  for(i = 1; i < NUMIN; i++) {
    res[i][0] = 0;
  }

  for(j = 1; j < NUMOUT; j++) {
    res[0][j] = 0;
    res[1][j] = 0;
    res[32][j] = 0;
    res[33][j] = 0;
  }
}

int additional_conditions( tab bias ) {
  int i,a,b1,j,b2;
  /* C5 */
  for(i = 0; i < KIN; i++ ) {
    a = 1<<i;
    for(b1 = 0; b1 < NUMOUT; b1++ ) {
      for(j = 0; j < KOUT; j++ ) {
	b2 = b1 ^ (1<<j);
	if (abs( bias[a][b1] * bias[a][b2] ) > 240) {
          return(0);
	}
      }
    }
  }
  /* C7 */
  a = 2;
  for(b1 = 0; b1 < NUMOUT; b1++ ) {
    for(j = 0; j < KOUT; j++ ) {
      b2 = b1 ^ (1<<j);
      if (bias[a][b1]!=0 && bias[a][b2]!=0) {
	return(0);
      }
    }
  }
  /* C8 symmetrized */
  for(b1=0; b1<NUMOUT; b1++) {
    if (hamming(b1)==1) {
      if(bias[4][b1]==0) return(1); // 000100
      if(bias[8][b1]==0) return(1); // 001000
    }
  }
  return(0);
}

// Computes a heuristical value that describes the quality of a linear table bias
// with respect to a maximal one 
double computepenalty(tab bias) {
  int alpha, beta;
  int tmp;
  //int biasalpha[NUMOUT], maxbiasalpha[NUMOUT];
  int *biasalpha, *maxbiasalpha;
 
  double res;
 
  res = 0;
  for(alpha = 0; alpha < NUMIN; alpha++) {
    biasalpha = (int*)(bias[alpha]);
    maxbiasalpha = (int*)(maxbias[alpha]);
    for(beta = 0; beta < NUMOUT; beta++) {
      tmp = abs(biasalpha[beta])-maxbiasalpha[beta];
      //tmp += tmp;
      res += ldexp( 1.0, tmp );
      res--;
    }
  }
  /*/ add small random value to make all penalties different
  res += (rand()&0x3FF) * 0.0000009765625;
  //*/
 
  return(res);
}

/******************************************************************/
/* Array helper */
/******************************************************************/

// Comparison function of two poswithpenalty elements wrt. the double stored in there
int comparePoswithpenalty(const void *p1, const void *p2) {
  struct poswithpenalty* s1;
  struct poswithpenalty* s2;
  double d;

  s1 = (struct poswithpenalty*) p1;
  s2 = (struct poswithpenalty*) p2;
  d = s1->penalty - s2->penalty;
  return((d>0) - (d<0));
}


// Prints nicely a poswithpenalty struct
void printPoswithpenalty(struct poswithpenalty p1) {
  printf("(%d, %f)", p1.pos, p1.penalty);
}

/******************************************************************
 permuting the four bits of four bit numbers can be done in 24 ways:
 (For speed this is completely precomputed.)
 ******************************************************************/
int fourbitperm[24][16] = {
  { 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 }, // [1, 2, 3, 4]
  { 0,2,1,3,4,6,5,7,8,10,9,11,12,14,13,15 }, // [1, 2, 4, 3]
  { 0,1,4,5,2,3,6,7,8,9,12,13,10,11,14,15 }, // [1, 3, 2, 4]
  { 0,2,4,6,1,3,5,7,8,10,12,14,9,11,13,15 }, // [1, 3, 4, 2]
  { 0,4,1,5,2,6,3,7,8,12,9,13,10,14,11,15 }, // [1, 4, 2, 3]
  { 0,4,2,6,1,5,3,7,8,12,10,14,9,13,11,15 }, // [1, 4, 3, 2]
  { 0,1,2,3,8,9,10,11,4,5,6,7,12,13,14,15 }, // [2, 1, 3, 4]
  { 0,2,1,3,8,10,9,11,4,6,5,7,12,14,13,15 }, // [2, 1, 4, 3]
  { 0,1,4,5,8,9,12,13,2,3,6,7,10,11,14,15 }, // [2, 3, 1, 4]
  { 0,2,4,6,8,10,12,14,1,3,5,7,9,11,13,15 }, // [2, 3, 4, 1]
  { 0,4,1,5,8,12,9,13,2,6,3,7,10,14,11,15 }, // [2, 4, 1, 3]
  { 0,4,2,6,8,12,10,14,1,5,3,7,9,13,11,15 }, // [2, 4, 3, 1]
  { 0,1,8,9,2,3,10,11,4,5,12,13,6,7,14,15 }, // [3, 1, 2, 4]
  { 0,2,8,10,1,3,9,11,4,6,12,14,5,7,13,15 }, // [3, 1, 4, 2]
  { 0,1,8,9,4,5,12,13,2,3,10,11,6,7,14,15 }, // [3, 2, 1, 4]
  { 0,2,8,10,4,6,12,14,1,3,9,11,5,7,13,15 }, // [3, 2, 4, 1]
  { 0,4,8,12,1,5,9,13,2,6,10,14,3,7,11,15 }, // [3, 4, 1, 2]
  { 0,4,8,12,2,6,10,14,1,5,9,13,3,7,11,15 }, // [3, 4, 2, 1]
  { 0,8,1,9,2,10,3,11,4,12,5,13,6,14,7,15 }, // [4, 1, 2, 3]
  { 0,8,2,10,1,9,3,11,4,12,6,14,5,13,7,15 }, // [4, 1, 3, 2]
  { 0,8,1,9,4,12,5,13,2,10,3,11,6,14,7,15 }, // [4, 2, 1, 3]
  { 0,8,2,10,4,12,6,14,1,9,3,11,5,13,7,15 }, // [4, 2, 3, 1]
  { 0,8,4,12,1,9,5,13,2,10,6,14,3,11,7,15 }, // [4, 3, 1, 2]
  { 0,8,4,12,2,10,6,14,1,9,5,13,3,11,7,15 }  // [4, 3, 2, 1]
};


void initfullsbox(
		  sbox s,
		  tab actdiff,
		  tab actbias,
		  optionstab actoptions
		  ) {
  initmeresbox(s);
  inittab(actbias, 0 );
  inittab(actdiff, 0 );
  initoptions(actoptions, TRUE );
}

void updatesbox(	
		int x0,
		int y0,
		sbox s,
		tab actdiff,
		tab actbias,
		optionstab actoptions
			) {
  
  updatediff(x0, y0, s, actdiff);
  updatebias(x0, y0, s, actbias);
  // updateoptions();
  s[x0] = y0;
}

/******************************************************************
 backtracking procedure.

 Gets an S-box s and a new assignment s[x0] = y0 as well as all
 necessary tables to find an S-box that fulfills the requirements
 stated by maxdiff and maxbias.

 ******************************************************************/

double nodefrac = 1.0;
double treefrac = 0.0;
long long unsigned backtrackcnt = 0;
long long unsigned ends = 0;
long long unsigned bottoms1 =0;
long long unsigned bottoms2 =0;
long long unsigned bottoms3 =0;

unsigned branchlevel = 0;
double branchpos = 0.5;
bool branchscan = FALSE;

int backtrack(
	      sbox s,
	      tab actdiff,
	      tab actbias,
	      optionstab actoptions,
	      int level) {
  int x1, lx, y1;
  int i, j, i0, i1, p, x;
  int numoptions, numclasses;
  bool* options;
  struct poswithpenalty penalties[NUMOUT];
  double minpenalty;
  int alloptions[NUMIN][NUMOUT];
  int bestnumoptions, bestnumclasses;
  int numbestx;
  int listbestx[NUMIN];
  int numgoodperms, goodperm[24];
  int randpos;
  sbox sbak;
  tab diffbak, biasbak;
  optionstab optionsbak;
  int backtrackanswer, fix, good;
  double treefracprev, nodefracprev;
  bool toplevel;

  backtrackcnt++;

  //  level = countUNDEF(s);

#ifdef DEBUGTM
  if(backtrackcnt>9999ull) {
    printf("%'18lld L%2d: Abort %.3e at %.12f of tree...\n",
	   backtrackcnt, level, nodefrac, treefrac );
    fflush(stdout);
    return(1);
  }
#endif
  toplevel = (level > NUMIN-branchlevel);
  if(branchscan && !toplevel) {
    printf("%'18lld L%2d: wanted STOP, do not decend below node at tree %.12f..%.12f.\n@subtree %.12f    ",
	   backtrackcnt, level,
	   treefrac, treefrac+nodefrac,
	   treefrac+0.5*nodefrac );
    printsbox(s);
    return(0);
  }
#ifdef QUIET
  if((backtrackcnt&0xFFFFFull) == 0) {
    printf("%'18lld L%2d: Considering subtree %.3e at %.12f of tree:\n                      S= ",
	   backtrackcnt, level, nodefrac, treefrac );
    printsbox(s);
  }
#endif

  dprintf("DEBUG: Number of undefined places is %d\n", level);

  if(level == 0) {
    printf("%'18lld L%2d: Complete %.3e at %.12f of tree...\n",
	   backtrackcnt, level, nodefrac, treefrac );
    fflush(stdout);
    if(!tababsleq(actbias, maxbias)) {
      bottoms1++;
      /*
      printf("BAD1: ");
      printsbox(s);
      //*/
      treefrac = treefrac + nodefrac;
      return(0);
    } 
#ifdef DESL
    else if (!additional_conditions(actbias)) {
      bottoms2++;
      printf("BAD3: ");
      printsbox(s);
      treefrac = treefrac + nodefrac;
      return(0);
    }
#endif
    else {
      bottoms3++;
      printf("GOOD: ");
      printsbox(s);
      treefrac = treefrac + nodefrac;
      return(backtrackdone);
    }
  }

#ifndef NOPURGE
  // Purge branches that cannot fulfill linear conditions any more.
  if(tababsmaxovershoot(actbias,maxbias)>level) {
    ends++;
#ifndef QUIET
    printf("%'18lld L%2d: Purge %.3e at %.12f of tree.\n",
	   backtrackcnt, level, nodefrac, treefrac );
    /*
    printf("BAD : ");
    printsbox(s);
    //*/
    fflush(stdout);
#endif
    treefrac = treefrac + nodefrac;
    return(0);
  }
#endif


  // Compute list of remaining output wire permutations
  numgoodperms=0;
  for (p=0; p<24; p++) {
    fix = TRUE;
    for (x=0; x<NUMIN; x++) {
      //dprintf("DEBUG: Hi! s=%X, s[00]=%X, s[01]=%X\n", s, s[0], s[1]);
      if (s[x] == UNDEF) continue;
      if (s[x] != fourbitperm[p][s[x]]) {
	fix = FALSE;
	break;
      }
    }
    if (fix) goodperm[numgoodperms++] = p;
    dprintf("DEBUG: Another good perm.\n");
  }	
  dprintf("DEBUG: %d remaining sigmas.\n", numgoodperms );

#ifdef TOPSQUARE
  lx = NUMIN;
  if(level>NUMIN-16) {
    // Use positions 00,04,08,0C, 10,14,18,1C, 20,24,28,2C until filled.
    for(x1=0; x1<NUMIN*3/4; x1+=4) if(s[x1]==UNDEF) break;
    if(s[x1]==UNDEF) {
      lx = x1+1;
      dprintf( "DEBUG: TOPSQUARE S[%02X] next.\n", x1 );
    }
  } 
  if(lx==NUMIN) {
    // pick best position on lower tree level
    x1 = 0;
    lx = NUMIN;
    dprintf( "DEBUG: TOPSQUARE complete, one of S[%02X..%02X] next.\n", x1, lx-1 );
  }
#else
  x1 = 0;
  lx = NUMIN;
  dprintf( "DEBUG: Auto x choice, S[%02X..%02X] next.\n", x1, lx-1 );
#endif

  bestnumoptions = NUMIN+1;
  bestnumclasses = NUMIN+1;
  numbestx = 0;
  for(; x1 < lx; x1++) {
    if(s[x1] == UNDEF) {
      updateoptionsat(s, actdiff, x1, actoptions[x1], &numoptions);
      
      if(numoptions == 0) {
	dprintf("DEBUG: FAIL. No options left for S[%02X]. Backtracking.\n", x1);
        treefrac = treefrac + nodefrac;
	return(0);
      }
      
      options = actoptions[x1];
      numclasses = 0;
      for(j = 0; j < NUMOUT; j++) {
	if (!options[j]) continue;
	// Check whether an option is isomorphic to a smaller one.
	good = TRUE;
	for (p=1; p<numgoodperms; p++) {
	  if (fourbitperm[goodperm[p]][j] < j) {
	    good = FALSE;
	    break;
	  }
	}
	if (good) {
	  // Store if representative of isomorphic ones.
	  dprintf("DEBUG: May use S[%02X]=%01X (numclasses=%d).\n",
		  x1, j, numclasses );
	  alloptions[x1][numclasses++] = j;
	}
      }
      dprintf("DEBUG: x1=0x%02X, fixes=%d, numoptions=%d, numclasses=%d.\n",
	     x1, numgoodperms, numoptions, numclasses );
      //*/
      //numclasseslist[x1] = numclasses;
      
      /*
	printf("Can pick S[%02X] in {", x1);
	for(i = 0; i < numoptions; i++) {
	y1 = options[i];
	printf("%d", y1);
	if(i < numoptions-1) {
	printf(", ");
	} else {
	printf("}\n");
	}
	}
      //*/
      
      if(numoptions < bestnumoptions) {
	numbestx = 0;
	bestnumoptions = numoptions;
	bestnumclasses = numclasses;
      } else if (numoptions==bestnumoptions && numclasses<bestnumclasses) {
	numbestx = 0;
	bestnumoptions = numoptions;
	bestnumclasses = numclasses;
      }
      
      if(numoptions==bestnumoptions && numclasses==bestnumclasses) {
	listbestx[numbestx++] = x1;
      }
    }
  }
  
#ifdef DETERMINEXS
  randpos = 0;
  x1 = listbestx[0];
  dprintf("DEBUG: DETERMINISTIC x, take first.\n");
#else
  if (toplevel)
    randpos = 0; // we must stay deterministic in TOPLEVELs
  else
    randpos = ((int) rand())%numbestx;
  x1 = listbestx[randpos];
  dprintf(
	  (lx<NUMIN)
	  ?"DEBUG: Random x, take %d: %02X.\n"
	  :"DEBUG: Fixed x.\n",
	  randpos, listbestx[randpos] );
#endif
  dprintf("DEBUG: Selected x0 = %X, sorting options by penalty...\n", x1);
  
  for(i = 0; i < bestnumclasses; i++) {
    y1 = alloptions[x1][i];
    dprintf("DEBUG: Option S[%02X]=%X,",x1,y1); fflush(stdout);
    tabcopy(actbias, biasbak);
    updatebias(x1, y1, s, biasbak);
    
    penalties[i].pos = y1;
    penalties[i].penalty = computepenalty(biasbak)
      // make sure that penalties are different:
      + y1 * 0.0000009536743164; 

    dprintf(" penalty=%.6f.\n", penalties[i].penalty );
  }
  
  //printf("\nHi!\n\n"); fflush(stdout);
  qsort( penalties,
	 bestnumclasses,
	 (size_t) sizeof(struct poswithpenalty),
	 comparePoswithpenalty);
  
#ifndef DEBUG
#ifndef QUIET
  if (toplevel || level>NUMIN-16 || level<8)
#else
  if (toplevel || level>NUMIN-12 || level<4)
#endif
#endif
    {
      printf("%'18lld L%2d: Try S[%02X] in %d{ ",
	     backtrackcnt, level, x1, numgoodperms );
      for(i = 0; i < bestnumclasses; i++)
	printf("%1X (%+.3f), ", penalties[i].pos, penalties[i].penalty );
      printf("\b\b }...\n");
      fflush(stdout);
    }

  // Now run over all or a certain branch below this node.
  treefracprev = treefrac;
  nodefracprev = nodefrac;
  nodefrac = nodefrac / bestnumclasses;
  sboxcopy( s, sbak);
  tabcopy( actdiff, diffbak);
  tabcopy( actbias, biasbak);
  optcopy( actoptions, optionsbak);

  if (level==NUMIN-branchlevel) {
    printf("%'18lld L%2d: TOPLEVEL complete [tree=%.12f..%.12f].\n@subtree %.12f    ",
	   backtrackcnt, level,
	   treefrac, treefrac+nodefrac,
	   treefrac+0.5*nodefrac );
    printsbox(s); }
  if (!branchscan && toplevel) {
    /* i s.t
       treefrac+i*nodefrac/bestnumclasses <= branch
       < treefrac+(i+1)*nodefrac/bestnumclasses
    */
    i0 = floor( (branchpos-treefrac)/nodefrac );
    if(i0<0) i0=0;
    if(i0>=bestnumclasses) i0=bestnumclasses-1;
    i1 = i0+1;
    treefrac = treefracprev + i0*nodefrac;
    printf("%'18lld L%2d: TOPLEVEL, consider child %d only [tree=%.12f..%.12f].\n",
	   backtrackcnt, level, i0, treefrac, treefrac+nodefrac );
    //*/
  } else {
    i0 = 0;
    i1 = bestnumclasses;
    dprintf("DEBUG: below TOPLEVEL, consider all childs.\n" );
  }  

  for(i = i0; i < i1; i++)
    {
    y1 = penalties[i].pos;
    treefrac = treefracprev + i*nodefrac;
    //printf("Trying S[%02X] = %X...\n", x1, y1);
    
    dprintf("DEBUG: Setting S[%02X] = %X\n", x1, y1);
    updatesbox( x1, y1, s, actdiff, actbias, actoptions );

    backtrackanswer = backtrack( s, actdiff, actbias, actoptions, level-1 );
    if(backtrackanswer) return(backtrackanswer); 

    // undo updatesbox:
    sboxcopy( sbak, s);
    tabcopy( diffbak, actdiff );
    tabcopy( biasbak, actbias );
    optcopy( optionsbak, actoptions);
  }
  nodefrac = nodefracprev;
  treefrac = treefracprev + nodefracprev;

  return(0);
}



void find_sbox() {
  tab actbias, actdiff;
  optionstab actoptions;
  sbox s;
  int x0, y0, branch, branch0, branch1;

  int numoptions, options[NUMOUT];

  printf("**********************************************\n");
  printf("*** Starting search for an S-box.          ***\n");
  printf("**********************************************\n\n");

  printf("Computing the bounds...\n");
  SETMAXDIFF(maxdiff);
  printf("(unnormalized) bounds for diff:\n");
  printtab(maxdiff);
  SETMAXBIAS(maxbias);
  printf("(unnormalized) abs. bounds for bias:\n");
  printtab(maxbias);
  printf("Computing the bounds: done.\n");
#ifdef DESL
  printf("Some additional nonlinear constraints will be considered for every hit.\n");
#endif

#if defined(DESL) && !defined(TESTDESL)
  if (branchscan) {
    branch0 = 0;
    branch1 = sizeof(sboxbranch)/sizeof(sbox);
  } else {
    branch=floor(
		 (branchpos-treefrac)
		 *(sizeof(sboxbranch)/sizeof(sbox))
		 );
    if (branch < 0) branch = 0;
    if (branch >= sizeof(sboxbranch)/sizeof(sbox)) {
      branch = sizeof(sboxbranch)/sizeof(sbox)-1;
    }
    branch0 = branch;
    branch1 = branch+1;
  }
  nodefrac = nodefrac / (sizeof(sboxbranch)/sizeof(sbox));
#else
  branch0 = 0;
  branch1 = 1;
#endif
  
  for(branch=branch0; branch<branch1; branch++) {
    printf("**********************************************\n");
    printf("Generating an empty S-box...\n");
    initfullsbox( s, actdiff, actbias, actoptions );

    printf("Setting random seed = %d.\n", seed );
    srand(seed);
    printf("Presetting...\n");
#ifdef TESTDESL
    //*// use partial values from desl S-box
    for
#if (TESTDESL>0)
      (x0 = TESTDESL; x0 < NUMIN; x0++)
#else
      (x0 = 0; x0 < NUMIN+TESTDESL; x0++)
#endif
	{
	  y0 = desl[x0];
	  updatesbox( x0, y0, s, actdiff, actbias, actoptions );
	  printf("Preset S[%02X]=%X.\n", x0, s[x0] );
	}
    //*/
#else
#ifdef DESL
    for (x0 = 0; x0 < NUMIN; x0++) {
      y0 = sboxbranch[branch][x0];
      if (y0!=UNDEF) {
	updatesbox( x0, y0, s, actdiff, actbias, actoptions );
	printf("Preset S[%02X]=%X.\n", x0, s[x0] );
      }
    }
    treefrac = branch * nodefrac;
#endif // DESL
#endif
    printf("**********************************************\n");
    printf("*** Start backtracking...                  ***\n");
    printf("**********************************************\n");
    backtrack( s, actdiff, actbias, actoptions, countUNDEF(s) );
    printf("**********************************************\n");
  }

  if(countUNDEF(s)>0) {
#ifdef FIRSTHIT
    printf("No complete result.\n");
#else
    printf("Search completed.\n");
#endif
  } else {
    computediff(s, actdiff);
    bias(s, actbias);
    if(tableq(actdiff, maxdiff)) {
      printf("Differential CA properties OK!\n");
    } else {
      printf("Violation of the differential CA properties :(\n");
    }
    if(tababsleq(actbias, maxbias)) {
      printf("Linear CA properties OK!\n");
    } else {
      printf("Violation of the linear CA properties :(\n");
    }
    if(additional_conditions(actbias)) {
      printf("Additional linear CA properties (nonlinear conditions on bias) OK!\n");
    } else {
      printf("Violation of the additional linear CA properties :(\n");
    }
  }
  printf("\nCIAO after %lld backtrack calls, %lld ends, %lld,%lld,%lld bottoms, at %.12f of tree.\n",
	 backtrackcnt, ends, bottoms1, bottoms2, bottoms3, treefrac);
}

int main(int argc, char *argv[]) {
  
  printf("       WELCOME to the S-box finder.\n\n");
  printf("@compileflags ");
  #ifdef DESL
  printf("-D DESL ");
#endif
  #ifdef PRESENT
  printf("-D PRESENT ");
#endif
  #ifdef TESTDESL
  printf("-D TESTDESL=%d ",TESTDESL);
#endif
  #ifdef TOPSQUARE
  printf("-D TOPSQUARE ");
#endif
  #ifdef FIRSTHIT
  printf("-D FIRSTHIT ");
#endif
  #ifdef DEBUG
  printf("-D DEBUG ");
#endif
  #ifdef DEBUGX
  printf("-D DEBUGX ");
#endif
  #ifdef DEBUGLVL
  printf("-D DEBUGLVL=%d ",DEBUGLVL);
#endif
  #ifdef DEBUGTM
  printf("-D DEBUGTM ");
#endif
  #ifdef QUIET
  printf("-D QUIET ");
#endif
  #ifdef NOPRINT
  printf("-D NOPRINT ");
#endif
  printf("\n\n");
  printf("**********************************************\n");
  printf("*** Checking command line                  ***\n");
  printf("**********************************************\n");
  
  if(argc==0) {
    seed = 20111211;
    printf("No valid input found. Using fixed random init...\n"); }
  if(argc>1) {
    if (!sscanf(argv[1],"%ud",&seed)==1)
      seed = time(NULL);
  }
  branchlevel = 0;
  branchpos = 0.0;
  branchscan = FALSE;
  if(argc>2) {
    if (0==sscanf(argv[2],"%ud",&branchlevel))
      branchlevel = 5;
    if(argc==3 || 0==sscanf(argv[3],"%lf",&branchpos)) {
      branchpos = -1;      
      branchscan = TRUE;
    } else {
      if (branchpos<0) branchpos = 0;
      if (branchpos>1) branchpos = 1;
    }
    printf("Choosing branch level=%d, ", branchlevel ); 
    if (branchpos<0) 
      printf("scan all positions.\n" ); 
    else
      printf("pos=%f.\n", branchpos ); 
  }

  printf("\n@commandline %d %d %.12f\n\n", seed, branchlevel, branchpos );

  fflush(stdout);
  find_sbox();
}

