[net.sources] PCB part 8 of 10

agn@cmu-cs-unh.ARPA (Andreas Nowatzyk) (08/13/85)

#
# type    sh /usru0/agn/pcb/usenet/part8   to unpack this archive.
#
echo extracting pplow.c...
cat >pplow.c <<'!E!O!F!'
/***************************************************************\
*								*
*	PCB program						*
*								*
*	Wire plowing stuff					*
*								*
*	(c) 1985	A. Nowatzyk				*
*								*
\***************************************************************/

#include <stdio.h>
#include "pparm.h"
#include "pcdst.h"

extern char uc_tab[];			/* see pwork: ck_rdnb	 */

static char plow_s;			/* plow side (either s1b or s2b) */

int pdr[8] =				/* offset direction table	 */
	{1, xmax + 1, xmax, xmax - 1, -1, -1 - xmax, -xmax, 1 - xmax};

extern int sp[9][2];			/* search pattern		*/

static char **seg_lst = 0;		/* segment list			 */
static char **dead_lst = 0;		/* dead segment list		 */
static char *first, *last;		/* ptr to the ends of a segment	 */
static int seg_max = xmax;		/* max number of points in seg	 */
static int seg_cnt;			/* segment count		 */
static char *dvt;			/* direction vectors for straight*/

char *straight ();


/********************************************************************\
* 								     *
*  Table 1 is to be indexed with an element of pcb:		     *
*     bit0 (LSB): 1 -> adjacent squares are illegal for side1 (s1b)  *
*     bit1      : 1 -> adjacent squares are illegal for side2 (s2b)  *
*     bit2      : 1 -> square is illegal for side1 (s1b)	     *
*     bit3      : 1 -> square is illegal for side2 (s2b)	     *
*     bit4      : 1 -> square is used by side1 (s1b)		     *
*     bit5      : 1 -> square is used by side2 (s2b)		     *
* 								     *
\********************************************************************/
char drc_tab1[256] = {
	   0,  17,  34,  51,   3,  19,  35,  51,
	   3,  19,  35,  51,   3,  19,  35,  51,
	   3,  19,  35,  51,   3,  19,  35,  51,
	   3,  19,  35,  51,   3,  19,  35,  51,
	   0,  17,  34,  51,   3,  19,  35,  51,
	   3,  19,  35,  51,   3,  19,  35,  51,
	   3,  19,  35,  51,   3,  19,  35,  51,
	   3,  19,  35,  51,   3,  19,  35,  51,
	   0,  17,  34,  51,   3,  19,  35,  51,
	   3,  19,  35,  51,   3,  19,  35,  51,
	   3,  19,  35,  51,   3,  19,  35,  51,
	   3,  19,  35,  51,   3,  19,  35,  51,
	   0,  17,  34,  51,   3,  19,  35,  51,
	   3,  19,  35,  51,   3,  19,  35,  51,
	   3,  19,  35,  51,   3,  19,  35,  51,
	   3,  19,  35,  51,   3,  19,  35,  51,
	   0,  24,  36,  50,   0,  16,  32,  48,
	   0,  16,  32,  48,   0,  16,  32,  48,
	   3,  27,  39,  51,   3,  19,  35,  51,
	   3,  19,  35,  51,   3,  19,  35,  51,
	   0,  24,  36,  49,   0,  16,  32,  48,
	   0,  16,  32,  48,   0,  16,  32,  48,
	   3,  27,  39,  51,   3,  19,  35,  51,
	   3,  19,  35,  51,   3,  19,  35,  51,
	   0,  24,  36,  50,   0,  16,  32,  48,
	   0,  16,  32,  48,   0,  16,  32,  48,
	   3,  27,  39,  51,   3,  19,  35,  51,
	   3,  19,  35,  51,   3,  19,  35,  51,
	   0,  24,  36,  49,   0,  16,  32,  48,
	   0,  16,  32,  48,   0,  16,  32,  48,
	   3,  27,  39,  51,   3,  19,  35,  51,
	   3,  19,  35,  51,   3,  19,  35,  51 };

eval_s5 (p)
    char *p;
/**************************************************************************\
* 									   *
*  Evaluate 5 by 5 square:						   *
* 									   *
*           p p p p p							   *
*           p 3 2 1 p							   *
*           p 4 x 0 p							   *
*           p 5 6 7 p							   *
*           p p p p p							   *
* 									   *
*  <p> points to the bitmap location x. For each adjacent squares 0-7,	   *
*  two things are checked:  a: is the square currently occupied		   *
*                           b: is it a leagal square for this trace	   *
*  for each square the following value is computed:			   *
*                           0: the square is empty and can be used	   *
*                           1: the square is in use by this trace	   *
*                           2: the square is blocked due to design rules   *
*  The values are combined to a table index (8 digits in a base 3 system)  *
* 									   *
\**************************************************************************/
{
    register char *pp;
    register int i, s;

/*******************************************************************\
* 								    *
*  Table 2 is used to convert a 8 bit vector into a base-3 number.  *
*  For each 1 in the bit-vector, the corresponding digit is 2.	    *
* 								    *
\*******************************************************************/
    static int tab2[256] = {
	   0,   2,   6,   8,  18,  20,  24,  26,
	  54,  56,  60,  62,  72,  74,  78,  80,
	 162, 164, 168, 170, 180, 182, 186, 188,
	 216, 218, 222, 224, 234, 236, 240, 242,
	 486, 488, 492, 494, 504, 506, 510, 512,
	 540, 542, 546, 548, 558, 560, 564, 566,
	 648, 650, 654, 656, 666, 668, 672, 674,
	 702, 704, 708, 710, 720, 722, 726, 728,
	1458,1460,1464,1466,1476,1478,1482,1484,
	1512,1514,1518,1520,1530,1532,1536,1538,
	1620,1622,1626,1628,1638,1640,1644,1646,
	1674,1676,1680,1682,1692,1694,1698,1700,
	1944,1946,1950,1952,1962,1964,1968,1970,
	1998,2000,2004,2006,2016,2018,2022,2024,
	2106,2108,2112,2114,2124,2126,2130,2132,
	2160,2162,2166,2168,2178,2180,2184,2186,
	4374,4376,4380,4382,4392,4394,4398,4400,
	4428,4430,4434,4436,4446,4448,4452,4454,
	4536,4538,4542,4544,4554,4556,4560,4562,
	4590,4592,4596,4598,4608,4610,4614,4616,
	4860,4862,4866,4868,4878,4880,4884,4886,
	4914,4916,4920,4922,4932,4934,4938,4940,
	5022,5024,5028,5030,5040,5042,5046,5048,
	5076,5078,5082,5084,5094,5096,5100,5102,
	5832,5834,5838,5840,5850,5852,5856,5858,
	5886,5888,5892,5894,5904,5906,5910,5912,
	5994,5996,6000,6002,6012,6014,6018,6020,
	6048,6050,6054,6056,6066,6068,6072,6074,
	6318,6320,6324,6326,6336,6338,6342,6344,
	6372,6374,6378,6380,6390,6392,6396,6398,
	6480,6482,6486,6488,6498,6500,6504,6506,
	6534,6536,6540,6542,6552,6554,6558,6560  };

/*static int ttt=0;*/
/* if (ttt){ i=(int) p - (int) pcb; test(i % xmax, i / xmax);} */

    pp = p;			/* for speed reasons		 */
    s = ~plow_s;

    i = 0;			/* compute DR constraints	 */
    if (drc_tab1[*(pp            + 2) & 0xff] & ~s)  i |= 0x83;
    if (drc_tab1[*(pp + 1 * xmax + 2) & 0xff] & ~s)  i |= 0x03;
    if (drc_tab1[*(pp + 2 * xmax + 2) & 0xff] & ~s)  i |= 0x02;
    if (drc_tab1[*(pp + 2 * xmax + 1) & 0xff] & ~s)  i |= 0x06;
    if (drc_tab1[*(pp + 2 * xmax    ) & 0xff] & ~s)  i |= 0x0e;
    if (drc_tab1[*(pp + 2 * xmax - 1) & 0xff] & ~s)  i |= 0x0c;
    if (drc_tab1[*(pp + 2 * xmax - 2) & 0xff] & ~s)  i |= 0x08;
    if (drc_tab1[*(pp + 1 * xmax - 2) & 0xff] & ~s)  i |= 0x18;
    if (drc_tab1[*(pp            - 2) & 0xff] & ~s)  i |= 0x38;
    if (drc_tab1[*(pp - 1 * xmax - 2) & 0xff] & ~s)  i |= 0x30;
    if (drc_tab1[*(pp - 2 * xmax - 2) & 0xff] & ~s)  i |= 0x20;
    if (drc_tab1[*(pp - 2 * xmax - 1) & 0xff] & ~s)  i |= 0x60;
    if (drc_tab1[*(pp - 2 * xmax    ) & 0xff] & ~s)  i |= 0xe0;
    if (drc_tab1[*(pp - 2 * xmax + 1) & 0xff] & ~s)  i |= 0xc0;
    if (drc_tab1[*(pp - 2 * xmax + 2) & 0xff] & ~s)  i |= 0x80;
    if (drc_tab1[*(pp - 1 * xmax + 2) & 0xff] & ~s)  i |= 0x81;

    s = ~(plow_s << 2);		/* s1b <-> s2b interaction	 */

    if (drc_tab1[*(pp        + 1) & 0xff] & ~s)  i |= 0x01;
    if (drc_tab1[*(pp + xmax + 1) & 0xff] & ~s)  i |= 0x02;
    if (drc_tab1[*(pp + xmax    ) & 0xff] & ~s)  i |= 0x04;
    if (drc_tab1[*(pp + xmax - 1) & 0xff] & ~s)  i |= 0x08;
    if (drc_tab1[*(pp        - 1) & 0xff] & ~s)  i |= 0x10;
    if (drc_tab1[*(pp - xmax - 1) & 0xff] & ~s)  i |= 0x20;
    if (drc_tab1[*(pp - xmax    ) & 0xff] & ~s)  i |= 0x40;
    if (drc_tab1[*(pp - xmax + 1) & 0xff] & ~s)  i |= 0x80;

    s = ~(plow_s << 4);		/* check connection		 */

    i = tab2[i];		/* compute connectivity 	 */
    if (drc_tab1[*(pp        + 1) & 0xff] & ~s)  i += 1;
    if (drc_tab1[*(pp + xmax + 1) & 0xff] & ~s)  i += 3;
    if (drc_tab1[*(pp + xmax    ) & 0xff] & ~s)  i += 9;
    if (drc_tab1[*(pp + xmax - 1) & 0xff] & ~s)  i += 27;
    if (drc_tab1[*(pp        - 1) & 0xff] & ~s)  i += 81;
    if (drc_tab1[*(pp - xmax - 1) & 0xff] & ~s)  i += 243;
    if (drc_tab1[*(pp - xmax    ) & 0xff] & ~s)  i += 729;
    if (drc_tab1[*(pp - xmax + 1) & 0xff] & ~s)  i += 2187;

    if (i >= 6561) {		/* illegal square in use	 */
	s = (int) pp - (int) pcb;
	err ("eval_s5: DR fault encountered", s % xmax, s / xmax, i, 0);
    }

    return i;
}

char *fnd_seg (x, y, s)
    int x, y, s;
/**************************************************************************\
* 									   *
*   find segment:							   *
*     <x,y> must point to a part of a trace on side <s>. fnd_seg dumps	   *
*     the pointer to all bits of that segment on the segment list. The	   *
*     segment is terminated by either the center of a hole, the center	   *
*     of a 'Y' or the last point of a floating end. The terminating	   *
*     point is not added to the segment list.				   *
* 									   *
*     fnd_seg returns a pointer to a point on the segment if it succeeds.  *
*     a '0' is returned otherwise.					   *
* 									   *
\**************************************************************************/
{
    register int i;

    if (!seg_lst) {		/* alloacte segment list	 */
	seg_lst = (char **) malloc (sizeof (char *) * seg_max);
	dead_lst = (char **) malloc (sizeof (char *) * seg_max);
    }
    seg_cnt = 0;		/* reset segment list counter	 */

    plow_s = s;
    if (!(pcb[y][x] & s))
	return 0;		/* no start point !!		 */

    ckgp (x, y, s);		/* prevent false starts		 */
    if (!(pcb[y][x] & s)) {	/* lost start			 */
	for (i = 0; i < 8; i++)
	    if (pcb[y + dr[i][1]][x + dr[i][0]] & s) {
		x += dr[i][0];
		y += dr[i][1];
		break;
	    }
	if (i >= 8)
	    return 0;		/* start on unconnected garbage	 */
    }

    for (i = 0; i <= 8; i++)	/* find direction		 */
	if (pcb[y + dr[i][1]][x + dr[i][0]] & s)
	   break;

    if (i > 7)
	return 0;		/* start on single point ??	 */

				/* scan one way			 */
    seg_scan (&pcb[y][x], i, s, &first);
				/* scan the other way		 */
    seg_scan (&pcb[y + dr[i][1]][x + dr[i][0]], (i + 4) & 7, s, &last);

    return seg_lst[0];
}

seg_scan (p, d, s, ep)
    char *p, **ep;
    int d, s;
/******************************************************************\
* 								   *
*  Segment scan:						   *
*    <p> points to the start point. <d> is the direction of the	   *
*    next point. The next point will be added to the list if it	   *
*    is a non-terminal point. If the next point was non-terminal,  *
*    it becomes the new start point. The scan is terminated	   *
*    otherwise. Hope that this does not loop!			   *
* 								   *
\******************************************************************/
{
    register char *pp, *t;
    register int i, j = d, k, ss = ~s;
    int l;

    pp = p + pdr[j];

    do {
	
	i = 0;
        if (*(pp        + 1) & ~ss) i++;
        if (*(pp + xmax + 1) & ~ss) i++;
        if (*(pp + xmax    ) & ~ss) i++;
        if (*(pp + xmax - 1) & ~ss) i++;
        if (*(pp        - 1) & ~ss) i++;
        if (*(pp - xmax - 1) & ~ss) i++;
        if (*(pp - xmax    ) & ~ss) i++;
        if (*(pp - xmax + 1) & ~ss) i++;

        if (i < 2) break;	/* floating terminal point	 */

	if (i > 2) {		/* might be a Y - terminal	 */
	    for (i = 5, k = 1; i <= 11; i++)
		if (*(t = pp + pdr[(i + j) & 7]) & ~ss) {
        	    if (*t & ahb &&	/* hole center ?	 */
			*(t        + 1) & ahb &&
			*(t + xmax + 1) & ahb &&
			*(t + xmax    ) & ahb &&
			*(t + xmax - 1) & ahb &&
			*(t        - 1) & ahb &&
			*(t - xmax - 1) & ahb &&
			*(t - xmax    ) & ahb &&
			*(t - xmax + 1) & ahb    ) k++;
		    else {		/* no !			 */
			if (*t & ahb)
			    color (0, plow_s);
			else
			    color (0, selb | plow_s);
			l = (int) t - (int) pcb;
			ck_rdnb (l % xmax, l / xmax, plow_s);
			if (*t & ~ss)
			    k++;	/* still here!		 */
		    }
		}
	    if (k > 2)
		break;		/* found a real Y - terminal	 */
	}

        if (*pp & ahb &&	/* hole terminal point check	 */
	    *(pp        + 1) & ahb &&
	    *(pp + xmax + 1) & ahb &&
	    *(pp + xmax    ) & ahb &&
	    *(pp + xmax - 1) & ahb &&
	    *(pp        - 1) & ahb &&
	    *(pp - xmax - 1) & ahb &&
	    *(pp - xmax    ) & ahb &&
	    *(pp - xmax + 1) & ahb    ) break;

        if (seg_cnt >= seg_max) {	/* need more space	 */
	    seg_max += 10 + seg_max / 2;
	    free (dead_lst);
	    seg_lst = (char **) realloc (seg_lst, sizeof (char *) * seg_max);
	    dead_lst = (char **) malloc (sizeof (char *) * seg_max);
	}

	seg_lst[seg_cnt++] = pp;	/* add point		 */

        for (i = 6; i < 11; i++)	/* find new direction	 */
	    if (*(pp + pdr[(j + i) & 7]) & ~ss)
		break;
	pp += pdr[j = (j + i) & 7];

    } while (i < 11);

    *ep = pp;
}

