/**
 * @file flip_carry_64.c
 *
 * This module deals with flipping discs.
 *
 * A function is provided for each square of the board. These functions are
 * gathered into an array of functions, so that a fast access to each function
 * is allowed. The generic form of the function take as input the player and
 * the opponent bitboards and return the flipped squares into a bitboard.
 *
 * Given the following notation:
 *  - x = square where we play,
 *  - P = player's disc pattern,
 *  - O = opponent's disc pattern,
 * the basic principle is to read into an array the result of a move. Doing
 * this is easier for a single line ; so we can use arrays of the form:
 *  - ARRAY[x][8-bits disc pattern].
 * The problem is thus to convert any line of a 64-bits disc pattern into an
 * 8-bits disc pattern. A fast way to do this is to select the right line,
 * with a bit-mask, to gather the masked-bits into a continuous set by a simple
 * multiplication and to right-shift the result to scale it into a number
 * between 0 and 255.
 * Once we get our 8-bits disc patterns,a first array (OUTFLANK) is used to
 * get the player's discs that surround the opponent discs:
 *  - outflank = OUTFLANK[x][O] & P
 * (Only inner 6-bits of the P are in interest here.)
 * The result is then used as an index to access a second array giving the
 * flipped discs according to the surrounding player's discs:
 *  - flipped = FLIPPED[x][outflank].
 * (Flipped discs fall into inner 6-bits.)
 * Finally, a precomputed array transform the inner 6-bits disc pattern back into a
 * 64-bits disc pattern, and the flipped squares for each line are gathered and
 * returned to generate moves.
 *
 * If the OUTFLANK search is in LSB to MSB direction, carry propagation 
 * can be used to determine contiguous opponent discs.
 * If the OUTFLANK search is in MSB to LSB direction, CONTIG_X tables
 * are used to determine coutiguous opponent discs.
 *
 * @date 1998 - 2020
 * @author Richard Delorme
 * @author Toshihiko Okuhara
 * @version 4.4
 */

#include "bit.h"

/** outflank array (indexed with inner 6 bits) */
/* static const uint8_t OUTFLANK_0[64] = {
	0x00, 0x04, 0x00, 0x08, 0x00, 0x04, 0x00, 0x10, 0x00, 0x04, 0x00, 0x08, 0x00, 0x04, 0x00, 0x20,
	0x00, 0x04, 0x00, 0x08, 0x00, 0x04, 0x00, 0x10, 0x00, 0x04, 0x00, 0x08, 0x00, 0x04, 0x00, 0x40,
	0x00, 0x04, 0x00, 0x08, 0x00, 0x04, 0x00, 0x10, 0x00, 0x04, 0x00, 0x08, 0x00, 0x04, 0x00, 0x20,
	0x00, 0x04, 0x00, 0x08, 0x00, 0x04, 0x00, 0x10, 0x00, 0x04, 0x00, 0x08, 0x00, 0x04, 0x00, 0x80
}; */

/* static const uint8_t OUTFLANK_1[64] = {
	0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x20, 0x00,
	0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x40, 0x00,
	0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x20, 0x00,
	0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x80, 0x00
}; */

static const uint8_t OUTFLANK_2[64] = {
	0x00, 0x01, 0x00, 0x00, 0x10, 0x11, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x20, 0x21, 0x00, 0x00,
	0x00, 0x01, 0x00, 0x00, 0x10, 0x11, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x40, 0x41, 0x00, 0x00,
	0x00, 0x01, 0x00, 0x00, 0x10, 0x11, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x20, 0x21, 0x00, 0x00,
	0x00, 0x01, 0x00, 0x00, 0x10, 0x11, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x80, 0x81, 0x00, 0x00
};

static const uint8_t OUTFLANK_3[64] = {
	0x00, 0x00, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x20, 0x20, 0x22, 0x21, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x40, 0x42, 0x41, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x20, 0x20, 0x22, 0x21, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x82, 0x81, 0x00, 0x00, 0x00, 0x00
};

static const uint8_t OUTFLANK_4[64] = {
	0x00, 0x00, 0x00, 0x00, 0x04, 0x04, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x40, 0x40, 0x40, 0x40, 0x44, 0x44, 0x42, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x04, 0x04, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x80, 0x80, 0x80, 0x80, 0x84, 0x84, 0x82, 0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};

static const uint8_t OUTFLANK_5[64] = {
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x08, 0x08, 0x04, 0x04, 0x02, 0x01,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x88, 0x88, 0x88, 0x88, 0x84, 0x84, 0x82, 0x81,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};

/* static const uint8_t OUTFLANK_6[64] = {
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x08, 0x08, 0x08, 0x08, 0x04, 0x04, 0x02, 0x01,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}; */

static const uint8_t OUTFLANK_7[64] = {
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
	0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x08, 0x08, 0x08, 0x08, 0x04, 0x04, 0x02, 0x01
};

/* (Count of leading 1 from bit 5) * 8 */
static const uint8_t CONTIG_UP[64] = {
	 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
	 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
	 8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,
	16, 16, 16, 16, 16, 16, 16, 16, 24, 24, 24, 24, 32, 32, 40, 48
};

/* (Count of leading 1 from bit 5) * 9 */
static const uint8_t CONTIG_UPLEFT[64] = {
	 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
	 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
	 9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
	18, 18, 18, 18, 18, 18, 18, 18, 27, 27, 27, 27, 36, 36, 45, 54
};

/* (Count of trailing 1) * 7 */
static const uint8_t CONTIG_UPRIGHT[64] = {
	 0,  7,  0, 14,  0,  7,  0, 21,  0,  7,  0, 14,  0,  7,  0, 28,
	 0,  7,  0, 14,  0,  7,  0, 21,  0,  7,  0, 14,  0,  7,  0, 35,
	 0,  7,  0, 14,  0,  7,  0, 21,  0,  7,  0, 14,  0,  7,  0, 28,
	 0,  7,  0, 14,  0,  7,  0, 21,  0,  7,  0, 14,  0,  7,  0, 42
};

/** flip array (indexed with outflank, returns inner 6 bits) */
static const uint64_t FLIPPED_2_H[130] = {
	0x0000000000000000, 0x0202020202020202, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x0808080808080808, 0x0a0a0a0a0a0a0a0a, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x1818181818181818, 0x1a1a1a1a1a1a1a1a, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x3838383838383838, 0x3a3a3a3a3a3a3a3a, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x7878787878787878, 0x7a7a7a7a7a7a7a7a
};

static const uint64_t FLIPPED_3_H[131] = {
	0x0000000000000000, 0x0606060606060606, 0x0404040404040404, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x1010101010101010, 0x1616161616161616, 0x1414141414141414, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x3030303030303030, 0x3636363636363636, 0x3434343434343434, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x7070707070707070, 0x7676767676767676, 0x7474747474747474
};

static const uint64_t FLIPPED_4_H[133] = {
	0x0000000000000000, 0x0e0e0e0e0e0e0e0e, 0x0c0c0c0c0c0c0c0c, 0x0000000000000000, 0x0808080808080808, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x2020202020202020, 0x2e2e2e2e2e2e2e2e, 0x2c2c2c2c2c2c2c2c, 0x0000000000000000, 0x2828282828282828, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x6060606060606060, 0x6e6e6e6e6e6e6e6e, 0x6c6c6c6c6c6c6c6c, 0x0000000000000000, 0x6868686868686868
};

static const uint64_t FLIPPED_5_H[137] = {
	0x0000000000000000, 0x1e1e1e1e1e1e1e1e, 0x1c1c1c1c1c1c1c1c, 0x0000000000000000, 0x1818181818181818, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x1010101010101010, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x4040404040404040, 0x5e5e5e5e5e5e5e5e, 0x5c5c5c5c5c5c5c5c, 0x0000000000000000, 0x5858585858585858, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x5050505050505050
};

static const uint64_t FLIPPED_2_V[130] = {
	0x0000000000000000, 0x000000000000ff00, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x00000000ff000000, 0x00000000ff00ff00, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x000000ffff000000, 0x000000ffff00ff00, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x0000ffffff000000, 0x0000ffffff00ff00, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x00ffffffff000000, 0x00ffffffff00ff00
};

static const uint64_t FLIPPED_3_V[131] = {
	0x0000000000000000, 0x0000000000ffff00, 0x0000000000ff0000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x000000ff00000000, 0x000000ff00ffff00, 0x000000ff00ff0000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x0000ffff00000000, 0x0000ffff00ffff00, 0x0000ffff00ff0000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x00ffffff00000000, 0x00ffffff00ffff00, 0x00ffffff00ff0000
};

static const uint64_t FLIPPED_4_V[133] = {
	0x0000000000000000, 0x00000000ffffff00, 0x00000000ffff0000, 0x0000000000000000, 0x00000000ff000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x0000ff0000000000, 0x0000ff00ffffff00, 0x0000ff00ffff0000, 0x0000000000000000, 0x0000ff00ff000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x00ffff0000000000, 0x00ffff00ffffff00, 0x00ffff00ffff0000, 0x0000000000000000, 0x00ffff00ff000000
};

static const uint64_t FLIPPED_5_V[137] = {
	0x0000000000000000, 0x000000ffffffff00, 0x000000ffffff0000, 0x0000000000000000, 0x000000ffff000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x000000ff00000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x00ff000000000000, 0x00ff00ffffffff00, 0x00ff00ffffff0000, 0x0000000000000000, 0x00ff00ffff000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x00ff00ff00000000
};

static const uint64_t FLIPPED_2_U[130] = {
	0x0000000000000000, 0x00ff000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x000000ff00000000, 0x00ff00ff00000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x000000ffff000000, 0x00ff00ffff000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x000000ffffff0000, 0x00ff00ffffff0000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x000000ffffffff00, 0x00ff00ffffffff00
};

static const uint64_t FLIPPED_3_U[131] = {
	0x0000000000000000, 0x00ffff0000000000, 0x0000ff0000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x00000000ff000000, 0x00ffff00ff000000, 0x0000ff00ff000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x00000000ffff0000, 0x00ffff00ffff0000, 0x0000ff00ffff0000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x00000000ffffff00, 0x00ffff00ffffff00, 0x0000ff00ffffff00
};

static const uint64_t FLIPPED_4_U[133] = {
	0x0000000000000000, 0x00ffffff00000000, 0x0000ffff00000000, 0x0000000000000000, 0x000000ff00000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x0000000000ff0000, 0x00ffffff00ff0000, 0x0000ffff00ff0000, 0x0000000000000000, 0x000000ff00ff0000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x0000000000ffff00, 0x00ffffff00ffff00, 0x0000ffff00ffff00, 0x0000000000000000, 0x000000ff00ffff00
};

