In case Flash no longer exists; a copy of this site is included in the Flashpoint archive's "ultimate" collection.

Dead Code Preservation :: Archived AS3 works from wonderfl.net

forked from: Reversi

AIを強化しました。(中級者向け)
CPUから手を変えるような工夫をいれました。
Get Adobe Flash player
by hamlet 03 Jun 2012
/**
 * Copyright hamlet ( http://wonderfl.net/user/hamlet )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/4GIx
 */

/**
 * Copyright hamlet ( http://wonderfl.net/user/hamlet )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/4GIx
 */

// forked from ProjectNya's Reversi
////////////////////////////////////////////////////////////////////////////////
// リバーシ Plus for AS3.0
// ※ProjectNya's ReversiのAI強化版
//
// special thanks to ProjectNya
// リバーシ for AS3.0 (1)
// http://www.project-nya.jp/modules/weblog/details.php?blog_id=1039
//
// special thanks to QURAGE
// http://qurage.net/labo/fl1/data/reversi.html
////////////////////////////////////////////////////////////////////////////////

package {

    import flash.display.Sprite;
    import flash.display.Shape;
    import flash.geom.Matrix;
    import flash.display.GradientType;
    import flash.text.TextField;
    import flash.text.TextFieldType;
    import flash.text.AntiAliasType;
    import flash.text.TextFormat;
    import flash.text.TextFormatAlign;
    import flash.filters.DropShadowFilter;

    [SWF(backgroundColor="#FFFFFF", width="465", height="465", frameRate="30")]

    public class Main extends Sprite {
        private static var color1:uint = 0x3F68AB;
        private static var color2:uint = 0x77B2EE;
        private static var tColor:uint = 0xFFFFFF;
        private static var sColor:uint = 0x00000;
        private static var fontType:String = "_ゴシック";

        public function Main() {
            //Wonderfl.capture_delay(10);
            init();
        }

        private function init():void {
            draw(465, 465);
            var game:Game = new Game();
            addChild(game);
            game.x = 42;
            game.y = 12;
        }
        private function draw(w:uint, h:uint):void {
            var colors:Array = [color1, color2];
            var alphas:Array = [1, 1];
            var ratios:Array = [0, 255];
            var matrix:Matrix = new Matrix();
            matrix.createGradientBox(w, h, 1.25*Math.PI, 0, 0);
            graphics.beginGradientFill(GradientType.LINEAR, colors, alphas, ratios, matrix);
            graphics.drawRect(0, 0, w, h);
            graphics.endFill();
            var tf:TextFormat = new TextFormat();
            tf.font = fontType;
            tf.size = 32;
            tf.align = TextFormatAlign.LEFT;
            var title:TextField = new TextField();
            addChild(title);
            title.x = 20;
            title.y = 2;
            title.width = 200;
            title.height = 40;
            title.type = TextFieldType.DYNAMIC;
            title.selectable = false;
            //title.embedFonts = true;
            //title.antiAliasType = AntiAliasType.ADVANCED;
            title.defaultTextFormat = tf;
            title.textColor = tColor;
            //タイトル修正 (by Hamlet)
            title.text = "Reversi +";
            var shade:DropShadowFilter = new DropShadowFilter(1, 90, sColor, 0.4, 4, 4, 2, 2, false, false);
            title.filters = [shade];
        }

    }

}


//////////////////////////////////////////////////
//    リバーシ全体を管理するクラス
//////////////////////////////////////////////////

import adobe.utils.CustomActions;
import flash.display.Sprite;

class Game extends Sprite {
    private static var pieces:uint = 8;
    private var board:Board;
    private var score:Score;
    private var help:Help;
    public static const INIT:String = "init";
    public static const PLAY:String = "play";
    public static const PUT:String = "put";
    public static const FINISH:String = "finish";
    public static const NO_POINT:String = "noPoint";
    public static const READY:String = "ready";
    public static const RESET:String = "reset";
    public static const NO_HELP:String = "";
    public static const MOVE:String = "move";
    public static const SELECT:String = "select";
    public static const PUT_COMPLETE:String = "putComplete";
    public static const TURN_COMPLETE:String = "turnComplete";

    public function Game() {
        init();
    }

    private function init():void {
        board = new Board();
        score = new Score();
        help = new Help();
        addChild(board);
        board.x = 22;
        board.y = 88;
        addChild(score);
        addChild(help);
        help.x = 194;
        help.y = 245;
        board.init(score, help);
    }
}


//////////////////////////////////////////////////
//    盤面を管理するクラス
//////////////////////////////////////////////////

import flash.display.Sprite;
import flash.display.Shape;
import flash.events.Event;
import flash.utils.Timer;
import flash.events.TimerEvent;
import flash.net.navigateToURL;
import flash.net.URLRequest;
import flash.events.MouseEvent;
import flash.utils.escapeMultiByte;

class Board extends Sprite {
    private var mode:String;
    private var player:uint = 0;
    private var map:Map;
    private var score:Score;
    private var help:Help;
    private var manager:Manager;
    private var cursor:Cursor;
    private static var pieces:uint = 8;
    private static var bColor:uint = 0x336600;
    private var pointList:Array;
    private var pieceList:Array;
    private static var pid:uint = 0;
    private var completed:uint = 0;
    private static var initTime:uint = 500;
    private static var startTime:uint = 1000;
    private static var cpuTime:uint = 500;
    private static var finishTime:uint = 1000;
    private static var resetTime:uint = 500;
    private var cpu:Object;
    private var turns:uint;
    private var passed1:Boolean = false;
    private var passed2:Boolean = false;
    //サウンド
    private var seready:SoundEffect;
    private var seput:SoundEffect;
    private var seturn:SoundEffect;
    private var sefanfare:SoundEffect;
    private var seclaps:SoundEffect;
    private var sefailure:SoundEffect;
    private var source1:String = "http://www.project-nya.jp/images/flash/reversi/ready.mp3";
    private var source2:String = "http://www.project-nya.jp/images/flash/reversi/put.mp3";
    private var source3:String = "http://www.project-nya.jp/images/flash/reversi/turn.mp3";
    private var source4:String = "http://www.project-nya.jp/images/flash/reversi/fanfare.mp3";
    private var source5:String = "http://www.project-nya.jp/images/flash/reversi/claps.mp3";
    private var source6:String = "http://www.project-nya.jp/images/flash/reversi/failure.mp3";
    //twitter
    private var twitterBtn:Btn;
    private static var twitterPath:String = "http://twitter.com/home/?status=";
    private var msgs:Array = new Array();
    private var result:String;
    private static var tag:String = " http://wonderfl.net/c/vDfO"


    public function Board() {
        draw();
        seready = new SoundEffect();
        seput = new SoundEffect();
        seturn = new SoundEffect();
        sefanfare = new SoundEffect();
        seclaps = new SoundEffect();
        sefailure = new SoundEffect();
    }

    public function init(s:Score, h:Help):void {
        score = s;
        help = h;
        seready.load(source1, "ready");
        seput.load(source2, "put");
        seturn.load(source3, "turn");
        sefanfare.load(source4, "fanfare");
        seclaps.load(source5, "claps");
        sefailure.load(source6, "failure");
        reset(null);
    }
    //カーソル位置にコマを配置する(キー設定)
    private function initialize():void {
        manager = new Manager(this);
        addChild(manager);
        manager.addEventListener(Game.READY, readySelect, false, 0, true);
        manager.addEventListener(Game.MOVE, moveCursor, false, 0, true);
        manager.addEventListener(Game.SELECT, selectCursor, false, 0, true);
        manager.addEventListener(Game.RESET, resetSelect, false, 0, true);
        manager.enable = false;
        cpu = new Object();
    }
    private function reset(evt:TimerEvent):void {
        if (evt) evt.target.removeEventListener(TimerEvent.TIMER_COMPLETE, reset);
        initialize();
        map = new Map();
        score.init();
        mode = Game.INIT;
        score.showMessage(mode);
        help.show("ready?");
        score.resetTime();
        seready.play("ready", 1);
        manager.help = Game.READY;
        if (pieceList) clearPieces();
        pieceList = new Array();
    }
    private function readySelect(evt:Event):void {
        manager.help = Game.NO_HELP;
        var timer:Timer = new Timer(initTime, 1);
        timer.addEventListener(TimerEvent.TIMER_COMPLETE, start, false, 0, true);
        timer.start();
        help.hide();
    }
    private function start(evt:TimerEvent):void {
        evt.target.removeEventListener(TimerEvent.TIMER_COMPLETE, start);
        score.startTime();
        
        //オセロの公式ルールに従い、黒石白石の初期配置を修正。(by Hamlet)
        putPiece(2, 3, 3);    //putPiece(1, 3, 3);
        putPiece(1, 3, 4);    //putPiece(2, 3, 4);
        putPiece(2, 4, 4);    //putPiece(1, 4, 4);
        putPiece(1, 4, 3);    //putPiece(2, 4, 3);
    }
    //盤面にコマを配置する
    private function put(px:uint, py:uint):void {
        if (map.getPoint(px, py)) {
            if (map.getHint(px, py)) {
                switch (player) {
                case 1 :
                    putPiece(player, px, py);
                    break;
                case 2 :
                    cpuPiece(player, px, py);
                    var timer:Timer = new Timer(cpuTime, 1);
                    timer.addEventListener(TimerEvent.TIMER_COMPLETE, cpuPut, false, 0, true);
                    timer.start();
                    break;
                }
            } else {
                score.showMessage(Game.NO_POINT);
            }
        } else {
            score.showMessage(Game.NO_POINT);
        }
    }
    //盤面にコマを配置する(配置可能なマスに)
    private function putPiece(p:uint, px:uint, py:uint):void {
        var point:Point = pointList[px+py*pieces];
        var xPos:uint = point.x;
        var yPos:uint = point.y;
        var id:uint = px+py*pieces;
        var piece:Piece = new Piece();
        addChild(piece);
        piece.id = id;
        piece.px = px;
        piece.py = py;
        piece.x = xPos;
        piece.y = yPos;
        pieceList[id] = piece;
        piece.addEventListener(Game.PUT_COMPLETE, putComplete, false, 0, true);
        piece.addEventListener(Game.TURN_COMPLETE, turnComplete, false, 0, true);
        piece.put(p);
        score.put(p);
        map.put(p, px, py);
        seput.play("put", 1);
        hideHint();
        pid ++;
        manager.enable = false;
    }
    private function cpuPiece(p:uint, px:uint, py:uint):void {
        cpu = {p: p, px: px, py: py};
    }
    private function cpuPut(evt:TimerEvent):void {
        evt.target.removeEventListener(TimerEvent.TIMER_COMPLETE, cpuPut);
        putPiece(cpu.p, cpu.px, cpu.py);
    }
    private function clearPieces():void {
        for (var px:uint = 0; px < pieces; px++) {
            for (var py:uint = 0; py < pieces; py++) {
                var piece:Piece = pieceList[px+py*pieces];
                if (piece) removeChild(piece);
                piece = null;
            }
        }
        pid = 0;
    }
    //コマ配置後の処理
    private function putComplete(evt:Event):void {
        switch (mode) {
            case Game.INIT :
                completed ++;
                if (completed == 4) {
                    completed = 0;
                    mode = Game.PLAY;
                    score.showMessage(mode);
                    player = 2;
                    var timer:Timer = new Timer(startTime, 1);
                    timer.addEventListener(TimerEvent.TIMER_COMPLETE, prepare, false, 0, true);
                    timer.start();
                }
                break;
            case Game.PLAY :
                turn(evt.target.px, evt.target.py);
                break;
        }
    }
    //反転するコマ情報を取得する
    private function turn(px:uint, py:uint):void {
        var list:Array = map.getTurnList(player, px, py);
        turns = list.length;
        if (turns > 0) {
            turnPieces(player, list);
            seturn.play("turn", 1);
        }
    }
    //コマを反転する
    private function turnPieces(p:uint, list:Array):void {
        for (var n:uint = 0; n < list.length; n++) {
            var tx:uint = list[n].x;
            var ty:uint = list[n].y;
            var piece:Piece = pieceList[tx+ty*pieces];
            piece.turn();
            score.turn(p);
            map.put(p, tx, ty);
        }
    }
    //コマ反転後の処理
    private function turnComplete(evt:Event):void {
        completed ++;
        if (completed == turns) {
            completed = 0;
            if (pid < pieces*pieces) {
                prepare(null);
            } else {
                finish();
            }
        }
    }
    //攻守交代
    private function prepare(evt:TimerEvent):void {
        if (evt) evt.target.removeEventListener(TimerEvent.TIMER_COMPLETE, prepare);
        player = player%2 + 1;
        switch (player) {
            case 1 :
                score.showMessage(Game.PUT, player, passed2);
                map.getBestPrio(player);
                if (showHint()) {
                    if (!cursor) {
                        cursor = new Cursor();
                        addChild(cursor);
                        setCursor(4, 4);
                        manager.setCursor(4, 4);
                    }
                    manager.enable = true;
                    passed1 = false;
                } else {
                    passed1 = true;
                }
                break;
            case 2 :
                score.showMessage(Game.PUT, player, passed1);
                var best:Object = map.getBestPrio(player);
                if (!isNaN(best.x) && !isNaN(best.y)) {
                    manager.autoCursor(best.x, best.y);
                    passed2 = false;
                } else {
                    passed2 = true;
                }
                break;
        }
        if (passed1 && passed2) {
            finish();
        } else if ((player == 1 && passed1) || (player == 2 && passed2)) {
            prepare(null);
        }
    }
    private function moveCursor(evt:Event):void {
        setCursor(evt.target.cx, evt.target.cy);
    }
    private function selectCursor(evt:Event):void {
        put(evt.target.cx, evt.target.cy);
    }
    //盤面にカーソルを配置する
    private function setCursor(cx:uint, cy:uint):void {
        var point:Point = pointList[cx+cy*pieces];
        var xPos:uint = point.x;
        var yPos:uint = point.y;
        cursor.x = xPos;
        cursor.y = yPos;
    }
    //ヒントを表示する
    private function showHint():Boolean {
        var hint:uint = 0;
        for (var px:uint = 0; px < pieces; px++) {
            for (var py:uint = 0; py < pieces; py++) {
                var point:Point = pointList[px+py*pieces];
                if (map.getHint(px, py)) {
                    hint ++;
                    point.hint();
                } else {
                    point.init();
                }
            }
        }
        if (hint > 0) {
            return true;
        } else {
            return false;
        }
    }
    //ヒントを非表示にする
    private function hideHint():void {
        for (var px:uint = 0; px < pieces; px++) {
            for (var py:uint = 0; py < pieces; py++) {
                var point:Point = pointList[px+py*pieces];
                point.init();
            }
        }
    }
    //ゲーム終了の処理
    private function finish():void {
        mode = Game.FINISH;
        score.showMessage(mode);
        var timer:Timer = new Timer(finishTime, 1);
        timer.addEventListener(TimerEvent.TIMER_COMPLETE, showHelp, false, 0, true);
        timer.start();
        score.stopTime();
        player = 0;
        passed1 = false;
        passed2 = false;
    }
    private function showHelp(evt:TimerEvent):void {
        evt.target.removeEventListener(TimerEvent.TIMER_COMPLETE, showHelp);
        var scr:Array = score.getScore();
        var p1:uint = scr[0];
        var p2:uint = scr[1];
        //twitter
        result = String(p1) + ":" + String(p2);
        if (p1 > p2) {
            help.show("You win!");
            sefanfare.play("fanfare", 1);
            msgs = ["コンピュータに ", " で勝ったよ!"];
        } else if (p1 == p2) {
            help.show("draw");
            seclaps.play("claps", 1);
            msgs = ["コンピュータと ", " の引き分けでした。"];
        } else {
            help.show("You lose");
            sefailure.play("failure", 1);
            msgs = ["コンピュータに ", " で負けました..."];
        }
        removeChild(cursor);
        cursor = null;
        manager.help = Game.RESET;
    }
    private function resetSelect(evt:Event):void {
        manager.help = Game.NO_HELP;
        var timer:Timer = new Timer(resetTime, 1);
        timer.addEventListener(TimerEvent.TIMER_COMPLETE, reset, false, 0, true);
        timer.start();
        help.hide();
    }
    private function draw():void {
        graphics.beginFill(bColor);
        graphics.drawRect(-2, -2, 340, 340);
        graphics.endFill();
        pointList = new Array();
        for (var px:uint = 0; px < pieces; px++) {
            for (var py:uint = 0; py < pieces; py++) {
                var point:Point = new Point();
                addChild(point);
                var id:uint = px+py*pieces;
                point.id = id;
                pointList[id] = point;
                point.x = 21 + 42*px;
                point.y = 21 + 42*py;
                point.init();
            }
        }
        for (var cx:uint = 0; cx < 2; cx++) {
            for (var cy:uint = 0; cy < 2; cy++) {
                var corner:Shape = new Shape();
                addChild(corner);
                corner.graphics.beginFill(bColor);
                corner.graphics.drawCircle(0, 0, 4);
                corner.graphics.endFill();
                corner.x = 84 + 168*cx;
                corner.y = 84 + 168*cy;
            }
        }
        //twitter
        twitterBtn = new Btn();
        addChild(twitterBtn);
        twitterBtn.x = 365;
        twitterBtn.y = 350;
        twitterBtn.init({label: "twitter"});
        twitterBtn.addEventListener(MouseEvent.CLICK, twitter, false, 0, true);
    }
    //twitter対応
    private function twitter(evt:MouseEvent):void {
        var msg:String = "";
        switch (mode) {
            case Game.INIT :
                msg = "ゲームを開始します。";
                break;
            case Game.PLAY :
                msg = "ゲーム中です。";
                break;
            case Game.FINISH :
                msg = msgs[0] + result + msgs[1];
                break;
        }
        navigateToURL(new URLRequest(twitterPath + escapeMultiByte(msg + tag)), "_blank");            
    }

}


//////////////////////////////////////////////////
//    盤面上のコマの位置を管理するクラス
//////////////////////////////////////////////////

class Map {
    private static var pieces:uint = 8;
    //空マップ
    private var aMap:Array;
    //盤面上のコマ配置マップ
    private var bMap:Array;
    //優先度マップ
    private var pMap:Array;
    //走査マップ
    private var cMap:Array;
    //ヒント表示マップ
    private var hMap:Array;
    
    //独自拡張部分。(by Hamlet) 
    private var Ai:AiManager;

    public function Map() {
        init();
    }

    private function init():void {
        aMap = new Array();
        aMap.push([0, 0, 0, 0, 0, 0, 0, 0]);
        aMap.push([0, 0, 0, 0, 0, 0, 0, 0]);
        aMap.push([0, 0, 0, 0, 0, 0, 0, 0]);
        aMap.push([0, 0, 0, 0, 0, 0, 0, 0]);
        aMap.push([0, 0, 0, 0, 0, 0, 0, 0]);
        aMap.push([0, 0, 0, 0, 0, 0, 0, 0]);
        aMap.push([0, 0, 0, 0, 0, 0, 0, 0]);
        aMap.push([0, 0, 0, 0, 0, 0, 0, 0]);
        bMap = copyMap(aMap);
        cMap = copyMap(aMap);
        pMap = new Array();
        pMap.push([7, 0, 5, 6, 6, 5, 0, 7]);
        pMap.push([0, 0, 2, 3, 3, 2, 0, 0]);
        pMap.push([5, 2, 5, 4, 4, 5, 2, 5]);
        pMap.push([6, 3, 4, 4 ,4, 4, 3, 6]);
        pMap.push([6, 3, 4, 4 ,4, 4, 3, 6]);
        pMap.push([5, 2, 5, 4, 4, 5, 2, 5]);
        pMap.push([0, 0, 2, 3, 3, 2, 0, 0]);
        pMap.push([7, 0, 5, 6, 6, 5, 0, 7]);

         //独自拡張部分。AIクラスのインスタンス化。(by Hamlet) 
        Ai = new AiManager();
    }
    private function copyMap(list:Array):Array {
        var map:Array = new Array();
        for (var n:uint = 0; n < list.length; n++) {
            map[n] = list[n].concat();
        }
        return map;
    }
    //コマの配置をマップに設定する
    public function put(p:uint, x:uint, y:uint):void {
        bMap[y][x] = p;
        cMap[y][x] = p;
        for (var cx:int = x-1; cx <= x+1; cx++) {
            for (var cy:int = y-1; cy <= y+1; cy++) {
                if (cx >= 0 && cx < pieces && cy >= 0 && cy < pieces) {
                    var player:Object = bMap[cy][cx];
                    player = (player == 0) ? "*" : player;
                    cMap[cy][cx] = player;
                }
            }
        }
    }
    //配置可能なマスかどうかを判定する
    public function getPoint(x:uint, y:uint):Boolean {
        if (bMap[y][x] == 0) {
            return true;
        } else {
            return false;
        }
    }
    //走査対象のコマかどうかを判定する
    private function getCheck(x:uint, y:uint):Boolean {
        var check:Object = cMap[y][x];
        if (check == "*") {
            return true;
        } else {
            return false;
        }
    }
    //ヒント表示するコマかどうかを判定する
    public function getHint(x:uint, y:uint):Boolean {
        var hint:Object = hMap[y][x];
        if (hint == "*") {
            return true;
        } else {
            return false;
        }
    }
    //評価値の高いマスを取得する({x: 0, y: 0}で返す)
    public function getBestPrio(p:uint):Object {
        var px:Number = undefined;
        var py:Number = undefined;
        var ev:int = -9999;
        var best:int = -9999;
        var bestpos:Array = new Array(35);
        var bestcnt:int = 0;
        hMap = copyMap(aMap);
        for (var x:uint = 0; x < pieces; x++) {
            for (var y:uint = 0; y < pieces; y++) {
                if (getCheck(x, y)) {
                    var turns:uint = getTurns(p, x, y);
                    if (turns > 0) {
                        hMap[y][x] = "*";
                        //独自拡張部分。思考エンジンをコールし評価値を得る。
                        ev = Ai.Think(bMap, p, x, y);
                        if (best < ev) {
                            //評価値がより大きい場合、bestを更新する。
                            bestcnt = 0;
                            bestpos[bestcnt++] = y * 8 + x;
                            best = ev;
                        } else if (best == ev) {
                            //bestと同じ評価値の場合、候補のリストに追加する。
                            bestpos[bestcnt++] = y * 8 + x;
                        }
                    }
                }
            }
        }
        
        var index:int = Math.floor (Math.random () * bestcnt)
        px = bestpos[index] % 8;
        py = (int)(bestpos[index] / 8);
        
        return {x: px, y: py};
    }
    //指定したマスの8方向に対して反転できるコマ数を取得する
    public function getTurns(p:uint, x:uint, y:uint):uint {
        var turns:uint = 0;
        for (var dx:int = -1; dx <= 1; dx++) {
            for (var dy:int = -1; dy <= 1; dy++) {
            if (dx == 0 && dy == 0) continue;
                var px:int = x + dx;
                var py:int = y + dy;
                while (px >= 0 && px < pieces && py >= 0 && py < pieces) {
                    var player:uint = bMap[py][px];
                    if (player == 0) break;
                    if (player == p) {
                        if (dx != 0) {
                            turns += dx*(px - x) - 1;
                        } else {
                            turns += dy*(py - y) - 1;
                        }
                        break;
                    }
                    px += dx;
                    py += dy;
                }
            }
        }
        return turns;
    }
    //反転するコマ情報を取得する
    public function getTurnList(p:uint, x:uint, y:uint):Array {
        var list:Array = new Array();
        for (var dx:int = -1; dx <= 1; dx++) {
            for (var dy:int = -1; dy <= 1; dy++) {
                if (dx == 0 && dy == 0) continue;
                var px:int = x + dx;
                var py:int = y + dy;
                var checking:Boolean = true;
                while (px >= 0 && px < pieces && py >= 0 && py < pieces) {
                    var player:uint = bMap[py][px];
                    if (player == 0) break;
                    if (player == p) {
                        if (checking) {
                            px = x + dx;
                            py = y + dy;
                            checking = false;
                            continue;
                        } else {
                            break;
                        }
                    }
                    if (!checking && player != p) {
                        list.push({x: px, y: py});
                    }
                    px += dx;
                    py += dy;
                }
            }
        }
        return list;
    }
}


//////////////////////////////////////////////////
//    コマの動きを管理するクラス
//////////////////////////////////////////////////

import flash.display.Sprite;
import flash.display.Shape;
import flash.events.Event;
import flash.utils.Timer;
import flash.events.TimerEvent;

class Piece extends Sprite {
    public var id:uint;
    public var px:uint;
    public var py:uint;
    private var piece1:PieceShape;
    private var piece2:PieceShape;
    private var scale:Number = 1;
    private var light:Shape;
    private var _brightness:Number = 0;

    public function Piece() {
        draw();
    }

    public function put(p:uint):void {
        id = p;
        var piece:PieceShape = this["piece"+id];
        addChild(piece);
        piece.scaleX = piece.scaleY = scale = 1.6;
        addEventListener(Event.ENTER_FRAME, putPiece, false, 0, true);
    }
    private function putPiece(evt:Event):void {
        var piece:PieceShape = this["piece"+id];
        scale -= 0.1;
        piece.scaleX = piece.scaleY = scale;
        if (scale <= 1) {
            piece.scaleX = piece.scaleY = scale = 1;
            removeEventListener(Event.ENTER_FRAME, putPiece);
            dispatchEvent(new Event(Game.PUT_COMPLETE))
        }
    }
    public function turn():void {
        var old:PieceShape = this["piece"+id];
        removeChild(old);
        id = id%2 + 1;
        var piece:PieceShape = this["piece"+id];
        addChild(piece);
        addChild(light);
        var timer:Timer = new Timer(50, 6);
        timer.addEventListener(TimerEvent.TIMER, turnPiece, false, 0, true);
        timer.addEventListener(TimerEvent.TIMER_COMPLETE, motion, false, 0, true);
        timer.start();
    }
    private function turnPiece(evt:TimerEvent):void {
        if (evt.target.currentCount == 4) {
            evt.target.removeEventListener(TimerEvent.TIMER, turnPiece);
            removeChild(light);
        }
    }
    private function motion(evt:TimerEvent):void {
        evt.target.removeEventListener(TimerEvent.TIMER_COMPLETE, motion);
        brightness = 100;
        addEventListener(Event.ENTER_FRAME, bright, false, 0, true);
    }
    private function bright(evt:Event):void {
        brightness -= 20;
        if (brightness <= 0) {
            brightness = 0;
            removeEventListener(Event.ENTER_FRAME, bright);
            dispatchEvent(new Event(Game.TURN_COMPLETE))
        }
    }
    private function draw():void {
        graphics.beginFill(0x000000);
        graphics.drawCircle(0, 0, 20);
        graphics.endFill();
        piece1 = new PieceShape(1);
        piece2 = new PieceShape(2);
        light = new Shape();
        light.graphics.beginFill(0xFFFFFF);
        light.graphics.drawCircle(0, 0, 20);
        light.graphics.drawCircle(0, 0, 15);
        light.graphics.endFill();
    }
    private function get brightness():Number {
        return _brightness;
    }
    private function set brightness(param:Number):void {
        _brightness = param;
        ColorManager.brightOffset(this, _brightness);
    }

}


//////////////////////////////////////////////////
//    コマを描画するクラス
//////////////////////////////////////////////////

import flash.display.Shape;
import flash.geom.Matrix;
import flash.display.GradientType;
import flash.display.SpreadMethod;
import flash.display.InterpolationMethod;

class PieceShape extends Shape {
    private var type:uint = 1;
    private static var cList:Array = [[0x888888, 0x000000], [0xFFFFFF, 0xBBBBBB]];
    private static var bList:Array = [0x444444, 0xDDDDDD];

    public function PieceShape(t:uint) {
        type = t;
        draw();
    }

    private function draw():void {
        var colors:Array = cList[type-1];
        var alphas:Array = [1, 1];
        var ratios:Array = [0, 255];
        var matrix:Matrix = new Matrix();
        matrix.createGradientBox(36, 36, 0.25*Math.PI, -18, -18);
        graphics.beginGradientFill(GradientType.LINEAR, colors, alphas, ratios, matrix, SpreadMethod.PAD, InterpolationMethod.RGB, 0);
        graphics.drawCircle(0, 0, 18);
        graphics.endFill();
        var bColor:uint = bList[type-1];
        graphics.beginFill(bColor);
        graphics.drawCircle(0, 0, 15);
        graphics.endFill();
    }

}


//////////////////////////////////////////////////
//    マスを着色するクラス
//////////////////////////////////////////////////

import flash.display.Shape;
import flash.geom.ColorTransform;

class Point extends Shape {
    public var id:uint;
    private static var bColor:uint = 0x66CC00;
    private static var cColor:uint = 0x66CCFF;
    private static var bColorTrans:ColorTransform;
    private static var cColorTrans:ColorTransform;

    public function Point() {
        draw();
    }

    public function init():void {
        transform.colorTransform = bColorTrans;
    }
    public function hint():void {
        transform.colorTransform = cColorTrans;
    }
    private function draw():void {
        graphics.beginFill(0xFFFFFF);
        graphics.drawRect(-20, -20, 40, 40);
        graphics.endFill();
        bColorTrans = new ColorTransform(0, 0, 0, 1, 0, 0, 0, 0);
        bColorTrans.color = bColor;
        cColorTrans = new ColorTransform(0, 0, 0, 1, 0, 0, 0, 0);
        cColorTrans.color = cColor;
    }

}


//////////////////////////////////////////////////
//    得点を管理するクラス
//////////////////////////////////////////////////

import flash.display.Sprite;
import flash.text.TextField;
import flash.text.TextFieldType;
import flash.text.AntiAliasType;
import flash.text.TextFormat;
import flash.text.TextFormatAlign;
import flash.filters.DropShadowFilter;

class Score extends Sprite {
    private var pieces1:uint = 0;
    private var pieces2:uint = 0;
    private var score1:TextField;
    private var score2:TextField;
    private var message:TextField;
    private var player:Array;
    private var msgs:Object;
    private var time:Time;
    private var txt:TextField;
    private static var bColor:uint = 0xFFFF00;
    private static var sColor:uint = 0x000000;
    private static var b1Color:uint = 0x66CC00;
    private static var b2Color:uint = 0xFFFFFF;
    private static var fontType:String = "_ゴシック";
    //private static var initMsg:String = "ゲームを初期化しています。";
    private static var initMsg:String = "Enterキー・上下左右キーで操作してください。";
    private static var playMsg:String = "ゲームを開始します。";
    private static var putMsg:String = "の番です。";
    private static var passMsg:String = "はパス。";
    private static var finishMsg:String = "ゲームは終了しました。";
    private static var noPointMsg:String = "そのマスにはコマを置けません。";

    public function Score() {
        draw();
        initialize();
    }