plow (x, y, s, d, n)
    int x, y, d, n;
/***************************************************************************\
* 									    *
* Move a wire-trace on side <s> in direction <d> by <n> units. The wire is  *
* selected by a point <x,y> on it. The corresponding net will be selected.  *
* 									    *
\***************************************************************************/
{
    struct nlhd *get_net (), *net;
    register char *p;
    register int i, j, k, l, ss = ~s;
    int m, dc, d1, d2, dec_b, add, lst_key ();

    static char tab3[6561] = {
/**************************************************************************\
* 									   *
*  This table is indexed by the configuration number returned by eval_s5.  *
*  For each of the 8 desired move directions, it has the corresonding bit  *
*  set to 1 if the move is legal (that is: no DR violation and no loss	   *
*  of connectivity)							   *
* 									   *
\**************************************************************************/
	255,239,124,143,239, 12,255,239,124,191,255, 60,191,255, 60,191,
	255, 60,241,225,112,129,225,  0,241,225,112, 62, 46, 60, 14, 46,
	 12, 62, 46, 60,191,255, 60,191,255, 60,191,255, 60, 48, 32, 48,
	  0, 32,  0, 48, 32, 48,255,239,124,143,239, 12,255,239,124,191,
	255, 60,191,255, 60,191,255, 60,241,225,112,129,225,  0,241,225,
	112,254,238,124,142,238, 12,254,238,124,255,255,124,255,255,124,
	255,255,124,240,224,112,128,224,  0,240,224,112,254,238,124,142,
	238, 12,254,238,124,255,255,124,255,255,124,255,255,124,240,224,
	112,128,224,  0,240,224,112,254,238,124,142,238, 12,254,238,124,
	255,255,124,255,255,124,255,255,124,240,224,112,128,224,  0,240,
	224,112,199,199, 68,135,199,  4,199,199, 68,135,199,  4,135,199,
	  4,135,199,  4,193,193, 64,129,193,  0,193,193, 64,  6,  6,  4,
	  6,  6,  4,  6,  6,  4,135,199,  4,135,199,  4,135,199,  4,  0,
	  0,  0,  0,  0,  0,  0,  0,  0,199,199, 68,135,199,  4,199,199,
	 68,135,199,  4,135,199,  4,135,199,  4,193,193, 64,129,193,  0,
	193,193, 64,248,232,120,136,232,  8,248,232,120,184,248, 56,184,
	248, 56,184,248, 56,240,224,112,128,224,  0,240,224,112, 56, 40,
	 56,  8, 40,  8, 56, 40, 56,184,248, 56,184,248, 56,184,248, 56,
	 48, 32, 48,  0, 32,  0, 48, 32, 48,248,232,120,136,232,  8,248,
	232,120,184,248, 56,184,248, 56,184,248, 56,240,224,112,128,224,
	  0,240,224,112,254,238,124,142,238, 12,254,238,124,255,255,124,
	255,255,124,255,255,124,240,224,112,128,224,  0,240,224,112,254,
	238,124,142,238, 12,254,238,124,255,255,124,255,255,124,255,255,
	124,240,224,112,128,224,  0,240,224,112,254,238,124,142,238, 12,
	254,238,124,255,255,124,255,255,124,255,255,124,240,224,112,128,
	224,  0,240,224,112,192,192, 64,128,192,  0,192,192, 64,128,192,
	  0,128,192,  0,128,192,  0,192,192, 64,128,192,  0,192,192, 64,
	  0,  0,  0,  0,  0,  0,  0,  0,  0,128,192,  0,128,192,  0,128,
	192,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,192,192, 64,128,192,
	  0,192,192, 64,128,192,  0,128,192,  0,128,192,  0,192,192, 64,
	128,192,  0,192,192, 64,255,239,124,143,239, 12,255,239,124,191,
	255, 60,191,255, 60,191,255, 60,241,225,112,129,225,  0,241,225,
	112, 62, 46, 60, 14, 46, 12, 62, 46, 60,191,255, 60,191,255, 60,
	191,255, 60, 48, 32, 48,  0, 32,  0, 48, 32, 48,255,239,124,143,
	239, 12,255,239,124,191,255, 60,191,255, 60,191,255, 60,241,225,
	112,129,225,  0,241,225,112,254,238,124,142,238, 12,254,238,124,
	255,255,124,255,255,124,255,255,124,240,224,112,128,224,  0,240,
	224,112,254,238,124,142,238, 12,254,238,124,255,255,124,255,255,
	124,255,255,124,240,224,112,128,224,  0,240,224,112,254,238,124,
	142,238, 12,254,238,124,255,255,124,255,255,124,255,255,124,240,
	224,112,128,224,  0,240,224,112,199,199, 68,135,199,  4,199,199,
	 68,135,199,  4,135,199,  4,135,199,  4,193,193, 64,129,193,  0,
	193,193, 64,  6,  6,  4,  6,  6,  4,  6,  6,  4,135,199,  4,135,
	199,  4,135,199,  4,  0,  0,  0,  0,  0,  0,  0,  0,  0,199,199,
	 68,135,199,  4,199,199, 68,135,199,  4,135,199,  4,135,199,  4,
	193,193, 64,129,193,  0,193,193, 64,251,255,120,139,255,  8,251,
	255,120,187,255, 56,187,255, 56,187,255, 56,241,241,112,129,241,
	  0,241,241,112, 58, 62, 56, 10, 62,  8, 58, 62, 56,187,255, 56,
	187,255, 56,187,255, 56, 48, 48, 48,  0, 48,  0, 48, 48, 48,251,
	255,120,139,255,  8,251,255,120,187,255, 56,187,255, 56,187,255,
	 56,241,241,112,129,241,  0,241,241,112,255,255,124,143,255, 12,
	255,255,124,255,255,124,255,255,124,255,255,124,241,241,112,129,
	241,  0,241,241,112,255,255,124,143,255, 12,255,255,124,255,255,
	124,255,255,124,255,255,124,241,241,112,129,241,  0,241,241,112,
	255,255,124,143,255, 12,255,255,124,255,255,124,255,255,124,255,
	255,124,241,241,112,129,241,  0,241,241,112,195,199, 64,131,199,
	  0,195,199, 64,131,199,  0,131,199,  0,131,199,  0,193,193, 64,
	129,193,  0,193,193, 64,  2,  6,  0,  2,  6,  0,  2,  6,  0,131,
	199,  0,131,199,  0,131,199,  0,  0,  0,  0,  0,  0,  0,  0,  0,
	  0,195,199, 64,131,199,  0,195,199, 64,131,199,  0,131,199,  0,
	131,199,  0,193,193, 64,129,193,  0,193,193, 64,251,255,120,139,
	255,  8,251,255,120,187,255, 56,187,255, 56,187,255, 56,241,241,
	112,129,241,  0,241,241,112, 58, 62, 56, 10, 62,  8, 58, 62, 56,
	187,255, 56,187,255, 56,187,255, 56, 48, 48, 48,  0, 48,  0, 48,
	 48, 48,251,255,120,139,255,  8,251,255,120,187,255, 56,187,255,
	 56,187,255, 56,241,241,112,129,241,  0,241,241,112,255,255,124,
	143,255, 12,255,255,124,255,255,124,255,255,124,255,255,124,241,
	241,112,129,241,  0,241,241,112,255,255,124,143,255, 12,255,255,
	124,255,255,124,255,255,124,255,255,124,241,241,112,129,241,  0,
	241,241,112,255,255,124,143,255, 12,255,255,124,255,255,124,255,
	255,124,255,255,124,241,241,112,129,241,  0,241,241,112,195,199,
	 64,131,199,  0,195,199, 64,131,199,  0,131,199,  0,131,199,  0,
	193,193, 64,129,193,  0,193,193, 64,  2,  6,  0,  2,  6,  0,  2,
	  6,  0,131,199,  0,131,199,  0,131,199,  0,  0,  0,  0,  0,  0,
	  0,  0,  0,  0,195,199, 64,131,199,  0,195,199, 64,131,199,  0,
	131,199,  0,131,199,  0,193,193, 64,129,193,  0,193,193, 64,251,
	255,120,139,255,  8,251,255,120,187,255, 56,187,255, 56,187,255,
	 56,241,241,112,129,241,  0,241,241,112, 58, 62, 56, 10, 62,  8,
	 58, 62, 56,187,255, 56,187,255, 56,187,255, 56, 48, 48, 48,  0,
	 48,  0, 48, 48, 48,251,255,120,139,255,  8,251,255,120,187,255,
	 56,187,255, 56,187,255, 56,241,241,112,129,241,  0,241,241,112,
	255,255,124,143,255, 12,255,255,124,255,255,124,255,255,124,255,
	255,124,241,241,112,129,241,  0,241,241,112,255,255,124,143,255,
	 12,255,255,124,255,255,124,255,255,124,255,255,124,241,241,112,
	129,241,  0,241,241,112,255,255,124,143,255, 12,255,255,124,255,
	255,124,255,255,124,255,255,124,241,241,112,129,241,  0,241,241,
	112,195,199, 64,131,199,  0,195,199, 64,131,199,  0,131,199,  0,
	131,199,  0,193,193, 64,129,193,  0,193,193, 64,  2,  6,  0,  2,
	  6,  0,  2,  6,  0,131,199,  0,131,199,  0,131,199,  0,  0,  0,
	  0,  0,  0,  0,  0,  0,  0,195,199, 64,131,199,  0,195,199, 64,
	131,199,  0,131,199,  0,131,199,  0,193,193, 64,129,193,  0,193,
	193, 64, 31, 15, 28, 15, 15, 12, 31, 15, 28, 31, 31, 28, 31, 31,
	 28, 31, 31, 28, 17,  1, 16,  1,  1,  0, 17,  1, 16, 30, 14, 28,
	 14, 14, 12, 30, 14, 28, 31, 31, 28, 31, 31, 28, 31, 31, 28, 16,
	  0, 16,  0,  0,  0, 16,  0, 16, 31, 15, 28, 15, 15, 12, 31, 15,
	 28, 31, 31, 28, 31, 31, 28, 31, 31, 28, 17,  1, 16,  1,  1,  0,
	 17,  1, 16, 30, 14, 28, 14, 14, 12, 30, 14, 28, 31, 31, 28, 31,
	 31, 28, 31, 31, 28, 16,  0, 16,  0,  0,  0, 16,  0, 16, 30, 14,
	 28, 14, 14, 12, 30, 14, 28, 31, 31, 28, 31, 31, 28, 31, 31, 28,
	 16,  0, 16,  0,  0,  0, 16,  0, 16, 30, 14, 28, 14, 14, 12, 30,
	 14, 28, 31, 31, 28, 31, 31, 28, 31, 31, 28, 16,  0, 16,  0,  0,
	  0, 16,  0, 16,  7,  7,  4,  7,  7,  4,  7,  7,  4,  7,  7,  4,
	  7,  7,  4,  7,  7,  4,  1,  1,  0,  1,  1,  0,  1,  1,  0,  6,
	  6,  4,  6,  6,  4,  6,  6,  4,  7,  7,  4,  7,  7,  4,  7,  7,
	  4,  0,  0,  0,  0,  0,  0,  0,  0,  0,  7,  7,  4,  7,  7,  4,
	  7,  7,  4,  7,  7,  4,  7,  7,  4,  7,  7,  4,  1,  1,  0,  1,
	  1,  0,  1,  1,  0, 24,  8, 24,  8,  8,  8, 24,  8, 24, 24, 24,
	 24, 24, 24, 24, 24, 24, 24, 16,  0, 16,  0,  0,  0, 16,  0, 16,
	 24,  8, 24,  8,  8,  8, 24,  8, 24, 24, 24, 24, 24, 24, 24, 24,
	 24, 24, 16,  0, 16,  0,  0,  0, 16,  0, 16, 24,  8, 24,  8,  8,
	  8, 24,  8, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 16,  0, 16,
	  0,  0,  0, 16,  0, 16, 30, 14, 28, 14, 14, 12, 30, 14, 28, 31,
	 31, 28, 31, 31, 28, 31, 31, 28, 16,  0, 16,  0,  0,  0, 16,  0,
	 16, 30, 14, 28, 14, 14, 12, 30, 14, 28, 31, 31, 28, 31, 31, 28,
	 31, 31, 28, 16,  0, 16,  0,  0,  0, 16,  0, 16, 30, 14, 28, 14,
	 14, 12, 30, 14, 28, 31, 31, 28, 31, 31, 28, 31, 31, 28, 16,  0,
	 16,  0,  0,  0, 16,  0, 16,  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,  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,  0,  0,  0,  0,  0,  0,  0,  0,  0,
	  0,  0,  0,  0,  0,  0,  0,  0, 31, 15, 28, 15, 15, 12, 31, 15,
	 28, 31, 31, 28, 31, 31, 28, 31, 31, 28, 17,  1, 16,  1,  1,  0,
	 17,  1, 16, 30, 14, 28, 14, 14, 12, 30, 14, 28, 31, 31, 28, 31,
	 31, 28, 31, 31, 28, 16,  0, 16,  0,  0,  0, 16,  0, 16, 31, 15,
	 28, 15, 15, 12, 31, 15, 28, 31, 31, 28, 31, 31, 28, 31, 31, 28,
	 17,  1, 16,  1,  1,  0, 17,  1, 16, 30, 14, 28, 14, 14, 12, 30,
	 14, 28, 31, 31, 28, 31, 31, 28, 31, 31, 28, 16,  0, 16,  0,  0,
	  0, 16,  0, 16, 30, 14, 28, 14, 14, 12, 30, 14, 28, 31, 31, 28,
	 31, 31, 28, 31, 31, 28, 16,  0, 16,  0,  0,  0, 16,  0, 16, 30,
	 14, 28, 14, 14, 12, 30, 14, 28, 31, 31, 28, 31, 31, 28, 31, 31,
	 28, 16,  0, 16,  0,  0,  0, 16,  0, 16,  7,  7,  4,  7,  7,  4,
	  7,  7,  4,  7,  7,  4,  7,  7,  4,  7,  7,  4,  1,  1,  0,  1,
	  1,  0,  1,  1,  0,  6,  6,  4,  6,  6,  4,  6,  6,  4,  7,  7,
	  4,  7,  7,  4,  7,  7,  4,  0,  0,  0,  0,  0,  0,  0,  0,  0,
	  7,  7,  4,  7,  7,  4,  7,  7,  4,  7,  7,  4,  7,  7,  4,  7,
	  7,  4,  1,  1,  0,  1,  1,  0,  1,  1,  0,227,239, 96,131,239,
	  0,227,239, 96,163,255, 32,163,255, 32,163,255, 32,225,225, 96,
	129,225,  0,225,225, 96, 34, 46, 32,  2, 46,  0, 34, 46, 32,163,
	255, 32,163,255, 32,163,255, 32, 32, 32, 32,  0, 32,  0, 32, 32,
	 32,227,239, 96,131,239,  0,227,239, 96,163,255, 32,163,255, 32,
	163,255, 32,225,225, 96,129,225,  0,225,225, 96,226,238, 96,130,
	238,  0,226,238, 96,227,255, 96,227,255, 96,227,255, 96,224,224,
	 96,128,224,  0,224,224, 96,226,238, 96,130,238,  0,226,238, 96,
	227,255, 96,227,255, 96,227,255, 96,224,224, 96,128,224,  0,224,
	224, 96,226,238, 96,130,238,  0,226,238, 96,227,255, 96,227,255,
	 96,227,255, 96,224,224, 96,128,224,  0,224,224, 96,195,199, 64,
	131,199,  0,195,199, 64,131,199,  0,131,199,  0,131,199,  0,193,
	193, 64,129,193,  0,193,193, 64,  2,  6,  0,  2,  6,  0,  2,  6,
	  0,131,199,  0,131,199,  0,131,199,  0,  0,  0,  0,  0,  0,  0,
	  0,  0,  0,195,199, 64,131,199,  0,195,199, 64,131,199,  0,131,
	199,  0,131,199,  0,193,193, 64,129,193,  0,193,193, 64,224,232,
	 96,128,232,  0,224,232, 96,160,248, 32,160,248, 32,160,248, 32,
	224,224, 96,128,224,  0,224,224, 96, 32, 40, 32,  0, 40,  0, 32,
	 40, 32,160,248, 32,160,248, 32,160,248, 32, 32, 32, 32,  0, 32,
	  0, 32, 32, 32,224,232, 96,128,232,  0,224,232, 96,160,248, 32,
	160,248, 32,160,248, 32,224,224, 96,128,224,  0,224,224, 96,226,
	238, 96,130,238,  0,226,238, 96,227,255, 96,227,255, 96,227,255,
	 96,224,224, 96,128,224,  0,224,224, 96,226,238, 96,130,238,  0,
	226,238, 96,227,255, 96,227,255, 96,227,255, 96,224,224, 96,128,
	224,  0,224,224, 96,226,238, 96,130,238,  0,226,238, 96,227,255,
	 96,227,255, 96,227,255, 96,224,224, 96,128,224,  0,224,224, 96,
	192,192, 64,128,192,  0,192,192, 64,128,192,  0,128,192,  0,128,
	192,  0,192,192, 64,128,192,  0,192,192, 64,  0,  0,  0,  0,  0,
	  0,  0,  0,  0,128,192,  0,128,192,  0,128,192,  0,  0,  0,  0,
	  0,  0,  0,  0,  0,  0,192,192, 64,128,192,  0,192,192, 64,128,
	192,  0,128,192,  0,128,192,  0,192,192, 64,128,192,  0,192,192,
	 64,227,239, 96,131,239,  0,227,239, 96,163,255, 32,163,255, 32,
	163,255, 32,225,225, 96,129,225,  0,225,225, 96, 34, 46, 32,  2,
	 46,  0, 34, 46, 32,163,255, 32,163,255, 32,163,255, 32, 32, 32,
	 32,  0, 32,  0, 32, 32, 32,227,239, 96,131,239,  0,227,239, 96,
	163,255, 32,163,255, 32,163,255, 32,225,225, 96,129,225,  0,225,
	225, 96,226,238, 96,130,238,  0,226,238, 96,227,255, 96,227,255,
	 96,227,255, 96,224,224, 96,128,224,  0,224,224, 96,226,238, 96,
	130,238,  0,226,238, 96,227,255, 96,227,255, 96,227,255, 96,224,
	224, 96,128,224,  0,224,224, 96,226,238, 96,130,238,  0,226,238,
	 96,227,255, 96,227,255, 96,227,255, 96,224,224, 96,128,224,  0,
	224,224, 96,195,199, 64,131,199,  0,195,199, 64,131,199,  0,131,
	199,  0,131,199,  0,193,193, 64,129,193,  0,193,193, 64,  2,  6,
	  0,  2,  6,  0,  2,  6,  0,131,199,  0,131,199,  0,131,199,  0,
	  0,  0,  0,  0,  0,  0,  0,  0,  0,195,199, 64,131,199,  0,195,
	199, 64,131,199,  0,131,199,  0,131,199,  0,193,193, 64,129,193,
	  0,193,193, 64,251,255,120,139,255,  8,251,255,120,187,255, 56,
	187,255, 56,187,255, 56,241,241,112,129,241,  0,241,241,112, 58,
	 62, 56, 10, 62,  8, 58, 62, 56,187,255, 56,187,255, 56,187,255,
	 56, 48, 48, 48,  0, 48,  0, 48, 48, 48,251,255,120,139,255,  8,
	251,255,120,187,255, 56,187,255, 56,187,255, 56,241,241,112,129,
	241,  0,241,241,112,255,255,124,143,255, 12,255,255,124,255,255,
	124,255,255,124,255,255,124,241,241,112,129,241,  0,241,241,112,
	255,255,124,143,255, 12,255,255,124,255,255,124,255,255,124,255,
	255,124,241,241,112,129,241,  0,241,241,112,255,255,124,143,255,
	 12,255,255,124,255,255,124,255,255,124,255,255,124,241,241,112,
	129,241,  0,241,241,112,195,199, 64,131,199,  0,195,199, 64,131,
	199,  0,131,199,  0,131,199,  0,193,193, 64,129,193,  0,193,193,
	 64,  2,  6,  0,  2,  6,  0,  2,  6,  0,131,199,  0,131,199,  0,
	131,199,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,195,199, 64,131,
	199,  0,195,199, 64,131,199,  0,131,199,  0,131,199,  0,193,193,
	 64,129,193,  0,193,193, 64,251,255,120,139,255,  8,251,255,120,
	187,255, 56,187,255, 56,187,255, 56,241,241,112,129,241,  0,241,
	241,112, 58, 62, 56, 10, 62,  8, 58, 62, 56,187,255, 56,187,255,
	 56,187,255, 56, 48, 48, 48,  0, 48,  0, 48, 48, 48,251,255,120,
	139,255,  8,251,255,120,187,255, 56,187,255, 56,187,255, 56,241,
	241,112,129,241,  0,241,241,112,255,255,124,143,255, 12,255,255,
	124,255,255,124,255,255,124,255,255,124,241,241,112,129,241,  0,
	241,241,112,255,255,124,143,255, 12,255,255,124,255,255,124,255,
	255,124,255,255,124,241,241,112,129,241,  0,241,241,112,255,255,
	124,143,255, 12,255,255,124,255,255,124,255,255,124,255,255,124,
	241,241,112,129,241,  0,241,241,112,195,199, 64,131,199,  0,195,
	199, 64,131,199,  0,131,199,  0,131,199,  0,193,193, 64,129,193,
	  0,193,193, 64,  2,  6,  0,  2,  6,  0,  2,  6,  0,131,199,  0,
	131,199,  0,131,199,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,195,
	199, 64,131,199,  0,195,199, 64,131,199,  0,131,199,  0,131,199,
	  0,193,193, 64,129,193,  0,193,193, 64,251,255,120,139,255,  8,
	251,255,120,187,255, 56,187,255, 56,187,255, 56,241,241,112,129,
	241,  0,241,241,112, 58, 62, 56, 10, 62,  8, 58, 62, 56,187,255,
	 56,187,255, 56,187,255, 56, 48, 48, 48,  0, 48,  0, 48, 48, 48,
	251,255,120,139,255,  8,251,255,120,187,255, 56,187,255, 56,187,
	255, 56,241,241,112,129,241,  0,241,241,112,255,255,124,143,255,
	 12,255,255,124,255,255,124,255,255,124,255,255,124,241,241,112,
	129,241,  0,241,241,112,255,255,124,143,255, 12,255,255,124,255,
	255,124,255,255,124,255,255,124,241,241,112,129,241,  0,241,241,
	112,255,255,124,143,255, 12,255,255,124,255,255,124,255,255,124,
	255,255,124,241,241,112,129,241,  0,241,241,112,195,199, 64,131,
	199,  0,195,199, 64,131,199,  0,131,199,  0,131,199,  0,193,193,
	 64,129,193,  0,193,193, 64,  2,  6,  0,  2,  6,  0,  2,  6,  0,
	131,199,  0,131,199,  0,131,199,  0,  0,  0,  0,  0,  0,  0,  0,
	  0,  0,195,199, 64,131,199,  0,195,199, 64,131,199,  0,131,199,
	  0,131,199,  0,193,193, 64,129,193,  0,193,193, 64,  3, 15,  0,
	  3, 15,  0,  3, 15,  0,  3, 31,  0,  3, 31,  0,  3, 31,  0,  1,
	  1,  0,  1,  1,  0,  1,  1,  0,  2, 14,  0,  2, 14,  0,  2, 14,
	  0,  3, 31,  0,  3, 31,  0,  3, 31,  0,  0,  0,  0,  0,  0,  0,
	  0,  0,  0,  3, 15,  0,  3, 15,  0,  3, 15,  0,  3, 31,  0,  3,
	 31,  0,  3, 31,  0,  1,  1,  0,  1,  1,  0,  1,  1,  0,  2, 14,
	  0,  2, 14,  0,  2, 14,  0,  3, 31,  0,  3, 31,  0,  3, 31,  0,
	  0,  0,  0,  0,  0,  0,  0,  0,  0,  2, 14,  0,  2, 14,  0,  2,
	 14,  0,  3, 31,  0,  3, 31,  0,  3, 31,  0,  0,  0,  0,  0,  0,
	  0,  0,  0,  0,  2, 14,  0,  2, 14,  0,  2, 14,  0,  3, 31,  0,
	  3, 31,  0,  3, 31,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  3,
	  7,  0,  3,  7,  0,  3,  7,  0,  3,  7,  0,  3,  7,  0,  3,  7,
	  0,  1,  1,  0,  1,  1,  0,  1,  1,  0,  2,  6,  0,  2,  6,  0,
	  2,  6,  0,  3,  7,  0,  3,  7,  0,  3,  7,  0,  0,  0,  0,  0,
	  0,  0,  0,  0,  0,  3,  7,  0,  3,  7,  0,  3,  7,  0,  3,  7,
	  0,  3,  7,  0,  3,  7,  0,  1,  1,  0,  1,  1,  0,  1,  1,  0,
	  0,  8,  0,  0,  8,  0,  0,  8,  0,  0, 24,  0,  0, 24,  0,  0,
	 24,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  8,  0,  0,  8,
	  0,  0,  8,  0,  0, 24,  0,  0, 24,  0,  0, 24,  0,  0,  0,  0,
	  0,  0,  0,  0,  0,  0,  0,  8,  0,  0,  8,  0,  0,  8,  0,  0,
	 24,  0,  0, 24,  0,  0, 24,  0,  0,  0,  0,  0,  0,  0,  0,  0,
	  0,  2, 14,  0,  2, 14,  0,  2, 14,  0,  3, 31,  0,  3, 31,  0,
	  3, 31,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  2, 14,  0,  2,
	 14,  0,  2, 14,  0,  3, 31,  0,  3, 31,  0,  3, 31,  0,  0,  0,
	  0,  0,  0,  0,  0,  0,  0,  2, 14,  0,  2, 14,  0,  2, 14,  0,
	  3, 31,  0,  3, 31,  0,  3, 31,  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,  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,  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,  3, 15,  0,  3, 15,  0,  3, 15,  0,  3, 31,  0,  3,
	 31,  0,  3, 31,  0,  1,  1,  0,  1,  1,  0,  1,  1,  0,  2, 14,
	  0,  2, 14,  0,  2, 14,  0,  3, 31,  0,  3, 31,  0,  3, 31,  0,
	  0,  0,  0,  0,  0,  0,  0,  0,  0,  3, 15,  0,  3, 15,  0,  3,
	 15,  0,  3, 31,  0,  3, 31,  0,  3, 31,  0,  1,  1,  0,  1,  1,
	  0,  1,  1,  0,  2, 14,  0,  2, 14,  0,  2, 14,  0,  3, 31,  0,
	  3, 31,  0,  3, 31,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  2,
	 14,  0,  2, 14,  0,  2, 14,  0,  3, 31,  0,  3, 31,  0,  3, 31,
	  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  2, 14,  0,  2, 14,  0,
	  2, 14,  0,  3, 31,  0,  3, 31,  0,  3, 31,  0,  0,  0,  0,  0,
	  0,  0,  0,  0,  0,  3,  7,  0,  3,  7,  0,  3,  7,  0,  3,  7,
	  0,  3,  7,  0,  3,  7,  0,  1,  1,  0,  1,  1,  0,  1,  1,  0,
	  2,  6,  0,  2,  6,  0,  2,  6,  0,  3,  7,  0,  3,  7,  0,  3,
	  7,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  3,  7,  0,  3,  7,
	  0,  3,  7,  0,  3,  7,  0,  3,  7,  0,  3,  7,  0,  1,  1,  0,
	  1,  1,  0,  1,  1,  0,255,239,124,143,239, 12,255,239,124,191,
	255, 60,191,255, 60,191,255, 60,241,225,112,129,225,  0,241,225,
	112, 62, 46, 60, 14, 46, 12, 62, 46, 60,191,255, 60,191,255, 60,
	191,255, 60, 48, 32, 48,  0, 32,  0, 48, 32, 48,255,239,124,143,
	239, 12,255,239,124,191,255, 60,191,255, 60,191,255, 60,241,225,
	112,129,225,  0,241,225,112,254,238,124,142,238, 12,254,238,124,
	255,255,124,255,255,124,255,255,124,240,224,112,128,224,  0,240,
	224,112,254,238,124,142,238, 12,254,238,124,255,255,124,255,255,
	124,255,255,124,240,224,112,128,224,  0,240,224,112,254,238,124,
	142,238, 12,254,238,124,255,255,124,255,255,124,255,255,124,240,
	224,112,128,224,  0,240,224,112,199,199, 68,135,199,  4,199,199,
	 68,135,199,  4,135,199,  4,135,199,  4,193,193, 64,129,193,  0,
	193,193, 64,  6,  6,  4,  6,  6,  4,  6,  6,  4,135,199,  4,135,
	199,  4,135,199,  4,  0,  0,  0,  0,  0,  0,  0,  0,  0,199,199,
	 68,135,199,  4,199,199, 68,135,199,  4,135,199,  4,135,199,  4,
	193,193, 64,129,193,  0,193,193, 64,248,232,120,136,232,  8,248,
	232,120,184,248, 56,184,248, 56,184,248, 56,240,224,112,128,224,
	  0,240,224,112, 56, 40, 56,  8, 40,  8, 56, 40, 56,184,248, 56,
	184,248, 56,184,248, 56, 48, 32, 48,  0, 32,  0, 48, 32, 48,248,
	232,120,136,232,  8,248,232,120,184,248, 56,184,248, 56,184,248,
	 56,240,224,112,128,224,  0,240,224,112,254,238,124,142,238, 12,
	254,238,124,255,255,124,255,255,124,255,255,124,240,224,112,128,
	224,  0,240,224,112,254,238,124,142,238, 12,254,238,124,255,255,
	124,255,255,124,255,255,124,240,224,112,128,224,  0,240,224,112,
	254,238,124,142,238, 12,254,238,124,255,255,124,255,255,124,255,
	255,124,240,224,112,128,224,  0,240,224,112,192,192, 64,128,192,
	  0,192,192, 64,128,192,  0,128,192,  0,128,192,  0,192,192, 64,
	128,192,  0,192,192, 64,  0,  0,  0,  0,  0,  0,  0,  0,  0,128,
	192,  0,128,192,  0,128,192,  0,  0,  0,  0,  0,  0,  0,  0,  0,
	  0,192,192, 64,128,192,  0,192,192, 64,128,192,  0,128,192,  0,
	128,192,  0,192,192, 64,128,192,  0,192,192, 64,255,239,124,143,
	239, 12,255,239,124,191,255, 60,191,255, 60,191,255, 60,241,225,
	112,129,225,  0,241,225,112, 62, 46, 60, 14, 46, 12, 62, 46, 60,
	191,255, 60,191,255, 60,191,255, 60, 48, 32, 48,  0, 32,  0, 48,
	 32, 48,255,239,124,143,239, 12,255,239,124,191,255, 60,191,255,
	 60,191,255, 60,241,225,112,129,225,  0,241,225,112,254,238,124,
	142,238, 12,254,238,124,255,255,124,255,255,124,255,255,124,240,
	224,112,128,224,  0,240,224,112,254,238,124,142,238, 12,254,238,
	124,255,255,124,255,255,124,255,255,124,240,224,112,128,224,  0,
	240,224,112,254,238,124,142,238, 12,254,238,124,255,255,124,255,
	255,124,255,255,124,240,224,112,128,224,  0,240,224,112,199,199,
	 68,135,199,  4,199,199, 68,135,199,  4,135,199,  4,135,199,  4,
	193,193, 64,129,193,  0,193,193, 64,  6,  6,  4,  6,  6,  4,  6,
	  6,  4,135,199,  4,135,199,  4,135,199,  4,  0,  0,  0,  0,  0,
	  0,  0,  0,  0,199,199, 68,135,199,  4,199,199, 68,135,199,  4,
	135,199,  4,135,199,  4,193,193, 64,129,193,  0,193,193, 64,251,
	255,120,139,255,  8,251,255,120,187,255, 56,187,255, 56,187,255,
	 56,241,241,112,129,241,  0,241,241,112, 58, 62, 56, 10, 62,  8,
	 58, 62, 56,187,255, 56,187,255, 56,187,255, 56, 48, 48, 48,  0,
	 48,  0, 48, 48, 48,251,255,120,139,255,  8,251,255,120,187,255,
	 56,187,255, 56,187,255, 56,241,241,112,129,241,  0,241,241,112,
	255,255,124,143,255, 12,255,255,124,255,255,124,255,255,124,255,
	255,124,241,241,112,129,241,  0,241,241,112,255,255,124,143,255,
	 12,255,255,124,255,255,124,255,255,124,255,255,124,241,241,112,
	129,241,  0,241,241,112,255,255,124,143,255, 12,255,255,124,255,
	255,124,255,255,124,255,255,124,241,241,112,129,241,  0,241,241,
	112,195,199, 64,131,199,  0,195,199, 64,131,199,  0,131,199,  0,
	131,199,  0,193,193, 64,129,193,  0,193,193, 64,  2,  6,  0,  2,
	  6,  0,  2,  6,  0,131,199,  0,131,199,  0,131,199,  0,  0,  0,
	  0,  0,  0,  0,  0,  0,  0,195,199, 64,131,199,  0,195,199, 64,
	131,199,  0,131,199,  0,131,199,  0,193,193, 64,129,193,  0,193,
	193, 64,251,255,120,139,255,  8,251,255,120,187,255, 56,187,255,
	 56,187,255, 56,241,241,112,129,241,  0,241,241,112, 58, 62, 56,
	 10, 62,  8, 58, 62, 56,187,255, 56,187,255, 56,187,255, 56, 48,
	 48, 48,  0, 48,  0, 48, 48, 48,251,255,120,139,255,  8,251,255,
	120,187,255, 56,187,255, 56,187,255, 56,241,241,112,129,241,  0,
	241,241,112,255,255,124,143,255, 12,255,255,124,255,255,124,255,
	255,124,255,255,124,241,241,112,129,241,  0,241,241,112,255,255,
	124,143,255, 12,255,255,124,255,255,124,255,255,124,255,255,124,
	241,241,112,129,241,  0,241,241,112,255,255,124,143,255, 12,255,
	255,124,255,255,124,255,255,124,255,255,124,241,241,112,129,241,
	  0,241,241,112,195,199, 64,131,199,  0,195,199, 64,131,199,  0,
	131,199,  0,131,199,  0,193,193, 64,129,193,  0,193,193, 64,  2,
	  6,  0,  2,  6,  0,  2,  6,  0,131,199,  0,131,199,  0,131,199,
	  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,195,199, 64,131,199,  0,
	195,199, 64,131,199,  0,131,199,  0,131,199,  0,193,193, 64,129,
	193,  0,193,193, 64,251,255,120,139,255,  8,251,255,120,187,255,
	 56,187,255, 56,187,255, 56,241,241,112,129,241,  0,241,241,112,
	 58, 62, 56, 10, 62,  8, 58, 62, 56,187,255, 56,187,255, 56,187,
	255, 56, 48, 48, 48,  0, 48,  0, 48, 48, 48,251,255,120,139,255,
	  8,251,255,120,187,255, 56,187,255, 56,187,255, 56,241,241,112,
	129,241,  0,241,241,112,255,255,124,143,255, 12,255,255,124,255,
	255,124,255,255,124,255,255,124,241,241,112,129,241,  0,241,241,
	112,255,255,124,143,255, 12,255,255,124,255,255,124,255,255,124,
	255,255,124,241,241,112,129,241,  0,241,241,112,255,255,124,143,
	255, 12,255,255,124,255,255,124,255,255,124,255,255,124,241,241,
	112,129,241,  0,241,241,112,195,199, 64,131,199,  0,195,199, 64,
	131,199,  0,131,199,  0,131,199,  0,193,193, 64,129,193,  0,193,
	193, 64,  2,  6,  0,  2,  6,  0,  2,  6,  0,131,199,  0,131,199,
	  0,131,199,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,195,199, 64,
	131,199,  0,195,199, 64,131,199,  0,131,199,  0,131,199,  0,193,
	193, 64,129,193,  0,193,193, 64, 31, 15, 28, 15, 15, 12, 31, 15,
	 28, 31, 31, 28, 31, 31, 28, 31, 31, 28, 17,  1, 16,  1,  1,  0,
	 17,  1, 16, 30, 14, 28, 14, 14, 12, 30, 14, 28, 31, 31, 28, 31,
	 31, 28, 31, 31, 28, 16,  0, 16,  0,  0,  0, 16,  0, 16, 31, 15,
	 28, 15, 15, 12, 31, 15, 28, 31, 31, 28, 31, 31, 28, 31, 31, 28,
	 17,  1, 16,  1,  1,  0, 17,  1, 16, 30, 14, 28, 14, 14, 12, 30,
	 14, 28, 31, 31, 28, 31, 31, 28, 31, 31, 28, 16,  0, 16,  0,  0,
	  0, 16,  0, 16, 30, 14, 28, 14, 14, 12, 30, 14, 28, 31, 31, 28,
	 31, 31, 28, 31, 31, 28, 16,  0, 16,  0,  0,  0, 16,  0, 16, 30,
	 14, 28, 14, 14, 12, 30, 14, 28, 31, 31, 28, 31, 31, 28, 31, 31,
	 28, 16,  0, 16,  0,  0,  0, 16,  0, 16,  7,  7,  4,  7,  7,  4,
	  7,  7,  4,  7,  7,  4,  7,  7,  4,  7,  7,  4,  1,  1,  0,  1,
	  1,  0,  1,  1,  0,  6,  6,  4,  6,  6,  4,  6,  6,  4,  7,  7,
	  4,  7,  7,  4,  7,  7,  4,  0,  0,  0,  0,  0,  0,  0,  0,  0,
	  7,  7,  4,  7,  7,  4,  7,  7,  4,  7,  7,  4,  7,  7,  4,  7,
	  7,  4,  1,  1,  0,  1,  1,  0,  1,  1,  0, 24,  8, 24,  8,  8,
	  8, 24,  8, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 16,  0, 16,
	  0,  0,  0, 16,  0, 16, 24,  8, 24,  8,  8,  8, 24,  8, 24, 24,
	 24, 24, 24, 24, 24, 24, 24, 24, 16,  0, 16,  0,  0,  0, 16,  0,
	 16, 24,  8, 24,  8,  8,  8, 24,  8, 24, 24, 24, 24, 24, 24, 24,
	 24, 24, 24, 16,  0, 16,  0,  0,  0, 16,  0, 16, 30, 14, 28, 14,
	 14, 12, 30, 14, 28, 31, 31, 28, 31, 31, 28, 31, 31, 28, 16,  0,
	 16,  0,  0,  0, 16,  0, 16, 30, 14, 28, 14, 14, 12, 30, 14, 28,
	 31, 31, 28, 31, 31, 28, 31, 31, 28, 16,  0, 16,  0,  0,  0, 16,
	  0, 16, 30, 14, 28, 14, 14, 12, 30, 14, 28, 31, 31, 28, 31, 31,
	 28, 31, 31, 28, 16,  0, 16,  0,  0,  0, 16,  0, 16,  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,  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,  0,  0,  0,
	  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 31, 15,
	 28, 15, 15, 12, 31, 15, 28, 31, 31, 28, 31, 31, 28, 31, 31, 28,
	 17,  1, 16,  1,  1,  0, 17,  1, 16, 30, 14, 28, 14, 14, 12, 30,
	 14, 28, 31, 31, 28, 31, 31, 28, 31, 31, 28, 16,  0, 16,  0,  0,
	  0, 16,  0, 16, 31, 15, 28, 15, 15, 12, 31, 15, 28, 31, 31, 28,
	 31, 31, 28, 31, 31, 28, 17,  1, 16,  1,  1,  0, 17,  1, 16, 30,
	 14, 28, 14, 14, 12, 30, 14, 28, 31, 31, 28, 31, 31, 28, 31, 31,
	 28, 16,  0, 16,  0,  0,  0, 16,  0, 16, 30, 14, 28, 14, 14, 12,
	 30, 14, 28, 31, 31, 28, 31, 31, 28, 31, 31, 28, 16,  0, 16,  0,
	  0,  0, 16,  0, 16, 30, 14, 28, 14, 14, 12, 30, 14, 28, 31, 31,
	 28, 31, 31, 28, 31, 31, 28, 16,  0, 16,  0,  0,  0, 16,  0, 16,
	  7,  7,  4,  7,  7,  4,  7,  7,  4,  7,  7,  4,  7,  7,  4,  7,
	  7,  4,  1,  1,  0,  1,  1,  0,  1,  1,  0,  6,  6,  4,  6,  6,
	  4,  6,  6,  4,  7,  7,  4,  7,  7,  4,  7,  7,  4,  0,  0,  0,
	  0,  0,  0,  0,  0,  0,  7,  7,  4,  7,  7,  4,  7,  7,  4,  7,
	  7,  4,  7,  7,  4,  7,  7,  4,  1,  1,  0,  1,  1,  0,  1,  1,
	  0 };

    net = get_net (x, y, s);	/* find net			 */

    if (V.cnet != net) {	/* select the net		 */
	if (V.cnet)
	    deseln (V.cnet);
	selnet (net);
    }

				/* find segment to work on	 */
    if (!fnd_seg (x, y, s) || seg_cnt <= 2)	/* not worth the efford */
	return;

    un_display (x, y);		/* un-display wire		 */

    dec_b = 1 << d;		/* decision bit			 */
    add = (s & s1b) ? selb | s1b : selb | s2b | resb;/* add bits */

    if (d & 1) {		/* diagonal move		 */
	d1 = pdr[(d + 1) & 7];
	d2 = pdr[(d + 7) & 7];

	for (n += n; 0 < n; n--) {	/* move loop			 */
/*********************************************************************\
* 								      *
*  The diagonal move is kind of complicated: it needs several phases  *
* 	1. find points to be moved (enter them in dead-list)	      *
* 	2. add all new points (2 for each removed points)	      *
* 	3. remove all dead points (this may overlap with those	      *
* 	   added in step 2)					      *
* 	4. remove new points that are redundant			      *
* 	5. update the seg_list: a) add new points		      *
* 				b) remove dead ones		      *
* 				c) remove multiples		      *
* 								      *
\*********************************************************************/
	    dc = 0;				/* dead point counter	 */
	    for (i = 0; i < seg_cnt; i++)	/** STEP 1		**/
	        if (dec_b & tab3[eval_s5 (seg_lst[i])]) /* move it	 */
		    dead_lst[dc++] = seg_lst[i];

	    if (seg_cnt + 2 * dc > seg_max) {	/* add space		 */
		seg_max = 10 + 2 * dc;
		seg_lst = (char **) realloc (seg_lst,
						sizeof (char *) * seg_max);
		dead_lst = (char **) realloc (dead_lst,
						sizeof (char *) * seg_max);
	    }

	    for (i = 0, j = seg_cnt; i < dc; i++) {	/** STEP 2	**/
		p = dead_lst[i];
		*(seg_lst[j++] = p + d1) |= add;	/* add wire (5a) */
		*(seg_lst[j++] = p + d2) |= add;
	    }

	    for (i = 0; i < dc; i++) {			/** STEP 3	**/
		p = dead_lst[i];
		if (!(*p & ahb && *(p + 1) & ahb && *(p - 1) & ahb &&
		      *(p + xmax) & ahb && *(p - xmax) & ahb)) {
		    *p &= ~add;				/* remove wire	 */
		    if (*p & ahb)
			*p |= selb;
		}
	    }

	  do {
	    m = 0;
	    for (k = i = seg_cnt; i < j; i++) {		/** STEP 4	**/
		p = seg_lst[i];
		if (*p & ~ss) {
/*l = (int) p - (int) pcb;
test(l%xmax,l/xmax);*/
		    l = 0;
		    if (*(p        + 1) & ~ss) l |= 0x01;
		    if (*(p + xmax + 1) & ~ss) l |= 0x02;
		    if (*(p + xmax    ) & ~ss) l |= 0x04;
		    if (*(p + xmax - 1) & ~ss) l |= 0x08;
		    if (*(p        - 1) & ~ss) l |= 0x10;
		    if (*(p - xmax - 1) & ~ss) l |= 0x20;
		    if (*(p - xmax    ) & ~ss) l |= 0x40;
		    if (*(p - xmax + 1) & ~ss) l |= 0x80;

		    if (uc_tab[l] && !(*p & ahb &&
				*(p + 1) & ahb && *(p - 1) & ahb &&
				*(p + xmax) & ahb && *(p - xmax) & ahb)){
						/* useless: remove	 */
			*p &= ~add;
			m = 1;
			if (*p & ahb)
			    *p |= selb;}
		    else
			seg_lst[k++] = p;
		}
	    }
	    j = k;
	  } while (m);				/* I know, this is horrible */
	    seg_cnt = j;

	    if (!dc)				/* nothing moved: exit	 */
		break;
	    else {					/** STEP 5	**/
		qsort (seg_lst, seg_cnt, sizeof (char *), lst_key);
		qsort (dead_lst, dc, sizeof (char *), lst_key);

		for (i = 0, k = 0, l = 0; i < j; i++) { /* rm dead (5b)	 */
		    while (k < dc && seg_lst[i] > dead_lst[k])
			k++;
		    if (k >= dc) {		/* dead list exhausted	 */
			while (i < j)		/* copy rest		 */
			    seg_lst[l++] = seg_lst[i++];
			break;
		    }
		    if (seg_lst[i] < dead_lst[k]) 	/* alive	 */
			seg_lst[l++] = seg_lst[i];
		}
				/* l has now the number of live entries	 */

		for (i = 0, j = 1; j < l; j++) /* rm multiples (5c)	 */
		    if (seg_lst[i] != seg_lst[j])
			seg_lst[++i] = seg_lst[j];
		seg_cnt = i + 1;
	    }
	}}
    else {
/************************************************\
* 						 *
*  horizontal move (much simpler):		 *
*     1. Identify new point (add to dead_lst)	 *
*     2. add them				 *
*     3. remove old ones			 *
*     4. update seg_lst (just remove multiples)	 *
* 						 *
\************************************************/
	d1 = pdr[d];

	for (; 0 < n; n--) {			/* move loop		 */

	    for (j = 0, i = 0; i < seg_cnt; i++)	/** STEP 1	**/
	        if (dec_b & tab3[eval_s5 (seg_lst[i])]) { /* move it	 */
		    p = seg_lst[i];
		    dead_lst[j++] = p;
		    seg_lst[i] = p + d1;
		}

	    for (i = 0; i < j; i++) 			/** STEP 2	**/
		*(dead_lst[i] + d1) |= add;		/* add trace	 */

	    for (i = 0; i < j; i++) {			/** STEP 3	**/
		p = dead_lst[i];
		if (!(*p & ahb && *(p + 1) & ahb && *(p - 1) & ahb &&
		    *(p + xmax) & ahb && *(p - xmax) & ahb)) {
		    *p &= ~add;				/* remove wire	 */
		    if (*p & ahb)
			*p |= selb;
		}
	    }

	    if (!j)			/* nothing moved: exit		 */
		break;
	    else {					/** STEP 4	**/
		j = seg_cnt;
		qsort (seg_lst, j, sizeof (char *), lst_key);
		for (i = 0, k = 1; k < j; k++)	/* remove multiples	 */
		    if (seg_lst[i] != seg_lst[k])
			seg_lst[++i] = seg_lst[k];
		seg_cnt = i + 1;
	    }
	}
    }

    re_display ();		/* redisplay trace		 */    
}