static const uint64_t  FLIPPED_5_U[137] = {
	0x0000000000000000, 0x00ffffffff000000, 0x0000ffffff000000, 0x0000000000000000, 0x000000ffff000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x00000000ff000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x000000000000ff00, 0x00ffffffff00ff00, 0x0000ffffff00ff00, 0x0000000000000000, 0x000000ffff00ff00, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
	0x00000000ff00ff00
};


/*
 * Set all bits below the sole outflank bit if outfrank != 0
 */
#if __has_builtin(__builtin_subcll)
static inline uint64_t OutflankToFlipmask(uint64_t outflank) {
	unsigned long long flipmask, cy;
	flipmask = __builtin_subcll(outflank, 1, 0, &cy);
	return __builtin_addcll(flipmask, 0, cy, &cy);
}
#elif (defined(_M_X64) && (_MSC_VER >= 1800)) || (defined(__x86_64__) && defined(__GNUC__) && (__GNUC__ > 7 || (__GNUC__ == 7 && __GNUC_MINOR__ >= 2)))
static inline uint64_t OutflankToFlipmask(uint64_t outflank) {
	uint64_t flipmask;
	uint8_t cy = _subborrow_u64(0, outflank, 1, &flipmask);
	_addcarry_u64(cy, flipmask, 0, &flipmask);
	return flipmask;
}
#else
	#define OutflankToFlipmask(outflank)	((outflank) - (unsigned int) ((outflank) != 0))
#endif

/*
 * Scan non-opponent bit (player or empty) from LSB
 */
#if 0 // LS1B
static uint64_t OUTFLANK_LEFT(uint64_t O, uint64_t M) {
	uint64_t b = ~O & M;
	return b & -b;
}
#else // carry propagation - less register pressure
/*
 *	((~O & M) & -(~O & M)) & P		// LS1B
 *	((~O & M) & (~(~O & M) + 1)) & P	// -x = (~x + 1)
 *	(~O & M & ((O | ~M) + 1)) & P		// De Morgan
 *	(((O | ~M) + 1) & M) & (P & ~O)		// P & O = 0, so P & ~O = P
 *	(((O | ~M) + 1) & M) & P		// carry propagation
 */
#define OUTFLANK_LEFT(O,M)	((((O) | ~(M)) + 1) & (M))
#endif

/**
 * Compute flipped discs when playing on square A1.
 *
 * @param P player's disc pattern.
 * @param O opponent's disc pattern.
 * @return flipped disc pattern.
 */
static uint64_t flip_A1(const uint64_t P, const uint64_t O)
{
	uint8_t outflank_h;
	uint64_t flipped, outflank_v, outflank_d9;

	outflank_v = OUTFLANK_LEFT(O, 0x0101010101010100) & P;
	flipped = OutflankToFlipmask(outflank_v) & 0x0101010101010100;

	outflank_d9 = OUTFLANK_LEFT(O, 0x8040201008040200) & P;
	flipped |= OutflankToFlipmask(outflank_d9) & 0x8040201008040200;

	outflank_h = (O + 0x02) & P;
	flipped += ((outflank_h * 0x7f) >> 8) << 1;

	return flipped;
}

/**
 * Compute flipped discs when playing on square B1.
 *
 * @param P player's disc pattern.
 * @param O opponent's disc pattern.
 * @return flipped disc pattern.
 */
static uint64_t flip_B1(const uint64_t P, const uint64_t O)
{
	uint8_t outflank_h;
	uint64_t flipped, outflank_v, outflank_d9;

	outflank_v = OUTFLANK_LEFT(O, 0x0202020202020200) & P;
	flipped = OutflankToFlipmask(outflank_v) & 0x0202020202020200;

	outflank_d9 = OUTFLANK_LEFT(O, 0x0080402010080400) & P;
	flipped |= OutflankToFlipmask(outflank_d9) & 0x0080402010080400;

	outflank_h = (O + 0x04) & P;
	flipped += ((outflank_h * 0x3f) >> 8) << 2;

	return flipped;
}

/**
 * Compute flipped discs when playing on square C1.
 *
 * @param P player's disc pattern.
 * @param O opponent's disc pattern.
 * @return flipped disc pattern.
 */
static uint64_t flip_C1(const uint64_t P, const uint64_t O)
{
	unsigned int outflank_h, outflank_d;
	uint64_t flipped, outflank_v;

	outflank_v = OUTFLANK_LEFT(O, 0x0404040404040400) & P;
	flipped = OutflankToFlipmask(outflank_v) & 0x0404040404040400;

	outflank_d = OUTFLANK_2[((O & 0x0000004020100a04) * 0x0101010101010101) >> 57]
		& (((P & 0x0000804020110a04) * 0x0101010101010101) >> 56);
	flipped |= FLIPPED_2_H[outflank_d] & 0x0000004020100a04;	// A3C1H6

	outflank_h = OUTFLANK_2[(O >> 1) & 0x3f] & P;
	flipped |= (uint8_t) FLIPPED_2_H[outflank_h];

	return flipped;
}

/**
 * Compute flipped discs when playing on square D1.
 *
 * @param P player's disc pattern.
 * @param O opponent's disc pattern.
 * @return flipped disc pattern.
 */
static uint64_t flip_D1(const uint64_t P, const uint64_t O)
{
	unsigned int outflank_h, outflank_d;
	uint64_t flipped, outflank_v;

	outflank_v = OUTFLANK_LEFT(O, 0x0808080808080800) & P;
	flipped = OutflankToFlipmask(outflank_v) & 0x0808080808080800;

	outflank_d = OUTFLANK_3[((O & 0x0000000040221408) * 0x0101010101010101) >> 57]
		& (((P & 0x0000008041221408) * 0x0101010101010101) >> 56);
	flipped |= FLIPPED_3_H[outflank_d] & 0x0000000040221408;	// A4D1H5

	outflank_h = OUTFLANK_3[(O >> 1) & 0x3f] & P;
	flipped |= (uint8_t) FLIPPED_3_H[outflank_h];

	return flipped;
}

/**
 * Compute flipped discs when playing on square E1.
 *
 * @param P player's disc pattern.
 * @param O opponent's disc pattern.
 * @return flipped disc pattern.
 */
static uint64_t flip_E1(const uint64_t P, const uint64_t O)
{
	unsigned int outflank_h, outflank_d;
	uint64_t flipped, outflank_v;

	outflank_v = OUTFLANK_LEFT(O, 0x1010101010101000) & P;
	flipped = OutflankToFlipmask(outflank_v) & 0x1010101010101000;

	outflank_d = OUTFLANK_4[((O & 0x0000000002442810) * 0x0101010101010101) >> 57]
		& (((P & 0x0000000182442810) * 0x0101010101010101) >> 56);
	flipped |= FLIPPED_4_H[outflank_d] & 0x0000000002442810;	// A5E1H4

	outflank_h = OUTFLANK_4[(O >> 1) & 0x3f] & P;
	flipped |= (uint8_t) FLIPPED_4_H[outflank_h];

	return flipped;
}

/**
 * Compute flipped discs when playing on square F1.
 *
 * @param P player's disc pattern.
 * @param O opponent's disc pattern.
 * @return flipped disc pattern.
 */
static uint64_t flip_F1(const uint64_t P, const uint64_t O)
{
	unsigned int outflank_h, outflank_d;
	uint64_t flipped, outflank_v;

	outflank_v = OUTFLANK_LEFT(O, 0x2020202020202000) & P;
	flipped = OutflankToFlipmask(outflank_v) & 0x2020202020202000;

	outflank_d = OUTFLANK_5[((O & 0x0000000204085020) * 0x0101010101010101) >> 57]
		& (((P & 0x0000010204885020) * 0x0101010101010101) >> 56);
	flipped |= FLIPPED_5_H[outflank_d] & 0x0000000204085020;	// A6F1H3

	outflank_h = OUTFLANK_5[(O >> 1) & 0x3f] & P;
	flipped |= (uint8_t) FLIPPED_5_H[outflank_h];

	return flipped;
}

/**
 * Compute flipped discs when playing on square G1.
 *
 * @param P player's disc pattern.
 * @param O opponent's disc pattern.
 * @return flipped disc pattern.
 */
static uint64_t flip_G1(const uint64_t P, const uint64_t O)
{
	unsigned int outflank_h;
	uint64_t flipped, outflank_v, outflank_d7;

	outflank_v = OUTFLANK_LEFT(O, 0x4040404040404000) & P;
	flipped = OutflankToFlipmask(outflank_v) & 0x4040404040404000;

	outflank_d7 = OUTFLANK_LEFT(O, 0x0001020408102000) & P;
	flipped |= OutflankToFlipmask(outflank_d7) & 0x0001020408102000;

	outflank_h = OUTFLANK_7[O & 0x3e] & (P << 1);
	flipped |= ((-outflank_h) & 0x3e) << 0;

	return flipped;
}

/**
 * Compute flipped discs when playing on square H1.
 *
 * @param P player's disc pattern.
 * @param O opponent's disc pattern.
 * @return flipped disc pattern.
 */
static uint64_t flip_H1(const uint64_t P, const uint64_t O)
{
	unsigned int outflank_h;
	uint64_t flipped, outflank_v, outflank_d7;

	outflank_v = OUTFLANK_LEFT(O, 0x8080808080808000) & P;
	flipped = OutflankToFlipmask(outflank_v) & 0x8080808080808000;

	outflank_d7 = OUTFLANK_LEFT(O, 0x0102040810204000) & P;
	flipped |= OutflankToFlipmask(outflank_d7) & 0x0102040810204000;

	outflank_h = OUTFLANK_7[(O >> 1) & 0x3f] & P;
	flipped |= ((-outflank_h) & 0x3f) << 1;

	return flipped;
}

/**
 * Compute flipped discs when playing on square A2.
 *
 * @param P player's disc pattern.
 * @param O opponent's disc pattern.
 * @return flipped disc pattern.
 */
static uint64_t flip_A2(const uint64_t P, const uint64_t O)
{
	unsigned short outflank_h;
	uint64_t flipped, outflank_v, outflank_d9;

	outflank_v = OUTFLANK_LEFT(O, 0x0101010101010000) & P;
	flipped = OutflankToFlipmask(outflank_v) & 0x0101010101010000;

	outflank_d9 = OUTFLANK_LEFT(O, 0x4020100804020000) & P;
	flipped |= OutflankToFlipmask(outflank_d9) & 0x4020100804020000;

	outflank_h = (O + 0x0200) & P;
	flipped |= ((outflank_h * 0x7f) >> 16) << 9;

	return flipped;
}

/**
 * Compute flipped discs when playing on square B2.
 *
 * @param P player's disc pattern.
 * @param O opponent's disc pattern.
 * @return flipped disc pattern.
 */