    private function initialize():void {
        msgs = new Object();
        msgs[Game.INIT] = initMsg;
        msgs[Game.PLAY] = playMsg;
        msgs[Game.PUT] = putMsg;
        msgs[Game.FINISH] = finishMsg;
        msgs[Game.NO_POINT] = noPointMsg;
        player = new Array();
        player[1] = "あなた";
        player[2] = "コンピュータ";
        time = new Time(txt);
    }
    public function init():void {
        pieces1 = 0;
        pieces2 = 0;
        showScore();
    }
    public function put(p:uint):void {
        this["pieces"+p] ++;
        showScore();
    }
    public function turn(p:uint):void {
        this["pieces"+p] ++;
        var r:uint = p%2 + 1;
        this["pieces"+r] --;
        showScore();
    }
    private function showScore():void {
        score1.text = String(pieces1);
        score2.text = String(pieces2);
    }
    public function showMessage(mode:String, p:uint = 0, passed:Boolean = false):void {
        switch (mode) {
            case Game.PUT :
                if (!passed) {
                    message.text = player[p] + msgs[mode];
                } else {
                    var r:uint = p%2 + 1;
                    message.text = player[r] + passMsg + player[p] + msgs[mode];
                }
                break;
            default :
                message.text = msgs[mode];
                break;
        }
    }
    public function getScore():Array {
        return [pieces1, pieces2];
    }
    public function startTime():void {
        time.start();
    }
    public function stopTime():void {
        time.stop();
    }
    public function resetTime():void {
        time.reset();
    }
    private function draw():void {
        graphics.beginFill(bColor);
        graphics.drawRect(20, 56, 340, 24);
        graphics.endFill();
        graphics.beginFill(b1Color);
        graphics.drawRoundRect(256, 0, 104, 44, 12);
        graphics.endFill();
        graphics.beginFill(b2Color);
        graphics.drawRoundRect(258, 2, 100, 40, 8);
        graphics.endFill();
        var piece1:PieceShape = new PieceShape(1);
        addChild(piece1);
        piece1.x = 288;
        piece1.y = 29;
        piece1.width = piece1.height = 24;
        var piece2:PieceShape = new PieceShape(2);
        addChild(piece2);
        piece2.x = 328;
        piece2.y = 29;
        piece2.width = piece2.height = 24;
        var shade:DropShadowFilter = new DropShadowFilter(1, 90, sColor, 0.3, 2, 2, 2, 2, false, false);
        filters = [shade];
        drawText();
    }
    private function drawText():void {
        var tf:TextFormat = new TextFormat();
        tf.font = "_ゴシック";
        tf.size = 12;
        tf.align = TextFormatAlign.LEFT;
        message = new TextField();
        addChild(message);
        message.x = 30;
        message.y = 59;
        message.width = 404;
        message.height = 21;
        message.type = TextFieldType.DYNAMIC;
        message.selectable = false;
        message.antiAliasType = AntiAliasType.ADVANCED;
        message.defaultTextFormat = tf;
        message.textColor = 0x000000;
        var shade:DropShadowFilter = new DropShadowFilter(1, 90, sColor, 0.4, 2, 2, 2, 2, false, false);
        var tfn:TextFormat = new TextFormat();
        tfn.font = fontType;
        tfn.size = 12;
        tfn.align = TextFormatAlign.CENTER;
        var name1:TextField = new TextField();
        addChild(name1);
        name1.x = 273;
        name1.y = 1;
        name1.width = 30;
        name1.height = 19;
        name1.type = TextFieldType.DYNAMIC;
        name1.selectable = false;
        //name1.embedFonts = true;
        //name1.antiAliasType = AntiAliasType.ADVANCED;
        name1.defaultTextFormat = tfn;
        name1.textColor = 0x000000;
        name1.text = "You";
        name1.filters = [shade];
        var name2:TextField = new TextField();
        addChild(name2);
        name2.x = 313;
        name2.y = 1;
        name2.width = 30;
        name2.height = 19;
        name2.type = TextFieldType.DYNAMIC;
        name2.selectable = false;
        //name2.embedFonts = true;
        //name2.antiAliasType = AntiAliasType.ADVANCED;
        name2.defaultTextFormat = tfn;
        name2.textColor = 0x000000;
        name2.text = "CPU";
        name2.filters = [shade];
        var tfc:TextFormat = new TextFormat();
        tfc.font = fontType;
        tfc.size = 14;
        tfc.align = TextFormatAlign.CENTER;
        score1 = new TextField();
        addChild(score1);
        score1.x = 273;
        score1.y = 19;
        score1.width = 30;
        score1.height = 23;
        score1.type = TextFieldType.DYNAMIC;
        score1.selectable = false;
        //score1.embedFonts = true;
        //score1.antiAliasType = AntiAliasType.ADVANCED;
        score1.defaultTextFormat = tfc;
        score1.textColor = 0xFFFFFF;
        score1.text = String(0);
        score2 = new TextField();
        addChild(score2);
        score2.x = 313;
        score2.y = 19;
        score2.width = 30;
        score2.height = 23;
        score2.type = TextFieldType.DYNAMIC;
        score2.selectable = false;
        //score2.embedFonts = true;
        //score2.antiAliasType = AntiAliasType.ADVANCED;
        score2.defaultTextFormat = tfc;
        score2.textColor = 0x000000;
        score2.text = String(0);
        var tft:TextFormat = new TextFormat();
        tft.font = fontType;
        tft.size = 16;
        tft.align = TextFormatAlign.LEFT;
        var timer:TextField = new TextField();
        addChild(timer);
        timer.x = 140;
        timer.y = 18;
        timer.width = 40;
        timer.height = 21;
        timer.type = TextFieldType.DYNAMIC;
        timer.selectable = false;
        //timer.embedFonts = true;
        //timer.antiAliasType = AntiAliasType.ADVANCED;
        timer.defaultTextFormat = tft;
        timer.textColor = 0xFFFFFF;
        timer.text = "Time";
        txt = new TextField();
        addChild(txt);
        txt.x = 185;
        txt.y = 18;
        txt.width = 55;
        txt.height = 21;
        txt.type = TextFieldType.DYNAMIC;
        txt.selectable = false;
        //txt.embedFonts = true;
        //txt.antiAliasType = AntiAliasType.ADVANCED;
        txt.defaultTextFormat = tft;
        txt.textColor = 0xFFFFFF;
        txt.text = "00:00";
    }

}


//////////////////////////////////////////////////
//    タイマーを管理するクラス
//////////////////////////////////////////////////

import flash.display.Sprite;
import flash.text.TextField;
import flash.utils.getTimer;
import flash.utils.Timer;
import flash.events.TimerEvent;

class Time extends Sprite {
    private var target:TextField;
    private var startTime:uint;
    private var timer:Timer;
    private var countTime:uint = 30;

    public function Time(tg:TextField) {
        target = tg;
    }

    public function start():void {
        startTime = getTimer();
        timer = new Timer(countTime);
        timer.addEventListener(TimerEvent.TIMER, count, false, 0, true);
        timer.start();
    }
    private function count(evt:TimerEvent):void {
        var sec:uint = Math.floor((getTimer() - startTime)/1000);
        var min:String  = String(Math.floor(sec/60));
        min = (uint(min) < 10) ? "0" + min : min;
        var msec:String = String(sec%60);
        msec = (uint(msec) < 10) ? "0" + msec : msec;
        target.text = min + ":" + msec;
    }
    public function stop():void {
        timer.removeEventListener(TimerEvent.TIMER, count);
    }
    public function reset():void {
        target.text = "00:00";
    }

}


//////////////////////////////////////////////////
//    カーソル操作を管理するクラス
//////////////////////////////////////////////////

import flash.display.Sprite;
import flash.events.Event;
import flash.ui.Keyboard;
import flash.events.KeyboardEvent;
import flash.utils.Timer;
import flash.events.TimerEvent;

class Manager extends Sprite {
    private var board:Board;
    private static var pieces:uint = 8;
    public var cx:int;
    public var cy:int;
    private var tx:uint;
    private var ty:uint;
    private var cpu:Object;
    private static var autoTime:uint = 200;
    private var helpMode:String = "";
    private var keyMode:Boolean = false;

    public function Manager(b:Board) {
        board = b;
        if (stage) init();
        else addEventListener(Event.ADDED_TO_STAGE, init, false, 0, true);
    }

    private function init(evt:Event = null):void {
        removeEventListener(Event.ADDED_TO_STAGE, init);
        cpu = new Object();
        stage.addEventListener(KeyboardEvent.KEY_DOWN, keyDown, false, 0, true);
    }
    //カーソル位置を設定する
    public function setCursor(x:uint, y:uint):void {
        cx = x;
        cy = y;
    }
    //キー操作の処理
    private function keyDown(evt:KeyboardEvent):void {
        if (helpMode) {
            if (evt.keyCode == Keyboard.ENTER) {
                dispatchEvent(new Event(helpMode));
            }
        }
        if (keyMode) {
            switch (evt.keyCode) {
                case Keyboard.ENTER :
                    dispatchEvent(new Event(Game.SELECT));
                    break;
                case Keyboard.LEFT :
                    cx --;
                    break;
                case Keyboard.UP :
                    cy --;
                    break;
                case Keyboard.RIGHT :
                    cx ++;
                    break;
                case Keyboard.DOWN :
                    cy ++;
                    break;
            }
            if (cx > pieces - 1) cx = 0;
            if (cx < 0) cx = pieces - 1;
            if (cy > pieces - 1) cy = 0;
            if (cy < 0) cy = pieces - 1;
            dispatchEvent(new Event(Game.MOVE));
        }
    }
    //カーソル位置を移動する
    public function autoCursor(px:uint, py:uint):void {
        tx = px;
        ty = py;
        var timer:Timer = new Timer(autoTime);
        timer.addEventListener(TimerEvent.TIMER, moveCursor, false, 0, true);
        timer.start();
    }
    private function moveCursor(evt:TimerEvent):void {
        var mx:int = uint(tx > cx) - uint(tx < cx);
        var my:int = uint(ty > cy) - uint(ty < cy);
        if (mx != 0 || my != 0) {
            cx += mx;
            cy += my;
            dispatchEvent(new Event(Game.MOVE));
            if (cx == tx && cy == ty) {
                evt.target.removeEventListener(TimerEvent.TIMER, moveCursor);
                dispatchEvent(new Event(Game.SELECT));
            }
        }
    }
    public function set enable(param:Boolean):void {
        keyMode = param;
    }
    public function set help(param:String):void {
        helpMode = param;
    }

}


//////////////////////////////////////////////////
//    カーソルを描画するクラス
//////////////////////////////////////////////////

import flash.display.Sprite;
import flash.display.Shape;
import flash.utils.Timer;
import flash.events.TimerEvent;

class Cursor extends Sprite {
    private var id:uint = 0;
    private var cursor0:Shape;
    private var cursor1:Shape;
    private static var bColor:uint = 0x66CC00;
    private static var cColor:uint = 0x66CCFF;

    public function Cursor() {
        draw();
        init();
    }

    private function init():void {
        var cursor:Shape = this["cursor"+id];
        addChild(cursor);
        var timer:Timer = new Timer(250);
        timer.addEventListener(TimerEvent.TIMER, change, false, 0, true);
        timer.start();
    }
    private function change(evt:TimerEvent):void {
        var old:Shape = this["cursor"+id];
        removeChild(old);
        id = (id+1)%2;
        var cursor:Shape = this["cursor"+id];
        addChild(cursor);
    }
    private function draw():void {
        cursor0 = new Shape();
        cursor0.graphics.beginFill(0xFFFFFF);
        cursor0.graphics.moveTo(-21, -21);
        cursor0.graphics.lineTo(-21, -6);
        cursor0.graphics.lineTo(-18, -6);
        cursor0.graphics.lineTo(-18, -18);
        cursor0.graphics.lineTo(-6, -18);
        cursor0.graphics.lineTo(-6, -21);
        cursor0.graphics.lineTo(-21, -21);
        cursor0.graphics.moveTo(21, -21);
        cursor0.graphics.lineTo(21, -6);
        cursor0.graphics.lineTo(18, -6);
        cursor0.graphics.lineTo(18, -18);
        cursor0.graphics.lineTo(6, -18);
        cursor0.graphics.lineTo(6, -21);
        cursor0.graphics.lineTo(21, -21);
        cursor0.graphics.moveTo(-21, 21);
        cursor0.graphics.lineTo(-21, 6);
        cursor0.graphics.lineTo(-18, 6);
        cursor0.graphics.lineTo(-18, 18);
        cursor0.graphics.lineTo(-6, 18);
        cursor0.graphics.lineTo(-6, 21);
        cursor0.graphics.lineTo(-21, 21);
        cursor0.graphics.moveTo(21, 21);
        cursor0.graphics.lineTo(21, 6);
        cursor0.graphics.lineTo(18, 6);
        cursor0.graphics.lineTo(18, 18);
        cursor0.graphics.lineTo(6, 18);
        cursor0.graphics.lineTo(6, 21);
        cursor0.graphics.lineTo(21, 21);
        cursor0.graphics.endFill();
        cursor1 = new Shape();
        cursor1.graphics.beginFill(0xFFFFFF);
        cursor1.graphics.moveTo(-22, -22);
        cursor1.graphics.lineTo(-22, -7);
        cursor1.graphics.lineTo(-19, -7);
        cursor1.graphics.lineTo(-19, -19);
        cursor1.graphics.lineTo(-7, -19);
        cursor1.graphics.lineTo(-7, -22);
        cursor1.graphics.lineTo(-22, -22);
        cursor1.graphics.moveTo(22, -22);
        cursor1.graphics.lineTo(22, -7);
        cursor1.graphics.lineTo(19, -7);
        cursor1.graphics.lineTo(19, -19);
        cursor1.graphics.lineTo(7, -19);
        cursor1.graphics.lineTo(7, -22);
        cursor1.graphics.lineTo(22, -22);
        cursor1.graphics.moveTo(-22, 22);
        cursor1.graphics.lineTo(-22, 7);
        cursor1.graphics.lineTo(-19, 7);
        cursor1.graphics.lineTo(-19, 19);
        cursor1.graphics.lineTo(-7, 19);
        cursor1.graphics.lineTo(-7, 22);
        cursor1.graphics.lineTo(-22, 22);
        cursor1.graphics.moveTo(22, 22);
        cursor1.graphics.lineTo(22, 7);
        cursor1.graphics.lineTo(19, 7);
        cursor1.graphics.lineTo(19, 19);
        cursor1.graphics.lineTo(7, 19);
        cursor1.graphics.lineTo(7, 22);
        cursor1.graphics.lineTo(22, 22);
        cursor1.graphics.endFill();
    }

}


//////////////////////////////////////////////////
//    ヘルプ表示を管理するクラス
//////////////////////////////////////////////////

import flash.display.Sprite;
import flash.events.Event;
import flash.text.TextField;
import flash.text.TextFieldType;
import flash.text.AntiAliasType;
import flash.text.TextFormat;
import flash.text.TextFormatAlign;
import flash.filters.GlowFilter;

class Help extends Sprite {
    private var amplitude:Number = 0;
    private var scale:Number = 1;
    private static var targetScale:Number = 2;
    private static var deceleration:Number = 0.5;
    private static var friction:Number = 0.6;
    private var txt:TextField;
    private static var tColor:uint = 0x000000;
    private static var gColor:uint = 0xFFFFFF;
    private static var fontType:String = "_ゴシック";

    public function Help() {
        draw();
        hide();
    }

    public function hide():void {
        visible = false;
    }
    public function show(help:String):void {
        txt.text = help;
        visible = true;
        amplitude = 0;
        scale = 1;
        addEventListener(Event.ENTER_FRAME, elastic, false, 0, true);
    }
    private function elastic(evt:Event):void {
        amplitude += targetScale - scale;
        scale += amplitude*friction;
        amplitude *= deceleration;
        scaleX = scaleY = scale;
        if (Math.abs(targetScale - scale) < 0.005 && Math.abs(amplitude) < 0.001) {
            scaleX = scaleY = targetScale;
            removeEventListener(Event.ENTER_FRAME, elastic);
        }
    }
    private function draw():void {
        var tf:TextFormat = new TextFormat();
        tf.font = fontType;
        tf.size = 32;
        tf.align = TextFormatAlign.CENTER;
        txt = new TextField();
        addChild(txt);
        txt.x = -75;
        txt.y = -19;
        txt.width = 150;
        txt.height = 39;
        txt.type = TextFieldType.DYNAMIC;
        txt.selectable = false;
        //txt.embedFonts = true;
        //txt.antiAliasType = AntiAliasType.ADVANCED;
        txt.defaultTextFormat = tf;
        txt.textColor = tColor;
        var glow:GlowFilter = new GlowFilter(gColor, 1, 10, 10, 10, 1, false, false);
        txt.filters = [glow];
    }

}


//////////////////////////////////////////////////
// ColorManagerクラス
//////////////////////////////////////////////////

import flash.display.DisplayObject;
import flash.geom.ColorTransform;
import flash.filters.ColorMatrixFilter;

class ColorManager {
    private static var rs:Number = 0.3086;
    private static var gs:Number = 0.6094;
    private static var bs:Number = 0.0820;

    public function ColorManager() {
    }

    public static function brightOffset(target:DisplayObject, param:Number):void {
        target.transform.colorTransform = getBrightOffset(param);
    }
    private static function getBrightOffset(param:Number):ColorTransform {
        var percent:Number = 1;
        var offset:Number = param*2.55;
        var colorTrans:ColorTransform = new ColorTransform(0, 0, 0, 1, 0, 0, 0, 0);
        colorTrans.redMultiplier = percent;
        colorTrans.greenMultiplier = percent;
        colorTrans.blueMultiplier = percent;
        colorTrans.redOffset = offset;
        colorTrans.greenOffset = offset;
        colorTrans.blueOffset = offset;
        colorTrans.alphaMultiplier = 1;
        colorTrans.alphaOffset = 0;
        return colorTrans;
    }
    public static function saturation(target:DisplayObject, param:Number):void {
        target.filters = [getSaturation(param)];
    }
    private static function getSaturation(param:Number):ColorMatrixFilter {
        var colorMatrix:ColorMatrixFilter = new ColorMatrixFilter();
        var p:Number = param*0.01;
        var r:Number = (1 - p)*rs;
        var g:Number = (1 - p)*gs;
        var b:Number = (1 - p)*bs;
        var matrix:Array = [r + p, g, b, 0, 0, r, g + p, b, 0, 0, r, g, b + p, 0, 0, 0, 0, 0, 1, 0];
        colorMatrix.matrix = matrix;
        return colorMatrix;
    }

}


//////////////////////////////////////////////////
// SoundEffectクラス
//////////////////////////////////////////////////

import flash.events.EventDispatcher;
import flash.events.Event;
import flash.events.ProgressEvent;
import flash.media.Sound;
import flash.media.SoundChannel;
import flash.media.SoundTransform;
import flash.events.ProgressEvent;
import flash.net.URLRequest;

class SoundEffect extends EventDispatcher {
    private static var soundList:Object;
    private var sound:Sound;
    private var channel:SoundChannel;
    private static var initialized:Boolean = false;
    private var volume:Number;
    private var looping:Boolean = false;

    public function SoundEffect() {
        if (!initialized) initialize();
    }

    private static function initialize():void {
        initialized = true;
        soundList = new Object();
    }
    public function init(Snd:Class, id:String):void {
        var snd:Sound = new Snd();
        soundList[id] = snd;
    }
    public function load(file:String, id:String):void {
        var snd:Sound = new Sound();
        snd.load(new URLRequest(file));
        snd.addEventListener(ProgressEvent.PROGRESS, progress, false, 0, true);
        snd.addEventListener(Event.COMPLETE, loaded, false, 0, true);
        soundList[id] = snd;
    }
    public function play(id:String, vol:Number, loop:Boolean = false):void {
        if (channel != null) channel.stop();
        sound = soundList[id];
        volume = vol;
        looping = loop;
        channel = sound.play();
        var transform:SoundTransform = channel.soundTransform;
        transform.volume = volume;
        channel.soundTransform = transform;
        if (looping) {
            channel.addEventListener(Event.SOUND_COMPLETE, complete, false, 0, true);
        }
    }
    public function stop():void {
        if (channel != null) {
            channel.stop();
            channel.removeEventListener(Event.SOUND_COMPLETE, complete);
        }
    }
    private function progress(evt:ProgressEvent):void {
        dispatchEvent(evt);
    }
    private function loaded(evt:Event):void {
        dispatchEvent(evt);
    }
    private function complete(evt:Event):void {
        channel.removeEventListener(Event.SOUND_COMPLETE, complete);
        if (looping) {
            channel = sound.play(0);
            channel.addEventListener(Event.SOUND_COMPLETE, complete, false, 0, true);
            var transform:SoundTransform = channel.soundTransform;
            transform.volume = volume;
            channel.soundTransform = transform;
        }
    }

}


//////////////////////////////////////////////////
// Btnクラス
//////////////////////////////////////////////////

import flash.display.Sprite;
import flash.display.Shape;
import flash.text.TextField;
import flash.text.TextFieldType;
import flash.text.AntiAliasType;
import flash.text.TextFormat;
import flash.text.TextFormatAlign;
import flash.filters.GlowFilter;
import flash.events.MouseEvent;

class Btn extends Sprite {
    public var id:uint;
    private var shade:Shape;
    private var bottom:Shape;
    private var light:Shape;
    private var base:Shape;
    private var txt:TextField;
    private var label:String = "";
    private static var fontType:String = "_ゴシック";
    private var _width:uint = 60;
    private static var _height:uint = 20;
    private static var corner:uint = 5;
    private var type:uint = 1;
    private static var bColor:uint = 0xFFFFFF;
    private static var sColor:uint = 0x000000;
    private static var upColor:uint = 0x666666;
    private static var overColor:uint = 0x333333;
    private static var offColor:uint = 0x999999;
    private static var gColor:uint = 0x0099FF;
    private var blueGlow:GlowFilter;
    private var shadeGlow:GlowFilter;
    private var _clicked:Boolean = false;
    private var _enabled:Boolean = true;

    public function Btn() {
    }

    public function init(option:Object):void {
        if (option.id != undefined) id = option.id;
        if (option.label != undefined) label = option.label;
        if (option.width != undefined) _width = option.width;
        if (option.type != undefined) type = option.type;
        draw();
    }
    private function draw():void {
        switch (type) {
        case 1 :
            bColor = 0xFFFFFF;
            sColor = 0x000000;
            upColor = 0x666666;
            overColor = 0x333333;
            offColor = 0x999999;
            break;
        case 2 :
            bColor = 0x000000;
            sColor = 0xFFFFFF;
            upColor = 0x666666;
            overColor = 0x999999;
            offColor = 0x333333;
            break;
        }
        blueGlow = new GlowFilter(gColor, 0.6, 5, 5, 2, 3, false, true);
        shadeGlow = new GlowFilter(sColor, 0.3, 4, 4, 2, 3, false, true);
        shade = new Shape();
        bottom = new Shape();
        light = new Shape();
        base = new Shape();
        txt = new TextField();
        addChild(shade);
        addChild(bottom);
        addChild(light);
        addChild(base);
        addChild(txt);
        createBase(shade, _width, _height, corner, sColor);
        shade.filters = [shadeGlow];
        createBase(bottom, _width, _height, corner, sColor, 0.3);
        createBase(light, _width, _height, corner, gColor);
        light.filters = [blueGlow];
        createBase(base, _width, _height, corner, bColor);
        txt.x = -_width*0.5;
        txt.y = -_height*0.5;
        txt.width = _width;
        txt.height = _height - 1;
        txt.type = TextFieldType.DYNAMIC;
        txt.selectable = false;
        //txt.embedFonts = true;
        //txt.antiAliasType = AntiAliasType.ADVANCED;
        var tf:TextFormat = new TextFormat();
        tf.font = fontType;
        tf.size = 12;
        tf.align = TextFormatAlign.CENTER;
        txt.defaultTextFormat = tf;
        txt.text = label;
        enabled = true;
        mouseChildren = false;
    }
    private function rollOver(evt:MouseEvent):void {
        _over();
    }
    private function rollOut(evt:MouseEvent):void {
        _up();
    }
    private function press(evt:MouseEvent):void {
        _down();
    }
    private function release(evt:MouseEvent):void {
        _up();
    }
    private function click(evt:MouseEvent):void {
    }
    private function _up():void {
        txt.y = -_height*0.5;
        txt.textColor = upColor;
        base.y = -1;
        light.visible = false;
        light.y = -1;
    }
    private function _over():void {
        txt.y = -_height*0.5;
        txt.textColor = overColor;
        base.y = -1;
        light.visible = true;
        light.y = -1;
    }
    private function _down():void {
        txt.y = -_height*0.5 + 1;
        txt.textColor = overColor;
        base.y = 0;
        light.visible = true;
        light.y = 0;
    }
    private function _off():void {
        txt.y = -_height*0.5 + 1;
        txt.textColor = offColor;
        base.y = 0;
        light.visible = false;
        light.y = 0;
    }
    public function get clicked():Boolean {
        return _clicked;
    }
    public function set clicked(param:Boolean):void {
        _clicked = param;
        enabled = !_clicked;
        if (_clicked) {
            _down();
        } else {
            _up();
        }
    }
    public function get enabled():Boolean {
        return _enabled;
    }
    public function set enabled(param:Boolean):void {
        _enabled = param;
        buttonMode = _enabled;
        mouseEnabled = _enabled;
        useHandCursor = _enabled;
        if (_enabled) {
            _up();
            addEventListener(MouseEvent.MOUSE_OVER, rollOver, false, 0, true);
            addEventListener(MouseEvent.MOUSE_OUT, rollOut, false, 0, true);
            addEventListener(MouseEvent.MOUSE_DOWN, press, false, 0, true);
            addEventListener(MouseEvent.MOUSE_UP, release, false, 0, true);
            addEventListener(MouseEvent.CLICK, click, false, 0, true);
        } else {
            _off();
            removeEventListener(MouseEvent.MOUSE_OVER, rollOver);
            removeEventListener(MouseEvent.MOUSE_OUT, rollOut);
            removeEventListener(MouseEvent.MOUSE_DOWN, press);
            removeEventListener(MouseEvent.MOUSE_UP, release);
            removeEventListener(MouseEvent.CLICK, click);
        }
    }
    private function createBase(target:Shape, w:uint, h:uint, c:uint, color:uint, alpha:Number = 1):void {
        target.graphics.beginFill(color, alpha);
        target.graphics.drawRoundRect(-w*0.5, -h*0.5, w, h, c*2);
        target.graphics.endFill();
    }
}


//////////////////////////////////////////////////
//    AI用共通const定義 (by Hamlet) 
//////////////////////////////////////////////////

class AiHeader {
    //石色定義
    public static const BLACK:int =  -1;
    public static const WHITE:int =  1;
    public static const EMPTY:int =  0;
    public static const DUMMY:int =  9;
    
    //盤面ポジション定義
    //     A  B  C  D  E  F  G  H
    // 1) 10 11 12 13 14 15 16 17
    // 2) 19 20 21 22 23 24 25 26
    // 3) 28 29 30 31 32 33 34 35
    // 4) 37 38 39 40 41 42 43 44
    // 5) 46 47 48 49 50 51 52 53
    // 6) 55 56 57 58 59 60 61 62
    // 7) 64 65 66 67 68 69 70 71
    // 8) 73 74 75 76 77 78 79 80
    public static const A1:int = 10;
    public static const B1:int = 11;
    public static const C1:int = 12;
    public static const D1:int = 13;
    public static const E1:int = 14;
    public static const F1:int = 15;
    public static const G1:int = 16;
    public static const H1:int = 17;
    public static const A2:int = 19;
    public static const B2:int = 20;
    public static const C2:int = 21;
    public static const D2:int = 22;
    public static const E2:int = 23;
    public static const F2:int = 24;
    public static const G2:int = 25;
    public static const H2:int = 26;
    public static const A3:int = 28;
    public static const B3:int = 29;
    public static const C3:int = 30;
    public static const D3:int = 31;
    public static const E3:int = 32;
    public static const F3:int = 33;
    public static const G3:int = 34;
    public static const H3:int = 35;
    public static const A4:int = 37;
    public static const B4:int = 38;
    public static const C4:int = 39;
    public static const D4:int = 40;
    public static const E4:int = 41;
    public static const F4:int = 42;
    public static const G4:int = 43;
    public static const H4:int = 44;
    public static const A5:int = 46;
    public static const B5:int = 47;
    public static const C5:int = 48;
    public static const D5:int = 49;
    public static const E5:int = 50;
    public static const F5:int = 51;
    public static const G5:int = 52;
    public static const H5:int = 53;
    public static const A6:int = 55;
    public static const B6:int = 56;
    public static const C6:int = 57;
    public static const D6:int = 58;
    public static const E6:int = 59;
    public static const F6:int = 60;
    public static const G6:int = 61;
    public static const H6:int = 62;
    public static const A7:int = 64;
    public static const B7:int = 65;
    public static const C7:int = 66;
    public static const D7:int = 67;
    public static const E7:int = 68;
    public static const F7:int = 69;
    public static const G7:int = 70;
    public static const H7:int = 71;
    public static const A8:int = 73;
    public static const B8:int = 74;
    public static const C8:int = 75;
    public static const D8:int = 76;
    public static const E8:int = 77;
    public static const F8:int = 78;
    public static const G8:int = 79;
    public static const H8:int = 80;
    
    //その他、定数定義
    public static const FASTESTFIRST:int = 8;
    public static const EVALUE_FIRST:int = 3;
    public static const INFINITY:int = 128;
    public static const MIDGAME_DEPTH:int = 4;    //中盤4手読み
    public static const ENDGAME_DEPTH:int = 12;    //終盤12手読み
}

//////////////////////////////////////////////////
//    盤面の評価値を算出するクラス (by Hamlet)
//////////////////////////////////////////////////
class AiManager extends AiHeader {
    //CPU思考用・仮想ボード配列
    private var ban:AiBoard = new AiBoard();
    //CPU思考用・先読み処理
    private var Search:SearchEngine = new SearchEngine();

    //機能: 指定の場所(x, y)に石を置いた場合の評価値を計算する
    //備考: 評価値計算ロジックに合わせるため、bMapの2次元盤面データをvtBoard1次元盤面配列に変換する。
     public function Think(bMap:Array, p:int , x:int , y:int):int {
        var nPos:int = 0, nCol:int=EMPTY;
        var nVal:int = 0, nTurn:int = 0;
        var nEmpties:int = 0, nDepth:int = MIDGAME_DEPTH;
        var i:int, j:int;
        var board:Array = ban.board;
        var bestmove:Array = [0];
        var discdiff:int = 0;
        var strX:Array = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H'];//debug用
        var strY:Array = ['1', '2', '3', '4', '5', '6', '7', '8'];//debug用
 
        //仮想盤面(vtBoard)に現在の盤面(bMap)の内容をセットする
        for (i = 0; i < 91; i++) {
            board[i] = DUMMY;
        }
        for (i = 0; i < 8; i++) {
            for (j = 0; j < 8; j++) {
                nPos = (i + 1) * 9 + j + 1;
                switch (bMap[i][j]) {
                    case 1:
                        if (p == 1) {
                            board[nPos] = BLACK;
                            discdiff++;
                        }
                        else {
                            board[nPos] = WHITE;
                            discdiff--;
                        }
                        break;
                    case 2:
                        if (p == 1) {
                            board[nPos] = WHITE;
                            discdiff--;
                        }
                        else {
                            board[nPos] = BLACK;
                            discdiff++;
                        }
                        break;
                    default:
                        board[nPos] = EMPTY;
                        nEmpties++;
                 }
             }
         }
 
        //仮想盤面(9*10+1)の座標に変換
        nPos = (y + 1) * 9 + x + 1;
        if (nEmpties > ENDGAME_DEPTH) {
            //評価関数による評価値算出
            if (nDepth >= nEmpties) nDepth = nEmpties - 1;
            nVal = Search.midGameThink(ban, BLACK, nEmpties, discdiff, nPos, nDepth) & 0xFFFFFFFE;
        }
        else {
            //終盤読み切りによる最終スコア算出
            nVal = Search.endGameThink(ban, BLACK, nEmpties, discdiff, nPos);
        }
        
        return nVal;
     }   
}

//////////////////////////////////////////////////
//    盤面の空所を記録するリスト (by Hamlet)
//////////////////////////////////////////////////
class EmptyList {
    public var square:int;
    public var pred:EmptyList;
    public var succ:EmptyList;
}

//////////////////////////////////////////////////
//    AI用盤面管理クラス。高速処理用に別途用意。 (by Hamlet)
//////////////////////////////////////////////////
class AiBoard extends AiHeader {
    public var board:Array = new Array(91);
    public var flipStack:Array = new Array(1200);
    public var flipStackP:int = 0;
    public var emHead:EmptyList = new EmptyList();
    public var ems:Array = new Array(60);
    
    private const dirMask:Array = [
        0,0,0,0,0,0,0,0,0,
        0,81,81,87,87,87,87,22,22,
        0,81,81,87,87,87,87,22,22,
        0,121,121,255,255,255,255,182,182,
        0,121,121,255,255,255,255,182,182,
        0,121,121,255,255,255,255,182,182,
        0,121,121,255,255,255,255,182,182,
        0,41,41,171,171,171,171,162,162,
        0,41,41,171,171,171,171,162,162,
        0,0,0,0,0,0,0,0,0,0
    ];
    
    public function undoFlips( flipCount:int, oppcol:int ):void {
        if ( (flipCount & 1) != 0 ) {
            flipCount--;
            board[flipStack[--flipStackP]] = oppcol;
        }
        while ( flipCount > 0 ) {
            flipCount -= 2;
            board[flipStack[--flipStackP]] = oppcol;
            board[flipStack[--flipStackP]] = oppcol;
        }
    }

    public function anyFlips( sqnum:int, color:int ):Boolean {
        var dir:int = dirMask[sqnum];
        
        if (board[sqnum] != EMPTY) 
            return false;

        if ( (dir & 128) != 0 )
            if ( anyDrctnlFlips( sqnum, -10, color ) > 0) return true;
        if ( (dir & 64) != 0 )
            if ( anyDrctnlFlips( sqnum,  10, color ) > 0) return true;
        if ( (dir & 32) != 0 )
            if ( anyDrctnlFlips( sqnum,  -9, color ) > 0) return true;
        if ( (dir & 16) != 0 )
            if ( anyDrctnlFlips( sqnum,   9, color ) > 0) return true;
        if ( (dir & 8) != 0 )
            if ( anyDrctnlFlips( sqnum,  -8, color ) > 0) return true;
        if ( (dir & 4) != 0 )
            if ( anyDrctnlFlips( sqnum,   8, color ) > 0) return true;
        if ( (dir & 2) != 0 )
            if ( anyDrctnlFlips( sqnum,  -1, color ) > 0) return true;
        if ( (dir & 1) != 0 )
            if ( anyDrctnlFlips( sqnum,   1, color ) > 0) return true;

        return false;
    }

    private function anyDrctnlFlips( sqnum:int, inc:int, color:int ):int {
        var pos:int = sqnum + inc;
        var oppcol:int = -color;
        
        if( board[pos] == oppcol ){
            pos += inc;
            if( board[pos] == oppcol ){
                pos += inc;
                if( board[pos] == oppcol ){
                    pos += inc;
                    if( board[pos] == oppcol ){
                        pos += inc;
                        if( board[pos] == oppcol ){
                            pos += inc;
                            if( board[pos] == oppcol ){
                                pos += inc;
                            }
                        }
                    }
                }
            }
            if( board[pos] == color ) return 1;
        }

        return 0;
    }
    