lst_key (a, b)			/* seg_lst sort key		 */
    int *a, *b;
{
    return *a - *b;
}

static int hole_x = 0, hole_y = 0; /* coordinate to restatrt wtrace */

un_display (x, y)		/* un-display wire		 */
    int x, y;
{
    int sv_hole (), rm_line ();

    wthf = sv_hole;		/* save hole			 */
    wtvf = rm_line;

    color (0, selb | plow_s);
    wtrace (x, y, plow_s);
}

sv_hole (x, y)			/* save hole			 */
    int x, y;
{
    if (pcb[y][x] & chb) {
	hole_x = x;
	hole_y = y;
    }

    return 0;
}

rm_line (x1, y1, x2, y2)	/* remove line			 */
    int x1, y1, x2, y2;
{
    if (wtsb == plow_s)
	plts (x1, y1, x2, y2);
}

re_display ()			/* redisplay wire		 */
{
    int rm_line (), sel_hole ();

    wthf = sel_hole;
    wtvf = rm_line;

    color (selb | plow_s, selb | plow_s);
    wtrace (hole_x, hole_y, vec);
}

sel_hole (x, y)			/* (re-) select holes		 */
    int x, y;
{
    color (selb, selb);
    dpin (x, y);
    color (selb | plow_s, selb | plow_s);

    return 0;
}