static uint64_t flip_B2(const uint64_t P, const uint64_t O)
{
	unsigned short outflank_h;
	uint64_t flipped, outflank_v, outflank_d9;

	outflank_v = OUTFLANK_LEFT(O, 0x0202020202020000) & P;
	flipped = OutflankToFlipmask(outflank_v) & 0x0202020202020000;

	outflank_d9 = OUTFLANK_LEFT(O, 0x8040201008040000) & P;
	flipped |= OutflankToFlipmask(outflank_d9) & 0x8040201008040000;

	outflank_h = (O + 0x0400) & P;
	flipped |= ((outflank_h * 0x3f) >> 16) << 10;

	return flipped;
}

/**
 * Compute flipped discs when playing on square C2.
 *
 * @param P player's disc pattern.
 * @param O opponent's disc pattern.
 * @return flipped disc pattern.
 */
static uint64_t flip_C2(const uint64_t P, const uint64_t O)
{
	unsigned int outflank_h, outflank_d;
	uint64_t flipped, outflank_v;

	outflank_v = OUTFLANK_LEFT(O, 0x0404040404040000) & P;
	flipped = OutflankToFlipmask(outflank_v) & 0x0404040404040000;

	outflank_d = OUTFLANK_2[((O & 0x00004020100a0400) * 0x0101010101010101) >> 57]
		& (((P & 0x00804020110a0400) * 0x0101010101010101) >> 56);
	flipped |= FLIPPED_2_H[outflank_d] & 0x00004020100a0400;	// A4C2H7

	outflank_h = OUTFLANK_2[(O >> 9) & 0x3f] & (P >> 8);
	flipped |= FLIPPED_2_H[outflank_h] & 0x000000000000ff00;

	return flipped;
}

/**
 * Compute flipped discs when playing on square D2.
 *
 * @param P player's disc pattern.
 * @param O opponent's disc pattern.
 * @return flipped disc pattern.
 */
static uint64_t flip_D2(const uint64_t P, const uint64_t O)
{
	unsigned int outflank_h, outflank_d;
	uint64_t flipped, outflank_v;

	outflank_v = OUTFLANK_LEFT(O, 0x0808080808080000) & P;
	flipped = OutflankToFlipmask(outflank_v) & 0x0808080808080000;

	outflank_d = OUTFLANK_3[((O & 0x0000004022140800) * 0x0101010101010101) >> 57]
		& (((P & 0x0000804122140800) * 0x0101010101010101) >> 56);
	flipped |= FLIPPED_3_H[outflank_d] & 0x0000004022140800;	// A5D2H6

	outflank_h = OUTFLANK_3[(O >> 9) & 0x3f] & (P >> 8);
	flipped |= FLIPPED_3_H[outflank_h] & 0x000000000000ff00;

	return flipped;
}

/**
 * Compute flipped discs when playing on square E2.
 *
 * @param P player's disc pattern.
 * @param O opponent's disc pattern.
 * @return flipped disc pattern.
 */
static uint64_t flip_E2(const uint64_t P, const uint64_t O)
{
	unsigned int outflank_h, outflank_d;
	uint64_t flipped, outflank_v;

	outflank_v = OUTFLANK_LEFT(O, 0x1010101010100000) & P;
	flipped = OutflankToFlipmask(outflank_v) & 0x1010101010100000;

	outflank_d = OUTFLANK_4[((O & 0x0000000244281000) * 0x0101010101010101) >> 57]
		& (((P & 0x0000018244281000) * 0x0101010101010101) >> 56);
	flipped |= FLIPPED_4_H[outflank_d] & 0x0000000244281000;	// A6E2H5

	outflank_h = OUTFLANK_4[(O >> 9) & 0x3f] & (P >> 8);
	flipped |= FLIPPED_4_H[outflank_h] & 0x000000000000ff00;

	return flipped;
}

/**
 * Compute flipped discs when playing on square F2.
 *
 * @param P player's disc pattern.
 * @param O opponent's disc pattern.
 * @return flipped disc pattern.
 */
static uint64_t flip_F2(const uint64_t P, const uint64_t O)
{
	unsigned int outflank_h, outflank_d;
	uint64_t flipped, outflank_v;

	outflank_v = OUTFLANK_LEFT(O, 0x2020202020200000) & P;
	flipped = OutflankToFlipmask(outflank_v) & 0x2020202020200000;

	outflank_d = OUTFLANK_5[((O & 0x0000020408502000) * 0x0101010101010101) >> 57]
		& (((P & 0x0001020488502000) * 0x0101010101010101) >> 56);
	flipped |= FLIPPED_5_H[outflank_d] & 0x0000020408502000;	// A7F2H4

	outflank_h = OUTFLANK_5[(O >> 9) & 0x3f] & (P >> 8);
	flipped |= FLIPPED_5_H[outflank_h] & 0x000000000000ff00;

	return flipped;
}

/**
 * Compute flipped discs when playing on square G2.
 *
 * @param P player's disc pattern.
 * @param O opponent's disc pattern.
 * @return flipped disc pattern.
 */
static uint64_t flip_G2(const uint64_t P, const uint64_t O)
{
	unsigned int outflank_h;
	uint64_t flipped, outflank_v, outflank_d7;

	outflank_v = OUTFLANK_LEFT(O, 0x4040404040400000) & P;
	flipped = OutflankToFlipmask(outflank_v) & 0x4040404040400000;

	outflank_d7 = OUTFLANK_LEFT(O, 0x0102040810200000) & P;
	flipped |= OutflankToFlipmask(outflank_d7) & 0x0102040810200000;

	outflank_h = OUTFLANK_7[(O >> 8) & 0x3e] & (P >> 7);
	flipped |= ((-outflank_h) & 0x3e) << 8;

	return flipped;
}

/**
 * Compute flipped discs when playing on square H2.
 *
 * @param P player's disc pattern.
 * @param O opponent's disc pattern.
 * @return flipped disc pattern.
 */
static uint64_t flip_H2(const uint64_t P, const uint64_t O)
{
	unsigned int outflank_h;
	uint64_t flipped, outflank_v, outflank_d7;

	outflank_v = OUTFLANK_LEFT(O, 0x8080808080800000) & P;
	flipped = OutflankToFlipmask(outflank_v) & 0x8080808080800000;

	outflank_d7 = OUTFLANK_LEFT(O, 0x0204081020400000) & P;
	flipped |= OutflankToFlipmask(outflank_d7) & 0x0204081020400000;

	outflank_h = OUTFLANK_7[(O >> 9) & 0x3f] & (P >> 8);
	flipped |= ((-outflank_h) & 0x3f) << 9;

	return flipped;
}

/**
 * Compute flipped discs when playing on square A3.
 *
 * @param P player's disc pattern.
 * @param O opponent's disc pattern.
 * @return flipped disc pattern.
 */
static uint64_t flip_A3(const uint64_t P, const uint64_t O)
{
	unsigned int outflank_h, outflank_a1a3f8, outflank_a8a3c1;
	uint64_t flipped;

	outflank_a1a3f8 = OUTFLANK_2[((O & 0x0010080402010100) * 0x0102040404040404) >> 57]
		& (((P & 0x2010080402010101) * 0x0102040404040404) >> 56);
	flipped = FLIPPED_2_V[outflank_a1a3f8] & 0x0010080402010100;

	outflank_a8a3c1 = OUTFLANK_5[((O & 0x0001010101010200) * 0x2020201008040201) >> 57]
		& (((P & 0x0101010101010204) * 0x2020201008040201) >> 56);
	flipped |= FLIPPED_5_U[outflank_a8a3c1] & 0x0001010101010200;

	outflank_h = ((O & 0x007e0000u) + 0x00020000u) & P;
	flipped |= ((outflank_h * 0x7f) >> 24) << 17;

	return flipped;
}

/**
 * Compute flipped discs when playing on square B3.
 *
 * @param P player's disc pattern.
 * @param O opponent's disc pattern.
 * @return flipped disc pattern.
 */
static uint64_t flip_B3(const uint64_t P, const uint64_t O)
{
	unsigned int outflank_h, outflank_b1b3g8, outflank_b8b3d1;
	uint64_t flipped;

	outflank_b1b3g8 = OUTFLANK_2[((O & 0x0020100804020200) * 0x0081020202020202) >> 57]
		& (((P & 0x4020100804020202) * 0x0081020202020202) >> 56);
	flipped = FLIPPED_2_V[outflank_b1b3g8] & 0x0020100804020200;

	outflank_b8b3d1 = OUTFLANK_5[((O & 0x0002020202020400) * 0x0010100804020100) >> 57]
		& ((((P & 0x0202020202020408) >> 1) * 0x2020201008040201) >> 56);
	flipped |= FLIPPED_5_U[outflank_b8b3d1] & 0x0002020202020400;

	outflank_h = ((O & 0x007c0000u) + 0x00040000u) & P;
	flipped |= ((outflank_h * 0x3f) >> 24) << 18;

	return flipped;
}

/**
 * Compute flipped discs when playing on square C3.
 *
 * @param P player's disc pattern.
 * @param O opponent's disc pattern.
 * @return flipped disc pattern.
 */
static uint64_t flip_C3(const uint64_t P, const uint64_t O)
{
	unsigned int outflank_h, outflank_v, outflank_d9;
	uint64_t flipped;

	outflank_v = OUTFLANK_2[((O & 0x0004040404040400) * 0x0040810204081020) >> 57]
		& (((P & 0x0404040404040404) * 0x0040810204081020) >> 56);
	flipped = FLIPPED_2_V[outflank_v] & 0x0004040404040400;

	outflank_h = OUTFLANK_2[(O >> 17) & 0x3f] & (P >> 16);
	flipped |= FLIPPED_2_H[outflank_h] & 0x0000000000ff0000;

	flipped |= (((P >> 7) | (P << 7)) & 0x000000002000800) & O;

	outflank_d9 = OUTFLANK_2[((O & 0x0040201008040200) * 0x0101010101010101) >> 57]
		& (((P & 0x8040201008040201) * 0x0101010101010101) >> 56);
	flipped |= FLIPPED_2_H[outflank_d9] & 0x0040201008040200;

	return flipped;
}

/**
 * Compute flipped discs when playing on square D3.
 *
 * @param P player's disc pattern.
 * @param O opponent's disc pattern.
 * @return flipped disc pattern.
 */
static uint64_t flip_D3(const uint64_t P, const uint64_t O)
{
	unsigned int outflank_h, outflank_v, outflank_d;
	uint64_t flipped;

	outflank_v = OUTFLANK_2[((O & 0x0008080808080800) * 0x0020408102040810) >> 57]
		& (((P & 0x0808080808080808) * 0x0020408102040810) >> 56);
	flipped = FLIPPED_2_V[outflank_v] & 0x0008080808080800;

	outflank_h = OUTFLANK_3[(O >> 17) & 0x3f] & (P >> 16);
	flipped |= FLIPPED_3_H[outflank_h] & 0x0000000000ff0000;

	outflank_d = OUTFLANK_3[((O & 0x0000402214080000) * 0x0101010101010101) >> 57]
		& (((P & 0x0080412214080000) * 0x0101010101010101) >> 56);
	flipped |= FLIPPED_3_H[outflank_d] & 0x0000402214080000;	// A6D3H7

	flipped |= (((P << 7) & 0x0000000000001000) | ((P << 9) & 0x000000000000400)) & O;

	return flipped;
}