    public function countFlips( sqnum:int, color:int ):int {
        var count:int = 0;
        var dir:int = dirMask[sqnum];
        
        switch (dir) {
        case    81:    // A1 A2 B1 B2
            count += ctDrctnlFlips( sqnum,  +1, color );
            count += ctDrctnlFlips( sqnum, +10, color );
            count += ctDrctnlFlips( sqnum,  +9, color );
            break;
        case    22:    // G1 G2 H1 H2
            count += ctDrctnlFlips( sqnum,  -1, color );
            count += ctDrctnlFlips( sqnum,  +8, color );
            count += ctDrctnlFlips( sqnum,  +9, color );
            break;
        case    41:    // A7 A8 B7 B8
            count += ctDrctnlFlips( sqnum,  -9, color );
            count += ctDrctnlFlips( sqnum,  -8, color );
            count += ctDrctnlFlips( sqnum,  +1, color );
            break;
        case    162:// G7 G8 H7 H8
            count += ctDrctnlFlips( sqnum,  -9, color );
            count += ctDrctnlFlips( sqnum, -10, color );
            count += ctDrctnlFlips( sqnum,  -1, color );
        break;
        case    87:    // C1 C2 D1 D2 E1 E2 F1 F2
            count += ctDrctnlFlips( sqnum,  -1, color );
            count += ctDrctnlFlips( sqnum,  +8, color );
            count += ctDrctnlFlips( sqnum,  +9, color );
            count += ctDrctnlFlips( sqnum, +10, color );
            count += ctDrctnlFlips( sqnum,  +1, color );
            break;
        case    121:// A3 A4 A5 A6 B3 B4 B5 B6
            count += ctDrctnlFlips( sqnum,  -9, color );
            count += ctDrctnlFlips( sqnum,  -8, color );
            count += ctDrctnlFlips( sqnum,  +1, color );
            count += ctDrctnlFlips( sqnum, +10, color );
            count += ctDrctnlFlips( sqnum,  +9, color );
            break;
        case    182:// G3 G4 G5 G6 H3 H4 H5 H6
            count += ctDrctnlFlips( sqnum,  -9, color );
            count += ctDrctnlFlips( sqnum, -10, color );
            count += ctDrctnlFlips( sqnum,  -1, color );
            count += ctDrctnlFlips( sqnum,  +8, color );
            count += ctDrctnlFlips( sqnum,  +9, color );
            break;
        case    171:// C7 C8 D7 D8 E7 E8 F7 F8
            count += ctDrctnlFlips( sqnum,  -1, color );
            count += ctDrctnlFlips( sqnum, -10, color );
            count += ctDrctnlFlips( sqnum,  -9, color );
            count += ctDrctnlFlips( sqnum,  -8, color );
            count += ctDrctnlFlips( sqnum,  +1, color );
            break;
        case    255:// C3 C4 C5 C6 D3 D4 D5 D6 E3 E4 E5 E6 F3 F4 F5 F6
            count += ctDrctnlFlips( sqnum, -10, color );
            count += ctDrctnlFlips( sqnum,  -9, color );
            count += ctDrctnlFlips( sqnum,  -8, color );
            count += ctDrctnlFlips( sqnum,  -1, color );
            count += ctDrctnlFlips( sqnum,  +1, color );
            count += ctDrctnlFlips( sqnum,  +8, color );
            count += ctDrctnlFlips( sqnum,  +9, color );
            count += ctDrctnlFlips( sqnum, +10, color );
            break;
        }

        return count;
    }
    
    private function ctDrctnlFlips( sqnum:int, inc:int, color:int ):int {
        var pos:int = sqnum + inc;
        var oppcol:int = -color;
        
        if( board[pos] == oppcol ){
            pos += inc;
            if( board[pos] == oppcol ){
                pos += inc;
                if( board[pos] == oppcol ){
                    pos += inc;
                    if( board[pos] == oppcol ){
                        pos += inc;
                        if( board[pos] == oppcol ){
                            pos += inc;
                            if( board[pos] == oppcol ){
                                if( board[pos + inc] == color ) return 6;
                            }
                            else if( board[pos] == color ) return 5;
                        }
                        else if( board[pos] == color ) return 4;
                    }
                    else if( board[pos] == color ) return 3;
                }
                else if( board[pos] == color ) return 2;
            }
            else if( board[pos] == color ) return 1;
        }

        return 0;
    }

    public function doFlips( sqnum:int, color:int ):int    {
        var dir:int = dirMask[sqnum];
        var OldFlipStackP:int = flipStackP;

        switch (dir) {
        case    81:        // A1 A2 B1 B2
            drctnlFlips( sqnum,  +1, color );
            drctnlFlips( sqnum, +10, color );
            drctnlFlips( sqnum,  +9, color );
            break;
        case    22:        // G1 G2 H1 H2
            drctnlFlips( sqnum,  -1, color );
            drctnlFlips( sqnum,  +8, color );
            drctnlFlips( sqnum,  +9, color );
            break;
        case    41:        // A7 A8 B7 B8
            drctnlFlips( sqnum,  -9, color );
            drctnlFlips( sqnum,  -8, color );
            drctnlFlips( sqnum,  +1, color );
            break;
        case    162:    // G7 G8 H7 H8
            drctnlFlips( sqnum,  -9, color );
            drctnlFlips( sqnum, -10, color );
            drctnlFlips( sqnum,  -1, color );
        break;
        case    87:        // C1 C2 D1 D2 E1 E2 F1 F2
            drctnlFlips( sqnum,  -1, color );
            drctnlFlips( sqnum,  +8, color );
            drctnlFlips( sqnum,  +9, color );
            drctnlFlips( sqnum, +10, color );
            drctnlFlips( sqnum,  +1, color );
            break;
        case    121:    // A3 A4 A5 A6 B3 B4 B5 B6
            drctnlFlips( sqnum,  -9, color );
            drctnlFlips( sqnum,  -8, color );
            drctnlFlips( sqnum,  +1, color );
            drctnlFlips( sqnum, +10, color );
            drctnlFlips( sqnum,  +9, color );
            break;
        case    182:    // G3 G4 G5 G6 H3 H4 H5 H6
            drctnlFlips( sqnum,  -9, color );
            drctnlFlips( sqnum, -10, color );
            drctnlFlips( sqnum,  -1, color );
            drctnlFlips( sqnum,  +8, color );
            drctnlFlips( sqnum,  +9, color );
            break;
        case    171:    // C7 C8 D7 D8 E7 E8 F7 F8
            drctnlFlips( sqnum,  -1, color );
            drctnlFlips( sqnum, -10, color );
            drctnlFlips( sqnum,  -9, color );
            drctnlFlips( sqnum,  -8, color );
            drctnlFlips( sqnum,  +1, color );
            break;
        case    255:    // C3 C4 C5 C6 D3 D4 D5 D6 E3 E4 E5 E6 F3 F4 F5 F6
            drctnlFlips( sqnum, -10, color );
            drctnlFlips( sqnum,  -9, color );
            drctnlFlips( sqnum,  -8, color );
            drctnlFlips( sqnum,  -1, color );
            drctnlFlips( sqnum,  +1, color );
            drctnlFlips( sqnum,  +8, color );
            drctnlFlips( sqnum,  +9, color );
            drctnlFlips( sqnum, +10, color );
            break;
        }

        return flipStackP - OldFlipStackP;
    }

    private function drctnlFlips( sqnum:int, inc:int, color:int ):void {
        var pos:int = sqnum + inc;
        var sq:int = board[pos];
        var oppcol:int = -color;
        
        if( sq == oppcol ) {
            sq = board[pos += inc];
            if( sq == oppcol ) {
                sq = board[pos += inc];
                if( sq == oppcol ) {
                    sq = board[pos += inc];
                    if( sq == oppcol ) {
                        sq = board[pos += inc];
                        if( sq == oppcol ) {
                            sq = board[pos += inc];
                            if( sq == oppcol ) {
                                if( board[ pos + inc] != color ) return;
                                board[pos] = color;
                                flipStack[ flipStackP++ ] = pos;
                            }
                            else if (sq != color) return;
                            pos -= inc;
                            board[pos] = color;
                            flipStack[ flipStackP++ ] = pos;
                        }
                        else if (sq != color) return;
                        pos -= inc;
                        board[pos] = color;
                        flipStack[ flipStackP++ ] = pos;
                    }
                    else if (sq != color) return;
                    pos -= inc;
                    board[pos] = color;
                    flipStack[ flipStackP++ ] = pos;
                }
                else if (sq != color) return;
                pos -= inc;
                board[pos] = color;
                flipStack[ flipStackP++ ] = pos;
            }
            else if (sq != color) return;
            pos -= inc;
            board[pos] = color;
            flipStack[ flipStackP++ ] = pos;
        }
    }
}

//////////////////////////////////////////////////
//    盤面の探索を行うクラス (by Hamlet)
//    先読みを実行する探索処理用クラス
//////////////////////////////////////////////////

class SearchEngine extends AiHeader {
    private var evalue:Evaluate;
    
    private const worst2best:Array = [
        20, 25, 65, 70,
        11, 16, 19, 26, 64, 71, 74, 79,
        21, 24, 29, 34, 56, 61, 66, 69,
        22, 23, 38, 43, 47, 52, 67, 68,
        31, 32, 39, 42, 48, 51, 58, 59,
        13, 14, 37, 44, 46, 53, 76, 77,
        30, 33, 57, 60,
        12, 15, 28, 35, 55, 62, 75, 78,
        10, 17, 73, 80 
    ];
    
    public function SearchEngine() {
        evalue = new Evaluate();
    }

    //指定の場所に石を打った場合の最終スコアを算出する。
    public function endGameThink( ban:AiBoard, color:int, empties:int, discdiff:int, sqnum:int ):int {
        var oppcol:int = -color;
        var flipped:int, score:int;
        var board:Array = ban.board;
        var square:Array = [0];
        
        flipped = ban.doFlips( sqnum, color );
        board[sqnum] = color;
        score = -endSolve( ban, square, oppcol, empties-1, -discdiff-(flipped*2)-1 );
        ban.undoFlips( flipped, oppcol );
        board[sqnum] = EMPTY;

        return score;
    }
    
    //指定の場所に石を打った場合の盤面評価値を算出する。
    public function midGameThink( ban:AiBoard, color:int, empties:int, discdiff:int, sqnum:int, depth:int ):int {
        var oppcol:int = -color;
        var flipped:int, score:int;
        var board:Array = ban.board;
        var square:Array = [0];
        
        flipped = ban.doFlips( sqnum, color );
        board[sqnum] = color;
        score = -midGame( ban, square, oppcol, empties-1, -discdiff-(flipped*2)-1, depth-1 );
        ban.undoFlips( flipped, oppcol );
        board[sqnum] = EMPTY;

        return score;
    }
    
    //ゲームの木の探索前の準備処理 (空き場所リストの作成)
    private function prepareToSolve( ban:AiBoard ):void {
        var i:int, j:int, sqnum:int;
        var board:Array = ban.board;
        var Ems:Array = ban.ems;

        j = 0;
        var EmPtr:EmptyList = ban.emHead;
        for (i = (60-1); i >= 0; i--) {
            sqnum = worst2best[i];
            if ( board[sqnum] == EMPTY ) {
                Ems[j] = new EmptyList();
                EmPtr.succ = Ems[j];
                Ems[j].pred = EmPtr;
                j++;
                EmPtr = EmPtr.succ;
                EmPtr.square = sqnum;
            }
        }
        EmPtr.succ = null;
    }

    //指定盤面に対する最善手と最終スコアを返す。
    private function endSolve ( ban:AiBoard, bestmove:Array, color:int, empties:int, discdiff:int ):int {
        prepareToSolve(ban);
        
          //終盤探索
        if ( empties > FASTESTFIRST ) {
            return fastestFirstEndSolve( ban, bestmove, -64, +64, color, empties, discdiff, 1 );
        }
          else {
              return alphaBetaEndSolve( ban, bestmove, -64, +64, color, empties, discdiff, 1 );
          }
    }

    //終盤の「速さ優先」探索を行う。
    private function fastestFirstEndSolve( ban:AiBoard, bestmove:Array, alpha:int, beta:int, color:int, empties:int, discdiff:int, prevmove:int ):int {
        var i:int, j:int;
        var score:int = -INFINITY;
        var oppcol:int = -color;
        var sqnum:int = 0, ev:int;
        var flipped:int;
        var moves:int = 0;
        var best_value:int, best_index:int;
        var square:Array = [0];
        var goodness:Array = new Array(64);
        var board:Array = ban.board;
        var em:EmptyList, old_em:EmptyList;
        var move_ptr:Array = new Array(64);


        for ( old_em = ban.emHead, em = old_em.succ; em != null; old_em = em, em = em.succ ) {
            sqnum = em.square;
            flipped = ban.doFlips( sqnum, color );
            if ( flipped > 0) {
                board[sqnum] = color;
                old_em.succ = em.succ;
                goodness[moves] = fastEval( ban, oppcol );
                ban.undoFlips( flipped, oppcol );
                board[sqnum] = EMPTY;
                old_em.succ = em;
                move_ptr[moves] = em;
                moves++;
            }
        }

        if ( moves != 0 ) {
              for ( i = 0; i < moves; i++ ) {
                  best_value = goodness[i];
                  best_index = i;
                  for ( j = i + 1; j < moves; j++ ) {
                      if ( goodness[j] > best_value ) {
                          best_value = goodness[j];
                          best_index = j;
                      }
                  }
                  
                em = move_ptr[best_index];
                move_ptr[best_index] = move_ptr[i];
                goodness[best_index] = goodness[i];
                sqnum = em.square;
                
                flipped = ban.doFlips( sqnum, color );
                board[sqnum] = color;
                
                em.pred.succ = em.succ;
                if ( em.succ != null )
                    em.succ.pred = em.pred;

                if ( empties < FASTESTFIRST ) {
                    ev = -alphaBetaEndSolve( ban, square, -beta, -alpha, oppcol, empties-1, -discdiff-(flipped*2)-1, 1);
                }
                else {
                    ev = -fastestFirstEndSolve( ban, square, -beta, -alpha, oppcol, empties-1, -discdiff-(flipped*2)-1, 1 );
                }
                
                ban.undoFlips( flipped, oppcol );
                board[sqnum] = EMPTY;
                
                em.pred.succ = em;
                if ( em.succ != null )
                    em.succ.pred = em;

                if (ev > score) {
                    score = ev;
                    bestmove[0] = sqnum;
                    if (ev > alpha) {
                        alpha = ev;
                        if (ev >= beta) {
                            return score;
                        }
                    }
                 }
            }
        }
        else {
            if ( prevmove == 0 ) {
                if ((discdiff+empties) ==  64) return  64;
                if ((discdiff-empties) == -64) return -64;
                return discdiff;
            }
            else {
                score = -fastestFirstEndSolve( ban, square, -beta, -alpha, oppcol, empties, -discdiff, 0 );
            }
        }
        
        return score;
    }

    //ゲームの木の末端処理。最終的な石差を計算する。
    private function alphaBetaEndSolve( ban:AiBoard, bestmove:Array, alpha:int, beta:int, color:int, empties:int, discdiff:int, prevmove:int ):int    {
        var score:int = -INFINITY;
        var oppcol:int = -color;
        var sqnum:int,flipped:int,ev:int;
        var square:Array = [0];
        var board:Array = ban.board;
        var em:EmptyList, old_em:EmptyList;

        for (old_em = ban.emHead, em = old_em.succ; em != null; old_em = em, em = em.succ) {
            sqnum = em.square;
            flipped = ban.doFlips( sqnum, color );
            if (flipped > 0) {
                board[sqnum] = color;
                old_em.succ = em.succ;
                if (empties == 2) {
                    var flipped1:int;
                    flipped1 = ban.countFlips( ban.emHead.succ.square, oppcol);
                    if (flipped1 > 0) {
                        ev = discdiff + ((flipped-flipped1)*2);
                    }
                    else {
                        flipped1 = ban.countFlips( ban.emHead.succ.square, color);
                        ev = discdiff + (flipped*2);
                        if (flipped1 > 0) {
                            ev += (flipped1+1)*2;
                        }
                        else { 
                            ev++;
                            if (ev == 63) ev++;
                        }
                    }
                }
                else {
                    ev = -alphaBetaEndSolve( ban, square, -beta, -alpha, oppcol, empties-1, -discdiff-(flipped*2)-1, 1);
                }

                ban.undoFlips( flipped, oppcol );
                board[sqnum] = EMPTY;
                old_em.succ = em;

                if (ev > score) {
                    score = ev;
                    bestmove[0] = sqnum;
                    if (ev > alpha) {
                        alpha = ev;
                        if (ev >= beta) {
                            return score;
                        }
                    }
                 }
            }
        }
        
        if(score == -INFINITY){
            if(prevmove == 0){
                if ((discdiff+empties) ==  64) return  64;
                if ((discdiff-empties) == -64) return -64;
                return discdiff;
            }
            else
                return -alphaBetaEndSolve( ban, square, -beta, -alpha, oppcol, empties, -discdiff, 0);
        }

        return score;
    }

    //速さ優先探索用関数。相手の着手可能手数が少なくなる手に高い評価を与える。(但し、隅周辺の石の配置により微調整)
    private function fastEval( ban:AiBoard, oppcol:int ):int {
          var square:int;
          var mobility:int = 0;
        var stability:int = 0;
          var color:int = -oppcol;
         var board:Array = ban.board;
          var em:EmptyList;
         
        //相手が打てる場所の数をカウント
        for ( em = ban.emHead.succ; em != null; em = em.succ ) {
            square = em.square;
            if ( ban.anyFlips( square, oppcol ) ) {
                mobility++;
            }
         }

        //以下、隅周辺の石の配置による微調整
        if (board[A1] == color) {
            stability++;
            if (board[B1] == color) {
                stability++;
            }
            if (board[A2] == color){
                stability++;
            }
        }
        else if (board[A1] == EMPTY) {
            if (board[B2] == color){
                stability--;
                stability--;
            }
        }
        
        if (board[A8] == color) {
            stability++;
            if (board[B8] == color) {
                stability++;
            }
            if (board[A7] == color) {
                stability++;
            }
        }
        else if (board[A8] == EMPTY) {
            if (board[B7] == color){
                stability--;
                stability--;
            }
        }
        
        if (board[H1] == color) {
            stability++;
            if (board[G1] == color) {
                stability++;
            }
            if (board[H2] == color) {
                stability++;
            }
        }
        else if (board[H1] == EMPTY) {
            if (board[G2] == color){
                stability--;
                stability--;
            }
        }
        
        if (board[H8] == color) {
            stability++;
            if (board[G8] == color) {
                stability++;
            }
            if (board[H7] == color) {
                stability++;
            }
        }
        else if (board[H8] == EMPTY) {
            if (board[G7] == color){
                stability--;
                stability--;
            }
        }

          return stability - ( mobility << 4 );
     }
    
    //指定盤面に対する中盤の評価値を返す。
    private function midGame( ban:AiBoard, bestmove:Array, color:int, empties:int, discdiff:int, depth:int ):int {
        prepareToSolve(ban);

        if ( depth > EVALUE_FIRST ) {
            //ゲームの木の上位ノード処理
            return evalFirstMidGame( ban, bestmove, -INFINITY, +INFINITY, color, empties, discdiff, depth, 1 );
        }
          else {
            //ゲームの木の末端ノード処理
              return alphaBetaMidGame( ban, bestmove, -INFINITY, +INFINITY, color, empties, discdiff, depth, 1 );
          }
    }

    //評価値が高いと予想される手を優先的に探索する中盤処理
    private function evalFirstMidGame( ban:AiBoard, bestmove:Array, alpha:int, beta:int, color:int, empties:int, discdiff:int, depth:int, prevmove:int ):int {
        var i:int, j:int;
        var score:int = -INFINITY;
        var oppcol:int = -color;
        var sqnum:int = 0, ev:int;
        var flipped:int;
        var moves:int = 0;
        var best_value:int, best_index:int;
        var square:Array = [0];
        var goodness:Array = new Array(64);
        var board:Array = ban.board;
        var em:EmptyList, old_em:EmptyList;
        var move_ptr:Array = new Array(64);


        //優先的に探索するための前準備
        for ( old_em = ban.emHead, em = old_em.succ; em != null; old_em = em, em = em.succ ) {
            sqnum = em.square;
            flipped = ban.doFlips( sqnum, color );
            if ( flipped > 0) {
                board[sqnum] = color;
                old_em.succ = em.succ;
                goodness[moves] = fastEval( ban, oppcol );
                ban.undoFlips( flipped, oppcol );
                board[sqnum] = EMPTY;
                old_em.succ = em;
                move_ptr[moves] = em;
                moves++;
            }
        }

        //打てる場所すべての評価値を算出する。
        if ( moves != 0 ) {
              for ( i = 0; i < moves; i++ ) {
                  best_value = goodness[i];
                  best_index = i;
                  for ( j = i + 1; j < moves; j++ ) {
                      if ( goodness[j] > best_value ) {
                          best_value = goodness[j];
                          best_index = j;
                      }
                  }
                  
                em = move_ptr[best_index];
                move_ptr[best_index] = move_ptr[i];
                goodness[best_index] = goodness[i];
                sqnum = em.square;
                flipped = ban.doFlips( sqnum, color );
                board[sqnum] = color;
                em.pred.succ = em.succ;
                
                if ( em.succ != null )
                    em.succ.pred = em.pred;

                if ( depth <= EVALUE_FIRST ) {
                    ev = -alphaBetaMidGame( ban, square,  -beta, -alpha, oppcol, empties-1, -discdiff-(flipped*2)-1, depth-1, 1);
                }
                else {
                    ev = -evalFirstMidGame( ban, square,  -beta, -alpha, oppcol, empties-1, -discdiff-(flipped*2)-1, depth-1, 1 );
                }
                
                ban.undoFlips( flipped, oppcol );
                board[sqnum] = EMPTY;
                em.pred.succ = em;
                if ( em.succ != null )
                    em.succ.pred = em;

                if (ev > score) {
                    score = ev;
                    bestmove[0] = sqnum;
                    if (ev > alpha) {
                        alpha = ev;
                        if (ev >= beta) {
                            return score;
                        }
                    }
                 }
            }
        }
        else {
            if ( prevmove == 0 ) {
                if (discdiff > 0) return +INFINITY;
                if (discdiff < 0) return -INFINITY;
                return 0;
            }
            else {
                score = -evalFirstMidGame( ban, square, -beta, -alpha, oppcol, empties, -discdiff, depth, 0 );
            }
        }
        
        return score;
    }

    //末端の探索と評価関数のコール処理
    private function alphaBetaMidGame( ban:AiBoard, bestmove:Array, alpha:int, beta:int, color:int, empties:int, discdiff:int, depth:int, prevmove:int ):int {
        if ( depth < 1 ) return evalue.Eval(ban.board, empties, color);    //末端のため、評価値を計算して返す。

        var score:int = -INFINITY;
        var oppcol:int = -color;
        var sqnum:int = 0, ev:int;
        var flipped:int;
        var moves:int = 0;
        var square:Array = [0];
        var board:Array = ban.board;
        var em:EmptyList, old_em:EmptyList;

        //打てる場所すべての評価値を算出する。
        for (old_em = ban.emHead, em = old_em.succ; em!=null; old_em = em, em = em.succ) {
            sqnum = em.square;
            flipped = ban.doFlips( sqnum, color );
            if (flipped > 0) {
                board[sqnum] = color;
                old_em.succ = em.succ;

                ev = -alphaBetaMidGame( ban, square, -beta, -alpha, oppcol, empties-1, -discdiff-(flipped*2)-1, depth-1, 1);

                ban.undoFlips( flipped, oppcol );
                board[sqnum] = EMPTY;
                old_em.succ = em;

                if (ev > score) {
                    score = ev;
                    bestmove[0] = sqnum;
                    if (ev > alpha) {
                        alpha = ev;
                        if (ev >= beta) {
                            return score;
                        }
                    }
                 }
            }
        }
        
        if(score == -INFINITY){
            if(prevmove == 0){
                if (discdiff > 0) return +INFINITY;
                if (discdiff < 0) return -INFINITY;
                return 0;
            }
            else
                return -alphaBetaMidGame( ban, square, -beta, -alpha, oppcol, empties, -discdiff, depth, 0);
        }

        return score;
    }
}

//////////////////////////////////////////////////
//    盤面の評価値を算出するクラス
//////////////////////////////////////////////////
class Evaluate extends AiHeader {
    //AIデータアレイ
    private var Line1:Array;
    private var Line2:Array;
    private var Line3:Array;
    private var Line4:Array;
    private var Edge8:Array;
    private var Diag8:Array;
    private var Diag7:Array;
    private var Diag6:Array;
    private var Diag5:Array;
    private var Diag4:Array;

    public function Evaluate() {
        init();
    }