static int x_start, y_start, started;	/* contex - info	 */
static int x_end, y_end, plen, pdir;

plow_ini (ctx)			/* initialize plowing		 */
    int ctx;
{
    if (ctx != PLOW)
        started = 0;
    return ctx;
}

plow_src (x, y, ctx)		/* source			 */
    int x, y, ctx;
{
    register int i;

    if (started){		/* remove pointer		 */
	color (0, resb);
	plts (x_start, y_start, x_end, y_end);
    }

    for (i = 0; i < 9; i++)
	if (pcb[y + sp[i][1]][x + sp[i][0]] & vec)
	    break;

    if (i >= 9) {
	started = 0;
	err_msg ("No trace found");}
    else {
	started = 1;
	x_end = x_start = x + sp[i][0];
	y_end = y_start = y + sp[i][1];
	plen = 0;
	color (resb, resb);
	point (x_start, y_start);
	plow_s = pcb[y + sp[i][1]][x + sp[i][0]] & vec;
	if (plow_s == vec)
	    plow_s = top_side;
    }

    return ctx;
}

plow_dst (x, y, ctx)			/* plow destination	 */
    int x, y, ctx;
{
    register int i, j;
    double atan2 ();

    if (!started)
	err_msg ("designate source first");
    else {
	color (0, resb);
	plts (x_start, y_start, x_end, y_end);

	pdir = (atan2 ((y - y_start) * 0.5, (x - x_start) * 0.5)
		 + 6.676885) * 1.27324;
        pdir = pdir % 8;		/* chose a direction		 */

	j = abs (y - y_start);
	i = abs (x - x_start);

	if (pdir & 1)
	    plen = (j < i) ? j : i;	/* run min. length (diag) */
	else
	    plen = dr[pdir][0] ? i : j;	/* run axis projection	 */

	x_end = x_start + plen * dr[pdir][0];
	y_end = y_start + plen * dr[pdir][1];

	color (resb, resb);
	plts (x_start, y_start, x_end, y_end);
    }

    return ctx;
}