/**
 * Compute flipped discs when playing on square E3.
 *
 * @param P player's disc pattern.
 * @param O opponent's disc pattern.
 * @return flipped disc pattern.
 */
static uint64_t flip_E3(const uint64_t P, const uint64_t O)
{
	unsigned int outflank_h, outflank_v, outflank_d;
	uint64_t flipped;

	outflank_v = OUTFLANK_2[((O & 0x0010101010101000) * 0x0010204081020408) >> 57]
		& (((P & 0x1010101010101010) * 0x0010204081020408) >> 56);
	flipped = FLIPPED_2_V[outflank_v] & 0x0010101010101000;

	outflank_h = OUTFLANK_4[(O >> 17) & 0x3f] & (P >> 16);
	flipped |= FLIPPED_4_H[outflank_h] & 0x0000000000ff0000;

	outflank_d = OUTFLANK_4[((O & 0x0000024428100000) * 0x0101010101010101) >> 57]
		& (((P & 0x0001824428100000) * 0x0101010101010101) >> 56);
	flipped |= FLIPPED_4_H[outflank_d] & 0x0000024428100000;	// A7E3H6

	flipped |= (((P << 7) & 0x0000000000002000) | ((P << 9) & 0x000000000000800)) & O;

	return flipped;
}

/**
 * Compute flipped discs when playing on square F3.
 *
 * @param P player's disc pattern.
 * @param O opponent's disc pattern.
 * @return flipped disc pattern.
 */
static uint64_t flip_F3(const uint64_t P, const uint64_t O)
{
	unsigned int outflank_h, outflank_v, outflank_d7;
	uint64_t flipped;

	outflank_v = OUTFLANK_2[((O & 0x0020202020202000) * 0x0008102040810204) >> 57]
		& (((P & 0x2020202020202020) * 0x0008102040810204) >> 56);
	flipped = FLIPPED_2_V[outflank_v] & 0x0020202020202000;

	outflank_h = OUTFLANK_5[(O >> 17) & 0x3f] & (P >> 16);
	flipped |= FLIPPED_5_H[outflank_h] & 0x0000000000ff0000;

	outflank_d7 = OUTFLANK_5[((O & 0x0002040810204000) * 0x0101010101010101) >> 57]
		& (((P & 0x0102040810204080) * 0x0101010101010101) >> 56);
	flipped |= FLIPPED_5_H[outflank_d7] & 0x0002040810204000;

	flipped |= (((P >> 9) | (P << 9)) & 0x0000000040001000) & O;

	return flipped;
}

/**
 * Compute flipped discs when playing on square G3.
 *
 * @param P player's disc pattern.
 * @param O opponent's disc pattern.
 * @return flipped disc pattern.
 */
static uint64_t flip_G3(const uint64_t P, const uint64_t O)
{
	unsigned int outflank_h, outflank_e1g3g8, outflank_b8g3g1;
	uint64_t flipped;

	outflank_e1g3g8 = OUTFLANK_2[((O & 0x0040404040402000) * 0x0010101020408102) >> 57]
		& (((P & 0x4040404040402010) * 0x0010101020408102) >> 56);
	flipped = FLIPPED_2_V[outflank_e1g3g8] & 0x0040404040402000;

	outflank_b8g3g1 = OUTFLANK_5[((O & 0x0004081020404000) * 0x0402010101010101) >> 58]
		& ((((P & 0x0204081020404040) >> 1) * 0x0402010101010101) >> 56);
	flipped |= FLIPPED_5_U[outflank_b8g3g1] & 0x0004081020404000;

	outflank_h = OUTFLANK_7[(O >> 16) & 0x3e] & (P >> 15);
	flipped |= ((-outflank_h) & 0x3e) << 16;

	return flipped;
}

/**
 * Compute flipped discs when playing on square H3.
 *
 * @param P player's disc pattern.
 * @param O opponent's disc pattern.
 * @return flipped disc pattern.
 */
static uint64_t flip_H3(const uint64_t P, const uint64_t O)
{
	unsigned int outflank_h, outflank_f1h3h8, outflank_c8h3h1;
	uint64_t flipped;

	outflank_f1h3h8 = OUTFLANK_2[((O & 0x0080808080804000) * 0x0008080810204081) >> 57]
		& (((P & 0x8080808080804020) * 0x0008080810204081) >> 56);
	flipped = FLIPPED_2_V[outflank_f1h3h8] & 0x0080808080804000;

	outflank_c8h3h1 = OUTFLANK_5[((O & 0x0008102040808000) * 0x0000804040404040) >> 57]
		& ((((P & 0x0408102040808080) >> 2) * 0x0402010101010101) >> 56);
	flipped |= FLIPPED_5_U[outflank_c8h3h1] & 0x0008102040808000;

	outflank_h = OUTFLANK_7[(O >> 17) & 0x3f] & (P >> 16);
	flipped |= ((-outflank_h) & 0x3f) << 17;

	return flipped;
}

/**
 * Compute flipped discs when playing on square A4.
 *
 * @param P player's disc pattern.
 * @param O opponent's disc pattern.
 * @return flipped disc pattern.
 */
static uint64_t flip_A4(const uint64_t P, const uint64_t O)
{
	unsigned int outflank_h, outflank_a1a4e8, outflank_a8a4d1;
	uint64_t flipped;

	outflank_a1a4e8 = OUTFLANK_3[((O & 0x0008040201010100) * 0x0102040808080808) >> 57]
		& (((P & 0x1008040201010101) * 0x0102040808080808) >> 56);
	flipped = FLIPPED_3_V[outflank_a1a4e8] & 0x0008040201010100;

	outflank_a8a4d1 = OUTFLANK_4[((O & 0x0001010101020400) * 0x1010101008040201) >> 57]
		& (((P & 0x0101010101020408) * 0x1010101008040201) >> 56);
	flipped |= FLIPPED_4_U[outflank_a8a4d1] & 0x0001010101020400;

	outflank_h = ((unsigned int) O + 0x02000000u) & P;
	flipped |= (outflank_h - (outflank_h >> 8)) & 0x7e000000u;

	return flipped;
}

/**
 * Compute flipped discs when playing on square B4.
 *
 * @param P player's disc pattern.
 * @param O opponent's disc pattern.
 * @return flipped disc pattern.
 */
static uint64_t flip_B4(const uint64_t P, const uint64_t O)
{
	unsigned int outflank_h, outflank_b1b4f8, outflank_b8b4e1;
	uint64_t flipped;

	outflank_b1b4f8 = OUTFLANK_3[((O & 0x0010080402020200) * 0x0081020404040404) >> 57]
		& (((P & 0x2010080402020202) * 0x0081020404040404) >> 56);
	flipped = FLIPPED_3_V[outflank_b1b4f8] & 0x0010080402020200;

	outflank_b8b4e1 = OUTFLANK_4[((O & 0x0002020202040800) * 0x1010101008040201) >> 58]
		& ((((P & 0x0202020202040810) >> 1) * 0x1010101008040201) >> 56);
	flipped |= FLIPPED_4_U[outflank_b8b4e1] & 0x0002020202040800;

	outflank_h = ((unsigned int) O + 0x04000000u) & P;
	flipped |= (outflank_h - (outflank_h >> 8)) & 0x7c000000u;

	return flipped;
}

/**
 * Compute flipped discs when playing on square C4.
 *
 * @param P player's disc pattern.
 * @param O opponent's disc pattern.
 * @return flipped disc pattern.
 */
static uint64_t flip_C4(const uint64_t P, const uint64_t O)
{
	unsigned int outflank_h, outflank_c1c4g8, outflank_c8c4f1;
	uint64_t flipped;

	outflank_c1c4g8 = OUTFLANK_3[((O & 0x0020100804040400) * 0x0040810202020202) >> 57]
		& (((P & 0x4020100804040404) * 0x0040810202020202) >> 56);
	flipped = FLIPPED_3_V[outflank_c1c4g8] & 0x0020100804040400;

	outflank_c8c4f1 = OUTFLANK_4[((O & 0x0004040404081000) * 0x0404040402010080) >> 57]
		& ((((P & 0x0404040404081020) >> 2) * 0x1010101008040201) >> 56);
	flipped |= FLIPPED_4_U[outflank_c8c4f1] & 0x0004040404081000;

	outflank_h = OUTFLANK_2[(O >> 25) & 0x3f] & (P >> 24);
	flipped |= FLIPPED_2_H[outflank_h] & 0x00000000ff000000;

	flipped |= (((P << 9) & 0x00000000000020000) | ((P >> 7) & 0x00000000200000000)) & O;

	return flipped;
}

/**
 * Compute flipped discs when playing on square D4.
 *
 * @param P player's disc pattern.
 * @param O opponent's disc pattern.
 * @return flipped disc pattern.
 */
static uint64_t flip_D4(const uint64_t P, const uint64_t O)
{
	unsigned int outflank_h, outflank_v, outflank_d7, outflank_d9;
	uint64_t flipped;

	outflank_v = OUTFLANK_3[((O & 0x0008080808080800) * 0x0020408102040810) >> 57]
		& (((P & 0x0808080808080808) * 0x0020408102040810) >> 56);
	flipped = FLIPPED_3_V[outflank_v] & 0x0008080808080800;

	outflank_h = OUTFLANK_3[(O >> 25) & 0x3f] & (P >> 24);
	flipped |= FLIPPED_3_H[outflank_h] & 0x00000000ff000000;

	outflank_d7 = OUTFLANK_3[((O & 0x0000020408102000) * 0x0101010101010101) >> 57]
		& (((P & 0x0001020408102040) * 0x0101010101010101) >> 56);
	flipped |= FLIPPED_3_H[outflank_d7] & 0x0000020408102000;

	outflank_d9 = OUTFLANK_3[((O & 0x0040201008040200) * 0x0101010101010101) >> 57]
		& (((P & 0x8040201008040201) * 0x0101010101010101) >> 56);
	flipped |= FLIPPED_3_H[outflank_d9] & 0x0040201008040200;

	return flipped;
}

/**
 * Compute flipped discs when playing on square E3.
 *
 * @param P player's disc pattern.
 * @param O opponent's disc pattern.
 * @return flipped disc pattern.
 */