    //機能: 評価値算出用パターンデータの登録。
    //戻値: なし。
    //備考: 固定値。変動なし。
    private function init():void {
        Line1 = [
            +0,+43,-69,-43,+45,-64,+20,+20,-66,-13,-3,-65,-37,+32,-69,
            +28,+14,-43,+2,+29,-3,-55,+48,-58,+26,+44,-58,-16,+29,-75,
            -47,+20,-59,+2,+10,-68,-22,-29,-56,-23,+39,-59,+10,+9,-14,
            +2,+24,-39,-48,+5,-49,+32,+40,-45,+0,+25,-54,-34,+14,-3,
            +0,-3,-42,-18,-11,-69,-48,+8,-49,+25,+55,-15,-1,+46,-42,
            -28,+49,-47,+25,+50,-58,-16,+19,-63,-31,+39,-80,+8,-27,-75,
            -32,-9,-60,-57,+18,-63,+5,+16,-21,-4,+16,-3,-73,+11,-57,
            +16,+16,-55,-29,+21,-82,-65,-27,-65,-9,+11,-58,-12,-1,-59,
            -20,+22,-57,+17,-16,-33,-4,+16,-51,-55,+21,-24,+20,+25,-42,
            +4,+13,-38,-24,+40,-31,+14,-3,-42,-23,-26,-36,-45,+8,-41,
            +45,+54,-2,+21,+36,-18,-33,+54,-59,+15,+20,-50,-2,+27,-58,
            -43,+33,-59,+24,+9,-59,-7,-7,-58,-25,+37,-3,+0,-3,+0,
            +0,+0,-3,-7,-3,-45,+7,+33,-40,-18,+1,-28,-38,+15,-25,
            +20,-3,-31,-23,-29,-9,-44,+26,-33,+25,+38,+7,+7,+54,-5,
            -13,+52,-26,+25,+64,-48,+1,+40,-30,-18,+20,-27,+20,+2,-53,
            -7,+21,-44,-26,+47,-51,+18,+37,-10,+0,+41,-27,-43,+37,-56,
            +28,+21,-55,-13,+20,-70,-53,+6,-58,+25,-6,-57,-12,-19,-56,
            -22,+35,-59,-14,-24,-55,-21,-12,-5,-83,+47,-64,+21,+11,-63,
            -32,+0,-68,-52,+52,-64,-2,-46,-71,-43,-61,-69,-28,+6,-62,
            +28,-7,-32,+0,+20,-56,-47,+3,-30,+43,+31,-56,-2,+17,-51,
            -27,+3,-3,+0,-3,-47,-23,-22,-24,-43,-2,-65,+18,+34,-30,
            -7,+23,-53,-30,+35,-41,+22,+18,-57,-22,-8,-65,-30,+30,-75,
            +10,-29,-85,-43,-43,-85,-57,+3,-67,+10,+11,-45,+4,+25,-3,
            -64,+18,-42,+18,+44,-51,-12,+32,-57,-45,-4,-50,+17,+18,-46,
            -6,+0,-47,-12,+33,-63,-8,-16,-55,-17,-21,-75,-54,-44,-65,
            +4,-18,-30,+9,-23,-27,-29,+5,-65,-13,-3,-85,-55,-36,-72,
            -66,+31,+1,+6,+15,+8,+2,+28,-36,-9,+68,-74,-3,+7,-27,
            -2,+4,-14,-60,-9,-91,-6,-25,-68,-13,-4,-76,-5,+14,-97,
            -3,-33,-43,-20,+7,-3,-7,-3,-16,-13,-101,-38,-48,-42,-86,
            -80,-96,-43,+0,-36,-53,-47,-61,-56,-62,-3,-72,-11,+1,-57,
            -10,+33,+5,-9,+4,-95,+76,+102,-40,-8,-12,-90,-43,+65,+21,
            -15,+1,+7,-33,+18,-14,-54,+32,-64,+8,-33,-56,-25,+1,-89,
            -75,+3,-96,-6,+75,-70,-20,-17,-92,-41,+15,-75,+0,-79,-88,
            -43,+21,-71,-35,+47,-25,+25,-33,-2,-24,-56,-3,+71,-68,-66,
            +5,+38,-29,-28,-3,-41,-85,-68,-81,+6,-18,-45,-30,-3,-69,
            -18,+22,-3,+0,-3,+0,+0,+0,-3,-7,-3,+1,+1,+1,+0,
            +0,+0,-3,-1,-1,-3,+0,-3,-7,-7,-7,-3,-7,-3,-47,
            -1,+16,-54,-20,-9,-101,+71,-101,-11,-40,-3,-23,-55,+4,-107,
            -85,+89,-8,+15,-8,-105,-83,-35,-8,+88,+89,-91,-19,-36,-40,
            -14,+58,-3,-7,-3,-103,-14,+11,-38,-73,-39,-105,-105,-8,-101,
            +13,-3,-82,-64,-38,+2,-48,+9,-41,+9,+11,-43,-18,+31,-61,
            -29,+36,-76,+10,+10,-58,-16,-9,-38,-25,+12,-75,+14,+2,-48,
            -24,+7,-36,-14,+58,-54,+23,+0,-40,-21,+18,-32,-43,+66,-56,
            -4,+38,-47,-26,+21,-81,-54,+16,-63,-5,-9,-59,-18,-18,-40,
            -14,+23,-47,+47,-48,-34,-7,-19,+2,-1,+2,-32,+0,-42,-60,
            -34,+3,-85,-49,+15,-23,+13,-50,-21,-27,-16,-29,-7,+45,-73,
            +10,+17,+14,-22,+42,-35,-60,+12,-70,+64,+22,-48,-25,-20,-85,
            -54,+2,-34,+40,+2,-72,-43,-13,-41,-51,+24,-31,+13,-34,-60,
            -28,+2,-63,-41,+10,-54,+0,+32,-54,-43,-15,-73,-47,-17,-88,
            +6,-61,-86,-53,-39,-71,-68,+27,-86,+18,-37,-64,-15,-18,-5,
            -85,-102,-44,+4,+22,-58,-31,+19,-103,-58,+21,-73,+3,-42,-65,
            -30,-13,-70,-17,+21,-67,+10,-61,-29,-43,-25,-65,-80,-5,+42,
            +0,+0,-49,-32,+0,-102,-49,-100,-5,-1,-5,-105,-38,-14,-102,
            -73,-102,-89,-3,-18,-84,-25,+0,-78,-85,-12,-12,-64,+74,-70,
            -47,-27,-85,-58,+93,-97,-76,-103,-35,-52,-80,-71,-103,-54,-46,
            +13,-30,-92,-20,+11,-5,-105,+93,-49,-10,+35,-48,-65,+25,-105,
            -6,-6,-56,-4,-21,-72,-45,-56,-75,-32,-2,-64,+12,-30,-70,
            -10,-14,-43,-66,-33,+34,-13,+6,-49,-5,+27,-101,-14,+19,-28,
            +19,-3,-96,-45,-44,-58,-63,-24,-52,+27,-33,-15,+14,+7,-11,
            -54,-14,-47,-18,+19,-18,-28,-26,-84,-51,+8,-78,-25,-46,-85,
            -26,-35,-34,-38,+11,-3,+0,-3,+0,+0,+0,-3,-7,-3,-54,
            -47,+94,-83,-48,+54,+3,-73,+89,-70,+3,-3,-50,-43,-7,-30,
            -67,-29,-26,+16,+26,-30,-18,+9,+1,-5,+51,-29,+3,+44,-77,
            -25,-8,-30,-14,+21,-76,+1,+1,-97,-25,-18,-29,-38,-10,-81,
            +0,+32,-5,-18,+33,+38,-35,+85,-81,-13,-69,-73,-37,+20,-103,
            -68,+21,-63,-8,-7,-58,-22,-50,-36,-8,+39,-44,-27,-66,-28,
            -45,-61,-6,+88,-6,-100,-23,+19,-84,-57,-20,-105,-103,-6,-103,
            -6,-65,+17,-57,-89,-46,-31,-18,-72,+0,-48,-65,-28,-25,-66,
            -62,-63,-43,-10,+27,-52,-10,-37,-51,-7,+15,-3,+0,-3,-65,
            -44,-76,-77,-67,+1,-37,-16,+8,-28,-25,+8,-29,-18,+45,-44,
            -10,+28,-43,-23,-12,-62,-17,+42,-52,+11,+7,-61,-28,-28,-96,
            -31,+40,-63,-12,-36,-40,-17,-11,-3,-48,-58,-57,-9,+0,-45,
            -20,+29,-65,-32,-6,-55,+8,-39,-35,-12,-29,-44,+0,+31,-27,
            +44,+15,+38,+47,+45,-32,-16,+23,+10,+75,+94,+31,+59,+42,+10,
            +11,+61,-75,-2,+0,-40,-16,-13,-32,-30,+10,+35,+46,+44,+11,
            +69,+88,+55,+1,+72,+51,+70,+99,+47,+56,+67,+3,+17,+28,+7,
            +69,-18,+42,+38,+32,+18,+26,+74,-10,+30,-4,-13,+9,+47,+0,
            -3,+0,-23,+29,+92,-26,+9,+53,-19,-61,-97,+41,+56,+18,-37,
            -7,+22,+0,-48,+43,+38,+96,+44,+103,+85,+103,+46,+15,+96,+6,
            +71,+105,+53,+60,+58,+1,+0,+101,+5,+8,+5,+99,+54,+65,+75,
            -33,+78,-36,+36,+104,+47,+56,+96,+45,-33,+69,-93,+71,-91,+9,
            +65,+52,-24,-34,+2,+0,+71,+32,-36,+37,+79,+0,+32,+78,-61,
            +34,+97,+3,+58,+101,+0,+16,+65,-11,+40,+103,+10,+55,+32,-99,
            -18,+33,+97,+76,+97,-15,+34,+67,-18,+8,+85,-31,+77,-4,+14,
            +24,+33,+0,-33,+53,+102,+102,+102,+8,+69,+86,+52,-48,+99,+0,
            +3,+0,-3,-3,-3,+0,-3,+0,-2,+29,+97,+51,+44,+85,+86,
            -33,+97,+44,+41,-13,-14,+14,+35,-30,-37,+93,+44,+14,+37,-61,
            -24,-32,-75,-66,+66,+15,+58,+65,+19,+36,+59,+0,-36,+32,-11,
            +36,+50,+34,+16,+69,-75,-30,+76,+37,+72,+95,-57,+11,+12,+32,
            -36,+57,-6,+65,+94,+103,+57,+60,+22,-18,+45,+8,+105,+107,+103,
            +82,+101,+3,+10,+91,+5,+105,+5,+99,+25,+70,+75,+6,+102,+49,
            +105,+105,+103,+68,+103,+105,+102,+105,-26,+103,+78,+86,+75,+85,+99,
            +22,+101,+1,+41,+22,+31,+64,+82,+99,+44,+18,+102,-3,+102,+8,
            +28,+105,+5,+1,+5,+3,+85,+5,+1,+40,+78,+0,+0,+0,+5,
            +86,+5,+50,+31,+80,+19,+27,+86,+12,+62,+99,-14,+65,+79,+78,
            +7,+84,+71,+85,+78,+63,+63,+66,+99,+38,+21,-7,+107,+7,+52,
            +20,+40,+30,+19,+85,+26,+103,-91,+44,+70,+86,+33,+75,+86,-93,
            +73,+104,+46,+69,+86,+0,+32,+55,+97,+92,+27,+9,+21,+66,+24,
            -69,+94,+73,+84,-13,+8,+58,+70,+0,-3,+0,+73,+81,-14,+62,
            +50,+69,-99,+74,+98,+0,+14,+31,+47,+18,+74,-3,+28,+86,-52,
            +51,+92,-38,+51,+62,-97,-101,+49,+24,+102,+5,-49,+54,+70,+0,
            -42,+99,+0,+3,+0,+94,+33,+83,-52,+94,+82,+7,+30,+103,+64,
            +30,+71,-40,+38,+103,+101,+85,-14,+73,+44,+43,-99,+22,+76,-99,
            +90,+96,+33,+11,+33,-1,+19,+65,-42,+101,+50,-94,+38,+101,+0,
            +11,+0,-9,+38,+4,+62,+16,+83,-3,+35,-1,+54,+27,+77,+7,
            +44,+72,-10,+0,+78,+0,+3,+0,+3,+3,+3,+0,-3,+0,+5,
            +5,+5,+3,+3,+3,+0,+2,+2,+0,+3,+0,-3,-3,-3,+0,
            -3,+0,+5,+6,+5,+5,+5,+5,+5,+1,+5,+5,+5,+7,+3,
            +3,+3,+0,+2,+2,+0,+3,+0,+2,+2,+2,+0,+1,+2,+0,
            +3,+0,+3,+3,+3,+0,-3,+0,-2,-2,+0,-3,-3,-3,-5,
            -5,-5,+0,+3,+0,-3,-3,-3,+0,-3,+0,-16,+29,-18,+55,
            +53,+83,-36,-25,+86,-98,+78,+22,+1,+42,+60,+40,-9,+91,+0,
            +101,+0,-23,+9,+12,-86,-46,+97,-54,-38,+32,+21,+27,+95,+0,
            -79,+97,-73,+63,+27,-23,+20,+33,-33,-61,+93,+21,+89,+31,-14,
            -6,+13,-45,-7,+82,-5,+11,+37,+44,+18,+57,-5,-8,-5,-101,
            +32,+96,-88,-27,+56,-105,-103,-6,-102,+36,+93,+23,-29,-41,-55,
            +7,-13,+11,+66,+18,+81,+56,+55,+0,-36,+46,+5,+65,+5,+25,
            +39,+101,+97,-50,+99,+0,+3,+0,-3,-3,-3,+0,-3,+0,-42,
            -1,+97,-35,+5,+75,+36,-18,+78,-82,+35,+31,-71,+10,+42,-78,
            -42,+83,+64,-5,+93,-41,-46,+22,-46,-65,+69,-36,+43,+95,-57,
            +51,+97,+0,-3,+0,-65,+61,+77,-13,+11,+36,-22,-21,+28,+30,
            +75,+0,+0,+18,+3,+32,-39,+60,-40,+35,+45,+20,+46,+82,+0,
            -21,+51,+27,+72,+60,+28,+58,+74,-7,+31,+73,-38,+82,+3,-5,
            +16,+31,+57,-14,+47,-24,-17,+103,+89,+71,+16,-23,+33,+77,+10,
            +65,+79,+43,+68,+85,-47,+42,+99,-35,+45,+83,+35,+54,+80,+15,
            +9,+81,+39,+50,+33,-8,+31,+57,+3,+0,+3,+1,+21,+62,+27,
            +24,+19,-50,-25,+14,+35,+53,+55,+0,+20,+30,+37,-25,+67,+29,
            +61,+88,+7,+85,+16,+41,+28,+37,+69,+35,+103,+58,+75,+87,-33,
            +18,+91,+102,+105,+5,+52,+36,+49,+61,+7,+76,-33,+58,+96,+40,
            +57,+70,+14,+1,+31,+51,+86,+86,-2,+66,+54,-9,+2,+5,-2,
            +88,+95,+0,+41,+56,+36,+33,+78,-7,+85,+85,+34,+59,+78,-2,
            -9,+18,-22,+59,+71,-18,+46,+68,-31,+0,+33,+14,+68,+75,-35,
            +23,+18,-42,+8,+82,-2,+65,+47,+70,+47,+57,+3,+7,+31,+8,
            +105,+105,+7,+42,+48,-94,-19,+103,+3,+7,+3,+0,+0,+0,+3,
            +0,+3,-24,+97,+101,+39,+53,+78,+23,-56,+3,+72,+72,+70,-20,
            +29,+43,-52,-18,+57,+47,-7,+57,-52,-12,+15,-99,-61,+96,+15,
            +96,+59,+46,+42,+104,+3,+58,+84,-68,+48,+101,-25,+16,+45,-99,
            +11,+41,+21,+85,+97,+5,+25,+45,+40,-11,+71,-37,+45,+42,+37,
            +51,+74,+13,-23,+52,+4,+48,+101,+53,+55,+64,-62,-9,+66,-94,
            +38,+3,+25,+13,-4,-34,+27,+83,+6,+84,+58,+38,+63,+87,+88,
            -12,+81,+1,+58,+66,+18,+58,+72,-62,-20,+45,+3,+29,+60,+18,
            +40,+66,-10,-8,+81,-19,+83,+86,-21,+40,+48,+3,+0,+3,-24,
            +60,+70,+0,+25,+45,-1,+0,-21,+31,+38,+101,-27,+17,+37,+26,
            -37,+72,-20,+43,+67,+58,+57,+85,+71,+4,+82,+18,+70,+85,+26,
            +58,+72,-73,+21,+46,+101,+23,+3,+20,+27,+30,+14,-26,+61,-13,
            +73,+52,+30,+55,+54,+23,-17,+35,+21,+54,+86,+0,+43,+57,-46,
            -15,+49,-11,+70,+33,+2,+20,+22,-9,+20,+47,-36,+18,+35,-15,
            +50,+43,-3,+4,+94,-10,+47,+43,-18,+19,+38,-86,-27,+67,-1,
            +27,+42,-43,-8,-26,-47,-12,+49,-28,+52,+53,+2,+56,+19,-25,
            -42,-4,-38,+49,+78,+0,+45,+45,+49,+3,+51,-3,+0,-3,-7,
            +1,+62,-8,+54,+72,-47,+77,+32,+24,+48,+68,-1,-3,+79,+9,
            +48,+69,-26,+29,+38,-63,+19,+62,-28,+40,+56,-58,+0,+45,-53,
            -20,+71,-63,+49,+69,+10,+42,+45,-3,-39,+94,-49,+58,+83,-53,
            +21,+37,-103,+25,+93,-51,+30,+36,-28,+32,+19,-31,+29,+62,-61,
            +40,-13,-6,+45,+31,+57,-36,+61,-35,+92,+70,-10,+21,-4,+94,
            +7,-15,-101,+40,-3,-46,-26,-3,-19,-44,+23,+20,+28,+65,+19,
            +55,+49,-44,+18,+99,+43,+64,+40,+15,+43,+30,-8,-13,+76,-3,
            +2,+12,-34,+21,-9,-3,-18,+36,-3,+0,-3,+0,+0,+0,-3,
            -7,-3,+92,+34,+83,+21,-11,+62,-8,-14,-8,+66,+43,-3,+8,
            -22,+19,+13,-76,+52,-28,+28,+32,+12,+30,+80,+35,-4,+88,+50,
            +84,+82,-24,+15,+66,-64,-18,+65,+99,+54,+2,-39,-7,-9,-51,
            -35,+71,-12,+5,+79,+0,+10,+56,-21,+21,+92,-55,+60,+66,-30,
            -3,+22,-44,-39,+95,-39,+56,+13,-40,-19,-16,-47,-50,+51,-41,
            +15,-32,-19,+2,+15,-5,-35,-5,-69,+40,+33,-38,-9,+45,-103,
            -80,-4,-84,-8,+22,-89,-43,-52,-11,-28,+55,-55,+65,+22,+0,
            +32,+30,-81,-61,+4,+34,+29,+80,-2,+14,+37,+38,-16,+43,-3,
            +0,-3,-70,-29,+19,-14,-7,+46,-7,+30,+67,-12,-7,+18,-55,
            -3,+98,-43,-14,+74,-58,-29,-26,+14,-13,+93,+60,+57,-41,-7,
            -61,-52,-103,-89,+85,-23,+70,+12,+6,+33,+45,-3,-38,+48,-22,
            +43,+72,-37,-1,+19,-103,-56,-30,-9,+55,+3,-20,+0,-3,-38,
            -29,+54,-49,+55,+23,+9,+50,+51,-30,-44,-36,-11,+56,+45,+51,
            +65,+52,-54,+36,+8,-97,+101,+0,-21,+21,+61,-37,-33,+70,+42,
            +103,+96,+84,+64,+37,+102,+4,-93,+33,+73,+84,+1,+59,+82,+0,
            +12,+41,-58,+81,+86,-14,+52,+88,-97,+51,+99,-61,+70,+53,-66,
            +25,+31,+0,-3,+0,-2,+23,+49,-31,+5,-4,-5,-5,-102,+0,
            +43,+46,-35,+3,+4,-41,-63,+29,+19,+52,+72,-60,+75,+77,-64,
            +68,-93,-91,+97,+105,+28,+80,+81,+99,+66,+28,+5,+8,+5,-47,
            +54,+99,-44,-14,+70,-44,+63,+69,+39,+58,+31,-21,+3,+69,-93,
            +88,+86,+11,+64,+35,-97,+10,+80,+0,+75,+97,+2,+37,+92,+0,
            +85,+63,-36,+78,+97,+3,+59,+3,+0,-101,+0,+73,+63,+103,-3,
            +49,+79,-1,-12,+98,+58,+91,+78,+35,+35,+98,-7,+45,+68,+0,
            +3,+0,+3,+3,+3,+0,-3,+0,+5,+5,+5,+3,+3,+3,+0,
            +2,+2,+0,+3,+0,-3,-3,-3,+0,-3,+0,-80,+76,+65,-99,
            +27,+18,+0,-68,+0,+95,+34,+0,-101,+48,+94,+7,-102,+93,-5,
            -21,-5,-102,+47,-5,-5,-6,+93,-91,+28,+32,+101,+31,+84,+0,
            -3,+0,+95,+75,+0,+94,+11,+94,-5,+93,-5,+97,+65,+0,+38,
            +18,+48,+75,-58,+71,-14,+57,+61,+22,+42,+73,+65,+5,+8,+3,
            +49,+91,+49,+57,+66,+9,+12,+0,-95,+103,+2,+68,+40,-15,+11,
            +19,+99,+31,+100,+101,+69,+64,+91,+101,+65,+28,-15,+44,+21,+10,
            +58,+46,-73,+2,+96,-73,+66,+91,+22,+20,+65,+11,+21,+37,-18,
            +54,+99,-92,+45,+103,+2,-1,+2,+0,+32,+99,+24,+14,+51,-3,
            -100,-100,+2,+16,+99,-1,+3,+43,+23,+15,+27,+9,+44,+28,+43,
            +41,+99,+82,-9,+41,-96,+12,+101,-9,+47,+45,-101,+16,+96,-95,
            +11,+2,-72,+33,+76,-44,+8,+59,+22,+81,+2,+55,+56,+5,+73,
            +15,+80,+0,+54,+55,-21,+45,+49,+93,-17,+95,+93,+96,+93,-51,
            +6,+95,+93,+21,+46,+31,+47,+93,-43,+59,+57,-5,+89,+93,+15,
            +56,+76,-1,+39,+62,+26,+93,+93,-33,+74,+83,-10,+30,+93,-51,
            +42,+61,-79,+43,-97,-34,+30,+14,-5,-96,-102,+0,-42,+0,+38,
            +49,-21,-24,+15,-100,-5,-1,-5,-8,+15,-8,-102,+89,+93,-34,
            +29,+33,-50,+26,+33,+98,-68,+98,+96,+70,+98,-18,+20,+67,-71,
            +21,+93,+91,+95,-6,-69,+52,-4,-6,-6,+93,+93,-34,+76,+35,
            +24,+41,-5,-8,-5,-3,+76,-1,-4,-27,+93,-8,-6,-6,+11,
            +65,+28,-27,-4,-30,-10,-6,+79,-4,+63,+10,+23,+67,+47,+36,
            +31,+70,-93,+46,+102,+63,+63,+83,+42,+58,+99,+91,+91,+0,-15,
            +8,+23,-15,-24,+23,+31,+44,+78,+41,+59,+76,+5,+32,+70,-31,
            +86,+85,+36,+69,+61,-73,+24,+59,+36,+25,+97,+7,+47,+71,+61,
            -10,+34,+0,+3,+0,+3,+3,+3,+0,-3,+0,+18,+47,+82,+19,
            +8,+72,-102,-102,+93,+61,+97,+0,-39,-2,+46,+10,+1,+91,-9,
            +37,+74,+7,+65,+81,+42,+14,+99,+34,+89,+18,+47,+49,+81,-7,
            +23,+37,+80,+47,+2,+24,+37,+36,+2,+11,+34,+0,+81,+78,+12,
            +51,+78,+54,+47,+63,-22,+31,+94,+13,+32,+47,-26,+27,+46,+44,
            +64,+82,+33,+35,+51,+36,+39,+86,-31,+52,+66,-20,+41,+96,-5,
            +89,+93,-31,+54,+65,-6,+18,+71,-49,-54,+93,-42,-1,+69,+24,
            +3,+85,-35,+40,+86,+0,+72,+43,+55,+62,+67,-11,-3,+29,+79,
            +67,+86,+28,+59,+72,+52,+45,+27,+0,+3,+0,+2,+26,+52,+31,
            -29,+91,+9,+26,+85,+28,+33,+82,+16,+22,+68,-9,+73,+86,+20,
            +39,+49,-12,+21,+61,-19,+72,-13,-29,+6,+55,-38,-18,+86,+4,
            +64,+57,+61,+57,+71,+0,+9,+71,+14,+41,+78,+37,+22,+62,+6,
            -2,+79,+49,+63,+60,+40,+33,+54,+27,+31,+56
        ];
 
        Line2 = [
            +0,-5,-31,-23,+4,-18,+11,-13,-6,-13,-13,-21,-10,+1,-14,
            -1,+1,+3,+2,-2,-18,-18,+1,-20,+5,+14,-7,-10,-14,-43,
            -18,-4,-18,-3,-4,-13,-16,-21,-27,-19,-8,-12,+1,+3,+5,
            +2,+0,-24,-16,+1,-5,+5,+15,+4,+0,-6,-21,-7,-2,-27,
            -10,-4,-17,-20,-23,-24,-19,-8,-11,-3,+8,+2,-1,-6,-18,
            -28,+2,-12,+3,+16,-4,-10,-17,-45,-30,-19,-23,-3,-11,-13,
            -18,-22,-37,-24,-11,-15,-5,-5,+3,+0,-3,-17,-18,-1,-21,
            -15,-5,-11,-16,-22,-41,-30,-16,-17,-5,-6,-14,-18,-22,-26,
            -17,-9,-11,+0,-5,+7,+2,+0,-16,-17,-3,-1,+5,+24,+7,
            +0,-4,-14,-10,+0,-18,-6,-12,-18,-21,-23,-21,-21,-15,+2,
            +11,+14,+13,+7,+3,-8,-5,+4,+8,+10,+30,+5,-2,-4,-26,
            -26,-9,-12,+11,-6,-9,-10,-13,-12,-11,-1,-9,-4,-6,+3,
            +0,-6,-7,-18,-2,-14,-14,+2,-14,-20,-22,-37,-25,-8,-18,
            -5,-10,-17,-20,-24,-17,-20,-12,-6,+4,+12,+6,+6,+3,-16,
            -9,-2,-1,-8,+17,+7,+1,-6,-21,-20,-1,-13,+2,+0,-7,
            -10,-12,-15,-14,+0,-15,-3,+12,+2,+0,-8,-9,-17,+3,-12,
            +1,+27,-8,-13,-16,-44,-35,-14,-24,-4,-19,-16,-23,-24,-39,
            -22,-10,-22,-7,-9,-6,-7,-13,-33,-25,-6,-18,-10,-9,-15,
            -18,-25,-52,-40,-23,-18,-8,-6,-23,-22,-26,-33,-27,-19,-11,
            -3,-8,+3,+0,-2,-18,-19,-5,-8,-5,+13,+1,-2,-6,-18,
            -14,-12,-21,-7,-8,-16,-20,-25,-18,-21,-11,-20,-7,-6,-5,
            -6,-14,-17,-25,-9,-15,+1,+6,-12,-16,-21,-47,-40,-32,-28,
            -10,-30,-21,-22,-28,-36,-28,-20,-11,-2,-7,+0,-2,-5,-16,
            -16,-3,-17,-13,+0,-12,-18,-24,-40,-26,-20,-14,-5,-8,-13,
            -16,-22,-23,-17,-9,-10,+4,+1,+6,+5,+3,-8,-14,+5,+4,
            +18,+11,+6,+5,-1,-13,-8,+3,-15,+3,+0,-14,-17,-14,-11,
            -18,-4,+4,+14,+17,+13,+8,+14,-4,-9,-8,-5,+9,+30,+0,
            +3,-1,-29,-26,-8,-10,+5,+7,+4,-9,-13,-5,-25,+3,-10,
            +7,+6,+8,+5,+6,-8,-14,+2,-11,+4,+4,-13,-16,-29,-35,
            -25,-3,-18,+0,+2,-18,-19,-20,-13,-19,-5,+5,+13,+22,+13,
            +10,+12,-18,-9,-2,+10,+18,+34,+12,+3,+15,-34,+6,-4,+1,
            +11,+32,-5,-5,-5,-22,-2,+13,+13,+32,+8,+11,+4,+5,+8,
            +8,+1,-3,+9,+41,+0,-11,-6,-42,-15,-11,+4,+0,+22,-9,
            -17,-16,-33,-31,+9,-22,-17,+14,-3,-11,-26,-3,-25,-5,-29,
            +10,+24,-3,-28,-17,-36,-20,-27,-11,-5,-21,-26,-25,-16,-23,
            -24,-13,-9,+2,+3,+9,+7,+5,-14,-14,+4,-7,+20,+19,+15,
            +10,+0,-15,+0,-17,-11,+0,-1,-14,-18,-15,-8,-17,-5,+1,
            +6,+21,+5,-2,-6,+16,-25,+12,-14,+18,+12,-11,-18,-24,-45,
            -37,-39,-25,-11,-19,-17,-25,-37,-29,-55,-35,-10,+9,+0,+1,
            +6,+0,-15,-20,+2,-8,+2,+9,-9,-18,-20,-38,-22,-26,-19,
            -3,-8,-18,-16,-19,-15,-20,-10,-10,+0,+3,+10,+13,+8,-16,
            -8,+2,+23,+5,+39,+21,+15,-4,+23,-13,+20,-19,-2,-15,-16,
            -10,-14,-12,-20,-10,-4,+5,+35,+4,+10,+20,-31,+6,+19,+5,
            -17,+28,+5,-5,-11,-9,-5,-18,+0,-10,+31,-12,-20,-32,-37,
            +4,+15,-1,+23,+5,+9,+14,+20,-11,+0,+0,+0,+0,-15,-3,
            -7,-15,-29,-26,+23,-14,-4,+16,-14,-14,-25,-11,-24,+0,-8,
            +18,+26,+3,-1,+9,-13,-26,+12,+5,+25,+45,+14,-3,-2,-15,
            -5,+0,-9,-18,+40,-15,-26,-15,-34,-27,-1,-23,-9,+16,-3,
            -1,-1,+21,-15,-15,-22,+0,+33,-13,-23,-18,-45,-36,+9,-47,
            -9,-24,-28,-35,-36,-47,-17,-6,-37,-5,-7,-18,-10,+9,-31,
            -37,-20,-28,+17,+30,-23,-30,-28,-54,-46,+1,-45,-9,-33,-38,
            -40,-39,-45,-40,-30,-21,-3,-14,-4,+5,+0,-31,-25,-17,-2,
            +0,+8,-23,-5,-12,-42,-26,-2,-23,-20,+14,-34,-25,-29,-29,
            -42,-10,-43,-11,+15,-17,+8,+8,-41,-20,-19,-22,-25,-25,-15,
            -18,-27,-54,-46,-52,-47,-18,+21,-36,-40,-33,-53,-55,+2,-24,
            +7,-19,-3,-5,-8,-23,-22,+2,-29,-5,+3,-35,-30,-36,-51,
            -43,+8,-26,-18,-13,-21,-26,-31,-35,-33,-21,-13,-1,-8,+2,
            +2,+0,-14,-18,-7,-3,-7,+12,+8,+5,-6,-20,-20,-6,-21,
            -9,-13,-22,-21,-24,-24,-21,-13,+19,+15,-9,+0,+7,+5,-20,
            -2,+5,+6,+5,+26,-5,+1,-10,-45,-27,-13,-10,+17,+10,-19,
            -14,-25,-37,-20,-14,-8,+0,-10,+7,+4,-1,-11,-17,-1,-22,
            -23,-16,-12,-19,-25,-49,-42,-36,-24,-7,-13,-20,-21,-26,-21,
            -25,-14,-6,+12,-7,-1,+7,-6,-21,-25,-13,-19,+11,+15,-14,
            +3,-2,-48,+4,-22,-41,-6,+9,-16,-11,-15,-32,-20,+0,-7,
            +0,-21,-11,+3,-13,-30,-31,-14,+3,+9,+34,-8,-10,-23,-51,
            -17,+5,-22,-32,-54,-22,-22,-23,-44,-15,-21,-37,-15,-11,-13,
            -11,-19,-40,-55,+4,-45,-5,+0,-24,-24,-32,-53,-55,-25,-28,
            -14,-19,-19,-28,-33,-40,-23,-21,-13,+0,-7,+4,+3,-2,-12,
            -19,-5,-14,+3,+0,+2,-1,-9,-19,-24,-11,-19,-2,-8,-17,
            -20,-24,-22,-25,-16,-23,-12,-13,-4,-4,-7,-19,-24,+2,-12,
            -18,+6,-17,-19,-20,-44,-40,-20,-20,-13,-25,-18,-27,-24,-50,
            -23,-23,-10,+1,-7,+1,+0,-4,-18,-20,-10,-14,+0,-17,-17,
            -17,-24,-35,-33,-32,-20,-4,-11,-16,-17,-21,-23,-18,-8,+4,
            +23,+10,+22,+23,+18,+7,+1,+14,+17,+35,+39,+27,+26,+19,+3,
            +3,+16,-1,+15,+8,-1,-5,-2,-6,-8,+5,+21,+40,+45,+35,
            +33,+23,+6,+22,+26,+42,+45,+49,+30,+27,+23,+7,+26,+20,+16,
            +23,+3,+21,+12,+12,-13,-7,+7,+13,+21,+15,+17,+17,+13,+7,
            +3,+17,+1,+11,+16,+5,+3,-1,-5,-14,-22,+0,+13,+4,-2,
            -8,-5,+0,-7,+5,+21,+50,+45,+29,+36,+35,+4,+17,+39,+40,
            +53,+50,+44,+37,+42,+12,+35,+35,+6,+29,+18,-15,+14,+27,+17,
            -9,+7,+24,+44,+29,+27,+39,+45,+14,+8,+14,+20,+47,+34,+25,
            +21,+29,+0,+16,+2,-19,+33,+19,+18,+12,+22,+0,-21,+31,+6,
            +37,+12,+17,+12,+16,+0,+21,+13,+23,+37,-10,+17,+8,+9,-5,
            +15,+25,+10,+5,+4,+4,-6,+0,+13,-13,-1,+8,+22,+15,+24,
            +18,+12,+15,+6,+23,+29,+29,+45,+18,+24,+27,+20,+5,+35,-5,
            +8,+4,-2,-6,-9,+0,-10,+8,-10,+32,+12,+36,+15,+17,+38,
            +14,+11,+10,+34,+38,+1,+1,+9,-14,-7,-47,-23,+22,-31,-9,
            -9,-7,-17,-11,-8,+13,+24,+14,+21,+21,+18,+0,+0,+15,+9,
            +12,+13,-1,-5,-4,-28,-19,+0,-2,+11,+6,-1,-7,-6,+6,
            -7,+4,+24,+35,+39,+43,+40,+38,+19,+11,+22,+59,+51,+24,+49,
            +41,+22,+41,+39,+48,+20,+38,+15,+29,+24,+15,+28,+12,+22,+38,
            +53,+50,+50,+52,+33,+57,+34,+50,+54,+54,+53,+32,+43,+36,+22,
            +45,+43,+16,+36,+30,+13,+17,+24,+5,+15,+27,+14,+49,+45,+22,
            +37,+26,+17,+19,-26,+47,+29,+34,+5,+15,+5,+0,+8,-9,+29,
            +35,+42,+21,+13,+18,+5,+0,+29,+40,+44,+49,+42,+47,+39,+40,
            +30,+37,+42,+54,+53,+47,+45,+45,+43,+28,+45,+52,+45,-5,+27,
            +30,+13,+14,+26,+44,+14,+51,+34,+39,+44,+43,+33,+41,+42,+40,
            +45,+52,+37,+31,+34,+0,+33,+36,+7,+42,+25,-9,+27,+32,+0,
            +34,+29,+7,+45,+38,+13,+26,+28,+38,+12,+23,-6,+9,+22,+31,
            +16,-25,-22,-25,-3,+27,+29,+20,+0,+6,+5,-7,+6,+27,+21,
            +19,+16,+16,+18,+28,-4,+4,+16,+50,+42,+34,+23,+21,+28,+0,
            -15,+40,-24,+15,+38,+20,+2,-17,-20,-16,+2,-21,+48,-10,+26,
            +21,+13,+9,+24,+27,+32,+15,+22,+13,+14,+5,-43,+30,-10,-5,
            +34,-43,-3,-9,+3,-12,+0,+8,+10,+20,+13,+14,+14,+9,+3,
            +9,+15,-25,-23,+4,-10,-5,+6,-41,+3,+2,-1,+13,+24,+0,
            +0,-4,-3,-17,+3,+4,+18,+8,+10,+16,+9,+4,+0,+13,+24,
            +23,+15,+17,+17,+33,-3,-15,+8,-1,+15,+19,-4,-12,-14,+0,
            -13,+7,+24,+40,+18,+34,+33,+34,+31,+32,-13,+12,+31,-5,+22,
            +18,+18,-38,+40,+40,+38,+3,+0,+27,+0,-9,+0,+9,-22,+1,
            +11,+4,+16,+7,-3,+0,-1,+6,+0,+11,+38,+13,-4,-30,-17,
            +14,+26,-7,+8,+6,-10,-8,-5,-7,-8,+0,-23,+19,+3,+15,
            +17,+11,-22,+7,+29,+8,+41,+30,+24,+18,+30,-9,+31,+8,+19,
            -16,+0,-17,-6,+13,-38,+10,-5,+18,+30,+19,+6,+9,+12,+0,
            +22,+19,+19,-21,+25,-8,-13,+14,-33,-24,+11,+9,-8,-14,+20,
            -19,-12,-14,-54,-12,-16,+20,-31,+20,+8,-28,-31,-19,+13,-45,
            +31,-43,-24,-11,+6,-57,+21,+21,-7,+4,-15,-19,-30,-21,-6,
            -25,+1,-3,+12,+4,+15,+18,+3,+0,+2,+8,+24,+31,+42,+24,
            +24,+22,+4,+16,+36,-3,+14,+6,-9,-10,-20,-15,-13,-5,+24,
            +21,+4,+7,+16,-8,+22,-21,+11,+0,+13,+20,-4,-4,-4,-40,
            -33,+5,+12,+18,-15,-3,-6,-6,-4,-19,-33,+5,+14,+6,+7,
            +16,+8,-4,-8,+6,+18,+16,+24,+2,-6,-9,-19,-13,+2,-5,
            +8,+10,-5,-8,-11,-7,-11,+2,+8,+16,+18,+18,+13,+9,+5,
            +3,+8,+15,+21,+38,+21,+14,+16,+0,+8,+12,+0,+18,+9,+1,
            +0,-4,+1,+0,+2,+27,+19,+35,+27,+23,+6,+19,+12,+18,+17,
            +38,+39,+15,+13,+9,+0,+9,+7,+28,+26,+11,+1,+3,-3,-4,
            -6,+6,+7,+20,+12,+14,+17,+11,+10,+5,+15,+8,+14,+28,+5,
            +0,-7,-21,+0,-9,+1,+18,+3,+0,-2,-9,+2,-2,+4,+3,
            +18,+23,+24,+21,+6,+3,+14,+6,+26,+36,+33,+32,+13,+14,+3,
            +20,+24,+17,+17,+34,+12,+3,+2,+9,+5,+18,+9,+22,+45,+26,
            +16,+21,-20,+5,+33,+11,+28,+43,+13,+6,+3,+9,-1,+5,+8,
            +9,+12,+0,-8,-9,-18,-13,+12,-8,+19,+17,+7,+9,+2,-27,
            -6,+5,-16,+12,+13,+0,-6,-10,-13,+8,+7,-6,-4,-8,-1,
            -14,-18,-21,-7,-1,+13,+17,+13,+16,+16,+11,+9,+6,+18,-1,
            +34,+26,+21,+17,+11,-20,+20,+9,+2,+14,-3,+0,-6,-13,+2,
            -1,+0,+21,+16,+16,+12,+7,+2,+17,-26,+5,-19,+15,+28,-10,
            -2,-6,-27,+9,-27,+19,+5,-28,-12,-13,-23,+15,-19,-10,+18,
            +22,+18,+20,+18,+10,+4,+0,+13,+4,+16,+9,+5,-3,-13,-29,
            -8,-7,+5,+14,+8,-1,-5,-12,+1,-4,+5,+7,+17,+19,+18,
            +12,+16,-2,-1,+13,+29,+35,+22,+11,+11,+2,+10,-4,+29,+1,
            +9,+33,-5,-4,-9,+1,-6,+5,+13,+24,+42,+24,+15,+14,+24,
            +15,+26,+9,+23,+45,+11,+7,+6,-31,-2,+14,+4,+3,+30,+0,
            -6,-7,-17,-2,+14,+12,+12,+27,+21,+14,+11,-13,+0,+21,+0,
            +3,+28,+0,-6,-13,-5,-12,+13,+13,+13,+22,-5,-6,-13,-5,
            -9,+6,+13,+17,+23,+16,+12,+9,+4,-1,+19,+1,+15,+36,+6,
            +4,+6,-13,-11,+21,+12,+11,+18,+10,-4,-12,-1,-10,+5,+0,
            +8,+29,+8,+8,+3,+8,-6,+7,-6,+13,+34,+0,-5,-4,-37,
            -18,+7,-23,+0,+14,-13,-16,-12,-25,-23,-1,-16,+5,+9,-2,
            -5,-6,-22,-24,+2,-24,-5,+5,-11,-17,-22,-32,-27,-1,-9,
            +0,-4,-15,-21,-25,-30,-20,-16,-7,-2,-1,+4,-1,-7,-24,
            -29,-16,-9,+23,+5,+0,-4,-13,-23,-15,-16,-22,-15,-30,-21,
            -22,-30,-18,-25,-5,-10,+14,+9,+9,-7,-10,-24,-17,-11,-24,
            -14,-25,-6,-14,-22,-47,-28,-40,-34,-12,+6,-32,-25,-21,-44,
            -32,-18,-16,-8,-4,-7,-7,-13,-17,-20,-13,-26,-21,+6,-11,
            -22,-23,-49,-36,+1,-22,-6,-9,-21,-24,-28,-27,-24,-21,-8,
            -1,-2,+1,+0,-4,-7,-14,-1,-5,+3,+15,+7,-3,-9,-14,
            -14,-9,-15,-1,-14,-20,-23,-28,-21,-24,-16,-6,+13,+27,+4,
            +6,+2,-20,-5,-4,+14,+18,+13,+2,-3,-12,-13,-15,-9,-12,
            +3,+13,-7,-12,-22,-17,-15,-17,-12,-7,-9,+0,-3,-13,-16,
            -15,+2,-20,-9,-17,-21,-23,-30,-22,-29,-20,-17,-8,-20,-14,
            -25,-30,-17,-24,-16,-13,+4,+12,+9,+5,-3,-7,-13,-6,-23,
            +17,+24,-9,-2,-7,-26,-32,-1,-3,-5,-9,-12,-13,-22,-36,
            -25,-2,+10,+11,+22,+0,-2,-9,-6,-16,-12,-22,+3,+32,-8,
            -13,-12,-39,-36,-5,-27,-11,-12,-26,-24,-32,-27,-23,-18,-29,
            +0,-7,-4,-13,-23,-34,-37,-17,-34,-4,+3,-24,-22,-21,-50,
            -33,-29,-23,-13,-6,-27,-28,-32,-35,-24,-15,-8,-4,-5,+0,
            -3,-9,-15,-20,-7,-12,+4,+18,-4,-5,-13,-16,-25,-10,-15,
            -9,-5,-16,-24,-30,-24,-26,-15,-16,+1,+0,-9,-6,-18,-15,
            -16,-17,-16,-3,+5,-16,-21,-25,-42,-39,-19,-16,-13,-21,-24,
            -26,-32,-29,-33,-22,-6,-2,-6,-1,-7,-12,-10,-19,-2,-12,
            -10,-4,-18,-22,-28,-43,-31,-7,-13,-6,-11,-18,-22,-24,-22,
            -21,-13,+4,+20,+14,+13,+14,+8,+5,+5,+14,+14,+26,+22,+22,
            +17,+13,+1,+2,+11,+0,+19,+13,-5,-3,-1,+2,-7,+11,+23,
            +28,+39,+23,+18,+6,+7,-2,+29,+16,+45,+37,+9,+18,+19,-27,
            +12,+21,-4,+11,+29,+6,-2,-6,-10,-13,+10,+11,+24,+23,+17,
            +18,+18,+7,+4,+18,-15,+14,+16,-13,+1,-16,-29,-17,-6,+0,
            +18,+8,-1,-5,-7,+0,-5,+8,+20,+20,+26,+16,+28,+18,-12,
            -8,+29,+25,+47,+50,+34,+23,+26,+5,+19,+33,+9,+25,-13,-19,
            +4,-4,+23,+5,-11,+28,+22,+14,+27,+24,+33,-9,+1,+10,+17,
            +47,+42,+23,+18,+7,-7,-15,+9,+0,-4,+19,-8,+3,-12,+19,
            -14,+2,-8,+10,+11,+12,+12,+5,-38,+12,+24,+4,+0,+27,-4,
            +2,-11,-16,-19,+2,+4,+10,+11,-28,-9,-17,-16,+2,-7,+6,
            +19,+17,+15,+21,+15,+3,+2,+18,+34,+23,-26,+22,+27,+21,+24,
            +0,+25,+0,+11,+6,-2,-2,+2,+5,-1,+11,-2,+41,+13,+3,
            +13,+5,-19,-5,+24,+36,+9,+23,-12,+1,+2,-52,-20,+18,-9,
            -1,+13,-17,-6,-17,-6,+4,-10,+7,+21,+15,+15,+18,+13,+1,
            +2,+6,+4,+19,+15,-1,-1,-13,-20,+2,+9,+0,+15,+6,+0,
            -3,-2,+1,-10,+7,-4,+14,+16,+12,+17,+12,-18,+3,+11,+27,
            +29,+48,+26,+21,+29,+25,+20,+38,-4,+8,+8,-4,+0,-9,-9,
            -6,+4,+11,+45,+35,+34,+18,+24,+45,-4,+33,+30,+28,+45,+24,
            +20,+21,+6,+0,+27,-4,+29,+8,+16,-1,-1,-23,-22,+28,+7,
            +22,+35,+20,+14,+9,+0,-17,+25,+0,+0,+40,+0,-2,-16,-47,
            -2,+3,+15,+11,+36,-8,-12,-10,-1,-11,+27,-1,+12,+20,+16,
            +15,+7,+0,-8,+21,-17,+22,+43,+24,+12,+14,-32,-18,+27,-36,
            +14,+40,+19,-9,-9,-10,-13,+11,-2,-3,+2,+22,+12,+5,-19,
            -11,+9,+0,+22,+36,+6,+4,+7,-40,+9,+15,-17,+3,+11,-11,
            -14,-5,-20,+5,-2,-8,-6,-47,-14,-8,-27,-12,-39,+18,-30,
            -5,-10,-9,-19,-40,-54,-52,+23,-16,+5,+5,-17,-32,-19,-42,
            -20,-15,+6,+14,-22,+12,+8,-9,-24,-3,-6,+0,+2,-9,+9,
            +5,+13,-50,+23,+3,-34,+7,+26,+1,-8,-20,-29,-36,-11,-7,
            +19,+25,+23,+1,+7,-8,-27,+2,+17,-5,-3,-1,-4,-1,-42,
            +1,+23,-25,-10,+21,-26,-23,-29,-40,-25,+23,-4,+3,+0,+5,
            +1,-7,-24,-26,+9,-27,-23,+2,-29,-16,+1,-59,+8,+10,-14,
            -4,+2,-15,-20,-7,-17,-32,-7,-1,+10,+5,+6,+11,+2,-5,
            -4,+11,+4,+24,+22,+16,+15,+5,-10,-10,+4,-7,+10,+7,-18,
            -15,-16,-13,-13,-5,+20,+37,+7,+29,+22,+18,+16,+13,-11,+8,
            +37,+44,+16,+14,+5,-7,-1,+11,+8,+22,-5,+8,+0,-2,-6,
            +0,+0,+0,+8,+8,+12,+9,+0,-1,-5,+11,-7,+1,+2,-12,
            -8,-5,-14,-10,-11,-11,+10,-5,-7,-11,-15,-13,-16,+2,+5,
            +23,+7,+16,+20,+6,-24,+3,+10,+7,+43,+27,+10,+11,+14,+21,
            +15,+28,+2,-1,-22,-21,-1,-17,+10,-14,+0,+0,+7,+31,-10,
            +15,+12,-18,+9,+2,+2,+23,+29,+0,+1,-1,-14,-6,-2,-28,
            -13,-12,-9,-10,-18,-24,-21,+13,-20,-19,-8,+6,-2,-10,-24,
            -35,-10,-11,+4,+8,-13,-11,-18,-38,+2,+23,-23,-4,-33,-27,
            -20,-22,-21,-23,-16,+0,+13,+5,+8,+11,+4,+3,-5,+8,-6,
            +21,+29,+7,+12,+6,-21,+0,+27,-6,+9,+0,-13,-12,-16,-8,
            -14,+2,-5,+6,-1,+13,+6,-1,+23,-13,-7,+1,+8,+27,-13,
            -8,-16,-40,-30,-15,-20,-5,+1,-3,-19,-15,-21,-21,-16,+1,
            +13,+4,+8,+11,+5,-4,-10,+7,+4,+10,+3,-7,-9,-21,-24,
            -21,-7,-4,+10,+2,-8,-9,-13,-4,-8,+4
        ];
 
        Line3 = [
            +0,-1,-10,-6,+0,-7,+2,-5,-3,-5,+1,-7,-6,+0,-5,
            +1,-3,-3,+0,-2,-10,-11,-7,-4,+0,+0,-3,-4,-2,-8,
            -7,-5,-5,+0,-2,-4,-5,-3,-7,-8,-4,-5,+3,-2,+1,
            +2,-1,-14,-10,-6,+0,+5,-2,+3,+0,-3,-3,-2,+0,-6,
            +2,-1,-13,-9,-8,-11,-10,-6,-5,+1,+6,-3,+0,+0,-6,
            -5,-3,-5,+0,-8,-3,-4,-9,-8,-8,-9,-12,-2,-2,-10,
            -7,-5,-12,-10,-10,-7,+1,-4,-3,-1,-5,-14,-11,-9,-6,
            +1,-3,-12,-6,-9,-8,-10,-12,-6,+0,-5,-5,-5,-7,-9,
            -7,-6,-2,+4,-4,+3,+2,+0,-10,-10,-6,+8,+5,+3,+1,
            +1,-2,-6,-5,-7,-4,+2,-4,-6,-9,-10,-9,-9,-8,+6,
            +8,+4,+4,+3,-4,+1,-6,+0,+3,+9,+2,+3,+0,-2,-7,
            -6,-8,-2,+0,-4,-5,-4,-7,-6,-8,-7,-3,+1,-3,+0,
            +0,-2,-10,-9,-7,-2,-6,-5,-11,-9,-13,-13,-17,-12,-4,
            +1,-2,-8,-10,-9,-8,-11,-8,+2,+4,+2,+1,+3,-1,-1,
            -3,-1,+4,+7,+3,-2,+0,-3,-1,-2,+2,+0,+8,+2,+0,
            -4,-11,+3,-6,+2,-2,+0,-2,-7,+0,-7,-6,-6,-3,-3,
            +1,-2,-8,-5,-3,-18,-10,-12,-4,-2,-19,-11,-9,-10,-17,
            -12,-9,-5,-2,-6,-4,-3,-8,-12,-13,-8,-7,-1,-5,-8,
            -7,-6,-19,-12,-11,-9,-4,-5,-12,-9,-12,-11,-12,-8,-4,
            +1,-5,-3,+0,-4,-13,-12,-8,+1,+3,-2,-3,-2,-3,-5,
            -7,-5,-7,-1,-7,-9,-10,-10,-12,-12,-9,-6,+0,-4,-3,
            -3,+0,-2,-10,-5,-5,+0,+0,-12,-5,-13,-26,-12,-11,-14,
            -7,-2,-11,-9,-3,-14,-11,-12,-6,-1,-6,-2,-2,-7,-14,
            -12,-9,-2,-1,+0,-5,-5,-8,-15,-12,-11,-6,-2,-7,-6,
            -6,-9,-11,-7,-7,-2,+2,-2,+2,+2,+0,-8,-11,-7,+2,
            +2,+4,+3,+0,-7,-1,-4,-4,-3,+0,-1,-9,-10,-10,-10,
            -11,-8,+12,+6,+13,+3,+4,+13,-9,-5,-5,+12,+6,+4,+8,
            +0,+1,+5,-10,-9,-10,+0,+9,-1,-3,+9,-3,-10,-15,-2,
            +0,+1,+3,-1,-2,-10,-12,-7,+5,-10,+2,-11,-10,-15,+1,
            -13,-15,-3,+0,+0,-9,-12,-9,-9,-12,-9,+10,+9,+4,+18,
            +7,+21,+13,-5,+4,-15,+13,+8,-5,+2,+14,-10,-10,+9,+9,
            +1,+8,-5,-6,-1,+1,-10,+10,+10,+4,+18,-6,+2,+3,+9,
            -6,+9,-7,+3,+6,+8,-2,+4,-20,-11,+5,+0,+0,-31,-4,
            -6,+17,+8,-5,-9,+2,+2,-3,+0,+0,-9,-1,-11,-5,+16,
            +0,+10,-1,-5,+3,-12,-12,-1,-5,+0,+2,-7,-10,+0,-10,
            -7,-4,-2,+2,-2,+0,+1,-2,-9,-12,-7,+1,+4,-3,+0,
            -2,-1,-3,-3,-7,-4,+0,-2,-8,-9,-11,-8,-11,-8,-15,
            -4,+5,-7,-8,+6,-24,-11,-18,-3,-5,+2,-13,-11,-10,-7,
            -14,-14,-8,-1,+10,-17,-13,-6,-26,-22,-18,-1,+1,+0,+1,
            -2,-8,-7,-11,-6,-9,-4,+5,-6,-11,-18,-8,-17,-17,-2,
            +0,+0,-10,-12,-18,-7,-12,-7,+4,+3,+5,+6,+1,-6,-1,
            -4,+1,+21,+13,-5,+10,-1,+3,+21,+7,+9,+7,+4,+8,-4,
            -5,-8,-3,-6,-1,+3,+6,+16,-10,+1,+9,-13,-10,-6,+4,
            +8,+9,-5,+0,-7,-5,-5,+27,-1,+0,+11,-6,-2,+0,-15,
            -11,-20,+4,+4,+6,+2,+6,+0,-8,-3,+2,+7,+0,+4,-2,
            -2,-8,+7,+0,+11,+5,+10,+14,-8,-7,+5,-5,-6,-1,-5,
            +1,+0,-19,+0,+1,+1,-10,+2,-8,+0,+14,-9,+0,+8,-14,
            -5,+4,+3,+5,+13,+8,-6,-1,+6,-9,+0,+2,+3,+3,-19,
            -1,-4,-9,-11,-5,-11,+0,+13,-9,-6,-2,+3,-12,-3,-19,
            -3,-28,-9,-10,-21,-27,-16,-7,-6,-3,-21,-5,-9,-15,+7,
            -14,-12,-16,-8,+2,-17,-8,-14,-24,-10,-10,-8,-6,-14,-5,
            -12,+8,-13,-11,-14,-5,-3,-7,-2,-3,-1,-14,-13,-11,+1,
            +0,-1,-1,-5,-19,-13,+0,-10,-8,-4,-6,-19,-17,-17,-16,
            -18,-13,-8,-8,-7,-12,-7,-18,-13,-12,-21,-7,+0,+17,-8,
            -7,-3,-14,-10,-25,-18,-13,-20,-11,-12,-15,-23,-19,-17,-9,
            -6,-10,-2,-5,-9,-17,-17,-14,-10,-13,+0,-7,-10,-13,+3,
            -13,-17,-9,-2,-5,-8,-12,-15,-12,-9,-9,-3,+1,-5,+0,
            +1,-2,-13,-11,-9,+3,+6,+1,+1,-1,-7,-7,-6,-6,-7,
            -1,-8,-11,-9,-12,-12,-12,-11,+7,-1,+0,-5,+2,-9,-2,
            -10,-3,-6,+3,+8,+9,-1,-6,-3,-9,-2,-10,-2,-8,+11,
            -6,-11,-4,-12,-17,-4,+0,-4,+1,-1,-5,-11,-11,-8,-6,
            -4,-10,-17,-10,-17,-17,-18,-26,-5,+0,-3,-13,-12,-13,-12,
            -12,-10,-1,+0,+3,+10,+0,+0,-1,-10,-6,-4,+8,-9,+10,
            -1,+7,-15,-11,+11,-7,+4,-2,+2,-8,-10,-2,-12,+3,+5,
            +0,-1,-2,+0,-14,-11,-5,+5,-21,-3,+4,+7,-6,+3,-31,
            -16,-2,-20,-4,-25,-19,-12,-12,-14,-13,-12,-9,+1,-15,-16,
            -8,+8,-17,-22,-10,-22,-6,-5,-9,-10,-3,+1,-19,-11,-14,
            -6,-2,-17,-11,-10,-20,-13,-11,-4,+0,-6,-1,-1,-6,-13,
            -12,-10,-2,+3,-6,-1,-3,-12,-8,-6,-15,-7,-2,-7,-9,
            -11,-14,-13,-12,-10,+3,+0,-2,-5,-4,-2,-5,-7,+1,-14,
            -1,-7,-5,-8,-10,-19,-11,-18,-10,-9,-5,-11,-12,-17,-14,
            -13,-9,-5,-1,-5,-3,-4,-10,-13,-12,-10,-6,-3,-5,-7,
            -7,-14,-20,-9,-14,-7,-2,-5,-8,-7,-11,-11,-8,-6,+8,
            +11,+10,+14,+11,+11,+0,-2,+3,+14,+12,+17,+17,+9,+10,+1,
            +5,+7,+5,+7,+7,-3,-4,-2,-1,-5,+0,+21,+20,+20,+9,
            +11,+18,+13,+4,+6,+25,+13,+26,+11,+7,+6,-5,+0,+18,+12,
            +10,+9,+5,+2,+5,+4,+3,+4,+8,+12,+7,+13,+8,+8,+4,
            -2,+1,+0,+5,+13,+4,-2,-1,-13,-7,-8,+6,+9,+9,-2,
            -5,-4,+0,-6,-1,+17,+14,+20,+8,+14,-2,+17,+13,+5,+18,
            +23,+22,+14,+12,+10,+11,+16,+5,+3,+26,+9,+1,+4,-22,-1,
            +0,-1,+27,+14,+32,+31,+17,+7,+34,+18,+13,+31,+27,+34,+15,
            +7,+14,-4,+3,+17,+8,-8,+26,-9,-2,+9,+0,-1,+14,+8,
            +4,+2,+21,+6,-4,-7,+5,+9,-11,+15,+33,+5,+6,-3,-18,
            -7,-10,+6,+3,+16,+18,-4,-17,-4,-2,-7,+8,+13,+7,+15,
            +12,+12,+0,+1,+2,+14,+16,+13,+24,+11,+12,-5,+6,+13,+6,
            +8,+6,+5,-3,+1,+0,-4,-1,+14,+2,+2,+6,-3,-24,-27,
            -3,-9,-23,-6,+27,+10,-3,+11,-22,-21,+16,+3,-1,+2,-8,
            -6,+6,+1,-15,-5,+10,+12,+10,+10,+9,+8,+5,+0,+4,+4,
            +3,+18,-8,-4,+2,-7,-10,-12,+8,+10,+10,-4,-6,-4,+1,
            -5,+0,+20,+20,+17,+9,+15,+18,+8,+4,+11,-23,-3,+35,+18,
            +8,+23,+1,-5,+24,+6,+8,+17,+17,+3,-4,+7,+1,+14,+9,
            -1,+22,+27,+19,+32,-21,+8,+33,+4,+24,+4,+31,+8,+4,+23,
            +14,+28,-9,+12,+1,+31,+3,+9,+18,-9,+19,+14,+17,+13,-1,
            +13,+5,-5,-3,+8,+28,-7,-24,-13,-2,+20,+0,-1,+0,+8,
            -1,+16,+17,-2,-12,+13,-6,+7,+21,+19,+26,+21,+26,+11,+22,
            +4,+10,+32,+14,+4,+31,+8,+27,+28,+9,+16,+18,+7,+29,+14,
            +2,+12,+22,+8,+5,+12,+31,+34,+23,+18,+23,+34,+6,+25,-1,
            -3,+33,+4,+10,+12,+0,+13,+29,-27,+20,-5,-13,-2,+16,+4,
            +4,+11,+2,+3,+27,+10,+7,+31,-27,+2,+7,-11,+5,-11,+6,
            -8,+21,-23,+17,+30,-11,-5,+5,-10,+0,-25,+5,-7,-6,+9,
            +8,+13,+0,+5,+2,+4,+2,+1,+13,+13,-24,-15,+3,+12,+0,
            +4,-4,+4,+3,+10,-3,-5,+21,+5,-10,-1,-11,+15,+33,+9,
            +1,-24,+6,+10,+20,-11,+14,-11,-17,+0,-19,-28,+2,+20,+9,
            +10,+27,+2,-5,+30,-11,-5,-1,-3,+7,+18,-18,+6,+10,+0,
            +5,+1,+3,-21,-22,-25,-3,+11,-1,+0,-26,+0,+1,+11,-2,
            +0,+0,-1,-5,-1,+7,+13,+7,+16,+14,+13,-3,-1,+0,+19,
            +17,+17,+13,+14,+13,+0,+8,+11,+3,+7,+5,-4,-4,-7,-5,
            -8,-3,+19,+17,+9,-8,+12,+18,-6,+8,+16,+30,-7,+29,+22,
            +10,+23,+27,+13,+2,+3,+1,+18,-9,+2,+20,+7,-2,+7,+7,
            +11,+6,+11,+10,+9,+0,-2,+1,+6,+8,+10,+1,-1,-10,+5,
            -6,-6,+4,+10,+7,-9,-7,-7,-4,-7,-3,+3,+5,+9,-6,
            +2,-30,+3,+9,+1,-2,+13,+1,-30,+6,+16,-6,+11,-3,-19,
            +24,+18,-12,-4,-3,+27,-8,-25,+10,+11,+26,+25,+6,+17,+0,
            -31,+27,+25,+9,-5,+9,-5,+8,-34,-28,+24,+6,-9,-6,-31,
            -19,-17,-34,-25,-14,-2,+2,+2,-10,-1,-28,+6,+10,-8,-9,
            +13,+27,-12,-2,+11,+21,-20,-16,+0,+9,+7,-32,-2,-32,-13,
            -5,-24,+9,+13,+9,+15,+13,+12,+0,+0,+3,+22,+14,+16,+16,
            +14,+9,-4,+14,+14,+6,+9,+7,+2,-2,-3,+0,-3,-1,+3,
            +1,+16,+15,+1,-2,-3,+2,+3,+12,-1,+5,-4,-2,-6,-22,
            -14,+15,-12,-13,+7,-2,-5,+6,-17,-2,-7,+9,+13,+10,+7,
            +10,+9,+3,+0,+4,+6,+1,+11,-8,-5,-1,-8,-5,-12,+5,
            +8,+9,-4,-7,-6,+0,-5,-1,+9,+8,+11,+11,+6,+8,+4,
            +0,+5,+11,+8,+18,+13,+5,+9,+2,-6,+6,+8,+10,+13,+0,
            +0,+1,+4,-2,+2,+13,+17,-2,+20,+12,+16,+32,+21,+2,+21,
            +5,+11,+24,+4,+13,+10,+1,+19,+15,+7,-30,+6,-1,-23,-18,
            +0,-1,+9,+13,+12,+16,+8,+8,+9,-2,+6,+5,+8,+2,+8,
            -1,+1,-17,-1,+0,+6,+9,+12,+0,-4,-5,+2,-6,+0,+7,
            +11,+18,+16,+11,+16,+2,+13,+6,+7,+11,+32,+15,+10,+25,-2,
            +9,+28,+14,+17,+18,+20,-4,+23,+8,-9,+6,+17,+19,+7,+27,
            +11,+21,+31,+3,+13,+10,+9,+23,+21,+3,+14,+13,-4,+19,+7,
            +4,+17,+0,-7,+3,+9,-14,-8,-2,-11,-24,+28,+5,-7,+9,
            +6,-6,+10,+6,-24,-7,+0,+7,-31,-18,+27,-12,+1,-2,-6,
            +0,-12,-5,-2,-3,+6,+9,+8,+18,+9,+8,-2,-2,+2,-3,
            +19,+5,+10,+13,+21,+3,+0,+20,+3,+8,+9,+0,-2,-4,-5,
            -5,+1,+24,-2,-4,+2,+0,-7,+12,-9,-9,-5,-8,+31,-2,
            -2,-5,-14,-15,+6,-3,+5,-28,-20,-8,+5,-1,+8,-19,+4,
            +11,+8,+10,+6,-4,+4,-8,+2,-4,+4,+10,+7,-5,-13,-17,
            -9,-15,+3,+9,+9,+0,-7,-4,+3,-10,-2,+9,+7,+10,+12,
            +5,+9,+8,-7,+5,+12,+7,+23,+28,+12,+9,+25,+3,+15,+12,
            +6,+13,-7,-2,+0,+8,-7,+5,+6,+9,+10,+11,+8,+25,+12,
            +14,+15,+28,+17,+27,+25,+3,+6,-6,+8,+10,+20,+1,+16,+7,
            -3,+1,-5,+7,+19,+9,+17,+12,-8,+11,+21,-1,-1,-2,-15,
            +2,+12,+0,-3,-17,+13,-19,-20,+8,+11,+9,-8,-3,-8,-4,
            -12,-1,+0,+5,+6,-5,+12,+13,+4,+1,+9,-22,+8,+4,-4,
            +3,+6,+17,-7,-5,-6,+13,+23,+2,-2,+1,-10,-6,+3,+10,
            -7,+14,-12,+8,+14,-9,+4,+22,+6,+9,+12,+0,-1,+6,-4,
            -2,+9,+7,-8,+8,-21,-3,+4,-15,+3,-8,-17,-9,+11,-14,
            -3,-5,-22,-10,+1,-14,+5,-19,-25,-9,-1,-31,-3,+17,-10,
            -8,-6,-24,-13,-11,-11,-10,-10,-3,+1,-1,+1,+3,+1,-16,
            -15,-4,-3,+1,+20,+0,-3,-17,+15,-8,+10,+0,+0,-10,-10,
            -13,-29,-24,-17,-6,+7,-10,-3,-16,+2,+7,+30,+3,+6,-6,
            +9,+21,+4,-2,-1,-31,-14,+17,-13,+5,+11,-15,-6,+10,-14,
            -3,-14,-1,-1,+2,-20,-1,-13,-13,-18,-10,-26,-10,+11,-28,
            -9,-1,-18,-13,-17,-5,-3,-1,-13,-8,-22,-17,-14,-9,+0,
            +3,-2,-1,+2,+1,-7,-10,-8,+5,+2,-4,+20,+3,+0,+18,
            -8,-1,-4,-1,-7,-10,-10,-17,-10,-12,-9,+5,+16,-22,-10,
            +4,+23,+10,-1,+1,+28,+5,+12,+14,+3,+1,-10,-1,-19,+1,
            +0,-3,-28,-11,-13,-21,-10,-2,-4,-1,+1,+0,+0,-4,-11,
            -11,-7,-1,-2,+21,+8,-8,-29,+1,-17,-4,-2,-3,-3,-16,
            -10,-21,-13,-14,-11,+11,+5,+5,+6,+3,-23,-15,+9,+10,+26,
            +12,+9,+16,+3,+1,-9,+0,-2,+2,+7,+20,-2,-7,-13,-6,
            -11,+1,+0,+2,+9,+0,+7,+3,-25,+17,+23,+15,+19,+16,+12,
            +1,+4,-23,-21,-7,-25,+6,-17,-27,-10,-1,-31,-12,-11,+0,
            +5,+6,+10,-4,+5,+8,-6,-8,-4,+10,+30,-11,-5,+10,-27,
            -15,-11,-7,-3,+6,-20,-3,-2,-9,-17,-11,-4,+1,-4,+0,
            +3,-5,-15,-9,-10,-7,+2,-12,-1,-1,-8,+0,+5,-11,-8,
            +0,-7,-18,-9,-21,-15,-13,-12,+9,-10,-17,-6,-1,-12,+6,
            +0,-2,+17,+19,-25,+5,-3,-11,-21,+8,+1,-11,-18,-32,-16,
            -12,-2,-8,-10,-20,-7,+0,-4,+1,-3,-4,-16,-18,-10,-7,
            -6,+0,-12,-7,-22,-9,-15,-25,-8,-2,-6,-11,-9,-14,-14,
            -11,-11,+3,+7,+3,+8,+6,+5,-5,-7,-4,+5,+9,+11,+5,
            +6,+5,+0,+1,+0,+0,+2,+0,-3,-6,-8,-8,-9,-7,+10,
            +14,+5,+7,+9,+6,+0,+4,+3,-1,+8,+10,+10,+5,+9,+11,
            +2,-6,-2,+5,+1,+12,-1,+10,-6,-6,-1,+2,+5,+2,+2,
            +4,+2,-4,-7,-4,-2,-5,+1,-8,-6,-4,-8,-11,-8,+0,
            +3,+3,-6,-8,-10,-6,-10,-6,+7,+10,+6,+11,+14,+2,+12,
            -5,+3,+22,+18,+33,+13,+12,+15,-9,-6,+13,+13,+8,+16,+3,
            +0,+1,-3,-3,-2,+16,+20,+13,+25,+4,+13,-6,+9,+5,-3,
            +19,+25,-7,+7,+22,+27,-5,+7,+0,+0,+27,-7,-3,+23,-8,
            +5,+1,+4,+10,-9,-1,+2,-9,-3,-18,-9,+3,+1,+20,-20,
            -3,+6,+9,-21,+16,+2,+10,+3,-15,-5,-2,-12,+1,-2,+3,
            +7,+1,+8,+7,+6,-6,-7,-4,+10,+8,+8,+0,+6,-2,-4,
            +2,+3,+0,+4,+1,-3,-7,-7,-6,-8,-7,+4,+7,+9,-2,
            +0,-6,+19,-5,-9,-24,-3,+7,+6,-7,+1,-18,-12,-28,-13,
            -9,-8,-14,-8,-8,-3,-10,-2,+4,+7,+4,+4,+4,+2,-3,
            -6,-3,-5,-7,+1,-12,-9,-10,-6,-14,-10,+0,+3,+4,-8,
            -9,-10,-5,-10,-5,+8,+6,+7,+7,+2,+6,-6,-4,+0,+7,
            +10,+24,+26,+6,+15,-3,+9,+20,+5,+9,+11,+4,-7,-1,-4,
            -6,+3,-4,+22,+5,+4,+7,+28,+9,+9,+13,+28,+16,+16,+14,
            +4,-5,+11,+4,+13,-3,-16,-3,-10,+2,-2,+11,+11,+6,+5,
            +6,+13,+1,+2,+20,-6,-7,+3,+0,-7,-4,+15,+0,+10,-28,
            -10,-1,+2,-5,+14,-5,-5,-11,+0,-15,-1,+8,+14,+18,-17,
            +5,+19,-12,-9,-6,+16,+7,+28,+6,+5,+10,+11,+27,+13,+24,
            +3,+2,+5,-8,-19,+23,-2,-5,-9,+21,+17,-15,+3,+19,-25,
            +5,+7,+0,+11,+29,-6,+0,+9,+1,-3,+24,+3,+7,+24,-10,
            -12,-7,-31,-2,+4,-13,+6,+16,-28,-3,+6,-30,-14,-28,-28,
            -4,+20,-28,-9,+17,-4,-25,-2,+1,-12,+15,-21,-11,+1,-25,
            -18,-17,-3,+2,-8,+7,-1,+0,-22,-15,-8,+0,-1,+0,+3,
            +0,-20,-13,+11,-1,-10,-1,-6,+3,-12,-4,-14,-26,-14,-13,
            +4,-10,-26,-4,+27,+2,-1,+16,-16,+8,+30,+22,-5,+17,-32,
            -10,-2,-22,+15,-16,-7,-11,-11,-18,-11,-19,-6,-3,-12,-5,
            -8,-15,-19,-17,-10,-7,-21,-26,-12,-12,-17,+23,-17,-2,-5,
            -2,-12,-11,-11,-25,-14,-14,-12,+1,+5,+0,+7,+6,+2,-9,
            -8,-7,+6,+9,+14,+1,+7,+5,+3,-1,+3,-4,+1,-3,-4,
            -8,-9,-10,-11,-8,+9,+9,-1,+0,+5,+6,+2,+10,-2,+13,
            +6,+5,+17,+5,+3,-2,+0,-5,-4,-2,-25,+2,+2,+1,-8,
            +3,-6,+0,+4,-1,+4,+3,+1,-7,-8,-7,-5,-4,-1,-9,
            -6,-6,-14,-13,-14,-2,+2,-1,-9,-9,-12,-8,-10,-8,+3,
            -3,+4,-9,+6,-1,-3,-15,-1,+13,+8,+19,-7,+5,+19,+11,
            -20,+6,-4,+15,+7,-24,-7,-2,-14,-17,-6,+0,-5,+14,+0,
            +2,-8,-10,-9,+1,+9,-2,+11,-10,+0,-8,-12,-7,+4,-16,
            -10,-14,-17,-9,-11,-27,-12,-9,-9,-7,-5,-5,-6,-19,-19,
            -18,-2,+4,-3,-1,-6,-10,-14,-9,-17,-19,-10,-12,-7,-13,
            -12,-20,-21,-9,-19,+0,+4,-1,+4,+4,+0,-9,-9,-6,+3,
            +5,+7,+3,+5,-1,-9,-1,-1,-3,+2,-3,-6,-8,-11,-8,
            -10,-8,-3,+1,-7,-11,-2,-3,-3,-4,-2,-8,+5,-6,+0,
            -4,-10,-21,-14,-17,-7,-10,-24,-7,-8,-11,-17,-11,-19,-1,
            +3,+0,+0,+2,-2,-7,-7,-5,-8,-4,-1,-9,-6,-9,-20,
            -9,-12,-3,+2,-1,-9,-7,-11,-8,-6,-6
        ];
 
        Line4 = [
            +0,-1,-10,-6,+0,-7,+2,-5,-3,-5,+1,-7,-6,+0,-5,
            +1,-3,-3,+0,-2,-10,-11,-7,-4,+0,+0,-3,-4,-2,-8,
            -7,-5,-5,+0,-2,-4,-5,-3,-7,-8,-4,-5,+3,-2,+1,
            +2,-1,-14,-10,-6,+0,+5,-2,+3,+0,-3,-3,-2,+0,-6,
            +2,-1,-13,-9,-8,-11,-10,-6,-5,+1,+6,-3,+0,+0,-6,
            -5,-3,-5,+0,-8,-3,-4,-9,-8,-8,-9,-12,-2,-2,-10,
            -7,-5,-12,-10,-10,-7,+1,-4,-3,-1,-5,-14,-11,-9,-6,
            +1,-3,-12,-6,-9,-8,-10,-12,-6,+0,-5,-5,-5,-7,-9,
            -7,-6,-2,+4,-4,+3,+2,+0,-10,-10,-6,+8,+5,+3,+1,
            +1,-2,-6,-5,-7,-4,+2,-4,-6,-9,-10,-9,-9,-8,+6,
            +8,+4,+4,+3,-4,+1,-6,+0,+3,+9,+2,+3,+0,-2,-7,
            -6,-8,-2,+0,-4,-5,-4,-7,-6,-8,-7,-3,+1,-3,+0,
            +0,-2,-10,-9,-7,-2,-6,-5,-11,-9,-13,-13,-17,-12,-4,
            +1,-2,-8,-10,-9,-8,-11,-8,+2,+4,+2,+1,+3,-1,-1,
            -3,-1,+4,+7,+3,-2,+0,-3,-1,-2,+2,+0,+8,+2,+0,
            -4,-11,+3,-6,+2,-2,+0,-2,-7,+0,-7,-6,-6,-3,-3,
            +1,-2,-8,-5,-3,-18,-10,-12,-4,-2,-19,-11,-9,-10,-17,
            -12,-9,-5,-2,-6,-4,-3,-8,-12,-13,-8,-7,-1,-5,-8,
            -7,-6,-19,-12,-11,-9,-4,-5,-12,-9,-12,-11,-12,-8,-4,
            +1,-5,-3,+0,-4,-13,-12,-8,+1,+3,-2,-3,-2,-3,-5,
            -7,-5,-7,-1,-7,-9,-10,-10,-12,-12,-9,-6,+0,-4,-3,
            -3,+0,-2,-10,-5,-5,+0,+0,-12,-5,-13,-26,-12,-11,-14,
            -7,-2,-11,-9,-3,-14,-11,-12,-6,-1,-6,-2,-2,-7,-14,
            -12,-9,-2,-1,+0,-5,-5,-8,-15,-12,-11,-6,-2,-7,-6,
            -6,-9,-11,-7,-7,-2,+2,-2,+2,+2,+0,-8,-11,-7,+2,
            +2,+4,+3,+0,-7,-1,-4,-4,-3,+0,-1,-9,-10,-10,-10,
            -11,-8,+12,+6,+13,+3,+4,+13,-9,-5,-5,+12,+6,+4,+8,
            +0,+1,+5,-10,-9,-10,+0,+9,-1,-3,+9,-3,-10,-15,-2,
            +0,+1,+3,-1,-2,-10,-12,-7,+5,-10,+2,-11,-10,-15,+1,
            -13,-15,-3,+0,+0,-9,-12,-9,-9,-12,-9,+10,+9,+4,+18,
            +7,+21,+13,-5,+4,-15,+13,+8,-5,+2,+14,-10,-10,+9,+9,
            +1,+8,-5,-6,-1,+1,-10,+10,+10,+4,+18,-6,+2,+3,+9,
            -6,+9,-7,+3,+6,+8,-2,+4,-20,-11,+5,+0,+0,-31,-4,
            -6,+17,+8,-5,-9,+2,+2,-3,+0,+0,-9,-1,-11,-5,+16,
            +0,+10,-1,-5,+3,-12,-12,-1,-5,+0,+2,-7,-10,+0,-10,
            -7,-4,-2,+2,-2,+0,+1,-2,-9,-12,-7,+1,+4,-3,+0,
            -2,-1,-3,-3,-7,-4,+0,-2,-8,-9,-11,-8,-11,-8,-15,
            -4,+5,-7,-8,+6,-24,-11,-18,-3,-5,+2,-13,-11,-10,-7,
            -14,-14,-8,-1,+10,-17,-13,-6,-26,-22,-18,-1,+1,+0,+1,
            -2,-8,-7,-11,-6,-9,-4,+5,-6,-11,-18,-8,-17,-17,-2,
            +0,+0,-10,-12,-18,-7,-12,-7,+4,+3,+5,+6,+1,-6,-1,
            -4,+1,+21,+13,-5,+10,-1,+3,+21,+7,+9,+7,+4,+8,-4,
            -5,-8,-3,-6,-1,+3,+6,+16,-10,+1,+9,-13,-10,-6,+4,
            +8,+9,-5,+0,-7,-5,-5,+27,-1,+0,+11,-6,-2,+0,-15,
            -11,-20,+4,+4,+6,+2,+6,+0,-8,-3,+2,+7,+0,+4,-2,
            -2,-8,+7,+0,+11,+5,+10,+14,-8,-7,+5,-5,-6,-1,-5,
            +1,+0,-19,+0,+1,+1,-10,+2,-8,+0,+14,-9,+0,+8,-14,
            -5,+4,+3,+5,+13,+8,-6,-1,+6,-9,+0,+2,+3,+3,-19,
            -1,-4,-9,-11,-5,-11,+0,+13,-9,-6,-2,+3,-12,-3,-19,
            -3,-28,-9,-10,-21,-27,-16,-7,-6,-3,-21,-5,-9,-15,+7,
            -14,-12,-16,-8,+2,-17,-8,-14,-24,-10,-10,-8,-6,-14,-5,
            -12,+8,-13,-11,-14,-5,-3,-7,-2,-3,-1,-14,-13,-11,+1,
            +0,-1,-1,-5,-19,-13,+0,-10,-8,-4,-6,-19,-17,-17,-16,
            -18,-13,-8,-8,-7,-12,-7,-18,-13,-12,-21,-7,+0,+17,-8,
            -7,-3,-14,-10,-25,-18,-13,-20,-11,-12,-15,-23,-19,-17,-9,
            -6,-10,-2,-5,-9,-17,-17,-14,-10,-13,+0,-7,-10,-13,+3,
            -13,-17,-9,-2,-5,-8,-12,-15,-12,-9,-9,-3,+1,-5,+0,
            +1,-2,-13,-11,-9,+3,+6,+1,+1,-1,-7,-7,-6,-6,-7,
            -1,-8,-11,-9,-12,-12,-12,-11,+7,-1,+0,-5,+2,-9,-2,
            -10,-3,-6,+3,+8,+9,-1,-6,-3,-9,-2,-10,-2,-8,+11,
            -6,-11,-4,-12,-17,-4,+0,-4,+1,-1,-5,-11,-11,-8,-6,
            -4,-10,-17,-10,-17,-17,-18,-26,-5,+0,-3,-13,-12,-13,-12,
            -12,-10,-1,+0,+3,+10,+0,+0,-1,-10,-6,-4,+8,-9,+10,
            -1,+7,-15,-11,+11,-7,+4,-2,+2,-8,-10,-2,-12,+3,+5,
            +0,-1,-2,+0,-14,-11,-5,+5,-21,-3,+4,+7,-6,+3,-31,
            -16,-2,-20,-4,-25,-19,-12,-12,-14,-13,-12,-9,+1,-15,-16,
            -8,+8,-17,-22,-10,-22,-6,-5,-9,-10,-3,+1,-19,-11,-14,
            -6,-2,-17,-11,-10,-20,-13,-11,-4,+0,-6,-1,-1,-6,-13,
            -12,-10,-2,+3,-6,-1,-3,-12,-8,-6,-15,-7,-2,-7,-9,
            -11,-14,-13,-12,-10,+3,+0,-2,-5,-4,-2,-5,-7,+1,-14,
            -1,-7,-5,-8,-10,-19,-11,-18,-10,-9,-5,-11,-12,-17,-14,
            -13,-9,-5,-1,-5,-3,-4,-10,-13,-12,-10,-6,-3,-5,-7,
            -7,-14,-20,-9,-14,-7,-2,-5,-8,-7,-11,-11,-8,-6,+8,
            +11,+10,+14,+11,+11,+0,-2,+3,+14,+12,+17,+17,+9,+10,+1,
            +5,+7,+5,+7,+7,-3,-4,-2,-1,-5,+0,+21,+20,+20,+9,
            +11,+18,+13,+4,+6,+25,+13,+26,+11,+7,+6,-5,+0,+18,+12,
            +10,+9,+5,+2,+5,+4,+3,+4,+8,+12,+7,+13,+8,+8,+4,
            -2,+1,+0,+5,+13,+4,-2,-1,-13,-7,-8,+6,+9,+9,-2,
            -5,-4,+0,-6,-1,+17,+14,+20,+8,+14,-2,+17,+13,+5,+18,
            +23,+22,+14,+12,+10,+11,+16,+5,+3,+26,+9,+1,+4,-22,-1,
            +0,-1,+27,+14,+32,+31,+17,+7,+34,+18,+13,+31,+27,+34,+15,
            +7,+14,-4,+3,+17,+8,-8,+26,-9,-2,+9,+0,-1,+14,+8,
            +4,+2,+21,+6,-4,-7,+5,+9,-11,+15,+33,+5,+6,-3,-18,
            -7,-10,+6,+3,+16,+18,-4,-17,-4,-2,-7,+8,+13,+7,+15,
            +12,+12,+0,+1,+2,+14,+16,+13,+24,+11,+12,-5,+6,+13,+6,
            +8,+6,+5,-3,+1,+0,-4,-1,+14,+2,+2,+6,-3,-24,-27,
            -3,-9,-23,-6,+27,+10,-3,+11,-22,-21,+16,+3,-1,+2,-8,
            -6,+6,+1,-15,-5,+10,+12,+10,+10,+9,+8,+5,+0,+4,+4,
            +3,+18,-8,-4,+2,-7,-10,-12,+8,+10,+10,-4,-6,-4,+1,
            -5,+0,+20,+20,+17,+9,+15,+18,+8,+4,+11,-23,-3,+35,+18,
            +8,+23,+1,-5,+24,+6,+8,+17,+17,+3,-4,+7,+1,+14,+9,
            -1,+22,+27,+19,+32,-21,+8,+33,+4,+24,+4,+31,+8,+4,+23,
            +14,+28,-9,+12,+1,+31,+3,+9,+18,-9,+19,+14,+17,+13,-1,
            +13,+5,-5,-3,+8,+28,-7,-24,-13,-2,+20,+0,-1,+0,+8,
            -1,+16,+17,-2,-12,+13,-6,+7,+21,+19,+26,+21,+26,+11,+22,
            +4,+10,+32,+14,+4,+31,+8,+27,+28,+9,+16,+18,+7,+29,+14,
            +2,+12,+22,+8,+5,+12,+31,+34,+23,+18,+23,+34,+6,+25,-1,
            -3,+33,+4,+10,+12,+0,+13,+29,-27,+20,-5,-13,-2,+16,+4,
            +4,+11,+2,+3,+27,+10,+7,+31,-27,+2,+7,-11,+5,-11,+6,
            -8,+21,-23,+17,+30,-11,-5,+5,-10,+0,-25,+5,-7,-6,+9,
            +8,+13,+0,+5,+2,+4,+2,+1,+13,+13,-24,-15,+3,+12,+0,
            +4,-4,+4,+3,+10,-3,-5,+21,+5,-10,-1,-11,+15,+33,+9,
            +1,-24,+6,+10,+20,-11,+14,-11,-17,+0,-19,-28,+2,+20,+9,
            +10,+27,+2,-5,+30,-11,-5,-1,-3,+7,+18,-18,+6,+10,+0,
            +5,+1,+3,-21,-22,-25,-3,+11,-1,+0,-26,+0,+1,+11,-2,
            +0,+0,-1,-5,-1,+7,+13,+7,+16,+14,+13,-3,-1,+0,+19,
            +17,+17,+13,+14,+13,+0,+8,+11,+3,+7,+5,-4,-4,-7,-5,
            -8,-3,+19,+17,+9,-8,+12,+18,-6,+8,+16,+30,-7,+29,+22,
            +10,+23,+27,+13,+2,+3,+1,+18,-9,+2,+20,+7,-2,+7,+7,
            +11,+6,+11,+10,+9,+0,-2,+1,+6,+8,+10,+1,-1,-10,+5,
            -6,-6,+4,+10,+7,-9,-7,-7,-4,-7,-3,+3,+5,+9,-6,
            +2,-30,+3,+9,+1,-2,+13,+1,-30,+6,+16,-6,+11,-3,-19,
            +24,+18,-12,-4,-3,+27,-8,-25,+10,+11,+26,+25,+6,+17,+0,
            -31,+27,+25,+9,-5,+9,-5,+8,-34,-28,+24,+6,-9,-6,-31,
            -19,-17,-34,-25,-14,-2,+2,+2,-10,-1,-28,+6,+10,-8,-9,
            +13,+27,-12,-2,+11,+21,-20,-16,+0,+9,+7,-32,-2,-32,-13,
            -5,-24,+9,+13,+9,+15,+13,+12,+0,+0,+3,+22,+14,+16,+16,
            +14,+9,-4,+14,+14,+6,+9,+7,+2,-2,-3,+0,-3,-1,+3,
            +1,+16,+15,+1,-2,-3,+2,+3,+12,-1,+5,-4,-2,-6,-22,
            -14,+15,-12,-13,+7,-2,-5,+6,-17,-2,-7,+9,+13,+10,+7,
            +10,+9,+3,+0,+4,+6,+1,+11,-8,-5,-1,-8,-5,-12,+5,
            +8,+9,-4,-7,-6,+0,-5,-1,+9,+8,+11,+11,+6,+8,+4,
            +0,+5,+11,+8,+18,+13,+5,+9,+2,-6,+6,+8,+10,+13,+0,
            +0,+1,+4,-2,+2,+13,+17,-2,+20,+12,+16,+32,+21,+2,+21,
            +5,+11,+24,+4,+13,+10,+1,+19,+15,+7,-30,+6,-1,-23,-18,
            +0,-1,+9,+13,+12,+16,+8,+8,+9,-2,+6,+5,+8,+2,+8,
            -1,+1,-17,-1,+0,+6,+9,+12,+0,-4,-5,+2,-6,+0,+7,
            +11,+18,+16,+11,+16,+2,+13,+6,+7,+11,+32,+15,+10,+25,-2,
            +9,+28,+14,+17,+18,+20,-4,+23,+8,-9,+6,+17,+19,+7,+27,
            +11,+21,+31,+3,+13,+10,+9,+23,+21,+3,+14,+13,-4,+19,+7,
            +4,+17,+0,-7,+3,+9,-14,-8,-2,-11,-24,+28,+5,-7,+9,
            +6,-6,+10,+6,-24,-7,+0,+7,-31,-18,+27,-12,+1,-2,-6,
            +0,-12,-5,-2,-3,+6,+9,+8,+18,+9,+8,-2,-2,+2,-3,
            +19,+5,+10,+13,+21,+3,+0,+20,+3,+8,+9,+0,-2,-4,-5,
            -5,+1,+24,-2,-4,+2,+0,-7,+12,-9,-9,-5,-8,+31,-2,
            -2,-5,-14,-15,+6,-3,+5,-28,-20,-8,+5,-1,+8,-19,+4,
            +11,+8,+10,+6,-4,+4,-8,+2,-4,+4,+10,+7,-5,-13,-17,
            -9,-15,+3,+9,+9,+0,-7,-4,+3,-10,-2,+9,+7,+10,+12,
            +5,+9,+8,-7,+5,+12,+7,+23,+28,+12,+9,+25,+3,+15,+12,
            +6,+13,-7,-2,+0,+8,-7,+5,+6,+9,+10,+11,+8,+25,+12,
            +14,+15,+28,+17,+27,+25,+3,+6,-6,+8,+10,+20,+1,+16,+7,
            -3,+1,-5,+7,+19,+9,+17,+12,-8,+11,+21,-1,-1,-2,-15,
            +2,+12,+0,-3,-17,+13,-19,-20,+8,+11,+9,-8,-3,-8,-4,
            -12,-1,+0,+5,+6,-5,+12,+13,+4,+1,+9,-22,+8,+4,-4,
            +3,+6,+17,-7,-5,-6,+13,+23,+2,-2,+1,-10,-6,+3,+10,
            -7,+14,-12,+8,+14,-9,+4,+22,+6,+9,+12,+0,-1,+6,-4,
            -2,+9,+7,-8,+8,-21,-3,+4,-15,+3,-8,-17,-9,+11,-14,
            -3,-5,-22,-10,+1,-14,+5,-19,-25,-9,-1,-31,-3,+17,-10,
            -8,-6,-24,-13,-11,-11,-10,-10,-3,+1,-1,+1,+3,+1,-16,
            -15,-4,-3,+1,+20,+0,-3,-17,+15,-8,+10,+0,+0,-10,-10,
            -13,-29,-24,-17,-6,+7,-10,-3,-16,+2,+7,+30,+3,+6,-6,
            +9,+21,+4,-2,-1,-31,-14,+17,-13,+5,+11,-15,-6,+10,-14,
            -3,-14,-1,-1,+2,-20,-1,-13,-13,-18,-10,-26,-10,+11,-28,
            -9,-1,-18,-13,-17,-5,-3,-1,-13,-8,-22,-17,-14,-9,+0,
            +3,-2,-1,+2,+1,-7,-10,-8,+5,+2,-4,+20,+3,+0,+18,
            -8,-1,-4,-1,-7,-10,-10,-17,-10,-12,-9,+5,+16,-22,-10,
            +4,+23,+10,-1,+1,+28,+5,+12,+14,+3,+1,-10,-1,-19,+1,
            +0,-3,-28,-11,-13,-21,-10,-2,-4,-1,+1,+0,+0,-4,-11,
            -11,-7,-1,-2,+21,+8,-8,-29,+1,-17,-4,-2,-3,-3,-16,
            -10,-21,-13,-14,-11,+11,+5,+5,+6,+3,-23,-15,+9,+10,+26,
            +12,+9,+16,+3,+1,-9,+0,-2,+2,+7,+20,-2,-7,-13,-6,
            -11,+1,+0,+2,+9,+0,+7,+3,-25,+17,+23,+15,+19,+16,+12,
            +1,+4,-23,-21,-7,-25,+6,-17,-27,-10,-1,-31,-12,-11,+0,
            +5,+6,+10,-4,+5,+8,-6,-8,-4,+10,+30,-11,-5,+10,-27,
            -15,-11,-7,-3,+6,-20,-3,-2,-9,-17,-11,-4,+1,-4,+0,
            +3,-5,-15,-9,-10,-7,+2,-12,-1,-1,-8,+0,+5,-11,-8,
            +0,-7,-18,-9,-21,-15,-13,-12,+9,-10,-17,-6,-1,-12,+6,
            +0,-2,+17,+19,-25,+5,-3,-11,-21,+8,+1,-11,-18,-32,-16,
            -12,-2,-8,-10,-20,-7,+0,-4,+1,-3,-4,-16,-18,-10,-7,
            -6,+0,-12,-7,-22,-9,-15,-25,-8,-2,-6,-11,-9,-14,-14,
            -11,-11,+3,+7,+3,+8,+6,+5,-5,-7,-4,+5,+9,+11,+5,
            +6,+5,+0,+1,+0,+0,+2,+0,-3,-6,-8,-8,-9,-7,+10,
            +14,+5,+7,+9,+6,+0,+4,+3,-1,+8,+10,+10,+5,+9,+11,
            +2,-6,-2,+5,+1,+12,-1,+10,-6,-6,-1,+2,+5,+2,+2,
            +4,+2,-4,-7,-4,-2,-5,+1,-8,-6,-4,-8,-11,-8,+0,
            +3,+3,-6,-8,-10,-6,-10,-6,+7,+10,+6,+11,+14,+2,+12,
            -5,+3,+22,+18,+33,+13,+12,+15,-9,-6,+13,+13,+8,+16,+3,
            +0,+1,-3,-3,-2,+16,+20,+13,+25,+4,+13,-6,+9,+5,-3,
            +19,+25,-7,+7,+22,+27,-5,+7,+0,+0,+27,-7,-3,+23,-8,
            +5,+1,+4,+10,-9,-1,+2,-9,-3,-18,-9,+3,+1,+20,-20,
            -3,+6,+9,-21,+16,+2,+10,+3,-15,-5,-2,-12,+1,-2,+3,
            +7,+1,+8,+7,+6,-6,-7,-4,+10,+8,+8,+0,+6,-2,-4,
            +2,+3,+0,+4,+1,-3,-7,-7,-6,-8,-7,+4,+7,+9,-2,
            +0,-6,+19,-5,-9,-24,-3,+7,+6,-7,+1,-18,-12,-28,-13,
            -9,-8,-14,-8,-8,-3,-10,-2,+4,+7,+4,+4,+4,+2,-3,
            -6,-3,-5,-7,+1,-12,-9,-10,-6,-14,-10,+0,+3,+4,-8,
            -9,-10,-5,-10,-5,+8,+6,+7,+7,+2,+6,-6,-4,+0,+7,
            +10,+24,+26,+6,+15,-3,+9,+20,+5,+9,+11,+4,-7,-1,-4,
            -6,+3,-4,+22,+5,+4,+7,+28,+9,+9,+13,+28,+16,+16,+14,
            +4,-5,+11,+4,+13,-3,-16,-3,-10,+2,-2,+11,+11,+6,+5,
            +6,+13,+1,+2,+20,-6,-7,+3,+0,-7,-4,+15,+0,+10,-28,
            -10,-1,+2,-5,+14,-5,-5,-11,+0,-15,-1,+8,+14,+18,-17,
            +5,+19,-12,-9,-6,+16,+7,+28,+6,+5,+10,+11,+27,+13,+24,
            +3,+2,+5,-8,-19,+23,-2,-5,-9,+21,+17,-15,+3,+19,-25,
            +5,+7,+0,+11,+29,-6,+0,+9,+1,-3,+24,+3,+7,+24,-10,
            -12,-7,-31,-2,+4,-13,+6,+16,-28,-3,+6,-30,-14,-28,-28,
            -4,+20,-28,-9,+17,-4,-25,-2,+1,-12,+15,-21,-11,+1,-25,
            -18,-17,-3,+2,-8,+7,-1,+0,-22,-15,-8,+0,-1,+0,+3,
            +0,-20,-13,+11,-1,-10,-1,-6,+3,-12,-4,-14,-26,-14,-13,
            +4,-10,-26,-4,+27,+2,-1,+16,-16,+8,+30,+22,-5,+17,-32,
            -10,-2,-22,+15,-16,-7,-11,-11,-18,-11,-19,-6,-3,-12,-5,
            -8,-15,-19,-17,-10,-7,-21,-26,-12,-12,-17,+23,-17,-2,-5,
            -2,-12,-11,-11,-25,-14,-14,-12,+1,+5,+0,+7,+6,+2,-9,
            -8,-7,+6,+9,+14,+1,+7,+5,+3,-1,+3,-4,+1,-3,-4,
            -8,-9,-10,-11,-8,+9,+9,-1,+0,+5,+6,+2,+10,-2,+13,
            +6,+5,+17,+5,+3,-2,+0,-5,-4,-2,-25,+2,+2,+1,-8,
            +3,-6,+0,+4,-1,+4,+3,+1,-7,-8,-7,-5,-4,-1,-9,
            -6,-6,-14,-13,-14,-2,+2,-1,-9,-9,-12,-8,-10,-8,+3,
            -3,+4,-9,+6,-1,-3,-15,-1,+13,+8,+19,-7,+5,+19,+11,
            -20,+6,-4,+15,+7,-24,-7,-2,-14,-17,-6,+0,-5,+14,+0,
            +2,-8,-10,-9,+1,+9,-2,+11,-10,+0,-8,-12,-7,+4,-16,
            -10,-14,-17,-9,-11,-27,-12,-9,-9,-7,-5,-5,-6,-19,-19,
            -18,-2,+4,-3,-1,-6,-10,-14,-9,-17,-19,-10,-12,-7,-13,
            -12,-20,-21,-9,-19,+0,+4,-1,+4,+4,+0,-9,-9,-6,+3,
            +5,+7,+3,+5,-1,-9,-1,-1,-3,+2,-3,-6,-8,-11,-8,
            -10,-8,-3,+1,-7,-11,-2,-3,-3,-4,-2,-8,+5,-6,+0,
            -4,-10,-21,-14,-17,-7,-10,-24,-7,-8,-11,-17,-11,-19,-1,
            +3,+0,+0,+2,-2,-7,-7,-5,-8,-4,-1,-9,-6,-9,-20,
            -9,-12,-3,+2,-1,-9,-7,-11,-8,-6,-6
        ];
 
        Edge8 = [
            +0,-9,-1,-14,-12,-8,-38,-45,-31,-64,-60,-11,-54,-28,+46,
            +57,+22,+66,+61,+16,-28,+24,+10,+0,+0,-11,-2,-12,-24,-10,
            -21,-24,-7,-17,-42,-15,-30,-27,-26,-49,-40,+25,+51,+25,+39,
            +27,+5,+15,+17,+2,+11,+13,+2,+28,+7,-2,+10,+3,-5,-17,
            -26,-34,-9,-54,-49,-27,-25,-48,+21,+50,+9,+45,+51,+10,+3,
            +28,-8,+10,+10,-4,+16,-2,-15,+0,-11,-15,+1,-32,-3,-20,
            -44,-42,-2,-27,-25,+26,+25,+16,+53,+50,+21,+2,-6,-2,+4,
            +7,-16,-2,-10,-26,-6,-13,-24,+6,-13,+7,-33,-51,-34,-18,
            -35,-32,+11,-21,-1,+40,+0,+21,+19,+27,+7,+8,-4,+18,+14,
            +0,+2,+4,+11,-2,-4,-68,-15,-13,+0,-13,+5,-39,-13,+1,
            +40,-3,+9,+0,+24,+8,+38,+11,+1,+9,+2,+0,+0,-1,-10,
            +3,-10,-5,-1,-1,-31,-6,-5,-21,-34,-18,+4,+54,-4,+42,
            +0,+63,-12,-58,-15,-3,-1,-9,-11,+0,-16,-16,-20,-17,-1,
            -23,-31,-23,+0,+24,-19,-18,-21,+28,+84,+27,-9,+0,+30,+20,
            +13,+5,+30,+0,+12,+18,+0,+5,+7,-4,-7,+33,+0,-61,-18,
            -11,-47,-26,-41,-52,+32,+0,+12,+59,+0,+18,+21,+12,+1,+21,
            +0,+1,+9,+0,-5,+7,-7,-12,+18,-7,-40,-2,-4,-41,-14,
            -48,-34,+42,+0,+26,+49,+0,+22,+24,+34,+5,+4,+0,-17,-16,
            +0,-21,+7,-9,-25,-5,-19,-11,-29,+64,-32,-2,-2,-24,+7,
            +10,+11,+33,+69,+33,-19,+29,-7,+24,+9,+15,+20,+15,+12,+0,
            +7,-3,+4,-69,+13,+12,-63,-24,-18,-65,-18,+13,+43,+17,+22,
            +26,+31,-2,+16,-8,+16,+18,+14,+4,+15,-2,-8,-7,-9,+2,
            -18,+12,-27,-32,-18,-28,-20,-16,+7,+15,+13,+19,+51,+13,+23,
            -18,+6,+2,+31,+0,+0,+5,-17,-18,-18,-17,-1,-17,+16,-33,
            +6,-35,-13,-42,-20,-7,-48,-27,+0,+0,+0,-6,+0,+0,-10,
            +4,-52,+0,+0,+0,-42,-84,-54,-56,-64,+47,-84,+0,+0,-48,
            -28,-66,+12,-76,-20,+0,+0,+0,-22,-56,+20,-14,-25,-36,+0,
            +0,+0,-20,-74,-14,-21,-19,-58,-62,-56,+0,+1,-70,-21,+3,
            -38,+18,+0,+0,+0,-17,+0,-6,-25,-33,-49,+0,+0,+0,-29,
            -84,-30,-35,-77,-68,-62,+0,-84,-15,-84,-20,+10,+66,+28,+84,
            +0,+0,-84,-84,-84,-4,-3,-23,+0,+0,+0,-32,-72,-75,-18,
            -84,-84,-84,-84,-84,-44,-69,-76,+24,+28,-9,+0,+84,+0,+5,
            -38,-22,-18,-32,-31,+0,+0,+0,-28,-21,-15,-31,-13,-61,-15,
            +27,+9,-10,-15,-21,+28,+84,+0,+0,+0,+0,-84,-42,+84,-22,
            -70,-50,+0,+0,+0,-23,-15,-47,-28,+46,-84,+51,+0,+0,-16,
            +37,-63,-13,+0,-56,+84,+0,+0,+84,+0,-84,-24,+0,-1,+0,
            +0,+0,-58,+0,-66,-84,+0,-84,+0,+0,+0,-40,+0,-32,+17,
            +0,-16,-84,+0,+0,-28,+0,-84,-13,-42,-10,+0,+0,+0,-47,
            +0,-63,-13,-84,-22,+0,+0,+0,-1,+0,-18,-18,+0,-54,+0,
            +0,+0,-84,+0,+84,-43,+13,-37,+0,+0,+0,-84,+0,+0,-75,
            +0,-36,-84,+0,+0,-84,+0,-52,+43,+51,+16,+0,+0,+0,+49,
            +67,+12,+8,-17,-16,+0,+0,+0,+4,-7,-8,-42,-84,-53,+44,
            +84,-84,-21,-25,-54,+13,+42,+23,+0,+0,+0,+21,-32,+10,-3,
            -56,-3,+0,+0,+0,-9,-30,-9,+12,-18,+8,+16,+60,-63,+7,
            -40,-21,+41,+7,+54,+0,+0,+0,+61,+84,+5,-14,-5,+3,+0,
            +0,+0,-15,-70,-35,-6,-84,-32,-20,+0,+0,-26,-62,-63,+30,
            +58,+59,+0,+0,+0,+45,+43,-17,+0,+0,+0,+0,+0,+0,+4,
            -3,-13,+63,+56,+84,+28,-57,-28,-12,-62,-57,+4,+0,+31,+0,
            +0,+0,+48,+24,-10,+0,+0,+0,+0,+0,+0,-28,-49,-22,-58,
            -59,-59,-78,-68,-55,-22,-52,-24,+44,+0,+84,+0,+0,+0,+73,
            +58,+63,+0,+0,+0,+0,+0,+0,-28,-56,-45,-49,+47,+23,+63,
            +68,+2,-33,-44,-55,+61,+0,+29,+0,+0,+0,+40,+56,+36,+0,
            +0,+0,+0,+0,+0,+1,+18,-26,-71,+0,-84,+84,+0,+36,-14,
            -52,-62,+47,+0,+37,+0,+0,+0,+56,+28,+16,+0,+0,+0,+0,
            +0,+0,-20,-49,-21,-84,+0,-84,+0,-84,-80,+11,-47,-34,-74,
            +0,+0,+0,+0,+0,+58,+0,+33,+0,+0,+0,+0,+0,+0,-43,
            -26,-37,+0,+0,-84,-84,+67,-84,-45,-84,-74,+22,+0,+84,+0,
            +0,+0,+0,-84,+0,-7,+0,-29,+0,+0,+0,-56,-84,-59,-49,
            +0,+84,+0,+0,+0,-60,-84,-53,+6,+0,-21,+0,+0,+0,-12,
            -84,+1,-5,+0,-10,+0,+0,+0,-26,-43,-31,-8,-74,+9,+28,
            +0,+0,-7,-49,-1,+22,+0,+0,+0,+0,+0,-34,+0,-84,-25,
            +0,-43,+0,+0,+0,-27,-4,-31,-24,-28,-68,-14,+0,-60,-19,
            -84,-21,+38,+0,+84,+0,+0,+0,+64,+0,+15,+0,+0,+0,+0,
            +0,+0,-3,+0,-12,-45,+0,-84,+0,+0,-79,-6,-59,-41,+36,
            +0,+41,+0,+0,+0,+36,+0,+6,+0,+0,+0,+0,+0,+0,-1,
            +0,-18,+29,+0,+12,+28,+0,-10,+6,+11,-25,+57,+0,+0,+0,
            +0,+0,+80,+0,+22,+0,+0,+0,+0,+0,+0,+1,+0,-30,-44,
            +0,+0,+42,+0,-28,+1,-39,-43,+38,-47,+32,+34,+0,+64,+55,
            -8,+41,+8,+33,-4,+17,-25,-24,+2,-9,+1,-36,-84,-48,-63,
            -84,-45,-41,-14,-41,+16,+18,+13,+24,+0,+39,+36,+2,+32,-5,
            -4,-6,+1,-36,-10,-9,-16,-7,-15,-8,-20,-39,-57,-32,-13,
            -42,-13,+57,+45,+56,+74,+0,+67,+67,+11,+51,-8,+50,-9,-8,
            +51,-25,-18,-14,-17,-32,+84,-34,-46,+84,-43,-35,-51,-37,+5,
            +54,+8,+27,+84,-41,-20,-47,-19,+0,+0,+0,+0,+0,+0,+0,
            +0,+0,+20,-45,+24,+17,-84,+35,+24,-60,+18,+14,+28,+12,+34,
            +84,+32,+0,+0,+29,+0,+0,+0,+0,+0,+0,+0,+0,+0,-3,
            +51,+4,+58,-84,+45,+4,+9,+3,+6,+57,+5,+47,+84,-18,-10,
            +84,-4,+29,+57,+35,+49,-84,+37,+30,+22,+6,+10,+51,+14,+77,
            +0,+62,+0,+64,+5,+28,+1,+2,-4,-72,-25,+84,+0,+63,+0,
            +0,+0,+0,+0,+0,+0,+0,+0,+65,+0,-20,+0,+0,+0,+84,
            +0,+72,+54,+67,+41,+78,+84,+84,+84,+0,+84,+0,+0,+0,+0,
            +0,+0,+0,+0,+0,+39,-36,-8,+84,+0,+0,+74,+0,+0,+54,
            +61,+48,+34,+0,+19,+77,+84,+52,+28,+0,+19,+0,+0,+0,+0,
            +0,+0,+60,+84,-1,+84,+84,+0,+75,+0,+33,+12,+0,+3,-28,
            +0,+64,+31,+84,-25,+0,+0,+0,+0,+0,+0,+0,+0,+0,+53,
            +0,+11,+0,+0,+0,+0,+0,-72,+20,+84,+20,+18,+0,+44,+45,
            +0,+34,+0,+0,+0,+0,+0,+0,+0,+0,+0,-17,-45,+3,+84,
            +0,+0,-28,+0,+0,+14,+63,-6,+28,+0,+76,+28,+84,+10,+2,
            +84,+41,+0,+0,+0,+84,+0,-60,-7,+84,+27,+0,+0,+0,+35,
            +0,+30,+51,-12,+38,+45,+84,+70,+56,+28,+0,+0,+0,+0,+0,
            +0,+0,+0,+0,+0,+51,+84,-42,-49,+0,-84,-84,+0,+0,+43,
            +84,+44,+47,+0,+28,+84,+0,+42,+0,+0,+0,+0,+0,+0,+0,
            +0,+0,+16,+3,-1,+80,+84,+84,+84,+0,+58,+62,+77,+51,+57,
            +51,+84,+31,+84,+84,+31,-84,+10,+0,+0,+0,+0,+0,+0,+72,
            +84,+8,+84,+0,+0,+71,+0,+50,+32,+38,+10,+49,-29,+10,+45,
            -48,-29,+0,+0,+0,+0,+0,+0,+0,+0,+0,+69,-28,+78,-14,
            -84,-80,+0,-84,-21,+73,+42,+36,+76,+70,+24,+84,+84,+60,+0,
            +0,+0,+0,+0,+0,+0,+0,+0,+31,+69,+20,+83,+78,+71,+84,
            +70,+67,+51,+68,+47,+76,+83,+68,+25,+84,+40,+45,+51,+60,+0,
            +0,+0,+0,+0,+0,+65,+82,+56,+27,+81,+84,+72,+65,+56,+42,
            +9,+6,+0,+0,-9,+42,+84,+12,+0,+0,+0,+0,+0,+0,+0,
            +0,+0,+59,+84,+21,+84,+0,-6,+84,+84,-9,+30,+84,-15,+84,
            +84,+73,+51,+0,+65,+0,+0,+0,+0,+0,+0,+0,+0,+0,+20,
            +3,-3,+42,+84,+63,+33,+28,+3,+68,+29,+51,+59,+0,+65,+69,
            +67,+41,+48,+84,+24,+0,+0,+0,+53,+12,+15,+71,+68,+22,+84,
            +0,+84,+48,+75,+20,+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,+22,+16,-10,+84,
            +0,+52,+23,-45,-13,+0,+0,+0,+0,+0,+0,+0,+0,+0,+0,
            -84,+0,+0,+0,+0,+0,+0,-84,+31,+56,+11,+84,+0,+13,+52,
            +18,+31,+0,+0,+0,+0,+0,+0,+0,+0,+0,+29,-21,-25,+84,
            +0,+84,-84,+0,+16,+23,+72,-2,-26,+42,-36,+10,-37,+11,+43,
            +54,+47,+0,+0,+0,+0,+0,+0,+41,+80,+16,+84,+0,+48,+67,
            -37,+21,+5,+44,+0,-11,+28,-6,+30,+0,+1,+0,+0,+0,+0,
            +0,+0,+0,+0,+0,+60,+0,+13,+0,+0,+0,+0,+0,+4,+4,
            +42,+8,+53,+84,+1,+3,-17,+22,+0,+0,+0,+0,+0,+0,+0,
            +0,+0,+16,-54,-12,+0,+0,+0,+14,+61,+5,+3,+68,-5,+11,
            +70,+22,+5,+64,+22,+14,+15,-5,+0,+0,+0,+84,-42,-21,+8,
            +56,+14,+0,+0,+72,-2,+81,+15,+33,+75,+33,+0,+84,+28,-47,
            +0,-25,+0,+0,+0,+0,+0,+0,+0,+0,+0,+19,+58,+15,+12,
            +84,-3,-11,+10,-22,+25,-84,+28,+74,+84,-43,+25,+84,+9,+0,
            +0,+0,+0,+0,+0,+0,+0,+0,+11,+27,+26,+22,+49,+6,-1,
            +34,+13,+53,+66,+54,+65,+84,+16,+0,+0,+36,+52,-10,+53,+16,
            +34,+37,-8,-84,+24,+34,+69,+25,+34,+84,+8,+10,+49,+6,+34,
            +28,-1,-17,+19,+84,+0,-56,+24,+0,+0,+0,+0,+0,+0,+0,
            +0,+0,+19,+8,+12,+4,-73,-38,+42,-36,-16,+49,+43,+22,+76,
            +71,+68,+14,+48,+20,+0,+0,+0,+0,+0,+0,+0,+0,+0,+44,
            +65,+15,+59,-42,+30,+42,+0,+19,+68,+70,+54,+67,+71,+71,+80,
            +84,+41,+61,+61,+43,+37,+0,+47,+47,+0,-13,+52,+59,+53,+58,
            -59,+25,+61,+16,+39,+18,+74,+18,+84,-84,-74,-72,+0,-7,+0,
            +0,+0,+0,+0,+0,+0,+0,+0,+19,+4,+10,-7,+0,+5,-32,
            +28,-5,+37,+60,+32,+18,+84,-58,-63,+0,+32,+0,+0,+0,+0,
            +0,+0,+0,+0,+0,+17,+29,+16,+32,+0,+35,-2,+51,+16,+83,
            +71,+45,+74,+56,+67,+38,+28,+41,+54,+38,+68,+78,+0,+65,+30,
            +36,+49,+24,+50,-7,+54,+0,+52,+19,+80,+1,+6,-17,-9,+0,
            +0,+0,+0,+0,+0,+0,+0,+0,+0,+0,+0,+0,+0,+0,+35,
            +32,+10,+15,+14,+21,+19,+42,-24,+0,+0,+0,+0,+0,+0,+0,
            +0,+0,+0,+0,+0,+0,+0,+0,+0,+0,+0,+23,+26,+12,+51,
            +10,+49,+28,+15,+37,+42,+73,+54,+60,+84,+45,+45,-24,+45,+59,
            +55,+48,+51,+28,+3,+31,+27,-15,+44,+52,+30,+53,+41,+49,+40,
            +10,+39,+26,+43,-4,+0,+0,+0,+0,+0,+0,+0,+0,+0,+0,
            +0,+0,+0,+0,+0,+36,+73,+27,+47,+10,-5,+38,+18,-6,+0,
            +0,+0,+0,+0,+0,+0,+0,+0,+0,+0,+0,+0,+0,+0,+0,
            +0,+0,+47,+55,+29,+62,+39,+44,+49,+29,+22,+64,+81,+36,+46,
            +46,+8,+43,+19,+18,+58,+46,+42,+42,+28,+6,+38,-7,+6,+53,
            +67,+42,+58,+42,+34,+48,+30,+16,+15,-21,+3,+0,+0,+0,+37,
            -18,+21,+0,+0,+0,+0,+0,+0,+0,+0,+0,+41,+60,+34,+25,
            +49,+12,+14,+12,+6,+0,+0,+0,+0,+0,+0,+0,+0,+0,+0,
            +0,+0,+0,+0,+0,+0,+0,+0,+18,+60,+20,+24,+23,+32,+44,
            +47,+21,+54,+84,+53,-34,+3,+2,+71,+78,+33,+44,+53,+24,+43,
            +8,+23,+17,+23,+4,+47,+19,+43,+51,+41,+34,+47,+51,+37,+11,
            -5,+5,+0,+0,+0,+10,+26,+0,+0,+0,+0,+0,+0,+0,+0,
            +0,+0,+5,+17,-14,-7,+0,-35,+26,+52,+8,+0,+0,+0,+0,
            +0,+0,+0,+0,+0,+0,+0,+0,+0,+0,+0,+0,+0,+0,+10,
            +13,+5,+38,+0,+67,+16,+59,+23,+24,-28,+42,+84,+0,+56,-15,
            +84,+57,+45,+21,+60,+45,+0,+46,-3,+25,+6,+18,+40,-4,+22,
            +84,+36,+7,+45,+25,+27,+0,-8,+0,+0,+0,+24,-84,-26,+0,
            +0,+0,+0,+0,+0,+0,+0,+0,+25,+84,+28,+84,+0,+5,-4,
            -5,-19,+0,+0,+0,+0,+0,+0,+0,+0,+0,+0,+0,+0,+0,
            +0,+0,+0,+0,+0,+26,+0,+10,+84,+0,+6,+21,-5,-5,+84,
            +0,-12,+84,+0,-42,-8,-38,-12,+72,+0,+32,+34,+0,+28,+36,
            -6,-8,+23,+42,-3,+32,-34,+29,+5,+0,-5,+40,-11,+26,+0,
            +0,+0,-12,-84,-11,+0,+0,+0,+0,+0,+0,+0,+0,+0,-3,
            +29,-2,+25,+60,+12,-11,+36,-20,+0,+0,+0,+0,+0,+0,+0,
            +0,+0,+0,+0,+0,+0,+0,+0,+0,+0,+0,+10,+0,+23,+23,
            +52,+27,+12,-34,-5,+60,+21,+67,+78,+64,+51,+4,+51,-1,+53,
            +66,+60,+35,+63,+13,+9,+51,+6,+2,+69,+11,+18,+2,+19,-7,
            +2,-21,-2,-5,-28,+0,+0,+0,+7,+0,+6,+0,+0,+0,+0,
            +0,+0,+0,+0,+0,-13,-15,+1,+72,+0,+0,+22,+0,+6,+47,
            +60,+34,+0,+0,+0,+59,+0,+68,+0,+0,+0,+0,+0,+0,+0,
            +0,+0,+19,+0,+8,-26,+0,+42,-4,+65,+1,+41,+84,+55,+0,
            +0,+0,+53,+0,+52,+48,+84,+60,+0,+0,+0,+42,-84,+41,+40,
            +76,+39,+56,+0,+0,+41,+45,+38,+23,+25,-15,+0,+0,+0,+11,
            -44,+24,+0,+0,+0,+0,+0,+0,+0,+0,+0,+29,+78,+2,+84,
            +84,+84,+22,-17,+18,+83,+84,+84,+0,+0,+0,+72,+84,+48,+0,
            +0,+0,+0,+0,+0,+0,+0,+0,+54,+84,+22,+0,-84,+84,+52,
            +45,+40,+64,-11,+64,+0,+0,+0,+70,+31,+14,+50,+72,+70,+0,
            +0,+0,+54,+55,+68,+63,+77,+24,+75,+84,+84,+66,+53,+48,+4,
            +9,-33,+0,+0,+0,-11,+0,-84,+0,+0,+0,+0,+0,+0,+0,
            +0,+0,-22,-63,-9,+0,+0,+0,+23,+0,-21,+48,+0,+28,+0,
            +0,+0,+0,+0,+0,+0,+0,+0,+0,+0,+0,+0,+0,+0,+28,
            +62,+36,+0,+0,+0,+61,+0,+23,+20,+0,+64,+0,+0,+0,+0,
            +0,-58,+53,+0,+44,+0,+0,+0,+0,+0,+0,+54,+84,+21,+84,
            +0,+0,+72,+0,+44,+12,+60,+59,+0,+0,+0,+16,+84,+1,+0,
            +0,+0,+0,+0,+0,+0,+0,+0,+24,-28,-13,+0,+0,+0,+3,
            -21,-31,+0,+0,+0,+0,+0,+0,+0,+0,+0,+0,+0,+0,+0,
            +0,+0,+0,+0,+0,+19,+84,+29,+0,+0,+0,+32,+51,+52,+62,
            +84,+14,+0,+0,+0,+12,+70,+84,+32,+79,+18,+0,+0,+0,+53,
            +59,+48,+71,+56,+81,+84,+0,+28,+51,+51,+30,+5,+0,-20,+0,
            +0,+0,+42,-51,-31,+0,+0,+0,+0,+0,+0,+0,+0,+0,+27,
            +84,+15,+0,+0,+0,+0,-15,-18,+0,+0,+0,+0,+0,+0,+0,
            +0,+0,+0,+0,+0,+0,+0,+0,+0,+0,+0,+21,+0,+28,+0,
            +0,+0,+46,+49,+33,+46,+0,+47,+0,+0,+0,+73,+63,+36,+0,
            +0,+0,+0,+0,+0,+40,+37,+19,+66,+81,+49,+52,+55,+31,+60,
            +57,+44,+82,+0,-7,+0,+0,+0,+44,+0,+21,+0,+0,+0,+0,
            +0,+0,+0,+0,+0,+23,+0,-35,+0,+0,+0,-8,-13,-24,+0,
            +0,+0,+0,+0,+0,+0,+0,+0,+0,+0,+0,+0,+0,+0,+0,
            +0,+0,+77,+0,+84,+0,+0,+0,+52,-34,+18,+84,+0,+0,+0,
            +0,+0,+18,+0,+31,+0,+0,+0,+0,+0,+0,+56,+0,+43,+84,
            +0,+28,+84,+0,+47,+44,+70,+22,+14,+20,+30,+69,+0,+84,+6,
            +0,+45,-10,+84,+84,+0,+0,+0,+39,-84,+19,+13,+51,+3,+0,
            -84,-56,-11,+49,+12,+15,+53,+73,+0,+0,+84,+21,+0,+65,+46,
            +0,+54,+0,+0,+0,+0,+67,+5,+20,+49,+48,+66,+0,-58,+35,
            +84,+24,+36,+24,-11,+84,+0,+84,+14,+84,-7,+31,+0,+23,+0,
            +0,+0,+12,+34,+32,+38,+81,+44,+84,+84,+14,+54,+64,+52,+40,
            -11,+6,+84,-22,+36,+42,+3,-5,+14,+33,+13,+0,+0,+0,+64,
            +84,-11,+13,+6,+3,-84,-46,-31,+23,+29,+6,+66,+18,+29,+84,
            -8,-19,+49,+73,+26,+46,+36,+40,+0,+0,+0,+57,+34,+19,+56,
            +52,+30,+84,+75,+84,+17,+35,+41,+59,+73,+33,+84,+77,+84,+65,
            +40,+27,+77,+81,+25,+0,+0,+0,+50,+21,+18,+79,+82,+42,+84,
            +84,+80,+71,+74,+39,+10,-11,+8,+42,-76,+0,+33,-18,+19,+28,
            +28,+25,+20,+0,+32,+15,+54,+17,+23,+25,+19,+3,-84,-7,+22,
            +20,+10,+34,+62,+48,+28,+84,+74,+59,+25,+48,+33,-10,+33,+34,
            +80,+19,+21,+40,+8,+15,+45,+17,+47,+55,+48,+29,+40,+35,+50,
            +68,+51,+84,+17,+68,+55,+42,+57,+47,+79,+49,+62,+0,+45,+27,
            +45,+31,+57,+75,+57,+58,+84,+68,+71,+63,+66
        ];
 
        Diag8 = [
            +0,+0,-10,-8,-8,-10,+0,-10,-8,-8,-8,-10,-16,-8,-10,
            +0,-10,+0,+0,+0,-10,-21,-10,+0,+0,+2,-8,-8,-8,-18,
            -16,-16,-10,+0,-10,-16,-16,-16,-10,-16,-8,-10,+0,-10,+0,
            +0,+0,-10,-21,-10,+8,+8,+8,+0,+0,+0,-10,-8,-8,-10,
            +0,-10,-21,-21,-21,-10,-21,-10,+0,+8,+2,+0,+0,+0,+2,
            -8,+2,+0,+0,+2,-8,-8,-8,-18,-16,-16,-18,-8,-18,-16,
            -16,-16,-18,-24,-16,-10,+0,-10,+0,+0,+0,-10,-21,-10,-8,
            -8,-5,-16,-16,-16,-26,-24,-24,-10,+0,-10,-16,-16,-16,-10,
            -16,-8,-10,+0,-10,+0,+0,+0,-10,-21,-10,+8,+8,+8,+0,
            +0,+0,-10,-8,-8,-10,+0,-10,-21,-21,-21,-10,-21,-10,+8,
            +16,+8,+8,+8,+8,+8,-2,+8,+8,+8,+10,+0,+0,+0,-10,
            -8,-8,-10,+0,-10,-8,-8,-8,-10,-16,-8,-10,+0,-10,+0,
            +0,+0,-10,-21,-10,-13,-13,-10,-21,-21,-21,-29,-29,-29,-10,
            +0,-10,-21,-21,-21,-10,-21,-10,+0,+8,+2,+8,+8,+8,+2,
            -8,+2,+8,+8,+10,+0,+0,+0,-10,-8,-8,+2,+13,+2,-8,
            -8,-8,+2,-8,+2,+0,+8,+2,+0,+0,+0,+2,-8,+2,+0,
            +0,+2,-8,-8,-8,-18,-16,-16,-18,-8,-18,-16,-16,-16,-18,
            -24,-16,-18,-8,-18,-8,-8,-8,-18,-29,-18,-8,-8,-5,-16,
            -16,-16,-26,-24,-24,-18,-8,-18,-24,-24,-24,-18,-24,-16,-10,
            +0,-10,+0,+0,+0,-10,-21,-10,+8,+8,+8,+0,+0,+0,-10,
            -8,-8,-10,+0,-10,-21,-21,-21,-10,-21,-10,-8,+0,-5,-8,
            -8,-8,-5,-16,-5,-8,-8,-5,-16,-16,-16,-26,-24,-24,-26,
            -16,-26,-24,-24,-24,-26,-32,-24,-10,+0,-10,+0,+0,+0,-10,
            -21,-10,-8,-8,-5,-16,-16,-16,-26,-24,-24,-10,+0,-10,-16,
            -16,-16,-10,-16,-8,-10,+0,-10,+0,+0,+0,-10,-21,-10,+8,
            +8,+8,+0,+0,+0,-10,-8,-8,-10,+0,-10,-21,-21,-21,-10,
            -21,-10,+8,+16,+8,+8,+8,+8,+8,-2,+8,+8,+8,+10,+0,
            +0,+0,-10,-8,-8,-10,+0,-10,-8,-8,-8,-10,-16,-8,-10,
            +0,-10,+0,+0,+0,-10,-21,-10,-13,-13,-10,-21,-21,-21,-29,
            -29,-29,-10,+0,-10,-21,-21,-21,-10,-21,-10,+8,+16,+8,+16,
            +16,+16,+8,-2,+8,+16,+16,+18,+8,+8,+8,-2,+0,+0,+8,
            +18,+8,-2,-2,-2,+8,-2,+8,+8,+16,+10,+8,+8,+8,+10,
            +0,+10,+8,+8,+10,+0,+0,+0,-10,-8,-8,-10,+0,-10,-8,
            -8,-8,-10,-16,-8,-10,+0,-10,+0,+0,+0,-10,-21,-10,+0,
            +0,+2,-8,-8,-8,-18,-16,-16,-10,+0,-10,-16,-16,-16,-10,
            -16,-8,-10,+0,-10,+0,+0,+0,-10,-21,-10,+8,+8,+8,+0,
            +0,+0,-10,-8,-8,-10,+0,-10,-21,-21,-21,-10,-21,-10,-13,
            -5,-10,-13,-13,-13,-10,-21,-10,-13,-13,-10,-21,-21,-21,-31,
            -29,-29,-29,-18,-29,-29,-29,-29,-29,-37,-29,-10,+0,-10,+0,
            +0,+0,-10,-21,-10,-13,-13,-10,-21,-21,-21,-29,-29,-29,-10,
            +0,-10,-21,-21,-21,-10,-21,-10,+0,+8,+2,+8,+8,+8,+2,
            -8,+2,+16,+16,+18,+8,+8,+8,-2,+0,+0,+2,+13,+2,-8,
            -8,-8,+2,-8,+2,+8,+16,+10,+8,+8,+8,+10,+0,+10,+8,
            +8,+10,+0,+0,+0,-10,-8,-8,-10,+0,-10,-8,-8,-8,-10,
            -16,-8,+2,+13,+2,+13,+13,+13,+2,-8,+2,+0,+0,+2,-8,
            -8,-8,-16,-16,-16,+2,+13,+2,-8,-8,-8,+2,-8,+2,+0,
            +8,+2,+8,+8,+8,+2,-8,+2,+8,+8,+10,+0,+0,+0,-10,
            -8,-8,+2,+13,+2,-8,-8,-8,+2,-8,+2,+0,+8,+2,+0,
            +0,+0,+2,-8,+2,+0,+0,+2,-8,-8,-8,-18,-16,-16,-18,
            -8,-18,-16,-16,-16,-18,-24,-16,-18,-8,-18,-8,-8,-8,-18,
            -29,-18,-8,-8,-5,-16,-16,-16,-26,-24,-24,-18,-8,-18,-24,
            -24,-24,-18,-24,-16,-18,-8,-18,-8,-8,-8,-18,-29,-18,+0,
            +0,+0,-8,-8,-8,-18,-16,-16,-18,-8,-18,-29,-29,-29,-18,
            -29,-18,-8,+0,-5,-8,-8,-8,-5,-16,-5,-8,-8,-5,-16,
            -16,-16,-26,-24,-24,-26,-16,-26,-24,-24,-24,-26,-32,-24,-18,
            -8,-18,-8,-8,-8,-18,-29,-18,-16,-16,-13,-24,-24,-24,-34,
            -32,-32,-18,-8,-18,-24,-24,-24,-18,-24,-16,-10,+0,-10,+0,
            +0,+0,-10,-21,-10,+8,+8,+8,+0,+0,+0,-10,-8,-8,-10,
            +0,-10,-21,-21,-21,-10,-21,-10,+8,+16,+8,+8,+8,+8,+8,
            -2,+8,+8,+8,+10,+0,+0,+0,-10,-8,-8,-10,+0,-10,-8,
            -8,-8,-10,-16,-8,-10,+0,-10,+0,+0,+0,-10,-21,-10,-13,
            -13,-10,-21,-21,-21,-29,-29,-29,-10,+0,-10,-21,-21,-21,-10,
            -21,-10,-8,+0,-5,+0,+0,+0,-5,-16,-5,+0,+0,+2,-8,
            -8,-8,-18,-16,-16,-5,+5,-5,-16,-16,-16,-5,-16,-5,-8,
            +0,-5,-8,-8,-8,-5,-16,-5,-8,-8,-5,-16,-16,-16,-26,
            -24,-24,-26,-16,-26,-24,-24,-24,-26,-32,-24,-26,-16,-26,-16,
            -16,-16,-26,-37,-26,-16,-16,-13,-24,-24,-24,-34,-32,-32,-26,
            -16,-26,-32,-32,-32,-26,-32,-24,-10,+0,-10,+0,+0,+0,-10,
            -21,-10,+8,+8,+8,+0,+0,+0,-10,-8,-8,-10,+0,-10,-21,
            -21,-21,-10,-21,-10,-8,+0,-5,-8,-8,-8,-5,-16,-5,-8,
            -8,-5,-16,-16,-16,-26,-24,-24,-26,-16,-26,-24,-24,-24,-26,
            -32,-24,-10,+0,-10,+0,+0,+0,-10,-21,-10,-8,-8,-5,-16,
            -16,-16,-26,-24,-24,-10,+0,-10,-16,-16,-16,-10,-16,-8,+0,
            +10,+0,+10,+10,+10,+0,-10,+0,+18,+18,+18,+10,+10,+10,+0,
            +2,+2,+0,+10,+0,-10,-10,-10,+0,-10,+0,+18,+26,+18,+18,
            +18,+18,+18,+8,+18,+18,+18,+21,+10,+10,+10,+0,+2,+2,+0,
            +10,+0,+2,+2,+2,+0,-5,+2,+0,+10,+0,+10,+10,+10,+0,
            -10,+0,-2,-2,+0,-10,-10,-10,-18,-18,-18,+0,+10,+0,-10,
            -10,-10,+0,-10,+0,+18,+26,+18,+26,+26,+26,+18,+8,+18,+26,
            +26,+29,+18,+18,+18,+8,+10,+10,+18,+29,+18,+8,+8,+8,+18,
            +8,+18,+18,+26,+21,+18,+18,+18,+21,+10,+21,+18,+18,+21,+10,
            +10,+10,+0,+2,+2,+0,+10,+0,+2,+2,+2,+0,-5,+2,+0,
            +10,+0,+10,+10,+10,+0,-10,+0,+10,+10,+13,+2,+2,+2,-8,
            -5,-5,+0,+10,+0,-5,-5,-5,+0,-5,+2,+0,+10,+0,+10,
            +10,+10,+0,-10,+0,+18,+18,+18,+10,+10,+10,+0,+2,+2,+0,
            +10,+0,-10,-10,-10,+0,-10,+0,-2,+5,+0,-2,-2,-2,+0,
            -10,+0,-2,-2,+0,-10,-10,-10,-21,-18,-18,-18,-8,-18,-18,
            -18,-18,-18,-26,-18,+0,+10,+0,+10,+10,+10,+0,-10,+0,-2,
            -2,+0,-10,-10,-10,-18,-18,-18,+0,+10,+0,-10,-10,-10,+0,
            -10,+0,+18,+26,+18,+26,+26,+26,+18,+8,+18,+34,+34,+37,+26,
            +26,+26,+16,+18,+18,+18,+29,+18,+8,+8,+8,+18,+8,+18,+26,
            +34,+29,+26,+26,+26,+29,+18,+29,+26,+26,+29,+18,+18,+18,+8,
            +10,+10,+8,+18,+8,+10,+10,+10,+8,+2,+10,+18,+29,+18,+29,
            +29,+29,+18,+8,+18,+16,+16,+18,+8,+8,+8,+0,+0,+0,+18,
            +29,+18,+8,+8,+8,+18,+8,+18,+18,+26,+21,+26,+26,+26,+21,
            +10,+21,+26,+26,+29,+18,+18,+18,+8,+10,+10,+21,+31,+21,+10,
            +10,+10,+21,+10,+21,+18,+26,+21,+18,+18,+18,+21,+10,+21,+18,
            +18,+21,+10,+10,+10,+0,+2,+2,+0,+10,+0,+2,+2,+2,+0,
            -5,+2,+0,+10,+0,+10,+10,+10,+0,-10,+0,+10,+10,+13,+2,
            +2,+2,-8,-5,-5,+0,+10,+0,-5,-5,-5,+0,-5,+2,+0,
            +10,+0,+10,+10,+10,+0,-10,+0,+18,+18,+18,+10,+10,+10,+0,
            +2,+2,+0,+10,+0,-10,-10,-10,+0,-10,+0,+10,+18,+13,+10,
            +10,+10,+13,+2,+13,+10,+10,+13,+2,+2,+2,-8,-5,-5,-8,
            +2,-8,-5,-5,-5,-8,-13,-5,+0,+10,+0,+10,+10,+10,+0,
            -10,+0,+2,+2,+5,-5,-5,-5,-16,-13,-13,+0,+10,+0,-5,
            -5,-5,+0,-5,+2,+0,+10,+0,+10,+10,+10,+0,-10,+0,+18,
            +18,+18,+10,+10,+10,+0,+2,+2,+0,+10,+0,-10,-10,-10,+0,
            -10,+0,+18,+26,+18,+18,+18,+18,+18,+8,+18,+18,+18,+21,+10,
            +10,+10,+0,+2,+2,+0,+10,+0,+2,+2,+2,+0,-5,+2,+0,
            +10,+0,+10,+10,+10,+0,-10,+0,-2,-2,+0,-10,-10,-10,-18,
            -18,-18,+0,+10,+0,-10,-10,-10,+0,-10,+0,-2,+5,+0,+5,
            +5,+5,+0,-10,+0,+5,+5,+8,-2,-2,-2,-13,-10,-10,+0,
            +10,+0,-10,-10,-10,+0,-10,+0,-2,+5,+0,-2,-2,-2,+0,
            -10,+0,-2,-2,+0,-10,-10,-10,-21,-18,-18,-21,-10,-21,-18,
            -18,-18,-21,-26,-18,-18,-8,-18,-8,-8,-8,-18,-29,-18,-10,
            -10,-8,-18,-18,-18,-29,-26,-26,-18,-8,-18,-26,-26,-26,-18,
            -26,-18,+0,+10,+0,+10,+10,+10,+0,-10,+0,+18,+18,+18,+10,
            +10,+10,+0,+2,+2,+0,+10,+0,-10,-10,-10,+0,-10,+0,-2,
            +5,+0,-2,-2,-2,+0,-10,+0,-2,-2,+0,-10,-10,-10,-21,
            -18,-18,-18,-8,-18,-18,-18,-18,-18,-26,-18,+0,+10,+0,+10,
            +10,+10,+0,-10,+0,-2,-2,+0,-10,-10,-10,-18,-18,-18,+0,
            +10,+0,-10,-10,-10,+0,-10,+0,+8,+16,+10,+16,+16,+16,+10,
            +0,+10,+24,+24,+26,+16,+16,+16,+5,+8,+8,+10,+21,+10,+0,
            +0,+0,+10,+0,+10,+24,+32,+26,+24,+24,+24,+26,+16,+26,+24,
            +24,+26,+16,+16,+16,+5,+8,+8,+5,+16,+5,+8,+8,+8,+5,
            +0,+8,+10,+21,+10,+21,+21,+21,+10,+0,+10,+8,+8,+10,+0,
            +0,+0,-8,-8,-8,+10,+21,+10,+0,+0,+0,+10,+0,+10,+16,
            +24,+18,+24,+24,+24,+18,+8,+18,+24,+24,+26,+16,+16,+16,+5,
            +8,+8,+18,+29,+18,+8,+8,+8,+18,+8,+18,+16,+24,+18,+16,
            +16,+16,+18,+8,+18,+16,+16,+18,+8,+8,+8,-2,+0,+0,-2,
            +8,-2,+0,+0,+0,-2,-8,+0,-2,+8,-2,+8,+8,+8,-2,
            -13,-2,+8,+8,+10,+0,+0,+0,-10,-8,-8,-2,+8,-2,-8,
            -8,-8,-2,-8,+0,+10,+21,+10,+21,+21,+21,+10,+0,+10,+29,
            +29,+29,+21,+21,+21,+10,+13,+13,+10,+21,+10,+0,+0,+0,+10,
            +0,+10,+8,+16,+10,+8,+8,+8,+10,+0,+10,+8,+8,+10,+0,
            +0,+0,-10,-8,-8,-8,+2,-8,-8,-8,-8,-8,-16,-8,+10,
            +21,+10,+21,+21,+21,+10,+0,+10,+8,+8,+10,+0,+0,+0,-8,
            -8,-8,+10,+21,+10,+0,+0,+0,+10,+0,+10,+8,+16,+10,+16,
            +16,+16,+10,+0,+10,+24,+24,+26,+16,+16,+16,+5,+8,+8,+10,
            +21,+10,+0,+0,+0,+10,+0,+10,+16,+24,+18,+16,+16,+16,+18,
            +8,+18,+16,+16,+18,+8,+8,+8,-2,+0,+0,-2,+8,-2,+0,
            +0,+0,-2,-8,+0,+10,+21,+10,+21,+21,+21,+10,+0,+10,+8,
            +8,+10,+0,+0,+0,-8,-8,-8,+10,+21,+10,+0,+0,+0,+10,
            +0,+10,+8,+16,+10,+16,+16,+16,+10,+0,+10,+16,+16,+18,+8,
            +8,+8,-2,+0,+0,+10,+21,+10,+0,+0,+0,+10,+0,+10,+8,
            +16,+10,+8,+8,+8,+10,+0,+10,+8,+8,+10,+0,+0,+0,-10,
            -8,-8,-10,+0,-10,-8,-8,-8,-10,-16,-8,-10,+0,-10,+0,
            +0,+0,-10,-21,-10,+0,+0,+2,-8,-8,-8,-18,-16,-16,-10,
            +0,-10,-16,-16,-16,-10,-16,-8,-10,+0,-10,+0,+0,+0,-10,
            -21,-10,+8,+8,+8,+0,+0,+0,-10,-8,-8,-10,+0,-10,-21,
            -21,-21,-10,-21,-10,+0,+8,+2,+0,+0,+0,+2,-8,+2,+0,
            +0,+2,-8,-8,-8,-18,-16,-16,-18,-8,-18,-16,-16,-16,-18,
            -24,-16,-10,+0,-10,+0,+0,+0,-10,-21,-10,-8,-8,-5,-16,
            -16,-16,-26,-24,-24,-10,+0,-10,-16,-16,-16,-10,-16,-8,-10,
            +0,-10,+0,+0,+0,-10,-21,-10,+8,+8,+8,+0,+0,+0,-10,
            -8,-8,-10,+0,-10,-21,-21,-21,-10,-21,-10,+8,+16,+8,+8,
            +8,+8,+8,-2,+8,+8,+8,+10,+0,+0,+0,-10,-8,-8,-10,
            +0,-10,-8,-8,-8,-10,-16,-8,-10,+0,-10,+0,+0,+0,-10,
            -21,-10,-13,-13,-10,-21,-21,-21,-29,-29,-29,-10,+0,-10,-21,
            -21,-21,-10,-21,-10,+0,+8,+2,+8,+8,+8,+2,-8,+2,+8,
            +8,+10,+0,+0,+0,-10,-8,-8,+2,+13,+2,-8,-8,-8,+2,
            -8,+2,+0,+8,+2,+0,+0,+0,+2,-8,+2,+0,+0,+2,-8,
            -8,-8,-18,-16,-16,-18,-8,-18,-16,-16,-16,-18,-24,-16,-18,
            -8,-18,-8,-8,-8,-18,-29,-18,-8,-8,-5,-16,-16,-16,-26,
            -24,-24,-18,-8,-18,-24,-24,-24,-18,-24,-16,-10,+0,-10,+0,
            +0,+0,-10,-21,-10,+8,+8,+8,+0,+0,+0,-10,-8,-8,-10,
            +0,-10,-21,-21,-21,-10,-21,-10,-8,+0,-5,-8,-8,-8,-5,
            -16,-5,-8,-8,-5,-16,-16,-16,-26,-24,-24,-26,-16,-26,-24,
            -24,-24,-26,-32,-24,-10,+0,-10,+0,+0,+0,-10,-21,-10,-8,
            -8,-5,-16,-16,-16,-26,-24,-24,-10,+0,-10,-16,-16,-16,-10,
            -16,-8,+0,+10,+0,+10,+10,+10,+0,-10,+0,+18,+18,+18,+10,
            +10,+10,+0,+2,+2,+0,+10,+0,-10,-10,-10,+0,-10,+0,+18,
            +26,+18,+18,+18,+18,+18,+8,+18,+18,+18,+21,+10,+10,+10,+0,
            +2,+2,+0,+10,+0,+2,+2,+2,+0,-5,+2,+0,+10,+0,+10,
            +10,+10,+0,-10,+0,-2,-2,+0,-10,-10,-10,-18,-18,-18,+0,
            +10,+0,-10,-10,-10,+0,-10,+0,+18,+26,+18,+26,+26,+26,+18,
            +8,+18,+26,+26,+29,+18,+18,+18,+8,+10,+10,+18,+29,+18,+8,
            +8,+8,+18,+8,+18,+18,+26,+21,+18,+18,+18,+21,+10,+21,+18,
            +18,+21,+10,+10,+10,+0,+2,+2,+0,+10,+0,+2,+2,+2,+0,
            -5,+2,+0,+10,+0,+10,+10,+10,+0,-10,+0,+10,+10,+13,+2,
            +2,+2,-8,-5,-5,+0,+10,+0,-5,-5,-5,+0,-5,+2,+0,
            +10,+0,+10,+10,+10,+0,-10,+0,+18,+18,+18,+10,+10,+10,+0,
            +2,+2,+0,+10,+0,-10,-10,-10,+0,-10,+0,-2,+5,+0,-2,
            -2,-2,+0,-10,+0,-2,-2,+0,-10,-10,-10,-21,-18,-18,-18,
            -8,-18,-18,-18,-18,-18,-26,-18,+0,+10,+0,+10,+10,+10,+0,
            -10,+0,-2,-2,+0,-10,-10,-10,-18,-18,-18,+0,+10,+0,-10,
            -10,-10,+0,-10,+0,+0,+8,+2,+8,+8,+8,+2,-8,+2,+16,
            +16,+18,+8,+8,+8,-2,+0,+0,+2,+13,+2,-8,-8,-8,+2,
            -8,+2,+8,+16,+10,+8,+8,+8,+10,+0,+10,+8,+8,+10,+0,
            +0,+0,-10,-8,-8,-10,+0,-10,-8,-8,-8,-10,-16,-8,+2,
            +13,+2,+13,+13,+13,+2,-8,+2,+0,+0,+2,-8,-8,-8,-16,
            -16,-16,+2,+13,+2,-8,-8,-8,+2,-8,+2,+0,+8,+2,+8,
            +8,+8,+2,-8,+2,+8,+8,+10,+0,+0,+0,-10,-8,-8,+2,
            +13,+2,-8,-8,-8,+2,-8,+2,+0,+8,+2,+0,+0,+0,+2,
            -8,+2,+0,+0,+2,-8,-8,-8,-18,-16,-16,-18,-8,-18,-16,
            -16,-16,-18,-24,-16,-18,-8,-18,-8,-8,-8,-18,-29,-18,-8,
            -8,-5,-16,-16,-16,-26,-24,-24,-18,-8,-18,-24,-24,-24,-18,
            -24,-16,-18,-8,-18,-8,-8,-8,-18,-29,-18,+0,+0,+0,-8,
            -8,-8,-18,-16,-16,-18,-8,-18,-29,-29,-29,-18,-29,-18,-8,
            +0,-5,-8,-8,-8,-5,-16,-5,-8,-8,-5,-16,-16,-16,-26,
            -24,-24,-26,-16,-26,-24,-24,-24,-26,-32,-24,-18,-8,-18,-8,
            -8,-8,-18,-29,-18,-16,-16,-13,-24,-24,-24,-34,-32,-32,-18,
            -8,-18,-24,-24,-24,-18,-24,-16,+0,+10,+0,+10,+10,+10,+0,
            -10,+0,+18,+18,+18,+10,+10,+10,+0,+2,+2,+0,+10,+0,-10,
            -10,-10,+0,-10,+0,+18,+26,+18,+18,+18,+18,+18,+8,+18,+18,
            +18,+21,+10,+10,+10,+0,+2,+2,+0,+10,+0,+2,+2,+2,+0,
            -5,+2,+0,+10,+0,+10,+10,+10,+0,-10,+0,-2,-2,+0,-10,
            -10,-10,-18,-18,-18,+0,+10,+0,-10,-10,-10,+0,-10,+0,+0,
            +8,+2,+8,+8,+8,+2,-8,+2,+8,+8,+10,+0,+0,+0,-10,
            -8,-8,+2,+13,+2,-8,-8,-8,+2,-8,+2,+0,+8,+2,+0,
            +0,+0,+2,-8,+2,+0,+0,+2,-8,-8,-8,-18,-16,-16,-18,
            -8,-18,-16,-16,-16,-18,-24,-16,-18,-8,-18,-8,-8,-8,-18,
            -29,-18,-8,-8,-5,-16,-16,-16,-26,-24,-24,-18,-8,-18,-24,
            -24,-24,-18,-24,-16,+0,+10,+0,+10,+10,+10,+0,-10,+0,+18,
            +18,+18,+10,+10,+10,+0,+2,+2,+0,+10,+0,-10,-10,-10,+0,
            -10,+0,+0,+8,+2,+0,+0,+0,+2,-8,+2,+0,+0,+2,-8,
            -8,-8,-18,-16,-16,-18,-8,-18,-16,-16,-16,-18,-24,-16,+0,
            +10,+0,+10,+10,+10,+0,-10,+0,+0,+0,+2,-8,-8,-8,-18,
            -16,-16,+0,+10,+0,-8,-8,-8,+0,-8,+0
        ];
 
        Diag7 = [
            +0,+0,-9,-6,-6,-9,+0,-9,-6,-6,-6,-9,-12,-6,-10,+0,-10,
            -1,+0,-1,-12,-19,-10,-3,+0,-3,-12,-7,-1,-18,-15,-14,
            -10,-1,-9,-13,-12,-13,-10,-13,-7,-10,+0,-10,+0,+0,-1,
            -12,-19,-11,+3,+8,+5,-3,+0,-4,-8,-9,-6,-10,+0,-9,
            -18,-19,-21,-11,-19,-10,+0,+6,+3,+0,+0,+0,+3,-6,+3,
            +0,+0,+3,-6,-6,-6,-15,-12,-12,-15,-6,-15,-12,-12,-12,
            -15,-17,-12,-10,+0,-10,+0,+0,-1,-12,-19,-11,-6,-6,-6,
            -13,-12,-13,-25,-21,-24,-10,-1,-10,-13,-13,-14,-11,-13,-7,
            -9,+0,-9,+1,+1,+0,-11,-20,-11,+15,+8,+10,-5,+1,-2,
            -5,-7,-3,-9,+0,-8,-19,-19,-20,-11,-20,-10,+6,+12,+6,
            +6,+6,+6,+6,-3,+6,+6,+6,+9,+0,+0,+0,-9,-6,-6,
            -9,+0,-9,-6,-6,-6,-9,-12,-6,-9,+1,-9,+0,+0,+0,
            -11,-19,-11,-11,-13,-16,-17,-19,-13,-32,-26,-18,-8,+0,-8,
            -20,-19,-20,-10,-19,-10,+1,+8,+1,+5,+6,+2,+4,-7,+3,
            -3,+10,+17,+4,+0,+0,+0,-8,+3,+5,+13,+6,+0,-9,-10,
            +3,-7,+5,+0,+6,+3,+0,+0,+0,+3,-6,+3,+0,+0,+3,
            -6,-6,-6,-15,-12,-12,-15,-6,-15,-12,-12,-12,-15,-17,-12,
            -18,-7,-17,-10,-8,-11,-20,-26,-17,-6,-10,-3,-20,-15,-20,
            -20,-22,-9,-18,-8,-17,-23,-21,-23,-18,-21,-14,-10,+0,-10,
            +0,+0,-1,-12,-20,-12,+4,+7,+5,-4,+0,-4,-15,-7,-3,
            -10,-1,-9,-19,-19,-20,-11,-20,-11,-6,+0,-3,-6,-6,-6,
            -3,-12,-3,-6,-6,-3,-12,-12,-12,-20,-17,-17,-20,-12,-20,
            -17,-17,-17,-20,-23,-17,-10,+0,-10,-1,+0,+0,-12,-19,-11,
            -11,-8,-12,-19,-13,-12,-28,-21,-15,-9,+0,-9,-14,-13,-12,
            -11,-14,-7,+1,+11,+3,+13,+11,+13,+0,-9,+0,+17,+18,+20,
            +17,+10,+11,-2,+1,+6,+2,+10,+3,-9,-10,-10,+0,-10,+0,
            +15,+20,+15,+15,+15,+15,+15,+6,+15,+15,+15,+17,+9,+9,+9,
            +0,+3,+3,+0,+9,+0,+3,+3,+3,+0,-3,+3,+2,+11,+2,
            +12,+11,+12,-1,-9,+0,+3,-3,+4,-2,-10,-10,-23,-17,-6,
            +2,+11,+3,-9,-10,-10,+0,-10,+1,+20,+28,+20,+29,+25,+12,
            +23,+10,+19,+20,+20,+23,+15,+18,+15,+6,+17,+17,+21,+32,+16,
            +6,+5,+6,+23,+5,+22,+15,+20,+17,+15,+15,+15,+17,+9,+17,
            +15,+15,+17,+9,+9,+9,+0,+3,+3,+0,+9,+0,+3,+3,+3,
            +0,-3,+3,-7,+15,+4,+9,+8,+9,+9,-16,-9,+9,+0,+12,
            +3,-3,+3,-6,-3,+6,+0,+5,-2,-3,-6,-3,+2,-12,+0,
            +2,+12,+3,+12,+12,+14,+0,-8,+0,+23,+20,+16,+9,+12,+6,
            -9,+6,+2,+2,+11,+3,-10,-9,-9,+1,-9,+1,-3,+3,+0,
            -3,-3,-3,+0,-9,+0,-3,-3,+0,-9,-9,-9,-17,-15,-15,
            -15,-6,-15,-15,-15,-15,-15,-20,-15,+2,+12,+3,+11,+12,+14,
            +0,-8,+1,-9,-4,-2,-3,-9,-15,-23,-17,-23,+2,+11,+3,
            -11,-10,-8,+0,-9,+1,+6,+14,+13,+18,+13,+20,+11,+0,+9,
            +17,+23,+12,+20,+13,+12,+3,+2,+8,+11,+20,+14,+9,-1,+4,
            +9,-1,+9,+12,+17,+15,+12,+12,+12,+15,+6,+15,+12,+12,+15,
            +6,+6,+6,-3,+0,+0,-3,+6,-3,+0,+0,+0,-3,-6,+0,
            +10,+19,+12,+15,+18,+26,+10,+0,+10,+6,+0,+9,-9,-1,+0,
            -6,-11,-6,+11,+19,+14,-9,-1,+2,+9,+0,+11,+11,+19,+11,
            +12,+13,+12,+3,-2,+12,+12,+20,+15,+6,+12,+6,-3,+0,+0,
            +15,+17,+6,+9,-4,+0,+2,-4,+6,+6,+12,+9,+6,+6,+6,
            +9,+0,+9,+6,+6,+9,+0,+0,+0,-9,-6,-6,-9,+0,-9,
            -6,-6,-6,-9,-12,-6,-12,+4,-10,+0,+3,+0,-9,-13,-3,
            +0,-4,+3,-6,-1,-6,-15,-20,-12,-11,+5,-15,-20,-13,-12,
            -17,-12,-8,-9,+1,-10,-1,+0,+4,-11,-20,-13,+6,+10,+6,
            +0,+1,+0,-9,-10,-6,-7,+0,-9,-15,-21,-17,-12,-20,-10,
            +0,+6,+3,+0,+0,+0,+3,-6,+3,+0,+0,+3,-6,-6,-6,
            -15,-12,-12,-15,-6,-15,-12,-12,-12,-15,-17,-12,-10,+0,-10,
            +1,+0,+2,-12,-20,-10,-15,-5,-3,-12,-13,-12,-29,-23,-17,
            -11,-1,-8,-18,-14,-20,-13,-12,-6,-1,+9,+0,+11,+10,+9,
            -2,-11,-2,+20,+18,+19,+11,+10,+12,+0,+3,+8,+0,+8,+0,
            -11,-11,-13,-2,-12,-2,+15,+20,+15,+15,+15,+15,+15,+6,+15,
            +15,+15,+17,+9,+9,+9,+0,+3,+3,+0,+9,+0,+3,+3,+3,
            +0,-3,+3,-1,+10,+0,+7,+10,+10,-2,-11,-2,-10,-5,-9,
            -15,-10,-3,-21,-17,-15,+0,+9,+1,-11,-11,-10,-2,-11,-2,
            +4,+11,+6,+15,+6,+8,+9,-3,+8,+6,+6,+17,+0,+3,+0,
            -9,+3,-6,+10,+11,+2,-6,-6,-6,-3,-3,+4,+0,+6,+3,
            +0,+0,+0,+3,-6,+3,+0,+0,+3,-6,-6,-6,-15,-12,-12,
            -15,-6,-15,-12,-12,-12,-15,-17,-12,-11,-4,-6,-6,-3,-6,
            -23,-18,-15,-6,+3,+6,-12,-14,-12,-20,-9,-17,-20,-15,-23,
            -17,-24,-17,-17,-15,-18,+0,+10,+0,+10,+10,+9,-2,-10,-2,
            +11,+18,+22,+12,+10,+6,+7,+5,+4,+1,+9,+1,-10,-10,-10,
            -2,-11,-2,+0,+6,+3,+0,+0,+0,+3,-6,+3,+0,+0,+3,
            -6,-6,-6,-15,-12,-12,-15,-6,-15,-12,-12,-12,-15,-17,-12,
            +0,+10,+1,+9,+10,+11,-2,-10,-2,-4,-1,+0,-11,-7,-8,
            -20,-14,-18,+1,+9,+1,-6,-7,-6,-1,-7,-1
        ];
 
        Diag6 = [
            +0,+0,-7,-5,-5,-7,+0,-7,-5,-5,-5,
            -7,-10,-5,-7,+0,-7,+0,+0,+0,-7,-15,-7,+0,+0,+2,
            -5,-5,-5,-12,-10,-10,-7,+0,-7,-10,-10,-10,-7,-10,-5,
            -7,+0,-7,+0,+0,+0,-7,-15,-7,+5,+5,+5,+0,+0,+0,
            -7,-5,-5,-7,+0,-7,-15,-15,-15,-7,-15,-7,+0,+5,+2,
            +0,+0,+0,+2,-5,+2,+0,+0,+2,-5,-5,-5,-12,-10,-10,
            -12,-5,-12,-10,-10,-10,-12,-15,-10,-7,+0,-7,+0,+0,+0,
            -7,-15,-7,-5,-5,-3,-10,-10,-10,-18,-15,-15,-7,+0,-7,
            -10,-10,-10,-7,-10,-5,+0,+7,+0,+7,+7,+7,+0,-7,+0,
            +12,+12,+12,+7,+7,+7,+0,+2,+2,+0,+7,+0,-7,-7,-7,
            +0,-7,+0,+12,+18,+12,+12,+12,+12,+12,+5,+12,+12,+12,+15,
            +7,+7,+7,+0,+2,+2,+0,+7,+0,+2,+2,+2,+0,-3,+2,
            +0,+7,+0,+7,+7,+7,+0,-7,+0,-2,-2,+0,-7,-7,-7,
            -12,-12,-12,+0,+7,+0,-7,-7,-7,+0,-7,+0,+5,+10,+7,
            +10,+10,+10,+7,+0,+7,+10,+10,+12,+5,+5,+5,-2,+0,+0,
            +7,+15,+7,+0,+0,+0,+7,+0,+7,+5,+10,+7,+5,+5,+5,
            +7,+0,+7,+5,+5,+7,+0,+0,+0,-7,-5,-5,-7,+0,-7,
            -5,-5,-5,-7,-10,-5,-7,+0,-7,+0,+0,+0,-7,-15,-7,
            +0,+0,+2,-5,-5,-5,-12,-10,-10,-7,+0,-7,-10,-10,-10,
            -7,-10,-5,+0,+7,+0,+7,+7,+7,+0,-7,+0,+12,+12,+12,
            +7,+7,+7,+0,+2,+2,+0,+7,+0,-7,-7,-7,+0,-7,+0,
            +0,+5,+2,+0,+0,+0,+2,-5,+2,+0,+0,+2,-5,-5,-5,
            -12,-10,-10,-12,-5,-12,-10,-10,-10,-12,-15,-10,+0,+7,+0,
            +7,+7,+7,+0,-7,+0,+0,+0,+2,-5,-5,-5,-12,-10,-10,
            +0,+7,+0,-5,-5,-5,+0,-5,+0
        ];
 
        Diag5 = [
            +0,+0,-5,-4,-4,-5,+0,-5,-4,-4,-4,-5,-7,-4,
            -5,+0,-5,+0,+0,+0,-5,-11,-5,+0,+0,+2,-4,-4,-4,
            -9,-7,-7,-5,+0,-5,-7,-7,-7,-5,-7,-4,+0,+5,+0,
            +5,+5,+5,+0,-5,+0,+9,+9,+9,+5,+5,+5,+0,+2,+2,
            +0,+5,+0,-5,-5,-5,+0,-5,+0,+4,+7,+5,+4,+4,+4,
            +5,+0,+5,+4,+4,+5,+0,+0,+0,-5,-4,-4,-5,+0,-5,
            -4,-4,-4,-5,-7,-4,+0,+5,+0,+5,+5,+5,+0,-5,+0,
            +0,+0,+2,-4,-4,-4,-9,-7,-7,+0,+5,+0,-4,-4,-4,
            +0,-4,+0
        ];
 
        Diag4 = [
            +0,+0,-4,-3,-3,
            -3,+0,-3,-2,-3,-3,-5,-5,-3,+1,+5,+1,+4,+4,+3,
            +0,-3,+0,+2,+2,+3,+0,+0,-1,-4,-3,-3,+0,+3,+0,
            -2,-3,-3,-1,-3,-1
        ];
    }