/*ARGSUSED*/
exc_plow (x, y, ctx)			/* execute plow		 */
    int x, y, ctx;
{
    if (!started)
	err_msg ("Nothing to move");
    else {
	color (0, resb);
	plts (x_start, y_start, x_end, y_end);
	if (plen)
	    plow (x_start, y_start, plow_s, pdir, plen);
	else
	    straight (x_start, y_start, plow_s);
	started = 0;
    }

    return START;
}

adj_sort (src, dst, n)
    int n;
    char *src, *dst;
/********************************************************************\
* 								     *
*   Adjacenty sort:						     *
* 								     *
*  "seg_lst" is the pointer to a array of <n> pcb-pointer that are   *
*  supposed to point to the pixel of a trace that starts at <src>.   *
*  "dvt" points to an char array (of at least <n> elements, that     *
*  will receive the direction vectors to get from <src> to <dst>.    *
*  <src> and <dst> must not be adjacent. Error conditions exists if  *
*  there is no path from <src> to <dst> (loss of connectivity).	     *
* 								     *
*   "seg_lst" will receive the points of the shortest path.	     *
* 								     *
*   Side-effect: dead_lst is used for scratch and must be > <n>	     *
* 								     *
*   Note: the dvt-vector has n+1 elsements: the last is pointing     *
*         to the destination.					     *
* 								     *
\********************************************************************/
{
    int lst_key ();
    register char *p;
    register int h, i, j, k, l;
    int m, add, suc;
    char *s;
    static int *nxt = 0, nxt_max;

/*
static char ttt = 0;
*/
    if (!nxt) {				/* need to next pointers	 */
	nxt_max = seg_max;
	nxt = (int *) malloc (sizeof (int) * nxt_max);}
    else if (nxt_max < n) {		/* need to add space		 */
	nxt_max = 10 + n;
	free (nxt);
	nxt = (int *) malloc (sizeof (int) * nxt_max);
    }

    qsort (seg_lst, n, sizeof (char *), lst_key);	/* sort pointer	 */

    for (i = 0, j = 0; j < n; j++) { 	/* remove multiples		 */
	p = seg_lst[j];
	if ((!i || seg_lst[i - 1] != p) && p != src && p != dst) {
	    dvt[i] = 1;
	    seg_lst[i++] = p;
	}
    }
    n = i;				/* update length		 */
    add = (plow_s & s1b) ? selb | s1b : selb | s2b | resb;
    
    dead_lst[0] = src;			/* enter start point		 */
    nxt[0] = 0;				/* terminate back pointer chain	 */

    for (m = 0, i = 1; m < i;m++) {	/* main loop			 */

        s = dead_lst[m];		/* get point to work on		 */
/*
if(ttt){s_test(((int)s-(int)pcb)%xmax,((int)s-(int)pcb)/xmax,
((int)dst-(int)pcb)%xmax,((int)dst-(int)pcb)/xmax,"DST");
getchar();}
*/
	suc = 1;			/* successor test		 */

	for (j = 0; j < 8; j++) {	/* find new direction		 */
	    p = s + pdr[j];		/* pointer to candidate		 */

	    if (!(*p & plow_s))		/* skip hyperspace		 */
		continue;

	    if (p == dst)
		break;			/* done !!!!!!			 */

	    l = 0;			/* do a binary search for p	 */
	    h = n - 1;
	    while (l <= h) {
		k = (l + h) >> 1;
		if (p > seg_lst[k]) {
		    l = k + 1;
		    continue; }
		if (p < seg_lst[k]) {
		    h = k - 1;
		    continue; }
		break;			/* found it!			 */
	    }

	    if (l <= h && dvt[k]) {	/* found it: k			 */
/*
if(ttt)
printf("found: i=%d  x=%3d y=%3d\n",i,
((int)p-(int)pcb)%xmax,((int)p-(int)pcb)/xmax);
*/
		suc = 0;
		dvt[k] = 0;
		nxt[i] = ((4 + j) & 7) + (m << 3);
		dead_lst[i++] = p;
	    }
	}

	if (j < 8)			/* Found the shortest path	 */
	    break;

	if (suc) {			/* need to eat unrelated trace	 */
/************************************************************************\
* 									 *
*  This is a rare case: during shortening, the connectivity of the new	 *
*  path becomes dependent on a piece of unrelated trace of the same	 *
*  net. The O(n*n) approach to cycle avoidence is ok because it happens	 *
*  rarely!								 *
* 									 *
\************************************************************************/
	    for (j = 0; j < 8; j++)
		if (*(p = s + pdr[j]) & plow_s && p != src) {
		    for (k = 0; k < i; k++)
			if (dead_lst[k] == p)
			    break;
		    if (k >= i) {	/* found a new point		 */
			if (i >= nxt_max) {	/* shit: need more space */
			    nxt_max = seg_max + 10 + seg_max / 2;
			    seg_max = nxt_max;
			    dead_lst = (char **) realloc (dead_lst,
					sizeof (char *) * seg_max);
			    seg_lst = (char **) realloc (seg_lst,
					sizeof (char *) * seg_max);
			    nxt = (int *) realloc (nxt,
					sizeof (int) * seg_max);
			    dvt = (char *) realloc (dvt,
					sizeof (char) * seg_max);
			}
/*
if(ttt)
printf("eat (%d,%d): i=%d m=%d\n",((int)p-(int)pcb)%xmax,((int)p-(int)pcb)/xmax,i,m);
*/
			nxt[i] = ((4 + j) & 7) + (m << 3);
			dead_lst[i++] = p;
		    }
		}
	}
    }

    if (i <= m)
	err ("adj_sort: loss of connectivity", i, m,
	    ((int) s - (int) pcb) % xmax, ((int) s - (int) pcb) / xmax);

    dvt[0] = (j + 4) & 7;		/* get direction vectors	 */
    for (i = 1; m; m = nxt[m] >> 3) {
	*dead_lst[m] |= mrkb;		/* mark trace to avoid delete	 */
	dvt[i++] = nxt[m] & 7;
    }
    n = --i;				/* number of points in new trace */

    for (j = 0, k = 0, l = ~plow_s, i = ~mrkb; j < n; j++) {
	p = seg_lst[j];			/* remove unreached points	 */ 

	if (*p & ~i)			/* point in use			 */
	    continue;

	h = 0;				/* check connectivity		 */
	if (*(p        + 1) & ~l) h |= 0x01;
	if (*(p + xmax + 1) & ~l) h |= 0x02;
	if (*(p + xmax    ) & ~l) h |= 0x04;
	if (*(p + xmax - 1) & ~l) h |= 0x08;
	if (*(p        - 1) & ~l) h |= 0x10;
	if (*(p - xmax - 1) & ~l) h |= 0x20;
	if (*(p - xmax    ) & ~l) h |= 0x40;
	if (*(p - xmax + 1) & ~l) h |= 0x80;

	if (*p & ahb) {
	    if (*(p - 1) & ahb && *(p + 1) & ahb &&
		*(p + xmax) & ahb && *(p - xmax) & ahb)
		continue;		/* skip holes			 */
	    if (uc_tab[h]) {
		*p &= ~add;		/* delete point			 */
		*p |= selb;}
	    else
		seg_lst[k++] = p;}
	else {
	    if (uc_tab[h])
		*p &= ~add;		/* delete point			 */
	    else
		seg_lst[k++] = p;
	}
    }

    for (i = k + 1; k && k < i;)	/* make sure that all are gone	 */
	for (j = 0, i = k, k = 0; j < i; j++) {
	    p = seg_lst[j];
	    h = 0;			/* check connectivity		 */
	    if (*(p        + 1) & ~l) h |= 0x01;
	    if (*(p + xmax + 1) & ~l) h |= 0x02;
	    if (*(p + xmax    ) & ~l) h |= 0x04;
	    if (*(p + xmax - 1) & ~l) h |= 0x08;
	    if (*(p        - 1) & ~l) h |= 0x10;
	    if (*(p - xmax - 1) & ~l) h |= 0x20;
	    if (*(p - xmax    ) & ~l) h |= 0x40;
	    if (*(p - xmax + 1) & ~l) h |= 0x80;

	    if (uc_tab[h]) {		/* delete point			 */
		if (*p & ahb) {
		    *p &= ~add;
		    *p |= selb;}
	        else
	    	    *p &= ~add;}
	    else
	    	seg_lst[k++] = p;
	}

    for (p = dst, j = n, i = 0, k = mrkb; i < j; i++)
	*(p += pdr[dvt[i]]) &= ~k;	/* remove mark bits	 */

    return n;
}

char *straight (x, y, s)
    int x, y, s;
/******************************************************************\
* 								   *
*  Try to remove unnecessary turn from a wire segment on side <s>  *
*  that is identified by <x,y>					   *
* 								   *
\******************************************************************/
{
    struct nlhd *net, *get_net ();
    register int i, j, k, c1, c2;
    char *t, *R_straight ();

    if (!(pcb[y][x] & s))		/* no trace found 	 */
	return 0;

    net = get_net (x, y, s);		/* find and selevt the net */

    if (!net)
	err ("straight: unconnected object via wtrace from pin?", x, y, s, 0);

    if (V.cnet != net) {
	if (V.cnet)
	    deseln (V.cnet);
	selnet (net);
    }

					/* find the segment	 */
    if (!fnd_seg (x, y, s) || seg_cnt <= 4)
	return 0;			/* not worth the efford	 */

    i = abs (x - ((int) first - (int) pcb) % xmax) +
	abs (y - ((int) first - (int) pcb) / xmax);
    j = abs (x - ((int) last - (int) pcb) % xmax) +
	abs (y - ((int) last - (int) pcb) / xmax);
    if (j > i) {		/* make sure that fisrt is first */
	t = first;
	first = last;
	last = t;
    }

    if (!batch)
	un_display (x, y);

    if (st_reroute)
	return R_straight ();

    dvt = (char *) malloc (sizeof (char) * seg_max);

    seg_cnt = adj_sort (first, last, seg_cnt);

    for (i = 0, c1 = 0, k = seg_cnt; i < k; i++)
	c1 += (dvt[i] & 1) + 2;		/* hv: 2  diag: 3 units	 */

    do {				/* s-loop		 */
	c2 = c1;

	s_move (last);

	if (j++ & 1) {			/* randomly sequence	 */
	    seg_cnt = adj_sort (last, first, seg_cnt);
	    s_move (first);}
	else {
	    seg_cnt = adj_sort (first, last, seg_cnt);
	    s_move (last);
	}

	seg_cnt = adj_sort (last, first, seg_cnt);
	s_move (first);

	seg_cnt = adj_sort (first, last, seg_cnt);

	for (i = 0, c1 = 0, k = seg_cnt; i < k; i++)
	    c1 += (dvt[i] & 1) + 2;	/* hv: 2  diag: 3 units	 */

    } while (c2 > c1);

    t = 0;
    if (seg_cnt > 3)
	t = last + (pdr[dvt[0]] + pdr[dvt[1]]);

    free (dvt);
    if (!batch)
	re_display ();

    return t;
}

char *R_straight ()
/*******************************************************************\
* 								    *
*   R_straight is a sub-function of 'straight': it removes the old  *
*   wire and uses the router to re-insert it.			    *
* 								    *
\*******************************************************************/
{
    register int i, j, x, y;
    int xl, yl, xh, yh;
    register char *p;

    xl = ((int) first - (int) pcb) % xmax;	/* consider start */
    yl = ((int) first - (int) pcb) / xmax;
    xh = ((int) last - (int) pcb) % xmax;	/* ... and end	 */
    yh = ((int) last - (int) pcb) / xmax;

    if (xl > xh) {i = xl; xl = xh; xh = i;}
    if (yl > yh) {i = yl; yl = yh; yh = i;}

    for (i = 0, j = (plow_s & s1b) ? selb | s1b : selb | s2b | resb;
							i < seg_cnt; i++) {
	p = seg_lst[i];

	x = (int) p - (int) pcb;	/* get maze-size	 */
	y = x / xmax;
	x = x % xmax;
	if (x < xl) xl = x;
	if (y < yl) yl = y;
	if (x > xh) xh = x;
	if (y > yh) yh = y;

	if (*p & ahb) {			/* erase point		 */
	    *p &= ~j;
	    *p |= selb;}
	else
	    *p &= ~j;
    }

    i = batch;
    batch = 1;
    RE_route (first, last, xl - 2, yl - 2, xh + 2, yh + 2, plow_s);
    batch = i;

    re_display ();

    return 0;				/*** need to find a ptr!!  ***/
}

s_move (st)
    char *st;