static uint64_t flip_E4(const uint64_t P, const uint64_t O)
{
	unsigned int outflank_h, outflank_v, outflank_d7, outflank_d9;
	uint64_t flipped;

	outflank_v = OUTFLANK_3[((O & 0x0010101010101000) * 0x0010204081020408) >> 57]
		& (((P & 0x1010101010101010) * 0x0010204081020408) >> 56);
	flipped = FLIPPED_3_V[outflank_v] & 0x0010101010101000;

	outflank_h = OUTFLANK_4[(O >> 25) & 0x3f] & (P >> 24);
	flipped |= FLIPPED_4_H[outflank_h] & 0x00000000ff000000;

	outflank_d7 = OUTFLANK_4[((O & 0x0002040810204000) * 0x0101010101010101) >> 57]
		& (((P & 0x0102040810204080) * 0x0101010101010101) >> 56);
	flipped |= FLIPPED_4_H[outflank_d7] & 0x0002040810204000;

	outflank_d9 = OUTFLANK_4[((O & 0x0000402010080400) * 0x0101010101010101) >> 57]
		& (((P & 0x0080402010080402) * 0x0101010101010101) >> 56);
	flipped |= FLIPPED_4_H[outflank_d9] & 0x0000402010080400;

	return flipped;
}

/**
 * Compute flipped discs when playing on square F4.
 *
 * @param P player's disc pattern.
 * @param O opponent's disc pattern.
 * @return flipped disc pattern.
 */
static uint64_t flip_F4(const uint64_t P, const uint64_t O)
{
	unsigned int outflank_h, outflank_c1f4f8, outflank_b8f4f1;
	uint64_t flipped;

	outflank_c1f4f8 = OUTFLANK_3[((O & 0x0020202020100800) * 0x0040404040810204) >> 57]
		& (((P & 0x2020202020100804) * 0x0040404040810204) >> 56);
	flipped = FLIPPED_3_V[outflank_c1f4f8] & 0x0020202020100800;

	outflank_b8f4f1 = OUTFLANK_4[((O & 0x0004081020202000) * 0x0804020101010101) >> 58]
		& ((((P & 0x0204081020202020) >> 1) * 0x0804020101010101) >> 56);
	flipped |= FLIPPED_4_U[outflank_b8f4f1] & 0x0004081020202000;

	outflank_h = OUTFLANK_5[(O >> 25) & 0x3f] & (P >> 24);
	flipped |= FLIPPED_5_H[outflank_h] & 0x00000000ff000000;

	flipped |= (((P << 7) & 0x0000000000400000) | ((P >> 9) & 0x0000004000000000)) & O;

	return flipped;
}

/**
 * Compute flipped discs when playing on square G4.
 *
 * @param P player's disc pattern.
 * @param O opponent's disc pattern.
 * @return flipped disc pattern.
 */
static uint64_t flip_G4(const uint64_t P, const uint64_t O)
{
	unsigned int outflank_h, outflank_d1g4g8, outflank_c8g4g1;
	uint64_t flipped;

	outflank_d1g4g8 = OUTFLANK_3[((O & 0x0040404040201000) * 0x0020202020408102) >> 57]
		& (((P & 0x4040404040201008) * 0x0020202020408102) >> 56);
	flipped = FLIPPED_3_V[outflank_d1g4g8] & 0x0040404040201000;

	outflank_c8g4g1 = OUTFLANK_4[((O & 0x0008102040404000) * 0x0001008040404040) >> 57]
		& ((((P & 0x0408102040404040) >> 2) * 0x0804020101010101) >> 56);
	flipped |= FLIPPED_4_U[outflank_c8g4g1] & 0x0008102040404000;

	outflank_h = OUTFLANK_7[(O >> 24) & 0x3e] & (P >> 23);
	flipped |= ((-outflank_h) & 0x3e) << 24;

	return flipped;
}

/**
 * Compute flipped discs when playing on square H4.
 *
 * @param P player's disc pattern.
 * @param O opponent's disc pattern.
 * @return flipped disc pattern.
 */
static uint64_t flip_H4(const uint64_t P, const uint64_t O)
{
	unsigned int outflank_h, outflank_e1h4h8, outflank_d8h4h1;
	uint64_t flipped;

	outflank_e1h4h8 = OUTFLANK_3[((O & 0x0080808080402000) * 0x0010101010204081) >> 57]
		& (((P & 0x8080808080402010) * 0x0010101010204081) >> 56);
	flipped = FLIPPED_3_V[outflank_e1h4h8] & 0x0080808080402000;

	outflank_d8h4h1 = OUTFLANK_4[((O & 0x0010204080808000) * 0x0000804020202020) >> 57]
		& ((((P & 0x0810204080808080) >> 3) * 0x0804020101010101) >> 56);
	flipped |= FLIPPED_4_U[outflank_d8h4h1] & 0x0010204080808000;

	outflank_h = OUTFLANK_7[(O >> 25) & 0x3f] & (P >> 24);
	flipped |= ((-outflank_h) & 0x3f) << 25;

	return flipped;
}

/**
 * Compute flipped discs when playing on square A5.
 *
 * @param P player's disc pattern.
 * @param O opponent's disc pattern.
 * @return flipped disc pattern.
 */
static uint64_t flip_A5(const uint64_t P, const uint64_t O)
{
	unsigned int outflank_a1a5d8, outflank_a8a5e1, outflank_h;
	uint64_t flipped;

	outflank_a1a5d8 = OUTFLANK_4[((O & 0x0004020101010100) * 0x0102040810101010) >> 57]
		& (((P & 0x0804020101010101) * 0x0102040810101010) >> 56);
	flipped = FLIPPED_4_V[outflank_a1a5d8] & 0x0004020101010100;

	outflank_a8a5e1 = OUTFLANK_3[((O & 0x0001010102040800) * 0x0808080808040201) >> 57]
		& (((P & 0x0101010102040810) * 0x0808080808040201) >> 56);
	flipped |= FLIPPED_3_U[outflank_a8a5e1] & 0x0001010102040800;

	outflank_h = ((unsigned int) (O >> 8) + 0x02000000) & (unsigned int) (P >> 8);
	flipped |= (((uint64_t) outflank_h << 8) - outflank_h) & 0x0000007e00000000;

	return flipped;
}

/**
 * Compute flipped discs when playing on square B5.
 *
 * @param P player's disc pattern.
 * @param O opponent's disc pattern.
 * @return flipped disc pattern.
 */
static uint64_t flip_B5(const uint64_t P, const uint64_t O)
{
	unsigned int outflank_b1b5e8, outflank_b8b5f1, outflank_h;
	uint64_t flipped;

	outflank_b1b5e8 = OUTFLANK_4[((O & 0x0008040202020200) * 0x0081020408080808) >> 57]
		& (((P & 0x1008040202020202) * 0x0081020408080808) >> 56);
	flipped = FLIPPED_4_V[outflank_b1b5e8] & 0x0008040202020200;

	outflank_b8b5f1 = OUTFLANK_3[((O & 0x0002020204081000) * 0x0808080808040201) >> 58]
		& ((((P & 0x0202020204081020) >> 1) * 0x0808080808040201) >> 56);
	flipped |= FLIPPED_3_U[outflank_b8b5f1] & 0x0002020204081000;

	outflank_h = ((unsigned int) (O >> 8) + 0x04000000) & (unsigned int) (P >> 8);
	flipped |= (((uint64_t) outflank_h << 8) - outflank_h) & 0x0000007c00000000;

	return flipped;
}

/**
 * Compute flipped discs when playing on square C5.
 *
 * @param P player's disc pattern.
 * @param O opponent's disc pattern.
 * @return flipped disc pattern.
 */
static uint64_t flip_C5(const uint64_t P, const uint64_t O)
{
	unsigned int outflank_h, outflank_c1c5f8, outflank_c8c5g1;
	uint64_t flipped;

	outflank_c1c5f8 = OUTFLANK_4[((O & 0x0010080404040400) * 0x0040810204040404) >> 57]
		& (((P & 0x2010080404040404) * 0x0040810204040404) >> 56);
	flipped = FLIPPED_4_V[outflank_c1c5f8] & 0x0010080404040400;

	outflank_c8c5g1 = OUTFLANK_3[((O & 0x0004040408102000) * 0x0002020202010080) >> 57]
		& ((((P & 0x0404040408102040) >> 2) * 0x0808080808040201) >> 56);
	flipped |= FLIPPED_3_U[outflank_c8c5g1] & 0x0004040408102000;

	outflank_h = OUTFLANK_2[(O >> 33) & 0x3f] & (P >> 32);
	flipped |= FLIPPED_2_H[outflank_h] & 0x000000ff00000000;

	flipped |= (((P << 9) & 0x0000000002000000) | ((P >> 7) & 0x0000020000000000)) & O;

	return flipped;
}

/**
 * Compute flipped discs when playing on square D5.
 *
 * @param P player's disc pattern.
 * @param O opponent's disc pattern.
 * @return flipped disc pattern.
 */
static uint64_t flip_D5(const uint64_t P, const uint64_t O)
{
	unsigned int outflank_h, outflank_v, outflank_d7, outflank_d9;
	uint64_t flipped;

	outflank_v = OUTFLANK_4[((O & 0x0008080808080800) * 0x0020408102040810) >> 57]
		& (((P & 0x0808080808080808) * 0x0020408102040810) >> 56);
	flipped = FLIPPED_4_V[outflank_v] & 0x0008080808080800;

	outflank_h = OUTFLANK_3[(O >> 33) & 0x3f] & (P >> 32);
	flipped |= FLIPPED_3_H[outflank_h] & 0x000000ff00000000;

	outflank_d7 = OUTFLANK_3[((O & 0x0002040810204000) * 0x0101010101010101) >> 57]
		& (((P & 0x0102040810204080) * 0x0101010101010101) >> 56);
	flipped |= FLIPPED_3_H[outflank_d7] & 0x0002040810204000;

	outflank_d9 = OUTFLANK_3[((O & 0x0020100804020000) * 0x0101010101010101) >> 57]
		& (((P & 0x4020100804020100) * 0x0101010101010101) >> 56);
	flipped |= FLIPPED_3_H[outflank_d9] & 0x0020100804020000;

	return flipped;
}

/**
 * Compute flipped discs when playing on square E5.
 *
 * @param P player's disc pattern.
 * @param O opponent's disc pattern.
 * @return flipped disc pattern.
 */
static uint64_t flip_E5(const uint64_t P, const uint64_t O)
{
	unsigned int outflank_h, outflank_v, outflank_d7, outflank_d9;
	uint64_t flipped;

	outflank_v = OUTFLANK_4[((O & 0x0010101010101000) * 0x0010204081020408) >> 57]
		& (((P & 0x1010101010101010) * 0x0010204081020408) >> 56);
	flipped = FLIPPED_4_V[outflank_v] & 0x0010101010101000;

	outflank_h = OUTFLANK_4[(O >> 33) & 0x3f] & (P >> 32);
	flipped |= FLIPPED_4_H[outflank_h] & 0x000000ff00000000;

	outflank_d7 = OUTFLANK_4[((O & 0x0004081020400000) * 0x0101010101010101) >> 57]
		& (((P & 0x0204081020408000) * 0x0101010101010101) >> 56);
	flipped |= FLIPPED_4_H[outflank_d7] & 0x0004081020400000;

	outflank_d9 = OUTFLANK_4[((O & 0x0040201008040200) * 0x0101010101010101) >> 57]
		& (((P & 0x8040201008040201) * 0x0101010101010101) >> 56);
	flipped |= FLIPPED_4_H[outflank_d9] & 0x0040201008040200;

	return flipped;
}