    //機能: 与えられた盤面の評価値を算出する。
    //備考: 白番で有利で+のデータ。黒番の時は、値を反転する。
    public function Eval(board:Array, empties:int, color:int):int {
        var Idx:int, Val:int, Val1:int, Val2:int, Val3:int, Val4:int;
        var Val5:int, Val6:int, Val7:int, Val8:int, Val9:int, Val0:int;
    
        //Line1
        Val1 = 0;
        Idx = ((((((board[A1]*3+board[B1])*3+board[C1])
              *3+board[D1])*3+board[E1])*3+board[F1])
              *3+board[G1])*3+board[H1];
        if (Idx < 0)
            Val1 -= Line1[-Idx];
        else 
            Val1 += Line1[Idx];
               
        Idx = ((((((board[A8]*3+board[B8])*3+board[C8])
              *3+board[D8])*3+board[E8])*3+board[F8])
              *3+board[G8])*3+board[H8];
        if (Idx < 0)
            Val1 -= Line1[-Idx];
        else 
            Val1 += Line1[Idx];
    
        Idx = ((((((board[A1]*3+board[A2])*3+board[A3])
              *3+board[A4])*3+board[A5])*3+board[A6])
              *3+board[A7])*3+board[A8];
        if (Idx < 0)
            Val1 -= Line1[-Idx];
        else 
            Val1 += Line1[Idx];
    
        Idx = ((((((board[H1]*3+board[H2])*3+board[H3])
              *3+board[H4])*3+board[H5])*3+board[H6])
              *3+board[H7])*3+board[H8];
        if (Idx < 0)
            Val1 -= Line1[-Idx];
        else 
            Val1 += Line1[Idx];
            
        //Line2
        Val2 = 0;
        Idx = ((((((board[A2]*3+board[B2])*3+board[C2])
              *3+board[D2])*3+board[E2])*3+board[F2])
              *3+board[G2])*3+board[H2];
        if (Idx < 0)
            Val2 -= Line2[-Idx];
        else 
            Val2 += Line2[Idx];
               
        Idx = ((((((board[A7]*3+board[B7])*3+board[C7])
              *3+board[D7])*3+board[E7])*3+board[F7])
              *3+board[G7])*3+board[H7];
        if (Idx < 0)
            Val2 -= Line2[-Idx];
        else 
            Val2 += Line2[Idx];
    
        Idx = ((((((board[B1]*3+board[B2])*3+board[B3])
              *3+board[B4])*3+board[B5])*3+board[B6])
              *3+board[B7])*3+board[B8];
        if (Idx < 0)
            Val2 -= Line2[-Idx];
        else 
            Val2 += Line2[Idx];
    
        Idx = ((((((board[G1]*3+board[G2])*3+board[G3])
              *3+board[G4])*3+board[G5])*3+board[G6])
              *3+board[G7])*3+board[G8];
        if (Idx < 0)
            Val2 -= Line2[-Idx];
        else 
            Val2 += Line2[Idx];
    
        //Line3
        Val3 = 0;
        Idx = ((((((board[A3]*3+board[B3])*3+board[C3])
              *3+board[D3])*3+board[E3])*3+board[F3])
              *3+board[G3])*3+board[H3];
        if (Idx < 0)
            Val3 -= Line3[-Idx];
        else 
            Val3 += Line3[Idx];
               
        Idx = ((((((board[A6]*3+board[B6])*3+board[C6])
              *3+board[D6])*3+board[E6])*3+board[F6])
              *3+board[G6])*3+board[H6];
        if (Idx < 0)
            Val3 -= Line3[-Idx];
        else 
            Val3 += Line3[Idx];
    
        Idx = ((((((board[C1]*3+board[C2])*3+board[C3])
              *3+board[C4])*3+board[C5])*3+board[C6])
              *3+board[C7])*3+board[C8];
        if (Idx < 0)
            Val3 -= Line3[-Idx];
        else 
            Val3 += Line3[Idx];
    
        Idx = ((((((board[F1]*3+board[F2])*3+board[F3])
              *3+board[F4])*3+board[F5])*3+board[F6])
              *3+board[F7])*3+board[F8];
        if (Idx < 0)
            Val3 -= Line3[-Idx];
        else 
            Val3 += Line3[Idx];
    
        //Line4
        Val4 = 0;
        Idx = ((((((board[A4]*3+board[B4])*3+board[C4])
              *3+board[D4])*3+board[E4])*3+board[F4])
              *3+board[G4])*3+board[H4];
        if (Idx < 0)
            Val4 -= Line4[-Idx];
        else 
            Val4 += Line4[Idx];
               
        Idx = ((((((board[A5]*3+board[B5])*3+board[C5])
              *3+board[D5])*3+board[E5])*3+board[F5])
              *3+board[G5])*3+board[H5];
        if (Idx < 0)
            Val4 -= Line4[-Idx];
        else 
            Val4 += Line4[Idx];
    
        Idx = ((((((board[D1]*3+board[D2])*3+board[D3])
              *3+board[D4])*3+board[D5])*3+board[D6])
              *3+board[D7])*3+board[D8];
        if (Idx < 0)
            Val4 -= Line4[-Idx];
        else 
            Val4 += Line4[Idx];
    
        Idx = ((((((board[E1]*3+board[E2])*3+board[E3])
              *3+board[E4])*3+board[E5])*3+board[E6])
              *3+board[E7])*3+board[E8];
        if (Idx < 0)
            Val4 -= Line4[-Idx];
        else 
            Val4 += Line4[Idx];
    
        //Diag4
        Val5 = 0;
        Idx = ((board[A4]*3+board[B3])*3+board[C2])
              *3+board[D1];
        if (Idx < 0)
            Val5 -= Diag4[-Idx];
        else 
            Val5 += Diag4[Idx];
        
        Idx = ((board[E1]*3+board[F2])*3+board[G3])
              *3+board[H4];
        if (Idx < 0)
            Val5 -= Diag4[-Idx];
        else 
            Val5 += Diag4[Idx];
        
        Idx = ((board[A5]*3+board[B6])*3+board[C7])
              *3+board[D8];
        if (Idx < 0)
            Val5 -= Diag4[-Idx];
        else 
            Val5 += Diag4[Idx];
        
        Idx = ((board[E8]*3+board[F7])*3+board[G6])
              *3+board[H5];
        if (Idx < 0)
            Val5 -= Diag4[-Idx];
        else 
            Val5 += Diag4[Idx];
        
        //Diag5
        Val6 = 0;
        Idx = (((board[A5]*3+board[B4])*3+board[C3])
              *3+board[D2])*3+board[E1];
        if (Idx < 0)
            Val6 -= Diag5[-Idx];
        else 
            Val6 += Diag5[Idx];
               
        Idx = (((board[D1]*3+board[E2])*3+board[F3])
              *3+board[G4])*3+board[H5];
        if (Idx < 0)
            Val6 -= Diag5[-Idx];
        else 
            Val6 += Diag5[Idx];
        
        Idx = (((board[A4]*3+board[B5])*3+board[C6])
              *3+board[D7])*3+board[E8];
        if (Idx < 0)
            Val6 -= Diag5[-Idx];
        else 
            Val6 += Diag5[Idx];
        
        Idx = (((board[D8]*3+board[E7])*3+board[F6])
              *3+board[G5])*3+board[H4];
        if (Idx < 0)
            Val6 -= Diag5[-Idx];
        else 
            Val6 += Diag5[Idx];
        
        //Diag6
        Val7 = 0;
        Idx = ((((board[A6]*3+board[B5])*3+board[C4])
              *3+board[D3])*3+board[E2])*3+board[F1];
        if (Idx < 0)
            Val7 -= Diag6[-Idx];
        else 
            Val7 += Diag6[Idx];
               
        Idx = ((((board[C1]*3+board[D2])*3+board[E3])
              *3+board[F4])*3+board[G5])*3+board[H6];
        if (Idx < 0)
            Val7 -= Diag6[-Idx];
        else 
            Val7 += Diag6[Idx];
        
        Idx = ((((board[A3]*3+board[B4])*3+board[C5])
              *3+board[D6])*3+board[E7])*3+board[F8];
        if (Idx < 0)
            Val7 -= Diag6[-Idx];
        else 
            Val7 += Diag6[Idx];
        
        Idx = ((((board[C8]*3+board[D7])*3+board[E6])
              *3+board[F5])*3+board[G4])*3+board[H3];
        if (Idx < 0)
            Val7 -= Diag6[-Idx];
        else 
            Val7 += Diag6[Idx];
        
        //Diag7
        Val8= 0;
        Idx = (((((board[A7]*3+board[B6])*3+board[C5])
              *3+board[D4])*3+board[E3])*3+board[F2])
              *3+board[G1];
        if (Idx < 0)
            Val8 -= Diag7[-Idx];
        else 
            Val8 += Diag7[Idx];
               
        Idx = (((((board[B1]*3+board[C2])*3+board[D3])
              *3+board[E4])*3+board[F5])*3+board[G6])
              *3+board[H7];
        if (Idx < 0)
            Val8 -= Diag7[-Idx];
        else 
            Val8 += Diag7[Idx];
        
        Idx = (((((board[A2]*3+board[B3])*3+board[C4])
              *3+board[D5])*3+board[E6])*3+board[F7])
              *3+board[G8];
        if (Idx < 0)
            Val8 -= Diag7[-Idx];
        else 
            Val8 += Diag7[Idx];
        
        Idx = (((((board[B8]*3+board[C7])*3+board[D6])
              *3+board[E5])*3+board[F4])*3+board[G3])
              *3+board[H2];
        if (Idx < 0)
            Val8 -= Diag7[-Idx];
        else 
            Val8 += Diag7[Idx];
        
        //Diag8
        Val9 = 0;
        Idx = ((((((board[A1]*3+board[B2])*3+board[C3])
              *3+board[D4])*3+board[E5])*3+board[F6])
              *3+board[G7])*3+board[H8];
        if (Idx < 0)
            Val9 -= Diag8[-Idx];
        else 
            Val9 += Diag8[Idx];
               
        Idx = ((((((board[A8]*3+board[B7])*3+board[C6])
              *3+board[D5])*3+board[E4])*3+board[F3])
              *3+board[G2])*3+board[H1];
        if (Idx < 0)
            Val9 -= Diag8[-Idx];
        else 
            Val9 += Diag8[Idx];
            
            
        //Edge8
        Val0 = 0;
        Idx = ((((((board[A1]*3+board[B1])*3+board[C1])
              *3+board[D1])*3+board[A2])*3+board[B2])
              *3+board[C2])*3+board[D2];
        if (Idx < 0)
            Val0 -= Edge8[-Idx];
        else 
            Val0 += Edge8[Idx];
               
        Idx = ((((((board[A1]*3+board[A2])*3+board[A3])
              *3+board[A4])*3+board[B1])*3+board[B2])
              *3+board[B3])*3+board[B4];
        if (Idx < 0)
            Val0 -= Edge8[-Idx];
        else 
            Val0 += Edge8[Idx];
    
        Idx = ((((((board[H1]*3+board[G1])*3+board[F1])
              *3+board[E1])*3+board[H2])*3+board[G2])
              *3+board[F2])*3+board[E2];
        if (Idx < 0)
            Val0 -= Edge8[-Idx];
        else 
            Val0 += Edge8[Idx];
    
        Idx = ((((((board[H1]*3+board[H2])*3+board[H3])
              *3+board[H4])*3+board[G1])*3+board[G2])
              *3+board[G3])*3+board[G4];
        if (Idx < 0)
            Val0 -= Edge8[-Idx];
        else 
            Val0 += Edge8[Idx];
    
        Idx = ((((((board[A8]*3+board[B8])*3+board[C8])
              *3+board[D8])*3+board[A7])*3+board[B7])
              *3+board[C7])*3+board[D7];
        if (Idx < 0)
            Val0 -= Edge8[-Idx];
        else 
            Val0 += Edge8[Idx];
               
        Idx = ((((((board[A8]*3+board[A7])*3+board[A6])
              *3+board[A5])*3+board[B8])*3+board[B7])
              *3+board[B6])*3+board[B5];
        if (Idx < 0)
            Val0 -= Edge8[-Idx];
        else 
            Val0 += Edge8[Idx];
    
        Idx = ((((((board[H8]*3+board[G8])*3+board[F8])
              *3+board[E8])*3+board[H7])*3+board[G7])
              *3+board[F7])*3+board[E7];
        if (Idx < 0)
            Val0 -= Edge8[-Idx];
        else 
            Val0 += Edge8[Idx];
    
        Idx = ((((((board[H8]*3+board[H7])*3+board[H6])
              *3+board[H5])*3+board[G8])*3+board[G7])
              *3+board[G6])*3+board[G5];
        if (Idx < 0)
            Val0 -= Edge8[-Idx];
        else 
            Val0 += Edge8[Idx];
            
            
        //空きマスの数によって、隅周辺の評価値を調整する。
        Val = 0;
        //if (board[A1] == BLACK)
        //    Val -= empties*2; 
        if (board[A1] == EMPTY && board[B2] == BLACK)
            Val += empties*2; 
        //if (board[A1] == WHITE)
        //    Val += empties*2; 
        if (board[A1] == EMPTY && board[B2] == WHITE)
            Val -= empties*2; 

        //if (board[H1] == BLACK)
        //    Val -= empties*2; 
        if (board[H1] == EMPTY && board[G2] == BLACK)
            Val += empties*2; 
        //if (board[H1] == WHITE)
        //    Val += empties*2; 
        if (board[H1] == EMPTY && board[G2] == WHITE)
            Val -= empties*2; 
    
        //if (board[A8] == BLACK)
        //    Val -= empties*2; 
        if (board[A8] == EMPTY && board[B7] == BLACK)
            Val += empties*2; 
        //if (board[A8] == WHITE)
        //    Val += empties*2; 
        if (board[A8] == EMPTY && board[B7] == WHITE)
            Val -= empties*2; 
    
        //if (board[H8] == BLACK)
        //    Val -= empties; 
        if (board[H8] == EMPTY && board[G7] == BLACK)
            Val += empties; 
        //if (board[H8] == WHITE)
        //    Val += empties; 
        if (board[H8] == EMPTY && board[G7] == WHITE)
            Val -= empties;  

        //評価値を石差の近似値に変換する。
        var ev:int = (int)((Val1 + Val2 + Val3 + Val4 + Val5 + Val6 + Val7 + Val8 + Val9 + Val0 + Val) / 10);
        if (ev > 50) ev = 50 + (int)((ev - 50) / 10);

        //評価値を戻す
        return (color == BLACK ? -ev : ev);
    }
}