/*******************************************************\
* 						        *
*  Scan a trace and move points if there appears to be  *
*  a better place for them.			        *
* 						        *
\*******************************************************/
{
    static char tab4[6561] ={
/********************************************************************\
* 								     *
*  Tab4 is indexed by the 5x5 configration as suplied by eval_s5:    *
*    MSB ----==== LSB						     *
*        ....0ddd     -> move center point in direction <ddd> (0-7)  *
*        ....1000     -> no move (do not change configuration)	     *
*        ....1001     -> remove center point			     *
*        ....else     -> not used				     *
* 								     *
*  All other values are currently unused (the 4 MSBs are reserved    *
*  for an other table)						     *
* 								     *
\********************************************************************/
	  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
	  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  2,  9,  2,  8,
	  2,  9,  2,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  8,  9,
	  8,  8,  8,  9,  8,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
	  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
	  9,  9,  8,  9,  2,  8,  2,  9,  8,  9,  9,  9,  9,  9,  9,  9,
	  9,  9,  9,  9,  8,  9,  8,  8,  8,  9,  8,  9,  9,  8,  9,  8,
	  8,  8,  9,  8,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  8,
	  9,  8,  8,  8,  9,  8,  9,  9,  8,  9,  2,  8,  2,  9,  8,  9,
	  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  8,  9,  8,  8,  8,  9,
	  8,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
	  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  2,  9,
	  2,  8,  2,  9,  2,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
	  8,  9,  8,  8,  8,  9,  8,  9,  9,  9,  9,  9,  9,  9,  9,  9,
	  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
	  9,  9,  9,  9,  6,  9,  8,  8,  8,  9,  6,  9,  4,  8,  4,  8,
	  8,  8,  4,  8,  4,  9,  6,  9,  8,  8,  8,  9,  6,  9,  4,  8,
	  4,  8,  8,  8,  4,  8,  4,  8,  8,  8,  8,  8,  8,  8,  8,  8,
	  4,  8,  4,  8,  8,  8,  4,  8,  4,  9,  6,  9,  8,  8,  8,  9,
	  6,  9,  4,  8,  4,  8,  8,  8,  4,  8,  4,  9,  6,  9,  8,  8,
	  8,  9,  6,  9,  9,  8,  9,  8,  8,  8,  9,  8,  9,  9,  9,  9,
	  9,  9,  9,  9,  9,  9,  9,  8,  9,  8,  8,  8,  9,  8,  9,  9,
	  8,  9,  8,  8,  8,  9,  8,  9,  9,  9,  9,  9,  9,  9,  9,  9,
	  9,  9,  8,  9,  8,  8,  8,  9,  8,  9,  9,  8,  9,  8,  8,  8,
	  9,  8,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  8,  9,  8,
	  8,  8,  9,  8,  9,  9,  6,  9,  8,  8,  8,  9,  6,  9,  8,  8,
	  8,  8,  8,  8,  8,  8,  8,  9,  6,  9,  8,  8,  8,  9,  6,  9,
	  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,
	  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  9,  6,  9,  8,  8,
	  8,  9,  6,  9,  8,  8,  8,  8,  8,  8,  8,  8,  8,  9,  6,  9,
	  8,  8,  8,  9,  6,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
	  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
	  9,  9,  2,  9,  2,  8,  2,  9,  2,  9,  9,  9,  9,  9,  9,  9,
	  9,  9,  9,  9,  8,  9,  8,  8,  8,  9,  8,  9,  9,  9,  9,  9,
	  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
	  9,  9,  9,  9,  9,  9,  9,  9,  8,  9,  2,  8,  2,  9,  8,  9,
	  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  8,  9,  8,  8,  8,  9,
	  8,  9,  9,  8,  9,  8,  8,  8,  9,  8,  9,  9,  9,  9,  9,  9,
	  9,  9,  9,  9,  9,  8,  9,  8,  8,  8,  9,  8,  9,  9,  8,  9,
	  2,  8,  2,  9,  8,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
	  8,  9,  8,  8,  8,  9,  8,  9,  9,  9,  9,  9,  9,  9,  9,  9,
	  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
	  9,  9,  9,  9,  2,  9,  2,  8,  2,  9,  2,  9,  9,  9,  9,  9,
	  9,  9,  9,  9,  9,  9,  8,  9,  8,  8,  8,  9,  8,  9,  9,  9,
	  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
	  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  0,  9,  8,  9,
	  9,  9,  8,  9,  8,  8,  9,  8,  8,  9,  8,  9,  9,  9,  0,  9,
	  8,  9,  9,  9,  4,  8,  4,  8,  8,  8,  4,  8,  4,  8,  9,  8,
	  8,  9,  8,  8,  9,  8,  4,  8,  4,  8,  8,  8,  4,  8,  4,  9,
	  9,  9,  0,  9,  8,  9,  9,  9,  8,  9,  8,  8,  9,  8,  8,  9,
	  8,  9,  9,  9,  0,  9,  8,  9,  9,  9,  9,  9,  9,  8,  9,  8,
	  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  8,
	  9,  8,  9,  9,  9,  9,  9,  9,  8,  9,  8,  9,  9,  9,  9,  9,
	  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  8,  9,  8,  9,  9,  9,
	  9,  9,  9,  8,  9,  8,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
	  9,  9,  9,  9,  9,  8,  9,  8,  9,  9,  9,  9,  9,  9,  0,  9,
	  8,  9,  9,  9,  8,  9,  8,  8,  9,  8,  8,  9,  8,  9,  9,  9,
	  0,  9,  8,  9,  9,  9,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,
	  9,  8,  8,  9,  8,  8,  9,  8,  8,  8,  8,  8,  8,  8,  8,  8,
	  8,  9,  9,  9,  0,  9,  8,  9,  9,  9,  8,  9,  8,  8,  9,  8,
	  8,  9,  8,  9,  9,  9,  0,  9,  8,  9,  9,  9,  9,  9,  9,  8,
	  9,  8,  9,  9,  9,  8,  9,  8,  8,  9,  8,  8,  9,  8,  9,  9,
	  9,  8,  9,  8,  9,  9,  9,  8,  8,  8,  8,  8,  8,  8,  8,  8,
	  8,  9,  8,  8,  9,  8,  8,  9,  8,  8,  8,  8,  8,  8,  8,  8,
	  8,  8,  9,  9,  9,  8,  9,  8,  9,  9,  9,  8,  9,  8,  8,  9,
	  8,  8,  9,  8,  9,  9,  9,  8,  9,  8,  9,  9,  9,  9,  9,  9,
	  8,  9,  8,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
	  9,  9,  8,  9,  8,  9,  9,  9,  9,  9,  9,  8,  9,  8,  9,  9,
	  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  8,  9,  8,
	  9,  9,  9,  9,  9,  9,  8,  9,  8,  9,  9,  9,  9,  9,  9,  9,
	  9,  9,  9,  9,  9,  9,  9,  9,  8,  9,  8,  9,  9,  9,  9,  9,
	  9,  8,  9,  8,  9,  9,  9,  8,  9,  8,  8,  9,  8,  8,  9,  8,
	  9,  9,  9,  8,  9,  8,  9,  9,  9,  8,  8,  8,  8,  8,  8,  8,
	  8,  8,  8,  9,  8,  8,  9,  8,  8,  9,  8,  8,  8,  8,  8,  8,
	  8,  8,  8,  8,  9,  9,  9,  8,  9,  8,  9,  9,  9,  8,  9,  8,
	  8,  9,  8,  8,  9,  8,  9,  9,  9,  8,  9,  8,  9,  9,  9,  9,
	  9,  9,  0,  9,  8,  9,  9,  9,  8,  9,  8,  8,  9,  8,  8,  9,
	  8,  9,  9,  9,  0,  9,  8,  9,  9,  9,  4,  8,  4,  8,  8,  8,
	  4,  8,  4,  8,  9,  8,  8,  9,  8,  8,  9,  8,  4,  8,  4,  8,
	  8,  8,  4,  8,  4,  9,  9,  9,  0,  9,  8,  9,  9,  9,  8,  9,
	  8,  8,  9,  8,  8,  9,  8,  9,  9,  9,  0,  9,  8,  9,  9,  9,
	  9,  9,  9,  8,  9,  8,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
	  9,  9,  9,  9,  9,  8,  9,  8,  9,  9,  9,  9,  9,  9,  8,  9,
	  8,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
	  8,  9,  8,  9,  9,  9,  9,  9,  9,  8,  9,  8,  9,  9,  9,  9,
	  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  8,  9,  8,  9,  9,
	  9,  9,  9,  9,  0,  9,  8,  9,  9,  9,  8,  9,  8,  8,  9,  8,
	  8,  9,  8,  9,  9,  9,  0,  9,  8,  9,  9,  9,  8,  8,  8,  8,
	  8,  8,  8,  8,  8,  8,  9,  8,  8,  9,  8,  8,  9,  8,  8,  8,
	  8,  8,  8,  8,  8,  8,  8,  9,  9,  9,  0,  9,  8,  9,  9,  9,
	  8,  9,  8,  8,  9,  8,  8,  9,  8,  9,  9,  9,  0,  9,  8,  9,
	  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
	  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  2,  9,
	  2,  8,  2,  9,  2,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
	  8,  9,  8,  8,  8,  9,  8,  9,  9,  9,  9,  9,  9,  9,  9,  9,
	  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
	  9,  9,  9,  9,  8,  9,  2,  8,  2,  9,  8,  9,  9,  9,  9,  9,
	  9,  9,  9,  9,  9,  9,  8,  9,  8,  8,  8,  9,  8,  9,  9,  8,
	  9,  8,  8,  8,  9,  8,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
	  9,  8,  9,  8,  8,  8,  9,  8,  9,  9,  8,  9,  2,  8,  2,  9,
	  8,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  8,  9,  8,  8,
	  8,  9,  8,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
	  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
	  2,  9,  2,  8,  2,  9,  2,  9,  9,  9,  9,  9,  9,  9,  9,  9,
	  9,  9,  8,  9,  8,  8,  8,  9,  8,  9,  9,  9,  9,  9,  9,  9,
	  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
	  9,  9,  9,  9,  9,  9,  8,  9,  8,  8,  8,  9,  8,  9,  4,  8,
	  4,  8,  8,  8,  4,  8,  4,  9,  8,  9,  8,  8,  8,  9,  8,  9,
	  4,  8,  4,  8,  8,  8,  4,  8,  4,  8,  8,  8,  8,  8,  8,  8,
	  8,  8,  4,  8,  4,  8,  8,  8,  4,  8,  4,  9,  8,  9,  8,  8,
	  8,  9,  8,  9,  4,  8,  4,  8,  8,  8,  4,  8,  4,  9,  8,  9,
	  8,  8,  8,  9,  8,  9,  9,  8,  9,  8,  8,  8,  9,  8,  9,  9,
	  9,  9,  9,  9,  9,  9,  9,  9,  9,  8,  9,  8,  8,  8,  9,  8,
	  9,  9,  8,  9,  8,  8,  8,  9,  8,  9,  9,  9,  9,  9,  9,  9,
	  9,  9,  9,  9,  8,  9,  8,  8,  8,  9,  8,  9,  9,  8,  9,  8,
	  8,  8,  9,  8,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  8,
	  9,  8,  8,  8,  9,  8,  9,  9,  8,  9,  8,  8,  8,  9,  8,  9,
	  8,  8,  8,  8,  8,  8,  8,  8,  8,  9,  8,  9,  8,  8,  8,  9,
	  8,  9,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,
	  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  9,  8,  9,
	  8,  8,  8,  9,  8,  9,  8,  8,  8,  8,  8,  8,  8,  8,  8,  9,
	  8,  9,  8,  8,  8,  9,  8,  9,  9,  9,  9,  9,  9,  9,  9,  9,
	  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
	  9,  9,  9,  9,  2,  9,  2,  8,  2,  9,  2,  9,  9,  9,  9,  9,
	  9,  9,  9,  9,  9,  9,  8,  9,  8,  8,  8,  9,  8,  9,  9,  9,
	  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
	  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  8,  9,  2,  8,  2,  9,
	  8,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  8,  9,  8,  8,
	  8,  9,  8,  9,  9,  8,  9,  8,  8,  8,  9,  8,  9,  9,  9,  9,
	  9,  9,  9,  9,  9,  9,  9,  8,  9,  8,  8,  8,  9,  8,  9,  9,
	  8,  9,  2,  8,  2,  9,  8,  9,  9,  9,  9,  9,  9,  9,  9,  9,
	  9,  9,  8,  9,  8,  8,  8,  9,  8,  9,  9,  9,  9,  9,  9,  9,
	  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
	  9,  9,  9,  9,  9,  9,  2,  9,  2,  8,  2,  9,  2,  9,  9,  9,
	  9,  9,  9,  9,  9,  9,  9,  9,  8,  9,  8,  8,  8,  9,  8,  9,
	  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
	  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  0,  9,
	  8,  9,  9,  9,  0,  9,  8,  8,  9,  8,  0,  9,  8,  9,  9,  9,
	  0,  9,  8,  9,  9,  9,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,
	  9,  8,  8,  9,  8,  8,  9,  8,  8,  8,  8,  8,  8,  8,  8,  8,
	  8,  9,  9,  9,  0,  9,  8,  9,  9,  9,  0,  9,  8,  8,  9,  8,
	  0,  9,  8,  9,  9,  9,  0,  9,  8,  9,  9,  9,  6,  8,  6,  8,
	  8,  8,  6,  8,  6,  8,  9,  8,  8,  9,  8,  8,  9,  8,  6,  8,
	  6,  8,  8,  8,  6,  8,  6,  8,  8,  8,  8,  8,  8,  8,  8,  8,
	  8,  9,  8,  8,  9,  8,  8,  9,  8,  8,  8,  8,  8,  8,  8,  8,
	  8,  8,  6,  8,  6,  8,  8,  8,  6,  8,  6,  8,  9,  8,  8,  9,
	  8,  8,  9,  8,  6,  8,  6,  8,  8,  8,  6,  8,  6,  9,  9,  9,
	  0,  9,  8,  9,  9,  9,  0,  9,  8,  8,  9,  8,  0,  9,  8,  9,
	  9,  9,  0,  9,  8,  9,  9,  9,  8,  8,  8,  8,  8,  8,  8,  8,
	  8,  8,  9,  8,  8,  9,  8,  8,  9,  8,  8,  8,  8,  8,  8,  8,
	  8,  8,  8,  9,  9,  9,  0,  9,  8,  9,  9,  9,  0,  9,  8,  8,
	  9,  8,  0,  9,  8,  9,  9,  9,  0,  9,  8,  9,  9,  9,  6,  8,
	  6,  8,  8,  8,  6,  8,  6,  8,  8,  8,  8,  8,  8,  8,  8,  8,
	  6,  8,  6,  8,  8,  8,  6,  8,  6,  8,  8,  8,  8,  8,  8,  8,
	  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,
	  8,  8,  8,  8,  6,  8,  6,  8,  8,  8,  6,  8,  6,  8,  8,  8,
	  8,  8,  8,  8,  8,  8,  6,  8,  6,  8,  8,  8,  6,  8,  6,  8,
	  8,  8,  8,  8,  8,  8,  8,  8,  8,  9,  8,  8,  9,  8,  8,  9,
	  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,
	  8,  8,  8,  8,  9,  8,  8,  9,  8,  8,  9,  8,  8,  8,  8,  8,
	  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  9,
	  8,  8,  9,  8,  8,  9,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,
	  6,  8,  6,  8,  8,  8,  6,  8,  6,  8,  8,  8,  8,  8,  8,  8,
	  8,  8,  6,  8,  6,  8,  8,  8,  6,  8,  6,  8,  8,  8,  8,  8,
	  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,
	  8,  8,  8,  8,  8,  8,  6,  8,  6,  8,  8,  8,  6,  8,  6,  8,
	  8,  8,  8,  8,  8,  8,  8,  8,  6,  8,  6,  8,  8,  8,  6,  8,
	  6,  9,  9,  9,  0,  9,  8,  9,  9,  9,  0,  9,  8,  8,  9,  8,
	  0,  9,  8,  9,  9,  9,  0,  9,  8,  9,  9,  9,  8,  8,  8,  8,
	  8,  8,  8,  8,  8,  8,  9,  8,  8,  9,  8,  8,  9,  8,  8,  8,
	  8,  8,  8,  8,  8,  8,  8,  9,  9,  9,  0,  9,  8,  9,  9,  9,
	  0,  9,  8,  8,  9,  8,  0,  9,  8,  9,  9,  9,  0,  9,  8,  9,
	  9,  9,  6,  8,  6,  8,  8,  8,  6,  8,  6,  8,  9,  8,  8,  9,
	  8,  8,  9,  8,  6,  8,  6,  8,  8,  8,  6,  8,  6,  8,  8,  8,
	  8,  8,  8,  8,  8,  8,  8,  9,  8,  8,  9,  8,  8,  9,  8,  8,
	  8,  8,  8,  8,  8,  8,  8,  8,  6,  8,  6,  8,  8,  8,  6,  8,
	  6,  8,  9,  8,  8,  9,  8,  8,  9,  8,  6,  8,  6,  8,  8,  8,
	  6,  8,  6,  9,  9,  9,  0,  9,  8,  9,  9,  9,  0,  9,  8,  8,
	  9,  8,  0,  9,  8,  9,  9,  9,  0,  9,  8,  9,  9,  9,  8,  8,
	  8,  8,  8,  8,  8,  8,  8,  8,  9,  8,  8,  9,  8,  8,  9,  8,
	  8,  8,  8,  8,  8,  8,  8,  8,  8,  9,  9,  9,  0,  9,  8,  9,
	  9,  9,  0,  9,  8,  8,  9,  8,  0,  9,  8,  9,  9,  9,  0,  9,
	  8,  9,  9,  9,  9,  9,  9,  8,  9,  8,  9,  9,  9,  8,  9,  8,
	  8,  9,  8,  8,  9,  8,  9,  9,  9,  8,  9,  8,  9,  9,  9,  8,
	  8,  8,  8,  8,  8,  8,  8,  8,  8,  9,  8,  8,  9,  8,  8,  9,
	  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  9,  9,  9,  8,  9,  8,
	  9,  9,  9,  8,  9,  8,  8,  9,  8,  8,  9,  8,  9,  9,  9,  8,
	  9,  8,  9,  9,  9,  9,  9,  9,  8,  9,  8,  9,  9,  9,  9,  9,
	  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  8,  9,  8,  9,  9,  9,
	  9,  9,  9,  8,  9,  8,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
	  9,  9,  9,  9,  9,  8,  9,  8,  9,  9,  9,  9,  9,  9,  8,  9,
	  8,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
	  8,  9,  8,  9,  9,  9,  9,  9,  9,  8,  9,  8,  9,  9,  9,  8,
	  9,  8,  8,  9,  8,  8,  9,  8,  9,  9,  9,  8,  9,  8,  9,  9,
	  9,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  9,  8,  8,  9,  8,
	  8,  9,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  9,  9,  9,  8,
	  9,  8,  9,  9,  9,  8,  9,  8,  8,  9,  8,  8,  9,  8,  9,  9,
	  9,  8,  9,  8,  9,  9,  9,  9,  9,  9,  8,  9,  8,  9,  9,  9,
	  8,  9,  8,  8,  9,  8,  8,  9,  8,  9,  9,  9,  8,  9,  8,  9,
	  9,  9,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  9,  8,  8,  9,
	  8,  8,  9,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  9,  9,  9,
	  8,  9,  8,  9,  9,  9,  8,  9,  8,  8,  9,  8,  8,  9,  8,  9,
	  9,  9,  8,  9,  8,  9,  9,  9,  9,  9,  9,  8,  9,  8,  9,  9,
	  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  8,  9,  8,
	  9,  9,  9,  9,  9,  9,  8,  9,  8,  9,  9,  9,  9,  9,  9,  9,
	  9,  9,  9,  9,  9,  9,  9,  9,  8,  9,  8,  9,  9,  9,  9,  9,
	  9,  8,  9,  8,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
	  9,  9,  9,  8,  9,  8,  9,  9,  9,  9,  9,  9,  8,  9,  8,  9,
	  9,  9,  8,  9,  8,  8,  9,  8,  8,  9,  8,  9,  9,  9,  8,  9,
	  8,  9,  9,  9,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  9,  8,
	  8,  9,  8,  8,  9,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  9,
	  9,  9,  8,  9,  8,  9,  9,  9,  8,  9,  8,  8,  9,  8,  8,  9,
	  8,  9,  9,  9,  8,  9,  8,  9,  9,  9,  9,  9,  9,  8,  9,  8,
	  9,  9,  9,  8,  9,  8,  8,  9,  8,  8,  9,  8,  9,  9,  9,  8,
	  9,  8,  9,  9,  9,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  9,
	  8,  8,  9,  8,  8,  9,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,
	  9,  9,  9,  8,  9,  8,  9,  9,  9,  8,  9,  8,  8,  9,  8,  8,
	  9,  8,  9,  9,  9,  8,  9,  8,  9,  9,  9,  9,  9,  9,  8,  9,
	  8,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
	  8,  9,  8,  9,  9,  9,  9,  9,  9,  8,  9,  8,  9,  9,  9,  9,
	  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  8,  9,  8,  9,  9,
	  9,  9,  9,  9,  8,  9,  8,  9,  9,  9,  9,  9,  9,  9,  9,  9,
	  9,  9,  9,  9,  9,  9,  8,  9,  8,  9,  9,  9,  9,  9,  9,  8,
	  9,  8,  9,  9,  9,  8,  9,  8,  8,  9,  8,  8,  9,  8,  9,  9,
	  9,  8,  9,  8,  9,  9,  9,  8,  8,  8,  8,  8,  8,  8,  8,  8,
	  8,  9,  8,  8,  9,  8,  8,  9,  8,  8,  8,  8,  8,  8,  8,  8,
	  8,  8,  9,  9,  9,  8,  9,  8,  9,  9,  9,  8,  9,  8,  8,  9,
	  8,  8,  9,  8,  9,  9,  9,  8,  9,  8,  9,  9,  9,  9,  9,  9,
	  0,  9,  8,  9,  9,  9,  0,  9,  8,  8,  9,  8,  0,  9,  8,  9,
	  9,  9,  0,  9,  8,  9,  9,  9,  8,  8,  8,  8,  8,  8,  8,  8,
	  8,  8,  9,  8,  8,  9,  8,  8,  9,  8,  8,  8,  8,  8,  8,  8,
	  8,  8,  8,  9,  9,  9,  0,  9,  8,  9,  9,  9,  0,  9,  8,  8,
	  9,  8,  0,  9,  8,  9,  9,  9,  0,  9,  8,  9,  9,  9,  8,  8,
	  8,  8,  8,  8,  8,  8,  8,  8,  9,  8,  8,  9,  8,  8,  9,  8,
	  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,
	  8,  8,  8,  9,  8,  8,  9,  8,  8,  9,  8,  8,  8,  8,  8,  8,
	  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  9,  8,
	  8,  9,  8,  8,  9,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  9,
	  9,  9,  0,  9,  8,  9,  9,  9,  0,  9,  8,  8,  9,  8,  0,  9,
	  8,  9,  9,  9,  0,  9,  8,  9,  9,  9,  8,  8,  8,  8,  8,  8,
	  8,  8,  8,  8,  9,  8,  8,  9,  8,  8,  9,  8,  8,  8,  8,  8,
	  8,  8,  8,  8,  8,  9,  9,  9,  0,  9,  8,  9,  9,  9,  0,  9,
	  8,  8,  9,  8,  0,  9,  8,  9,  9,  9,  0,  9,  8,  9,  9,  9,
	  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,
	  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,
	  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,
	  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,
	  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,
	  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  9,  8,  8,  9,  8,
	  8,  9,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,
	  8,  8,  8,  8,  8,  8,  9,  8,  8,  9,  8,  8,  9,  8,  8,  8,
	  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,
	  8,  9,  8,  8,  9,  8,  8,  9,  8,  8,  8,  8,  8,  8,  8,  8,
	  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,
	  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,
	  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,
	  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,
	  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,
	  8,  8,  8,  9,  9,  9,  0,  9,  8,  9,  9,  9,  0,  9,  8,  8,
	  9,  8,  0,  9,  8,  9,  9,  9,  0,  9,  8,  9,  9,  9,  8,  8,
	  8,  8,  8,  8,  8,  8,  8,  8,  9,  8,  8,  9,  8,  8,  9,  8,
	  8,  8,  8,  8,  8,  8,  8,  8,  8,  9,  9,  9,  0,  9,  8,  9,
	  9,  9,  0,  9,  8,  8,  9,  8,  0,  9,  8,  9,  9,  9,  0,  9,
	  8,  9,  9,  9,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  9,  8,
	  8,  9,  8,  8,  9,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,
	  8,  8,  8,  8,  8,  8,  8,  8,  8,  9,  8,  8,  9,  8,  8,  9,
	  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,
	  8,  8,  8,  8,  9,  8,  8,  9,  8,  8,  9,  8,  8,  8,  8,  8,
	  8,  8,  8,  8,  8,  9,  9,  9,  0,  9,  8,  9,  9,  9,  0,  9,
	  8,  8,  9,  8,  0,  9,  8,  9,  9,  9,  0,  9,  8,  9,  9,  9,
	  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  9,  8,  8,  9,  8,  8,
	  9,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  9,  9,  9,  0,  9,
	  8,  9,  9,  9,  0,  9,  8,  8,  9,  8,  0,  9,  8,  9,  9,  9,
	  0,  9,  8,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
	  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
	  9,  9,  2,  9,  2,  8,  2,  9,  2,  9,  9,  9,  9,  9,  9,  9,
	  9,  9,  9,  9,  8,  9,  8,  8,  8,  9,  8,  9,  9,  9,  9,  9,
	  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
	  9,  9,  9,  9,  9,  9,  9,  9,  8,  9,  2,  8,  2,  9,  8,  9,
	  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  8,  9,  8,  8,  8,  9,
	  8,  9,  9,  8,  9,  8,  8,  8,  9,  8,  9,  9,  9,  9,  9,  9,
	  9,  9,  9,  9,  9,  8,  9,  8,  8,  8,  9,  8,  9,  9,  8,  9,
	  2,  8,  2,  9,  8,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
	  8,  9,  8,  8,  8,  9,  8,  9,  9,  9,  9,  9,  9,  9,  9,  9,
	  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
	  9,  9,  9,  9,  2,  9,  2,  8,  2,  9,  2,  9,  9,  9,  9,  9,
	  9,  9,  9,  9,  9,  9,  8,  9,  8,  8,  8,  9,  8,  9,  9,  9,
	  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
	  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  6,  9,  8,  8,  8,  9,
	  6,  9,  4,  8,  4,  8,  8,  8,  4,  8,  4,  9,  6,  9,  8,  8,
	  8,  9,  6,  9,  4,  8,  4,  8,  8,  8,  4,  8,  4,  8,  8,  8,
	  8,  8,  8,  8,  8,  8,  4,  8,  4,  8,  8,  8,  4,  8,  4,  9,
	  6,  9,  8,  8,  8,  9,  6,  9,  4,  8,  4,  8,  8,  8,  4,  8,
	  4,  9,  6,  9,  8,  8,  8,  9,  6,  9,  9,  8,  9,  8,  8,  8,
	  9,  8,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  8,  9,  8,
	  8,  8,  9,  8,  9,  9,  8,  9,  8,  8,  8,  9,  8,  9,  9,  9,
	  9,  9,  9,  9,  9,  9,  9,  9,  8,  9,  8,  8,  8,  9,  8,  9,
	  9,  8,  9,  8,  8,  8,  9,  8,  9,  9,  9,  9,  9,  9,  9,  9,
	  9,  9,  9,  8,  9,  8,  8,  8,  9,  8,  9,  9,  6,  9,  8,  8,
	  8,  9,  6,  9,  8,  8,  8,  8,  8,  8,  8,  8,  8,  9,  6,  9,
	  8,  8,  8,  9,  6,  9,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,
	  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,
	  8,  9,  6,  9,  8,  8,  8,  9,  6,  9,  8,  8,  8,  8,  8,  8,
	  8,  8,  8,  9,  6,  9,  8,  8,  8,  9,  6,  9,  9,  9,  9,  9,
	  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
	  9,  9,  9,  9,  9,  9,  9,  9,  2,  9,  2,  8,  2,  9,  2,  9,
	  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  8,  9,  8,  8,  8,  9,
	  8,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
	  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  8,  9,
	  2,  8,  2,  9,  8,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
	  8,  9,  8,  8,  8,  9,  8,  9,  9,  8,  9,  8,  8,  8,  9,  8,
	  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  8,  9,  8,  8,  8,
	  9,  8,  9,  9,  8,  9,  2,  8,  2,  9,  8,  9,  9,  9,  9,  9,
	  9,  9,  9,  9,  9,  9,  8,  9,  8,  8,  8,  9,  8,  9,  9,  9,
	  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
	  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  2,  9,  2,  8,  2,  9,
	  2,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  8,  9,  8,  8,
	  8,  9,  8,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
	  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
	  9,  9,  0,  9,  8,  9,  9,  9,  8,  9,  8,  8,  9,  8,  8,  9,
	  8,  9,  9,  9,  0,  9,  8,  9,  9,  9,  4,  8,  4,  8,  8,  8,
	  4,  8,  4,  8,  9,  8,  8,  9,  8,  8,  9,  8,  4,  8,  4,  8,
	  8,  8,  4,  8,  4,  9,  9,  9,  0,  9,  8,  9,  9,  9,  8,  9,
	  8,  8,  9,  8,  8,  9,  8,  9,  9,  9,  0,  9,  8,  9,  9,  9,
	  9,  9,  9,  8,  9,  8,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
	  9,  9,  9,  9,  9,  8,  9,  8,  9,  9,  9,  9,  9,  9,  8,  9,
	  8,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
	  8,  9,  8,  9,  9,  9,  9,  9,  9,  8,  9,  8,  9,  9,  9,  9,
	  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  8,  9,  8,  9,  9,
	  9,  9,  9,  9,  0,  9,  8,  9,  9,  9,  8,  9,  8,  8,  9,  8,
	  8,  9,  8,  9,  9,  9,  0,  9,  8,  9,  9,  9,  8,  8,  8,  8,
	  8,  8,  8,  8,  8,  8,  9,  8,  8,  9,  8,  8,  9,  8,  8,  8,
	  8,  8,  8,  8,  8,  8,  8,  9,  9,  9,  0,  9,  8,  9,  9,  9,
	  8,  9,  8,  8,  9,  8,  8,  9,  8,  9,  9,  9,  0,  9,  8,  9,
	  9,  9,  9,  9,  9,  8,  9,  8,  9,  9,  9,  8,  9,  8,  8,  9,
	  8,  8,  9,  8,  9,  9,  9,  8,  9,  8,  9,  9,  9,  8,  8,  8,
	  8,  8,  8,  8,  8,  8,  8,  9,  8,  8,  9,  8,  8,  9,  8,  8,
	  8,  8,  8,  8,  8,  8,  8,  8,  9,  9,  9,  8,  9,  8,  9,  9,
	  9,  8,  9,  8,  8,  9,  8,  8,  9,  8,  9,  9,  9,  8,  9,  8,
	  9,  9,  9,  9,  9,  9,  8,  9,  8,  9,  9,  9,  9,  9,  9,  9,
	  9,  9,  9,  9,  9,  9,  9,  9,  8,  9,  8,  9,  9,  9,  9,  9,
	  9,  8,  9,  8,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
	  9,  9,  9,  8,  9,  8,  9,  9,  9,  9,  9,  9,  8,  9,  8,  9,
	  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  8,  9,
	  8,  9,  9,  9,  9,  9,  9,  8,  9,  8,  9,  9,  9,  8,  9,  8,
	  8,  9,  8,  8,  9,  8,  9,  9,  9,  8,  9,  8,  9,  9,  9,  8,
	  8,  8,  8,  8,  8,  8,  8,  8,  8,  9,  8,  8,  9,  8,  8,  9,
	  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  9,  9,  9,  8,  9,  8,
	  9,  9,  9,  8,  9,  8,  8,  9,  8,  8,  9,  8,  9,  9,  9,  8,
	  9,  8,  9,  9,  9,  9,  9,  9,  0,  9,  8,  9,  9,  9,  8,  9,
	  8,  8,  9,  8,  8,  9,  8,  9,  9,  9,  0,  9,  8,  9,  9,  9,
	  4,  8,  4,  8,  8,  8,  4,  8,  4,  8,  9,  8,  8,  9,  8,  8,
	  9,  8,  4,  8,  4,  8,  8,  8,  4,  8,  4,  9,  9,  9,  0,  9,
	  8,  9,  9,  9,  8,  9,  8,  8,  9,  8,  8,  9,  8,  9,  9,  9,
	  0,  9,  8,  9,  9,  9,  9,  9,  9,  8,  9,  8,  9,  9,  9,  9,
	  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  8,  9,  8,  9,  9,
	  9,  9,  9,  9,  8,  9,  8,  9,  9,  9,  9,  9,  9,  9,  9,  9,
	  9,  9,  9,  9,  9,  9,  8,  9,  8,  9,  9,  9,  9,  9,  9,  8,
	  9,  8,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
	  9,  8,  9,  8,  9,  9,  9,  9,  9,  9,  0,  9,  8,  9,  9,  9,
	  8,  9,  8,  8,  9,  8,  8,  9,  8,  9,  9,  9,  0,  9,  8,  9,
	  9,  9,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  9,  8,  8,  9,
	  8,  8,  9,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  9,  9,  9,
	  0,  9,  8,  9,  9,  9,  8,  9,  8,  8,  9,  8,  8,  9,  8,  9,
	  9,  9,  0,  9,  8,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
	  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
	  9,  9,  9,  9,  2,  9,  2,  8,  2,  9,  2,  9,  9,  9,  9,  9,
	  9,  9,  9,  9,  9,  9,  8,  9,  8,  8,  8,  9,  8,  9,  9,  9,
	  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
	  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  8,  9,  2,  8,  2,  9,
	  8,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  8,  9,  8,  8,
	  8,  9,  8,  9,  9,  8,  9,  8,  8,  8,  9,  8,  9,  9,  9,  9,
	  9,  9,  9,  9,  9,  9,  9,  8,  9,  8,  8,  8,  9,  8,  9,  9,
	  8,  9,  2,  8,  2,  9,  8,  9,  9,  9,  9,  9,  9,  9,  9,  9,
	  9,  9,  8,  9,  8,  8,  8,  9,  8,  9,  9,  9,  9,  9,  9,  9,
	  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
	  9,  9,  9,  9,  9,  9,  2,  9,  2,  8,  2,  9,  2,  9,  9,  9,
	  9,  9,  9,  9,  9,  9,  9,  9,  8,  9,  8,  8,  8,  9,  8,  9,
	  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
	  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  8,  9,  8,  8,
	  8,  9,  8,  9,  4,  8,  4,  8,  8,  8,  4,  8,  4,  9,  8,  9,
	  8,  8,  8,  9,  8,  9,  4,  8,  4,  8,  8,  8,  4,  8,  4,  8,
	  8,  8,  8,  8,  8,  8,  8,  8,  4,  8,  4,  8,  8,  8,  4,  8,
	  4,  9,  8,  9,  8,  8,  8,  9,  8,  9,  4,  8,  4,  8,  8,  8,
	  4,  8,  4,  9,  8,  9,  8,  8,  8,  9,  8,  9,  9,  8,  9,  8,
	  8,  8,  9,  8,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  8,
	  9,  8,  8,  8,  9,  8,  9,  9,  8,  9,  8,  8,  8,  9,  8,  9,
	  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  8,  9,  8,  8,  8,  9,
	  8,  9,  9,  8,  9,  8,  8,  8,  9,  8,  9,  9,  9,  9,  9,  9,
	  9,  9,  9,  9,  9,  8,  9,  8,  8,  8,  9,  8,  9,  9,  8,  9,
	  8,  8,  8,  9,  8,  9,  8,  8,  8,  8,  8,  8,  8,  8,  8,  9,
	  8,  9,  8,  8,  8,  9,  8,  9,  8,  8,  8,  8,  8,  8,  8,  8,
	  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,
	  8,  8,  8,  9,  8,  9,  8,  8,  8,  9,  8,  9,  8,  8,  8,  8,
	  8,  8,  8,  8,  8,  9,  8,  9,  8,  8,  8,  9,  8,  9,  9,  9,
	  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
	  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  2,  9,  2,  8,  2,  9,
	  2,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  8,  9,  8,  8,
	  8,  9,  8,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
	  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
	  8,  9,  2,  8,  2,  9,  8,  9,  9,  9,  9,  9,  9,  9,  9,  9,
	  9,  9,  8,  9,  8,  8,  8,  9,  8,  9,  9,  8,  9,  8,  8,  8,
	  9,  8,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  8,  9,  8,
	  8,  8,  9,  8,  9,  9,  8,  9,  2,  8,  2,  9,  8,  9,  9,  9,
	  9,  9,  9,  9,  9,  9,  9,  9,  8,  9,  8,  8,  8,  9,  8,  9,
	  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
	  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  2,  9,  2,  8,
	  2,  9,  2,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  8,  9,
	  8,  8,  8,  9,  8,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
	  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
	  9 };

    static char tab5[64] = {		/* origin move translation */
		-1, 6, 7,-1,-1,-1, 1, 2,
		 2,-1, 0,-1,-1,-1,-1,-1,
		 3, 4,-1, 0, 1,-1,-1,-1,
		-1,-1, 4,-1, 2,-1,-1,-1,
		-1,-1, 5, 6,-1, 2, 3,-1,
		-1,-1,-1,-1, 6,-1, 4,-1,
		 5,-1,-1,-1, 7, 0,-1, 4,
		 6,-1,-1,-1,-1,-1, 0,-1 };

    register int i, j, k, lstm, add;
    register char *p;
/*
static int ttt=0;
*/
    lstm = 8;				/* last move			 */

    add = (plow_s & s1b) ? selb | s1b : selb | s2b | resb;

    for (p = st, i = 0, k = 0; i < seg_cnt; i++) {
	p += pdr[dvt[i]];
	j = tab4[eval_s5(p)];
/*
if(ttt){
 test(((int)p -(int)pcb)%xmax,((int)p -(int)pcb)/xmax);
printf("=====> j=%d\n",j);
getchar();}
*/
	if (!(j & 8)) {			/* filter 			 */
	    if (lstm & 8) {
		if (dvt[i] == dvt[i + 1]) j = 8;}
	    else {
		if (tab5[lstm + (dvt[i] << 3)] == dvt[i + 1]) j = 8;
	    }
	}
	lstm = j;

	if (j & 0x08) {			/* either delete or unchnged	 */
	    if (j & 1 &&		/* remove center point		 */
		!(*p & ahb && *(p - 1) & ahb && *(p + 1) & ahb &&
		*(p - xmax) & ahb && *(p + xmax) & ahb)) {
		*p &= ~add;
		if (*p & ahb)
		    *p |= selb;}
	    else
		seg_lst[k++] = p;	/* just keep it			 */
	} else {
	    *(seg_lst[k++] = p + pdr[j & 7]) |= add;
	    if (*p & ahb) {
		if (!(*p & ahb && *(p - 1) & ahb && *(p + 1) & ahb &&
		      *(p - xmax) & ahb && *(p + xmax) & ahb)) {
	            *p &= ~add;
		    *p |= selb;
		}}
	    else
		*p &= ~add;
	}
    }

}