/**
 * Compute flipped discs when playing on square F5.
 *
 * @param P player's disc pattern.
 * @param O opponent's disc pattern.
 * @return flipped disc pattern.
 */
static uint64_t flip_F5(const uint64_t P, const uint64_t O)
{
	unsigned int outflank_h, outflank_b1f5f8, outflank_c8f5f1;
	uint64_t flipped;

	outflank_b1f5f8 = OUTFLANK_4[((O & 0x0020202010080400) * 0x0080808080810204) >> 57]
		& (((P & 0x2020202010080402) * 0x0080808080810204) >> 56);
	flipped = FLIPPED_4_V[outflank_b1f5f8] & 0x0020202010080400;

	outflank_c8f5f1 = OUTFLANK_3[((O & 0x0008102020202000) * 0x0002010080404040) >> 57]
		& ((((P & 0x0408102020202020) >> 2) * 0x1008040201010101) >> 56);
	flipped |= FLIPPED_3_U[outflank_c8f5f1] & 0x0008102020202000;

	outflank_h = OUTFLANK_5[(O >> 33) & 0x3f] & (P >> 32);
	flipped |= FLIPPED_5_H[outflank_h] & 0x000000ff00000000;

	flipped |= (((P << 7) & 0x0000000040000000) | ((P >> 9) & 0x0000400000000000)) & O;

	return flipped;
}

/**
 * Compute flipped discs when playing on square G5.
 *
 * @param P player's disc pattern.
 * @param O opponent's disc pattern.
 * @return flipped disc pattern.
 */
static uint64_t flip_G5(const uint64_t P, const uint64_t O)
{
	unsigned int outflank_h, outflank_c1g5g8, outflank_d8g5g1;
	uint64_t flipped;

	outflank_c1g5g8 = OUTFLANK_4[((O & 0x0040404020100800) * 0x0040404040408102) >> 57]
		& (((P & 0x4040404020100804) * 0x0040404040408102) >> 56);
	flipped = FLIPPED_4_V[outflank_c1g5g8] & 0x0040404020100800;

	outflank_d8g5g1 = OUTFLANK_3[((O & 0x0010204040404000) * 0x0001008040202020) >> 57]
		& ((((P & 0x0810204040404040) >> 3) * 0x1008040201010101) >> 56);
	flipped |= FLIPPED_3_U[outflank_d8g5g1] & 0x0010204040404000;

	outflank_h = OUTFLANK_7[(O >> 32) & 0x3e] & (P >> 31);
	flipped |= (uint64_t) ((-outflank_h) & 0x3e) << 32;

	return flipped;
}

/**
 * Compute flipped discs when playing on square H5.
 *
 * @param P player's disc pattern.
 * @param O opponent's disc pattern.
 * @return flipped disc pattern.
 */
static uint64_t flip_H5(const uint64_t P, const uint64_t O)
{
	unsigned int outflank_h, outflank_d1h5h8, outflank_e8h5h1;
	uint64_t flipped;

	outflank_d1h5h8 = OUTFLANK_4[((O & 0x0080808040201000) * 0x0020202020204081) >> 57]
		& (((P & 0x8080808040201008) * 0x0020202020204081) >> 56);
	flipped = FLIPPED_4_V[outflank_d1h5h8] & 0x0080808040201000;

	outflank_e8h5h1 = OUTFLANK_3[((O & 0x0020408080808000) * 0x0000804020101010) >> 57]
		& ((((P & 0x1020408080808080) >> 4) * 0x1008040201010101) >> 56);
	flipped |= FLIPPED_3_U[outflank_e8h5h1] & 0x0020408080808000;

	outflank_h = OUTFLANK_7[(O >> 33) & 0x3f] & (P >> 32);
	flipped |= (uint64_t) ((-outflank_h) & 0x3f) << 33;

	return flipped;
}

/**
 * Compute flipped discs when playing on square A6.
 *
 * @param P player's disc pattern.
 * @param O opponent's disc pattern.
 * @return flipped disc pattern.
 */
static uint64_t flip_A6(const uint64_t P, const uint64_t O)
{
	unsigned int outflank_a1a6c8, outflank_a8a6f1, outflank_h;
	uint64_t flipped;

	outflank_a1a6c8 = OUTFLANK_5[((O & 0x0002010101010100) * 0x0102040810202020) >> 57]
		& (((P & 0x0402010101010101) * 0x0102040810202020) >> 56);
	flipped = FLIPPED_5_V[outflank_a1a6c8] & 0x0002010101010100;

	outflank_a8a6f1 = OUTFLANK_2[((O & 0x0001010204081000) * 0x0404040404040201) >> 57]
		& (((P & 0x0101010204081020) * 0x0404040404040201) >> 56);
	flipped |= FLIPPED_2_U[outflank_a8a6f1] & 0x0001010204081000;

	outflank_h = ((unsigned int) (O >> 16) + 0x02000000) & (unsigned int) (P >> 16);
	flipped |= (((uint64_t) outflank_h << 16) - outflank_h) & 0x00007e0000000000;

	return flipped;
}

/**
 * Compute flipped discs when playing on square B6.
 *
 * @param P player's disc pattern.
 * @param O opponent's disc pattern.
 * @return flipped disc pattern.
 */
static uint64_t flip_B6(const uint64_t P, const uint64_t O)
{
	unsigned int outflank_a1a6c8, outflank_a8a6f1, outflank_h;
	uint64_t flipped;

	outflank_a1a6c8 = OUTFLANK_5[((O & 0x0004020202020200) * 0x0081020408101010) >> 57]
		& (((P & 0x0804020202020202) * 0x0081020408101010) >> 56);
	flipped = FLIPPED_5_V[outflank_a1a6c8] & 0x0004020202020200;

	outflank_a8a6f1 = OUTFLANK_2[((O & 0x0002020408102000) * 0x0404040404040201) >> 58]
		& ((((P & 0x0202020408102040) >> 1) * 0x0404040404040201) >> 56);
	flipped |= FLIPPED_2_U[outflank_a8a6f1] & 0x0002020408102000;

	outflank_h = ((unsigned int) (O >> 16) + 0x04000000) & (unsigned int) (P >> 16);
	flipped |= (((uint64_t) outflank_h << 16) - outflank_h) & 0x00007c0000000000;

	return flipped;
}

/**
 * Compute flipped discs when playing on square C6.
 *
 * @param P player's disc pattern.
 * @param O opponent's disc pattern.
 * @return flipped disc pattern.
 */
static uint64_t flip_C6(const uint64_t P, const uint64_t O)
{
	unsigned int outflank_h, outflank_v, outflank_d7;
	uint64_t flipped;

	outflank_v = OUTFLANK_5[((O & 0x0004040404040400) * 0x0040810204081020) >> 57]
		& (((P & 0x0404040404040404) * 0x0040810204081020) >> 56);
	flipped = FLIPPED_5_V[outflank_v] & 0x0004040404040400;

	outflank_h = OUTFLANK_2[(O >> 41) & 0x3f] & (P >> 40);
	flipped |= FLIPPED_2_H[outflank_h] & 0x0000ff0000000000;

	outflank_d7 = OUTFLANK_2[((O & 0x0002040810204000) * 0x0101010101010101) >> 57]
		& (((P & 0x0102040810204080) * 0x0101010101010101) >> 56);
	flipped |= FLIPPED_2_H[outflank_d7] & 0x0002040810204000;

	flipped |= ((P >> 9) | (P << 9)) & 0x0008000200000000 & O;

	return flipped;
}

/**
 * Compute flipped discs when playing on square D6.
 *
 * @param P player's disc pattern.
 * @param O opponent's disc pattern.
 * @return flipped disc pattern.
 */
static uint64_t flip_D6(const uint64_t P, const uint64_t O)
{
	unsigned int outflank_h, outflank_v, outflank_d;
	uint64_t flipped;

	outflank_v = OUTFLANK_5[((O & 0x0008080808080800) * 0x0020408102040810) >> 57]
		& (((P & 0x0808080808080808) * 0x0020408102040810) >> 56);
	flipped = FLIPPED_5_V[outflank_v] & 0x0008080808080800;

	outflank_h = OUTFLANK_3[(O >> 41) & 0x3f] & (P >> 40);
	flipped |= FLIPPED_3_H[outflank_h] & 0x0000ff0000000000;

	outflank_d = OUTFLANK_3[((O & 0x0000081422400000) * 0x0101010101010101) >> 57]
		& (((P & 0x0000081422418000) * 0x0101010101010101) >> 56);
	flipped |= FLIPPED_3_H[outflank_d] & 0x0000081422400000;	// A3D6H2

	flipped |= (((P >> 9) & 0x0010000000000000) | ((P >> 7) & 0x0004000000000000)) & O;

	return flipped;
}

/**
 * Compute flipped discs when playing on square E6.
 *
 * @param P player's disc pattern.
 * @param O opponent's disc pattern.
 * @return flipped disc pattern.
 */
static uint64_t flip_E6(const uint64_t P, const uint64_t O)
{
	unsigned int outflank_h, outflank_v, outflank_d;
	uint64_t flipped;

	outflank_v = OUTFLANK_5[((O & 0x0010101010101000) * 0x0010204081020408) >> 57]
		& (((P & 0x1010101010101010) * 0x0010204081020408) >> 56);
	flipped = FLIPPED_5_V[outflank_v] & 0x0010101010101000;

	outflank_h = OUTFLANK_4[(O >> 41) & 0x3f] & (P >> 40);
	flipped |= FLIPPED_4_H[outflank_h] & 0x0000ff0000000000;

	outflank_d = OUTFLANK_4[((O & 0x0000102844020000) * 0x0101010101010101) >> 57]
		& (((P & 0x0000102844820100) * 0x0101010101010101) >> 56);
	flipped |= FLIPPED_4_H[outflank_d] & 0x0000102844020000;	// A2E6H3

	flipped |= (((P >> 9) & 0x0020000000000000) | ((P >> 7) & 0x0008000000000000)) & O;

	return flipped;
}

/**
 * Compute flipped discs when playing on square F6.
 *
 * @param P player's disc pattern.
 * @param O opponent's disc pattern.
 * @return flipped disc pattern.
 */