static char **sa_s1, **sa_s2;		/* pointer to segments	 */
static int sa_s1c, sa_s2c;		/* counters		 */
static int sa_1max = 1000,		/* max size		 */
	   sa_2max = 1000;
static char **sal_s1, **sal_s2;		/* local pointer (in a net) */
static int sal_s1c, sal_s2c;		/* counter		 */
static int sal_1max = 100,		/* max size		 */
	   sal_2max = 100;

get_seg ()
/***********************************************************************\
* 								        *
*  Get segment pointer:						        *
*  For each net, the associated wires are scanned and a entry is made   *
*  for each segment (here: a piece of trace that runs on one side and   *
*  is terminated by holes, 'Y'-s or floating end). The 'straight' will  *
*  operate on these segments.					        *
* 								        *
\***********************************************************************/
{
    register int i;
    int gs_vf(), gs_hf();

    if (V.cnet)				/* no selection		 */
	deseln (V.cnet);

					/* allocate space	 */
    sa_s1 = (char **) malloc (sizeof (char *) * sa_1max);
    sa_s1c = 0;
    sa_s2 = (char **) malloc (sizeof (char *) * sa_2max);
    sa_s2c = 0;
    sal_s1 = (char **) malloc (sizeof (char *) * sal_1max);
    sal_s2 = (char **) malloc (sizeof (char *) * sal_2max);

    wthf = gs_hf;			/* prepare wtrace	 */
    wtvf = gs_vf;

    for (i = 0; i < V.nnh; i++)		/* scan all nets	 */
	gs_scan (&NH[i]);
}

gs_hf (x, y)				/* hole function	 */
    int x, y;
{
    register struct hole *hp;
    struct hole *fndh();

    if (pcb[y][x] & chb) {
	hp = fndh (x, y);
	hp -> n -> mk = 0;
    }

    return 0;
}

gs_vf (x1, y1, x2, y2)
    int x1, y1, x2, y2;
{
    register int dx, dy;

    dx = x2 - x1;
    dy = y2 - y1;
    if (dx && dy) {
	dx = (dx + 1) >> 1;
	dy = (dy > 0) ? abs (dx) : -abs (dx);}
    else {
	dx = (dx + 1) >> 1;
	dy = (dy + 1) >> 1;
    }

    if (wtsb == s1b) {
	if (sal_s1c >= sal_1max) {	/* need more space	 */
	    sal_1max += 10 + sal_1max / 2;	/* add 50%	 */
	    sal_s1 = (char **) realloc (sal_s1, sizeof (char *) * sal_1max);
	}
	sal_s1[sal_s1c++] = &pcb[y1 + dy][x1 + dx];}
    else {
	if (sal_s2c >= sal_2max) {	/* need more space	 */
	    sal_2max += 10 + sal_2max / 2;	/* add 50%	 */
	    sal_s2 = (char **) realloc (sal_s2, sizeof (char *) * sal_2max);
	}
	sal_s2[sal_s2c++] = &pcb[y1 + dy][x1 + dx];
    }
}

gs_scan (net)
    struct nlhd *net;
/***********************************************************************\
* 								        *
*  Get segments scan:						        *
*  the centers of all vectors that form a paricular net are collected.  *
*  A segment scan is done for each potential candidate, and the	        *
*  generic segment pointer are added to sa_s1/2.		        *
* 								        *
\***********************************************************************/
{
    register struct nlst *p;
    register int i, j, k, c1, c2;
    char *t;
    int lst_key();

    sal_s1c = 0;
    sal_s2c = 0;

    for (p = net -> lp; p; p = p -> n)	/* reset marks		 */
	p -> mk = -1;

    for (p = net -> lp; p; p = p -> n) 	/* get vector centers	 */
	if (p -> mk) {
	    i = p -> c -> x;
	    j = p -> c -> y;
	    wtrace (i, j, vec);
	}

    if (sal_s1c) {			/* process stuff on side 1 */
	qsort (sal_s1, sal_s1c, sizeof (char *), lst_key);

	while (sal_s1c) {		/* copy generic ptr-s	 */
	    if (sa_s1c >= sa_1max) {	/* need more space	 */
		sa_1max += 10 + sa_1max / 2;	/* add 50%	 */
		sa_s1 = (char **) realloc (sa_s1, sizeof (char *) * sa_1max);
	    }
	    t = sal_s1[--sal_s1c];

	    if (!(*t & s1b))
		continue; /* point was deleted by earlier fnd_seg */

	    t = fnd_seg (((int) t - (int) pcb) % xmax,
		     ((int) t - (int) pcb) / xmax, s1b);
	    if (!t || seg_cnt < 4)	/* not worth the efford	 */
		continue;

	    sa_s1[sa_s1c++] = t;

	    qsort (seg_lst, seg_cnt, sizeof (char *), lst_key);

	    c1 = sal_s1c;		/* save a few nsec	 */
	    c2 = seg_cnt;
	    for (i = 0, j = 0, k = 0; i < c1; i++) {
		while (j < c2 && sal_s1[i] > seg_lst[j])
		    j++;
		if (j >= c2) {		/* segment list exhausted */
		    while (i < c1)
			sal_s1[k++] = sal_s1[i++];
		    break;
		}
		if (sal_s1[i] < seg_lst[j])
		    sal_s1[k++] = sal_s1[i];
	    }
	    sal_s1c = k;
	}
    }


    if (sal_s2c) {			/* process stuff on side 2 */
	qsort (sal_s2, sal_s2c, sizeof (char *), lst_key);

	while (sal_s2c) {		/* copy generic ptr-s	 */
	    if (sa_s2c >= sa_2max) {	/* need more space	 */
		sa_2max += 10 + sa_2max / 2;	/* add 50%	 */
		sa_s2 = (char **) realloc (sa_s2, sizeof (char *) * sa_2max);
	    }
	    t = sal_s2[--sal_s2c];

	    if (!(*t & s2b))
		continue; /* point was deleted by earlier fnd_seg */

	    t = fnd_seg (((int) t - (int) pcb) % xmax,
		     ((int) t - (int) pcb) / xmax, s2b);
	    if (!t || seg_cnt < 4)
		continue;		/* not worth the efford	 */

	    sa_s2[sa_s2c++] = t;

	    qsort (seg_lst, seg_cnt, sizeof (char *), lst_key);

	    c1 = sal_s2c;		/* save a few nsec	 */
	    c2 = seg_cnt;
	    for (i = 0, j = 0, k = 0; i < c1; i++) {
		while (j < c2 && sal_s2[i] > seg_lst[j])
		    j++;
		if (j >= c2) {		/* segment list exhausted */
		    while (i < c1)
			sal_s2[k++] = sal_s2[i++];
		    break;
		}
		if (sal_s2[i] < seg_lst[j])
		    sal_s2[k++] = sal_s2[i];
	    }
	    sal_s2c = k;
	}
    }
}

straight_all ()			/* total pcb improver		 */
{
    register int i;
    int lst_key (), alt_key ();

    Ferr_msg ("Prepare wire straightening");

    st_reroute = 0;		/* use move strategy for first 2 pases */
    get_seg ();
    printf ("Wire segments: %d on side1 %d on side2\n", sa_s1c, sa_s2c);

    Ferr_msg ("Straight wires: pass 1");
    for (i = 0; i < sa_s1c; i++)
	sa_s1[i] = straight (((int) sa_s1[i] - (int) pcb) % xmax,
		             ((int) sa_s1[i] - (int) pcb) / xmax, s1b);
    for (i = 0; i < sa_s2c; i++)
	sa_s2[i] = straight (((int) sa_s2[i] - (int) pcb) % xmax,
			     ((int) sa_s2[i] - (int) pcb) / xmax, s2b);

    Ferr_msg ("Straight wires: pass 2");
    qsort (sa_s1, sa_s1c, sizeof (char *), lst_key);
    qsort (sa_s2, sa_s2c, sizeof (char *), lst_key);
    for (i = 0; i < sa_s1c; i++)
	sa_s1[i] = straight (((int) sa_s1[i] - (int) pcb) % xmax,
		             ((int) sa_s1[i] - (int) pcb) / xmax, s1b);
    for (i = 0; i < sa_s2c; i++)
	sa_s2[i] = straight (((int) sa_s2[i] - (int) pcb) % xmax,
			     ((int) sa_s2[i] - (int) pcb) / xmax, s2b);

    Ferr_msg ("Straight wires: pass 3");
    st_reroute = 1;		/* use re-route for last pass	 */
    qsort (sa_s1, sa_s1c, sizeof (char *), alt_key);
    qsort (sa_s2, sa_s2c, sizeof (char *), alt_key);
    for (i = 0; i < sa_s1c; i++)
	sa_s1[i] = straight (((int) sa_s1[i] - (int) pcb) % xmax,
		             ((int) sa_s1[i] - (int) pcb) / xmax, s1b);
    for (i = 0; i < sa_s2c; i++)
	sa_s2[i] = straight (((int) sa_s2[i] - (int) pcb) % xmax,
			     ((int) sa_s2[i] - (int) pcb) / xmax, s2b);

    Ferr_msg ("Done");

    save (0);
    pgen_stat ();

}

alt_key (a, b)			/* alternate sort key		 */
    int *a, *b;
{
    return *b - *a;
}
!E!O!F!