static uint64_t flip_F6(const uint64_t P, const uint64_t O)
{
	unsigned int outflank_h, outflank_v, outflank_d9;
	uint64_t flipped;

	outflank_v = OUTFLANK_5[((O & 0x0020202020202000) * 0x0008102040810204) >> 57]
		& (((P & 0x2020202020202020) * 0x0008102040810204) >> 56);
	flipped = FLIPPED_5_V[outflank_v] & 0x0020202020202000;

	outflank_h = OUTFLANK_5[(O >> 41) & 0x3f] & (P >> 40);
	flipped |= FLIPPED_5_H[outflank_h] & 0x0000ff0000000000;

	flipped |= ((P >> 7) | (P << 7)) & 0x0010004000000000 & O;

	outflank_d9 = OUTFLANK_5[((O & 0x0040201008040200) * 0x0101010101010101) >> 57]
		& (((P & 0x8040201008040201) * 0x0101010101010101) >> 56);
	flipped |= FLIPPED_5_H[outflank_d9] & 0x0040201008040200;

	return flipped;
}

/**
 * Compute flipped discs when playing on square G6.
 *
 * @param P player's disc pattern.
 * @param O opponent's disc pattern.
 * @return flipped disc pattern.
 */
static uint64_t flip_G6(const uint64_t P, const uint64_t O)
{
	unsigned int outflank_h, outflank_b1g6g8, outflank_e8g6g1;
	uint64_t flipped;

	outflank_b1g6g8 = OUTFLANK_5[((O & 0x0040402010080400) * 0x0080808080808102) >> 57]
		& (((P & 0x4040402010080402) * 0x0080808080808102) >> 56);
	flipped = FLIPPED_5_V[outflank_b1g6g8] & 0x0040402010080400;

	outflank_e8g6g1 = OUTFLANK_2[((O & 0x0020404040404000) * 0x0001008040201010) >> 57]
		& ((((P & 0x1020404040404040) >> 4) * 0x2010080402010101) >> 56);
	flipped |= FLIPPED_2_U[outflank_e8g6g1] & 0x0020404040404000;

	outflank_h = OUTFLANK_7[(O >> 40) & 0x3e] & (P >> 39);
	flipped |= (uint64_t) ((-outflank_h) & 0x3e) << 40;

	return flipped;
}

/**
 * Compute flipped discs when playing on square H6.
 *
 * @param P player's disc pattern.
 * @param O opponent's disc pattern.
 * @return flipped disc pattern.
 */
static uint64_t flip_H6(const uint64_t P, const uint64_t O)
{
	unsigned int outflank_h, outflank_c1h6h8, outflank_f8h6h1;
	uint64_t flipped;

	outflank_c1h6h8 = OUTFLANK_5[((O & 0x0080804020100800) * 0x0040404040404081) >> 57]
		& (((P & 0x8080804020100804) * 0x0040404040404081) >> 56);
	flipped = FLIPPED_5_V[outflank_c1h6h8] & 0x0080804020100800;

	outflank_f8h6h1 = OUTFLANK_2[((O & 0x0040808080808000) * 0x0000804020100808) >> 57]
		& ((((P & 0x2040808080808080) >> 5) * 0x2010080402010101) >> 56);
	flipped |= FLIPPED_2_U[outflank_f8h6h1] & 0x0040808080808000;

	outflank_h = OUTFLANK_7[(O >> 41) & 0x3f] & (P >> 40);
	flipped |= (uint64_t) ((-outflank_h) & 0x3f) << 41;

	return flipped;
}

/**
 * Compute flipped discs when playing on square A7.
 *
 * @param P player's disc pattern.
 * @param O opponent's disc pattern.
 * @return flipped disc pattern.
 */
static uint64_t flip_A7(const uint64_t P, const uint64_t O)
{
	uint64_t flipped, outflank_v, outflank_d7;
	unsigned int outflank_h;

	outflank_v = (0x0000010000000000 >> CONTIG_UP[((O & 0x0000010101010100) * 0x0102040810204080) >> 56]) & P;
	flipped  = (-outflank_v * 2) & 0x0000010101010100;

	outflank_d7 = (0x0000020000000000 >> CONTIG_UPRIGHT[((O & 0x0000020408102000) * 0x0101010101010101) >> 57]) & P;
	flipped |= (-outflank_d7 * 2) & 0x0000020408102000;

	outflank_h = ((unsigned int) (O >> 24) + 0x02000000) & (unsigned int) (P >> 24);
	flipped |= (((uint64_t) outflank_h << 24) - outflank_h) & 0x007e000000000000;

	return flipped;
}

/**
 * Compute flipped discs when playing on square B7.
 *
 * @param P player's disc pattern.
 * @param O opponent's disc pattern.
 * @return flipped disc pattern.
 */
static uint64_t flip_B7(const uint64_t P, const uint64_t O)
{
	uint64_t flipped, outflank_v, outflank_d7;
	unsigned int outflank_h;

	outflank_v = (0x0000020000000000 >> CONTIG_UP[((O & 0x0000020202020200) * 0x0081020408102040) >> 56]) & P;
	flipped  = (-outflank_v * 2) & 0x0000020202020200;

	outflank_d7 = (0x0000040000000000 >> CONTIG_UPRIGHT[((O & 0x0000040810204000) * 0x0101010101010101) >> 58]) & P;
	flipped |= (-outflank_d7 * 2) & 0x0000040810204000;

	outflank_h = ((unsigned int) (O >> 24) + 0x04000000) & (unsigned int) (P >> 24);
	flipped |= (((uint64_t) outflank_h << 24) - outflank_h) & 0x007c000000000000;

	return flipped;
}

/**
 * Compute flipped discs when playing on square C7.
 *
 * @param P player's disc pattern.
 * @param O opponent's disc pattern.
 * @return flipped disc pattern.
 */
static uint64_t flip_C7(const uint64_t P, const uint64_t O)
{
	unsigned int outflank_h, outflank_d;
	uint64_t flipped, outflank_v;

	outflank_v = (0x0000040000000000 >> CONTIG_UP[((O & 0x0000040404040400) * 0x0040810204081020) >> 56]) & P;
	flipped  = (-outflank_v * 2) & 0x0000040404040400;

	outflank_h = OUTFLANK_2[(O >> 49) & 0x3f] & (P >> 48);
	flipped |= FLIPPED_2_H[outflank_h] & 0x00ff000000000000;

	outflank_d = OUTFLANK_2[((O & 0x00040a1020400000) * 0x0101010101010101) >> 57]
		& (((P & 0x00040a1120408000) * 0x0101010101010101) >> 56);
	flipped |= FLIPPED_2_H[outflank_d] & 0x00040a1020400000;	// A5C7H2

	return flipped;
}

/**
 * Compute flipped discs when playing on square D7.
 *
 * @param P player's disc pattern.
 * @param O opponent's disc pattern.
 * @return flipped disc pattern.
 */
static uint64_t flip_D7(const uint64_t P, const uint64_t O)
{
	unsigned int outflank_h, outflank_d;
	uint64_t flipped, outflank_v;

	outflank_v = (0x0000080000000000 >> CONTIG_UP[((O & 0x0000080808080800) * 0x0020408102040810) >> 56]) & P;
	flipped  = (-outflank_v * 2) & 0x0000080808080800;

	outflank_h = OUTFLANK_3[(O >> 49) & 0x3f] & (P >> 48);
	flipped |= FLIPPED_3_H[outflank_h] & 0x00ff000000000000;

	outflank_d = OUTFLANK_3[((O & 0x0008142240000000) * 0x0101010101010101) >> 57]
		& (((P & 0x0008142241800000) * 0x0101010101010101) >> 56);
	flipped |= FLIPPED_3_H[outflank_d] & 0x0008142240000000;	// A4D7H3

	return flipped;
}

/**
 * Compute flipped discs when playing on square E7.
 *
 * @param P player's disc pattern.
 * @param O opponent's disc pattern.
 * @return flipped disc pattern.
 */
static uint64_t flip_E7(const uint64_t P, const uint64_t O)
{
	unsigned int outflank_h, outflank_d;
	uint64_t flipped, outflank_v;

	outflank_v = (0x0000100000000000 >> CONTIG_UP[((O & 0x0000101010101000) * 0x0010204081020408) >> 56]) & P;
	flipped  = (-outflank_v * 2) & 0x0000101010101000;

	outflank_h = OUTFLANK_4[(O >> 49) & 0x3f] & (P >> 48);
	flipped |= FLIPPED_4_H[outflank_h] & 0x00ff000000000000;

	outflank_d = OUTFLANK_4[((O & 0x0010284402000000) * 0x0101010101010101) >> 57]
		& (((P & 0x0010284482010000) * 0x0101010101010101) >> 56);
	flipped |= FLIPPED_4_H[outflank_d] & 0x0010284402000000;	// A3E7H4

	return flipped;
}

/**
 * Compute flipped discs when playing on square F7.
 *
 * @param P player's disc pattern.
 * @param O opponent's disc pattern.
 * @return flipped disc pattern.
 */
static uint64_t flip_F7(const uint64_t P, const uint64_t O)
{
	unsigned int outflank_h, outflank_d;
	uint64_t flipped, outflank_v;

	outflank_v = (0x0000200000000000 >> CONTIG_UP[((O & 0x0000202020202000) * 0x0008102040810204) >> 56]) & P;
	flipped  = (-outflank_v * 2) & 0x0000202020202000;

	outflank_h = OUTFLANK_5[(O >> 49) & 0x3f] & (P >> 48);
	flipped |= FLIPPED_5_H[outflank_h] & 0x00ff000000000000;

	outflank_d = OUTFLANK_5[((O & 0x0020500804020000) * 0x0101010101010101) >> 57]
		& (((P & 0x0020508804020100) * 0x0101010101010101) >> 56);
	flipped |= FLIPPED_5_H[outflank_d] & 0x0020500804020000;	// A2F7H5

	return flipped;
}

/**
 * Compute flipped discs when playing on square G7.
 *
 * @param P player's disc pattern.
 * @param O opponent's disc pattern.
 * @return flipped disc pattern.
 */
static uint64_t flip_G7(const uint64_t P, const uint64_t O)
{
	unsigned int outflank_h;
	uint64_t flipped, outflank_v, outflank_d9;

	outflank_v = (0x0000400000000000 >> CONTIG_UP[((O & 0x0000404040404000) * 0x0004081020408102) >> 56]) & P;
	flipped  = (-outflank_v * 2) & 0x0000404040404000;

	outflank_d9 = (0x0000200000000000 >> CONTIG_UPLEFT[((O & 0x0000201008040200) * 0x0101010101010101) >> 56]) & P;
	flipped |= (-outflank_d9 * 2) & 0x0000201008040200;

	outflank_h = OUTFLANK_7[(O >> 48) & 0x3e] & (P >> 47);
	flipped |= (uint64_t) ((-outflank_h) & 0x3e) << 48;

	return flipped;
}

/**
 * Compute flipped discs when playing on square H7.
 *
 * @param P player's disc pattern.
 * @param O opponent's disc pattern.
 * @return flipped disc pattern.
 */
static uint64_t flip_H7(const uint64_t P, const uint64_t O)
{
	unsigned int outflank_h;
	uint64_t flipped, outflank_v, outflank_d9;

	outflank_v = (0x0000800000000000 >> CONTIG_UP[((O & 0x0000808080808000) * 0x0002040810204081) >> 56]) & P;
	flipped  = (-outflank_v * 2) & 0x0000808080808000;

	outflank_d9 = (0x0000400000000000 >> CONTIG_UPLEFT[((O & 0x0000402010080400) * 0x0101010101010101) >> 57]) & P;
	flipped |= (-outflank_d9 * 2) & 0x0000402010080400;

	outflank_h = OUTFLANK_7[(O >> 49) & 0x3f] & (P >> 48);
	flipped |= (uint64_t) ((-outflank_h) & 0x3f) << 49;

	return flipped;
}

/**
 * Compute flipped discs when playing on square A8.
 *
 * @param P player's disc pattern.
 * @param O opponent's disc pattern.
 * @return flipped disc pattern.
 */
static uint64_t flip_A8(const uint64_t P, const uint64_t O)
{
	uint64_t flipped, outflank_v, outflank_h, outflank_d7;

	outflank_v = (0x0001000000000000 >> CONTIG_UP[((O & 0x0001010101010100) * 0x0102040810204080) >> 57]) & P;
	flipped  = (-outflank_v * 2) & 0x0001010101010100;

	outflank_d7 = (0x0002000000000000 >> CONTIG_UPRIGHT[((O & 0x0002040810204000) * 0x0101010101010101) >> 57]) & P;
	flipped |= (-outflank_d7 * 2) & 0x0002040810204000;

	outflank_h = (O + 0x0200000000000000) & P;
	flipped |= (outflank_h - (outflank_h >> 8)) & 0x7e00000000000000;

	return flipped;
}

/**
 * Compute flipped discs when playing on square B8.
 *
 * @param P player's disc pattern.
 * @param O opponent's disc pattern.
 * @return flipped disc pattern.
 */
static uint64_t flip_B8(const uint64_t P, const uint64_t O)
{
	uint64_t flipped, outflank_v, outflank_h, outflank_d7;

	outflank_v = (0x0002000000000000 >> CONTIG_UP[((O & 0x0002020202020200) * 0x0081020408102040) >> 57]) & P;
	flipped  = (-outflank_v * 2) & 0x0002020202020200;

	outflank_d7 = (0x0004000000000000 >> CONTIG_UPRIGHT[((O & 0x0004081020400000) * 0x0101010101010101) >> 58]) & P;
	flipped |= (-outflank_d7 * 2) & 0x0004081020400000;

	outflank_h = (O + 0x0400000000000000) & P;
	flipped |= (outflank_h - (outflank_h >> 8)) & 0x7c00000000000000;

	return flipped;
}

/**
 * Compute flipped discs when playing on square C8.
 *
 * @param P player's disc pattern.
 * @param O opponent's disc pattern.
 * @return flipped disc pattern.
 */
static uint64_t flip_C8(const uint64_t P, const uint64_t O)
{
	unsigned int outflank_h, outflank_d;
	uint64_t flipped, outflank_v;

	outflank_v = (0x0004000000000000 >> CONTIG_UP[((O & 0x0004040404040400) * 0x0040810204081020) >> 57]) & P;
	flipped  = (-outflank_v * 2) & 0x0004040404040400;

	outflank_h = OUTFLANK_2[(O >> 57) & 0x3f] & (P >> 56);
	flipped |= FLIPPED_2_H[outflank_h] & 0xff00000000000000;

	outflank_d = OUTFLANK_2[((O & 0x040a102040000000) * 0x0101010101010101) >> 57]
		& (((P & 0x040a112040800000) * 0x0101010101010101) >> 56);
	flipped |= FLIPPED_2_H[outflank_d] & 0x040a102040000000;	// A6C8H3

	return flipped;
}

/**
 * Compute flipped discs when playing on square D8.
 *
 * @param P player's disc pattern.
 * @param O opponent's disc pattern.
 * @return flipped disc pattern.
 */
static uint64_t flip_D8(const uint64_t P, const uint64_t O)
{
	unsigned int outflank_h, outflank_d;
	uint64_t flipped, outflank_v;

	outflank_v = (0x0008000000000000 >> CONTIG_UP[((O & 0x0008080808080800) * 0x0020408102040810) >> 57]) & P;
	flipped  = (-outflank_v * 2) & 0x0008080808080800;

	outflank_h = OUTFLANK_3[(O >> 57) & 0x3f] & (P >> 56);
	flipped |= FLIPPED_3_H[outflank_h] & 0xff00000000000000;

	outflank_d = OUTFLANK_3[((O & 0x0814224000000000) * 0x0101010101010101) >> 57]
		& (((P & 0x0814224180000000) * 0x0101010101010101) >> 56);
	flipped |= FLIPPED_3_H[outflank_d] & 0x0814224000000000;	// A5D8H4

	return flipped;
}

/**
 * Compute flipped discs when playing on square E8.
 *
 * @param P player's disc pattern.
 * @param O opponent's disc pattern.
 * @return flipped disc pattern.
 */
static uint64_t flip_E8(const uint64_t P, const uint64_t O)
{
	unsigned int outflank_h, outflank_d;
	uint64_t flipped, outflank_v;

	outflank_v = (0x0010000000000000 >> CONTIG_UP[((O & 0x0010101010101000) * 0x0010204081020408) >> 57]) & P;
	flipped  = (-outflank_v * 2) & 0x0010101010101000;

	outflank_h = OUTFLANK_4[(O >> 57) & 0x3f] & (P >> 56);
	flipped |= FLIPPED_4_H[outflank_h] & 0xff00000000000000;

	outflank_d = OUTFLANK_4[((O & 0x1028440200000000) * 0x0101010101010101) >> 57]
		& (((P & 0x1028448201000000) * 0x0101010101010101) >> 56);
	flipped |= FLIPPED_4_H[outflank_d] & 0x1028440200000000;	// A4E8H5

	return flipped;
}

/**
 * Compute flipped discs when playing on square F8.
 *
 * @param P player's disc pattern.
 * @param O opponent's disc pattern.
 * @return flipped disc pattern.
 */
static uint64_t flip_F8(const uint64_t P, const uint64_t O)
{
	unsigned int outflank_h, outflank_d;
	uint64_t flipped, outflank_v;

	outflank_v = (0x0020000000000000 >> CONTIG_UP[((O & 0x0020202020202000) * 0x0008102040810204) >> 57]) & P;
	flipped  = (-outflank_v * 2) & 0x0020202020202000;

	outflank_h = OUTFLANK_5[(O >> 57) & 0x3f] & (P >> 56);
	flipped |= FLIPPED_5_H[outflank_h] & 0xff00000000000000;

	outflank_d = OUTFLANK_5[((O & 0x2050080402000000) * 0x0101010101010101) >> 57]
		& (((P & 0x2050880402010000) * 0x0101010101010101) >> 56);
	flipped |= FLIPPED_5_H[outflank_d] & 0x2050080402000000;	// A3F8H6

	return flipped;
}

/**
 * Compute flipped discs when playing on square G8.
 *
 * @param P player's disc pattern.
 * @param O opponent's disc pattern.
 * @return flipped disc pattern.
 */
static uint64_t flip_G8(const uint64_t P, const uint64_t O)
{
	unsigned int outflank_h;
	uint64_t flipped, outflank_v, outflank_d9;

	outflank_v = (0x0040000000000000 >> CONTIG_UP[((O & 0x0040404040404000) * 0x0004081020408102) >> 57]) & P;
	flipped  = (-outflank_v * 2) & 0x0040404040404000;

	outflank_d9 = (0x0020000000000000 >> CONTIG_UPLEFT[((O & 0x0020100804020000) * 0x0101010101010101) >> 56]) & P;
	flipped |= (-outflank_d9 * 2) & 0x0020100804020000;

	outflank_h = OUTFLANK_7[(O >> 56) & 0x3e] & (P >> 55);
	flipped |= (uint64_t) ((-outflank_h) & 0x3e) << 56;

	return flipped;
}

/**
 * Compute flipped discs when playing on square H8.
 *
 * @param P player's disc pattern.
 * @param O opponent's disc pattern.
 * @return flipped disc pattern.
 */
static uint64_t flip_H8(const uint64_t P, const uint64_t O)
{
	unsigned int outflank_h;
	uint64_t flipped, outflank_v, outflank_d9;

	outflank_v = (0x0080000000000000 >> CONTIG_UP[((O & 0x0080808080808000) * 0x0002040810204081) >> 57]) & P;
	flipped  = (-outflank_v * 2) & 0x0080808080808000;

	outflank_d9 = (0x0040000000000000 >> CONTIG_UPLEFT[((O & 0x0040201008040200) * 0x0101010101010101) >> 57]) & P;
	flipped |= (-outflank_d9 * 2) & 0x0040201008040200;

	outflank_h = OUTFLANK_7[(O >> 57) & 0x3f] & (P >> 56);
	flipped |= (uint64_t) ((-outflank_h) & 0x3f) << 57;

	return flipped;
}

/**
 * Compute (zero-) flipped discs when plassing.
 *
 * @param P player's disc pattern.
 * @param O opponent's disc pattern.
 * @return flipped disc pattern.
 */
static uint64_t flip_pass(const uint64_t P, const uint64_t O)
{
	(void) P; // useless code to shut-up compiler warning
	(void) O;
	return 0;
}

/** Array of functions to compute flipped discs */
uint64_t (*FLIP[])(const uint64_t, const uint64_t) = {
	flip_A1, flip_B1, flip_C1, flip_D1, flip_E1, flip_F1, flip_G1, flip_H1,
	flip_A2, flip_B2, flip_C2, flip_D2, flip_E2, flip_F2, flip_G2, flip_H2,
	flip_A3, flip_B3, flip_C3, flip_D3, flip_E3, flip_F3, flip_G3, flip_H3,
	flip_A4, flip_B4, flip_C4, flip_D4, flip_E4, flip_F4, flip_G4, flip_H4,
	flip_A5, flip_B5, flip_C5, flip_D5, flip_E5, flip_F5, flip_G5, flip_H5,
	flip_A6, flip_B6, flip_C6, flip_D6, flip_E6, flip_F6, flip_G6, flip_H6,
	flip_A7, flip_B7, flip_C7, flip_D7, flip_E7, flip_F7, flip_G7, flip_H7,
	flip_A8, flip_B8, flip_C8, flip_D8, flip_E8, flip_F8, flip_G8, flip_H8,
	flip_pass, flip_pass
};

uint64_t board_flip(const Board *board, const int x) 
{
	return FLIP[x](board->player, board->opponent);
}

uint64_t flip(const int x, const uint64_t P, const uint64_t O) {
	return FLIP[x](P, O);
}	

