diff --git a/LICENSE b/LICENSE index d645695..59cfcac 100644 --- a/LICENSE +++ b/LICENSE @@ -176,18 +176,7 @@ END OF TERMS AND CONDITIONS - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] + Copyright 2018, Stichting Mapcode Foundation Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/NOTICE b/NOTICE index 55a41cf..6b16f41 100644 --- a/NOTICE +++ b/NOTICE @@ -4,4 +4,4 @@ MAPCODE PHP LIBRARY PHP library ported by Pieter Geelen from JavaScript version. -Copyright (C) 2014-2015 Stichting Mapcode Foundation (http://www.mapcode.com) +Copyright (C) 2014-2020 Stichting Mapcode Foundation (http://www.mapcode.com) diff --git a/README.md b/README.md index 29884c5..8f66f3e 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Mapcode Library for PHP -Copyright (C) 2014-2015 Stichting Mapcode Foundation (http://www.mapcode.com) +Copyright (C) 2014-2022 Stichting Mapcode Foundation (http://www.mapcode.com) ---- @@ -9,7 +9,7 @@ and to decode mapcodes back to latitude/longitude pairs. **Online documentation can be found at: http://mapcode-foundation.github.io/mapcode-php/** -# License +## License Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -23,28 +23,71 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -# PHP Files for Mapcode Support +## PHP Files for Mapcode Support - mapcode_data.php - Data table for mapcode support - mapcode_func.php - Key routines for mapcode support - - mapcode_ctrynams.php - Optional array with english territory names + mapcode_data.php - Data table for mapcode support + mapcode_func.php - Key routines for mapcode support + mapcode_fast_encode.php - Data for fast encoding of coordinates + mapcode_ctrynams.php - Optional array with english territory names sample.php - Sample php code to interpret or generate mapcodes (upload all 4 files to a server, then open sample.php in a web browser) -# Documentation + unittest\unittest.php - Unit test for mapcode library + +## Documentation mapcode_library_php.doc - Manual: how to use the PHP Mapcode Library LICENSE - Apache License, Version 2.0 NOTICE - About this package README.md - This document -# Version History +## Version History + +### 2.2.3 + +* Updated to support PHP version 8.1.4 (thanks, Bert Hooyman). + +### 2.2.2 + +* Fixed PHP errors for new version of PHP. + +* Cleaned up/reformatted source code. + +### 2.2.0 - 2.2.1 + +* Solved 1-microdegree gap in a few spots on Earth, noticable now extreme precision is possible. + +### 2.1.5 + +* Reworked high-precision to pure integer math. + +* Enforce encode(decode(m))=m except at territory borders. +* Added maxErrorinMeters to API. + +### 2.1.1 + +* Added DistanceInMeters to API. + +### 2.1.0 + +* Rewrote fraction floating points to integer arithmetic. + +* Several fixes; extended unit tests. + +### 2.0.3 + +* Added unittest.php, which verifies that the library works as expected. + +### 2.0.2 + +* Ported fast_encode from C library (4x faster global encoding). + +* Minor improvements (stricter tests). -* 2.0.0 +### 2.0.0 - Initial open source release. (The release starts at 2.0.0 because the - mapcode algorithms match the 2.0.x releases in Java, C/C++, and other - languages.) +* Initial open source release. (The release starts at 2.0.0 because the +mapcode algorithms match the 2.0.x releases in Java, C/C++, and other +languages.) diff --git a/mapcode_api.php b/mapcode_api.php index 40f3a7a..88e5d45 100644 --- a/mapcode_api.php +++ b/mapcode_api.php @@ -1,7 +1,7 @@ '9') { - return false; + return ''; } } return substr($GLOBALS['aliases'], $p + 4, 3); @@ -143,8 +143,11 @@ function getParentOf($territory) function iso2ccode($territory) { - $isocode = strtoupper(trim($territory)); + $sep = strpos($isocode, ' '); + if ($sep !== false) { + $isocode = substr($isocode, 0, $sep); + } if (is_numeric($isocode)) { return intval($isocode); } @@ -214,13 +217,13 @@ function iso2ccode($territory) return -1; } -function getTerritoryNumber($territory, $contextTerritoryNumber = -1) +function getTerritoryNumber($territory, $contextTerritory = -1) { - if ($contextTerritoryNumber >= 0) { + if ($contextTerritory != -1) { + $contextTerritoryNumber = getTerritoryNumber($contextTerritory); set_disambiguate($GLOBALS['entity_iso'][$contextTerritoryNumber]); } - $nr = iso2ccode($territory); - return $nr; + return iso2ccode($territory); } /// PUBLIC - return name of $territory (optional keepindex=1 for bracketed aliases) @@ -312,7 +315,6 @@ function getTerritoryAlphaCode($territory, $international = 1) } } } else { - $i; for ($i = 0; $i < MAX_CCODE; $i++) { if ($GLOBALS['entity_iso'][$i] == $n) { $count++; @@ -342,6 +344,7 @@ function hasSubdivision($territory) class Coord { public $lat, $lon; + public $minlat, $maxlat, $minlon, $maxlon; // FORCE_RECODE public function __construct($lat, $lon) { @@ -367,6 +370,12 @@ public function __construct($minx, $maxx, $miny, $maxy) $this->maxy = $maxy; } + public function extendBounds($dx, $dy) + { + return new Rect($this->minx - $dx, $this->maxx + $dx, $this->miny - $dy, $this->maxy + $dy); + } + + public function __toString() { return sprintf('[%d...%d , %d...%d]', $this->miny, $this->maxy, $this->minx, $this->maxx); @@ -379,12 +388,8 @@ class EncodeRec public function __construct($lat, $lon) { - - if (!is_numeric($lat)) { - $lat = 0; - } else { - $lat += 0; - } + $lat = floatval(trim($lat)); + $lon = floatval(trim($lon)); if ($lat > 90) { $lat = 90; } else { @@ -392,21 +397,14 @@ public function __construct($lat, $lon) $lat = -90; } } - $lat += 90; - $lat *= 1000000; - $lat32 = (int)($lat); - $fraclat = $lat - $lat32; - $fraclat *= 810000; - if ($fraclat < 1) { - $fraclat = 0; - } else { - if ($fraclat > 809999) { - $fraclat = 0; - $lat32++; - } else { - $fraclat /= 810000; - } - } + $lat += 90; // lat now [0..180] + $lat *= 810000000000; + $fraclat = floor($lat + 0.1); + $f = $fraclat / 810000; + $lat32 = intval($f); + $fraclat -= ($lat32 * 810000); + $lat32 -= 90000000; + $this->fraclat = $fraclat; if (!is_numeric($lon)) { @@ -414,39 +412,144 @@ public function __construct($lat, $lon) } else { $lon += 0; } - if ($lon >= 180) { - $lon -= 360; - } else { - if ($lon < -180) { - $lon += 360; - } - } - $lon += 180; - $lon *= 1000000; - $lon32 = (int)($lon); - $fraclon = $lon - $lon32; - $fraclon *= 810000; - if ($fraclon < 1) { - $fraclon = 0; + $lon -= (360 * floor($lon / 360)); // lon now in [0..360> + $lon *= 3240000000000; + $fraclon = floor($lon + 0.1); + $f = $fraclon / 3240000; + $lon32 = floor($f); + $fraclon -= ($lon32 * 3240000); + $this->fraclon = $fraclon; + if ($lon32 >= 180000000) + $lon32 -= 360000000; + + $this->coord32 = new Coord($lat32, $lon32); + } + + public function __toString() + { + return sprintf('[%0.11f,%0.11f]', ($this->coord32->lat + $this->fraclat / 810000) / 1000000.0, ($this->coord32->lon + $this->fraclon / 3240000) / 1000000.0); + } +} + +// + +class MapcodeZone +{ + public $fminx, $fmaxx, $fminy, $fmaxy; + + public function __construct($zone = null) + { + if ($zone !== null) { + $this->fminx = $zone->fminx; + $this->fmaxx = $zone->fmaxx; + $this->fminy = $zone->fminy; + $this->fmaxy = $zone->fmaxy; } else { - if ($fraclon > 809999) { - $fraclon = 0; - $lon32++; - } else { - $fraclon /= 810000; - } + $this->fminx = 0; + $this->fmaxx = 0; + $this->fminy = 0; + $this->fmaxy = 0; } - $this->fraclon = $fraclon; + } - $this->coord32 = new Coord($lat32 - 90000000, $lon32 - 180000000); + public function isEmpty() + { + return (($this->fmaxx <= $this->fminx) || ($this->fmaxy <= $this->fminy)); } public function __toString() { - return sprintf('[%0.9f,%0.9f]', ($this->coord32->lat + $this->fraclat) / 1000000.0, ($this->coord32->lon + $this->fraclon) / 1000000.0); + return sprintf("%s[%f,%f),[%f,%f)", + ($this->isEmpty() ? "empty" : "ok"), + ($this->fminy / (810000 * 1000000.0)), + ($this->fmaxy / (810000 * 1000000.0)), + ($this->fminx / (3240000 * 1000000.0)), + ($this->fmaxx / (3240000 * 1000000.0))); + } + + public function midPointFractions() + { + return new Coord( + floor(($this->fminy + $this->fmaxy) / 2), + floor(($this->fminx + $this->fmaxx) / 2)); + } + + public static function convertFractionsToCoord32($p) + { + return new Coord( + floor($p->lat / 810000.0), + floor($p->lon / 3240000.0)); + } + + public static function convertFractionsToDegrees($p) + { + $lon = $p->lon / (3240000 * 1000000.0); + $lon += (360 * floor($lon / 360.0)); + while ($lon <= -180) { + $lon += 360; + } + while ($lon > 180) { + $lon -= 360; + } + $lat = $p->lat / (810000 * 1000000.0); + if ($lat < -90.0) { + $lat = -90.0; + } + if ($lat > 90.0) { + $lat = 90.0; + } + return new Coord($lat, $lon); + } + + public function SetFromFractions($y, $x, $yDelta, $xDelta) + { + if ($yDelta < 0) { + $this->fminx = $x; + $this->fmaxx = $x + $xDelta; + $this->fminy = $y + 1 + $yDelta; // y+yDelta can NOT be represented + $this->fmaxy = $y + 1; // y CAN be represented + } else { + $this->fminx = $x; + $this->fmaxx = $x + $xDelta; + $this->fminy = $y; + $this->fmaxy = $y + $yDelta; + } + } + + public function RestrictZoneTo($mm) + { + $z = new MapcodeZone($this); + $miny = $mm->miny * 810000; + if ($z->fminy < $miny) { + $z->fminy = $miny; + } + $maxy = $mm->maxy * 810000; + if ($z->fmaxy > $maxy) { + $z->fmaxy = $maxy; + } + if ($z->fminy < $z->fmaxy) { + $minx = $mm->minx * 3240000; + $maxx = $mm->maxx * 3240000; + if (($maxx < 0) && ($z->fminx > 0)) { + $minx += (360000000 * 3240000); + $maxx += (360000000 * 3240000); + } else if (($minx > 1) && ($z->fmaxx < 0)) { + $minx -= (360000000 * 3240000); + $maxx -= (360000000 * 3240000); + } + if ($z->fminx < $minx) { + $z->fminx = $minx; + } + if ($z->fmaxx > $maxx) { + $z->fmaxx = $maxx; + } + } + return $z; } } +// data + function dataFirstRecord($territoryNumber) { return $GLOBALS['data_start'][$territoryNumber]; @@ -536,7 +639,7 @@ function decodeTriple($input) $c1 = decodeChar($input); $x = decodeBase31(substr($input, 1)); if ($x < 0) { - return 0; + return null; } if ($c1 < 24) { return new Coord((int)($c1 / 6) * 34 + (int)($x % 34), ($c1 % 6) * 28 + (int)($x / 34)); @@ -557,48 +660,72 @@ function decodeSixWide($v, $width, $height) return new Coord($height - 1 - (int)($w / $D), ($col * 6) + ($w % $D)); } -function decodeExtension($extensionchars, $Coord, $dividerx4, $dividery, $ydirection) +// returns a mapcodezone +function decodeExtension($extensionchars, $coord, $dividerx4, $dividery, $lon_offset4, $extremeLatMicroDeg, $maxLonMicroDeg) { - $dividerx = $dividerx4 / 4.0; - $processor = 1.0; - $extrax = 0; - $extray = 0; + $mapcodeZone = new MapcodeZone(); + $processor = 1; + $lon32 = 0; + $lat32 = 0; + $odd = false; $idx = 0; $len = strlen($extensionchars); if ($len > 8) { - return 0; + return $mapcodeZone; } while ($idx < $len) { - $halfcolumn = 0; $c = decodeChar($extensionchars[$idx++]); - if ($c < 0 || $c > 30) { - return 0; - } + if ($c < 0 || $c == 30) { + return $mapcodeZone; + } // illegal extension character $row1 = (int)($c / 5); $column1 = ($c % 5); if ($idx < $len) { $c = decodeChar($extensionchars[$idx++]); if ($c < 0 || $c == 30) { - return 0; - } + return $mapcodeZone; + } // illegal extension character $row2 = (int)($c / 6); $column2 = ($c % 6); } else { - $row2 = 2; - $halfcolumn = 0.5; - $column2 = 3; + $row2 = 0; + $odd = true; + $column2 = 0; } $processor *= 30; - $extrax += (($column1 * 6 + $column2)) / $processor; - $extray += (($row1 * 5 + $row2 - $halfcolumn)) / $processor; + $lon32 = $lon32 * 30 + $column1 * 6 + $column2; + $lat32 = $lat32 * 30 + $row1 * 5 + $row2; } - $extrax += (0.5 / $processor); - $extray += (0.5 / $processor); - $extrax *= $dividerx; - $extray *= $dividery; - $Coord->lon += $extrax; - $Coord->lat += $extray * $ydirection; - return $Coord; + + while ($processor < 810000.0) { + $dividerx4 *= 30; + $dividery *= 30; + $processor *= 30; + } + + $lon4 = ($coord->lon * 3240000) + ($lon32 * $dividerx4) + ($lon_offset4 * 810000); + $lat1 = ($coord->lat * 810000) + ($lat32 * $dividery); + + if ($odd) { // odd + $mapcodeZone->SetFromFractions($lat1, $lon4, 5 * $dividery, 6 * $dividerx4); + } else { // not odd + $mapcodeZone->SetFromFractions($lat1, $lon4, $dividery, $dividerx4); + } // not odd + + // FORCE_RECODE - restrict the coordinate range to the extremes that were provided + if ($mapcodeZone->fmaxx > ($maxLonMicroDeg * 3240000.0)) { + $mapcodeZone->fmaxx = ($maxLonMicroDeg * 3240000.0); + } + if ($dividery >= 0) { + if ($mapcodeZone->fmaxy > ($extremeLatMicroDeg * 810000.0)) { + $mapcodeZone->fmaxy = ($extremeLatMicroDeg * 810000.0); + } + } else { + if ($mapcodeZone->fminy < ($extremeLatMicroDeg * 810000.0)) { + $mapcodeZone->fminy = ($extremeLatMicroDeg * 810000.0); + } + } + return $mapcodeZone; } function decodeGrid($input, $extensionchars, $m) @@ -626,7 +753,7 @@ function decodeGrid($input, $extensionchars, $m) $v = decodeBase31($input); if ($v < 0) { - return 0; + return new MapcodeZone(); } if ($divx != $divy && $prefixlength > 2) { @@ -654,8 +781,8 @@ function decodeGrid($input, $extensionchars, $m) if ($postfixlength == 3) { $d = decodeTriple($rest); - if ($d == 0) { - return 0; + if (!$d) { + return new MapcodeZone(); } $difx = $d->lon; $dify = $d->lat; @@ -665,7 +792,7 @@ function decodeGrid($input, $extensionchars, $m) } $v = decodeBase31($rest); if ($v < 0) { - return 0; + return new MapcodeZone(); } $difx = (int)($v / $yp); $dify = (int)($v % $yp); @@ -673,9 +800,16 @@ function decodeGrid($input, $extensionchars, $m) $dify = $yp - 1 - $dify; - $corner = new Coord($rely + ($dify * $dividery), $relx + ($difx * $dividerx)); + $corner = new Coord($rely + ($dify * $dividery), $relx + ($difx * $dividerx)); // grid - return decodeExtension($extensionchars, $corner, ($dividerx) << 2, $dividery, 1); + if (!fitsInside($corner, $mm)) { + return new MapcodeZone(); + } + + $decodeMaxx = (($relx + $xgridsize) < $mm->maxx) ? ($relx + $xgridsize) : $mm->maxx; + $decodeMaxy = (($rely + $ygridsize) < $mm->maxy) ? ($rely + $ygridsize) : $mm->maxy; + return decodeExtension($extensionchars, $corner, ($dividerx) << 2, $dividery, + 0, $decodeMaxy, $decodeMaxx); // grid } function firstNamelessRecord($index, $firstcode) @@ -744,7 +878,7 @@ function decodeNameless($input, $extensionchars, $m, $firstindex) $v = decodeBase31($input); if ($v < 0) { - return 0; + return new MapcodeZone(); } $X = (int)($v / $BASEPOWERA); $v %= $BASEPOWERA; @@ -760,7 +894,7 @@ function decodeNameless($input, $extensionchars, $m, $firstindex) if ($codexm != 21 && $A <= 31) { $v = decodeBase31($input); if ($v < 0) { - return 0; + return new MapcodeZone(); } if ($X > 0) { $v -= (($X * $p + ($X < $r ? $X : $r)) * (961 * 961)); @@ -769,7 +903,7 @@ function decodeNameless($input, $extensionchars, $m, $firstindex) if ($codexm != 21 && $A < 62) { $v = decodeBase31(substr($input, 1)); if ($v < 0) { - return 0; + return new MapcodeZone(); } if ($X >= (62 - $A)) { if ($v >= (16 * 961 * 31)) { @@ -781,7 +915,7 @@ function decodeNameless($input, $extensionchars, $m, $firstindex) } if ($X > $A) { - return 0; + return new MapcodeZone(); } $m = $F + $X; $mm = minmaxSetup($m); @@ -805,18 +939,15 @@ function decodeNameless($input, $extensionchars, $m, $firstindex) } if ($dx >= $XSIDE) { - return 0; + return new MapcodeZone(); } $dividerx4 = xDivider4($mm->miny, $mm->maxy); $dividery = 90; $corner = new Coord($mm->maxy - ($dy * $dividery), $mm->minx + (int)(($dx * $dividerx4) / 4)); - $ret = decodeExtension($extensionchars, $corner, $dividerx4, $dividery, -1); - if ($ret != 0) { - $ret->lon += (($dx * $dividerx4) % 4) / 4.0; - } - return $ret; + return decodeExtension($extensionchars, $corner, $dividerx4, -$dividery, + ($dx * $dividerx4) % 4, $mm->miny, $mm->maxx); // nameless } function decodeAutoHeader($input, $extensionchars, $m) @@ -826,12 +957,12 @@ function decodeAutoHeader($input, $extensionchars, $m) $value = decodeBase31($input); if ($value < 0) { - return 0; + return new MapcodeZone(); } $value *= (961 * 31); $triple = decodeTriple(substr($input, strlen($input) - 3)); - if ($triple == 0) { - return 0; + if (!$triple) { + return new MapcodeZone(); } for (; Codex($m) == $codexm; $m++) { $mm = minmaxSetup($m); @@ -863,15 +994,17 @@ function decodeAutoHeader($input, $extensionchars, $m) $corner = new Coord($mm->maxy - $vy * $dividery, $mm->minx + $vx * $dividerx); if ($corner->lon < $mm->minx || $corner->lon >= $mm->maxx || $corner->lat < $mm->miny || $corner->lat > $mm->maxy) { - return 0; + return new MapcodeZone(); } - return decodeExtension($extensionchars, $corner, $dividerx << 2, $dividery, -1); + return decodeExtension($extensionchars, $corner, $dividerx << 2, -$dividery, + 0, $mm->miny, $mm->maxx); // autoheader decode } $STORAGE_START += $product; } - return 0; + return new MapcodeZone(); } +// returns unpacked string, or '' in case of error function aeu_unpack($str) { $voweled = 0; @@ -945,21 +1078,23 @@ function aeu_unpack($str) return ''; } + $nrletters = 0; for ($v = 0; $v <= $lastpos; $v++) { if ($v != $dotpos) { if (decodeChar($str[$v]) < 0) { return ''; - } else { - if ($voweled && decodeChar($str[$v]) > 9) { - return ''; - } + } else if (decodeChar($str[$v]) > 9) { + $nrletters++; } } } + if (!$voweled && !$nrletters) return ''; + if ($voweled && $nrletters) return ''; return $str; } +// packs mapcode $r into not-all-digit form function aeu_pack($r, $short = 0) { $dotpos = -9; @@ -993,7 +1128,7 @@ function aeu_pack($r, $short = 0) return $r . $rest; } -define('MAXLANS', 14); +define('MAPCODE_ALPHABETS_TOTAL', 14); $lannam = array( "Roman", @@ -1085,7 +1220,7 @@ function to_ascii($str) $result .= chr($c); } else { $found = 0; - for ($lan = 0; $lan < MAXLANS; $lan++) { + for ($lan = 0; $lan < MAPCODE_ALPHABETS_TOTAL; $lan++) { for ($j = 0; $j < 36; $j++) { if ($c == $GLOBALS['asc2lan'][$lan][$j]) { $result .= $letters[$j]; @@ -1102,8 +1237,10 @@ function to_ascii($str) } } } - if ($result[0] == 'A') { - $result = aeu_pack(aeu_unpack($result)); + $p = strrpos($result, ' '); + if ($p === false) $p = 0; else $p++; + if ((strlen($result)) && ($result[$p] == 'A')) { + $result = substr($result, 0, $p) . aeu_pack(aeu_unpack(substr($result, $p))); } return $result; } @@ -1158,6 +1295,41 @@ function showinlan($str, $lan, $asHTML) return $result; } +function multipleBordersNearby($point, $territory) +{ + $territoryNumber = getTerritoryNumber($territory); + if ($territoryNumber != ccode_earth) { + if (getParentOf($territoryNumber) >= 0) { + // there is a parent! check its borders as well... + if (multipleBordersNearby($point, getParentOf($territoryNumber))) { + return true; + } + } + { + $coord32 = new Coord($point->lat * 1000000.0, $point->lon * 1000000.0); + $nrFound = 0; + $from = dataFirstRecord($territoryNumber); + $upto = dataLastRecord($territoryNumber); + for ($m = $upto; $m >= $from; $m--) { + if (!isRestricted($m)) { + $mm = minmaxSetup($m); + $xdiv8 = xDivider4($mm->miny, $mm->maxy) / 4; //@@@ + if (fitsInside($coord32, $mm->extendBounds($xdiv8, 60))) { + if (!fitsInside($coord32, $mm->extendBounds(-$xdiv8, -60))) { + $nrFound++; + if ($nrFound > 1) { + return true; + } + } + } + } + } + } + } + return false; +} + +// returns coordinate, or 0 function master_decode($mapcode, $territoryNumber = -1) { $mapcode = to_ascii($mapcode); @@ -1192,70 +1364,73 @@ function master_decode($mapcode, $territoryNumber = -1) $postfixlength = $mclen - 1 - $prefixlength; $incodex = $prefixlength * 10 + $postfixlength; - $result = null; + $zone = new MapcodeZone(); for ($m = $from; $m <= $upto; $m++) { $codexm = Codex($m); if (($incodex == $codexm || ($incodex == 22 && $codexm == 21)) && recType($m) == 0 && isNameless($m) == 0) { - $result = decodeGrid($mapcode, $extensionchars, $m); - if ($result && isRestricted($m)) { - $fitssomewhere = 0; + $zone = decodeGrid($mapcode, $extensionchars, $m); + + // first of all, make sure the zone fits the country + $zone = $zone->RestrictZoneTo(minmaxSetup($upto)); + + if (!$zone->isEmpty() && isRestricted($m)) { + $nrZoneOverlaps = 0; + $coord32 = MapcodeZone::convertFractionsToCoord32($zone->MidPointFractions()); for ($j = $upto - 1; $j >= $from; $j--) { if (!isRestricted($j)) { - if (fitsInsideWithRoom($result, minmaxSetup($j))) { - $fitssomewhere = 1; + if (fitsInside($coord32, minmaxSetup($j))) { + $nrZoneOverlaps++; break; } } } - if ($fitssomewhere == 0) { - $result = null; - } - } - break; - } else { - if ($codexm + 10 == $incodex && recType($m) == 1 && headerLetter($m) == $mapcode[0]) { - $result = decodeGrid(substr($mapcode, 1), $extensionchars, $m); - break; - } else { - if (isNameless($m) && (($codexm == 21 && $incodex == 22) || ($codexm == 22 && $incodex == 32) || ($codexm == 13 && $incodex == 23))) { - $result = decodeNameless($mapcode, $extensionchars, $m, $from); - break; - } else { - if ($postfixlength == 3 && recType($m) > 1 && CodexLen($m) == $prefixlength + 2) { - $result = decodeAutoHeader($mapcode, $extensionchars, $m); - break; - } else { - $result = null; + + if ($nrZoneOverlaps == 0) { // FORCE_RECODE + $zfound = new MapcodeZone(); + for ($j = $from; $j < $m; $j++) { // try all smaller rectangles j + if (!isRestricted($j)) { + $z = $zone->RestrictZoneTo(minmaxSetup($j)); + if (!$z->isEmpty()) { + $nrZoneOverlaps++; + if ($nrZoneOverlaps == 1) { + $zfound = new MapcodeZone($z); + } else { // nrZoneOverlaps > 1 + // more than one hit + break; // give up! + } + } + } + } + if ($nrZoneOverlaps == 1) { // intersected exactly ONE sub-area? + $zone = $zfound; // use the intersection found... } } - } - } - } - if ($result) { - if ($result->lon > 180000000) { - $result->lon -= 360000000; - } else { - if ($result->lon < -180000000) { - $result->lon += 360000000; + if ($nrZoneOverlaps == 0) { + $zone = new MapcodeZone(); + } } + break; + } else if ($codexm + 10 == $incodex && recType($m) == 1 && headerLetter($m) == $mapcode[0]) { + $zone = decodeGrid(substr($mapcode, 1), $extensionchars, $m); + break; + } else if (isNameless($m) && (($codexm == 21 && $incodex == 22) || ($codexm == 22 && $incodex == 32) || ($codexm == 13 && $incodex == 23))) { + $zone = decodeNameless($mapcode, $extensionchars, $m, $from); + break; + } else if ($postfixlength == 3 && recType($m) > 1 && CodexLen($m) == $prefixlength + 2) { + $zone = decodeAutoHeader($mapcode, $extensionchars, $m); + break; } + } - if ($territoryNumber != ccode_earth) { - if (!(fitsInsideWithRoom($result, minmaxSetup($upto)))) { - return 0; - } - } + $zone = $zone->restrictZoneTo(minmaxSetup($upto)); - $result->lon /= 1000000.0; - $result->lat /= 1000000.0; - if ($result->lat > 90) { - $result->lat = 90; - } + if ($zone->isEmpty()) { + return 0; } - return $result; + return MapcodeZone::convertFractionsToDegrees($zone->MidPointFractions()); } function decode($mapcodeString, $territory = -1) @@ -1279,7 +1454,7 @@ function decode($mapcodeString, $territory = -1) } else { return master_decode($mapcodeString, $contextTerritoryNumber); } - return 0; + return null; } function encodeSixWide($x, $y, $width, $height) @@ -1321,28 +1496,35 @@ function encodeExtension($result, $enc, $extrax4, $extray, $dividerx4, $dividery if ($extraDigits > 8) { $extraDigits = 8; } - $encx = ($extrax4 + 4 * $enc->fraclon) / $dividerx4; - $ency = ($extray + $enc->fraclat * $ydirection) / $dividery; + + $factorx = 810000 * $dividerx4; // perfect integer! + $factory = 810000 * $dividery; // perfect integer! + $valx = (810000 * $extrax4) + $enc->fraclon; // perfect integer! + $valy = (810000 * $extray) + ($ydirection * $enc->fraclat); // perfect integer! + + // protect against floating point errors + if ($valx < 0) { + $valx = 0; + } else if ($valx >= $factorx) { + $valx = $factorx - 1; + } + if ($valy < 0) { + $valy = 0; + } else if ($valy >= $factory) { + $valy = $factory - 1; + } + $result .= '-'; + while ($extraDigits-- > 0) { - $encx *= 30; - $gx = (int)($encx); - if ($gx < 0) { - $gx = 0; - } else { - if ($gx > 29) { - $gx = 29; - } - } - $ency *= 30; - $gy = (int)($ency); - if ($gy < 0) { - $gy = 0; - } else { - if ($gy > 29) { - $gy = 29; - } - } + $factorx /= 30; + $gx = (int)($valx / $factorx); + $valx -= $factorx * $gx; + + $factory /= 30; + $gy = (int)($valy / $factory); + $valy -= $factory * $gy; + $column1 = (int)($gx / 6); $column2 = ($gx % 6); $row1 = (int)($gy / 5); @@ -1351,8 +1533,6 @@ function encodeExtension($result, $enc, $extrax4, $extray, $dividerx4, $dividery if ($extraDigits-- > 0) { $result .= encodeChar($row2 * 6 + $column2); } - $encx -= $gx; - $ency -= $gy; } return $result; } @@ -1488,14 +1668,9 @@ function encodeNameless($enc, $m, $firstcode, $extraDigits) $SIDE = smartdiv($m); $orgSIDE = $SIDE; $XSIDE = $SIDE; - if (isSpecialShape($m)) { - $XSIDE *= $SIDE; - $SIDE = 1 + (int)(($mm->maxy - $mm->miny) / 90); - $XSIDE = (int)($XSIDE / $SIDE); - } $dividerx4 = xDivider4($mm->miny, $mm->maxy); - $xFracture = (int)(4 * $enc->fraclon); + $xFracture = (int)(4 * $enc->fraclon / 3240000); $dx = (int)((4 * ($enc->coord32->lon - $mm->minx) + $xFracture) / $dividerx4); $extrax4 = ($enc->coord32->lon - $mm->minx) * 4 - $dx * $dividerx4; @@ -1510,6 +1685,9 @@ function encodeNameless($enc, $m, $firstcode, $extraDigits) $v = $storage_offset; if (isSpecialShape($m)) { + $XSIDE *= $SIDE; + $SIDE = 1 + (int)(($mm->maxy - $mm->miny) / 90); + $XSIDE = (int)($XSIDE / $SIDE); $v += encodeSixWide($dx, $SIDE - 1 - $dy, $XSIDE, $SIDE); } else { $v += ($dx * $SIDE + $dy); @@ -1573,20 +1751,15 @@ function encodeAutoHeader($enc, $m, $extraDigits) $extray = (($mm->maxy - $enc->coord32->lat) % $dividery); $spx = $vx % 168; - $spy = $vy % 176; - $vx = (int)($vx / 168); $value = $vx * (int)($H / 176); if ($extray == 0 && $enc->fraclat > 0) { - if ($vy == 0) { - $STORAGE_START += $product; - continue; - } $vy--; $extray += $dividery; } + $spy = $vy % 176; $vy = (int)($vy / 176); $value += $vy; @@ -1603,16 +1776,42 @@ function mapcoderEngine($enc, $tn, $getshortest, $isrecursive, $state_override, { $dsr = $GLOBALS['debugStopRecord']; $results = array(); - - $fromTerritory = 0; - $uptoTerritory = ccode_earth; - if (is_numeric($tn) && $tn >= 0 && $tn <= $uptoTerritory) { - $fromTerritory = $tn; - $uptoTerritory = $tn; + $use_redivar = 0; + + $fromRun = 0; + $uptoRun = ccode_earth; + if (is_numeric($tn) && $tn >= 0 && $tn <= $uptoRun) { + $fromRun = $tn; + $uptoRun = $tn; + } else if (array_key_exists('redivar', $GLOBALS)) { + $use_redivar = 1; + $HOR = 1; + $i = 0; // pointer into redivar + for (; ;) { + $v2 = $GLOBALS['redivar'][$i++]; + $HOR = 1 - $HOR; + if ($v2 >= 0 && $v2 < 1024) { // leaf? + $fromRun = $i; + $uptoRun = $i + $v2; + break; + } else { + $coord = ($HOR ? $enc->coord32->lon : $enc->coord32->lat); + if ($coord > $v2) { + $i = $GLOBALS['redivar'][$i]; + } else { + $i++; + } + } + } } $debugStopFailed = 1; - for ($territoryNumber = $fromTerritory; $territoryNumber <= $uptoTerritory; $territoryNumber++) { + for ($run = $fromRun; $run <= $uptoRun; $run++) { + if ($use_redivar) + $territoryNumber = ($run == $uptoRun ? ccode_earth : $GLOBALS['redivar'][$run]); + else + $territoryNumber = $run; + $original_length = count($results); $from = dataFirstRecord($territoryNumber); $upto = dataLastRecord($territoryNumber); @@ -1635,7 +1834,7 @@ function mapcoderEngine($enc, $tn, $getshortest, $isrecursive, $state_override, if (recType($i) > 1) { $r = encodeAutoHeader($enc, $i, $extraDigits); } else { - if (isRestricted($i) && $i == $upto && getParentOf($territoryNumber) >= 0) { + if (($i == $upto) && (getParentOf($territoryNumber) >= 0)) { $results = array_merge($results, mapcoderEngine($enc, getParentOf($territoryNumber), $getshortest, 1/*recursive*/, $territoryNumber, $extraDigits)); continue; } else { @@ -1667,7 +1866,6 @@ function mapcoderEngine($enc, $tn, $getshortest, $isrecursive, $state_override, if ($getshortest || $dsr == $i) { break; } - } else { } } } @@ -1681,29 +1879,32 @@ function mapcoderEngine($enc, $tn, $getshortest, $isrecursive, $state_override, return $results; } +function maxErrorinMeters($precision) +{ + $maxErrorForPrecision = array( + 7.49, + 1.39, + 0.251, + 0.0462, + 0.00837, + 0.00154, + 0.000279, + 0.0000514, + 0.0000093); + return $maxErrorForPrecision[$precision]; +} + function distanceInMeters($latDeg1, $lonDeg1, $latDeg2, $lonDeg2) { - $worstParallel = 0; - if ($latDeg1 > $latDeg2) { - if ($latDeg1 < 0) { - $worstParallel = $latDeg2; - } else { - if ($latDeg2 > 0) { - $worstParallel = $latDeg1; - } - } - } else { - if ($latDeg2 < 0) { - $worstParallel = $latDeg1; - } else { - if ($latDeg1 > 0) { - $worstParallel = $latDeg2; - } - } + if ($lonDeg1 < 0 && $lonDeg2 > 1) { + $lonDeg1 += 360; + } + if ($lonDeg2 < 0 && $lonDeg1 > 1) { + $lonDeg2 += 360; } - $dy = ($latDeg2 - $latDeg1); - $dx = ($lonDeg2 - $lonDeg1) * cos(deg2rad($worstParallel)); - return sqrt($dx * $dx + $dy * $dy) * 1000000.0 / 9.0; + $dx = 111319.49079327 * ($lonDeg2 - $lonDeg1) * cos(deg2rad(($latDeg1 + $latDeg2) / 2.0)); + $dy = 110946.25213273 * ($latDeg2 - $latDeg1); + return sqrt($dx * $dx + $dy * $dy); } /// PUBLIC convert a mapcode (without territory abbreviation) into a particular alphabet @@ -1749,6 +1950,3 @@ function encodeShortest($latitudeDegrees, $longitudeDegrees, $territory = -1) { return encodeShortestWithPrecision($latitudeDegrees, $longitudeDegrees, 0, $territory); } - -?> - diff --git a/mapcode_countrynames.php b/mapcode_countrynames.php index 57a07b7..427578b 100644 --- a/mapcode_countrynames.php +++ b/mapcode_countrynames.php @@ -1,7 +1,7 @@ - + "?"); \ No newline at end of file diff --git a/mapcode_data.php b/mapcode_data.php index e29b336..912c560 100644 --- a/mapcode_data.php +++ b/mapcode_data.php @@ -1,7 +1,7 @@ +1,1290,3,1,1,3,1,1,166,3,1,3844,3721,167,679,679,1,1,1,1, +41,4,4,4,4,4,4,4,4,4,1,39,1,1,1,1,1,1,554,554, +554,1,78,28,1,679,679,1,1,1,176,168,679,679,1,1,30,1290,3,34, +1,1,3,25,28,43,1,16,1,1,3,1,1,429,429,429,429,429,1,176, +168,679,679,3187,3038,3038,151,429,429,429,429,429,1,1290,3,1,1,55,1,177, +1,1,1,1,1,33,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,33,4,4,4,4,239,1,26, +1,176,169,1,1,1,1,1,1,1,1,1,1,679,679,1,679,679,4,4, +97,1,1,1,1,1,1,1,1,1,1,1,1,1,1,177,4,4,4,4, +1,1,4,4,4,4,4,1,26,1,1,34,22,4,4,117,208,679,679,1, +679,679,1,165,151,1,3,22,4,4,4,224,1,106,1,1,1,177,1,169, +1,27,33,1,176,147,14,589,1,1,42,201,169,1,1,39,1,338,397,1, +1,169,3,679,679,1,1,1,1,3,1,1,1,23,176,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,169,410,158, +1,1,22,1,1,177,227,1,1048,1,1,1,679,679,35,189,216,15,3844,3721, +1664,1664,1664,1664,1664,1664,1664,1664,1664,1359,1359,262,1,1,571,192,1,41,4,4, +4,4,4,170,138,1,1,176,168,1,147,181,3,22,1,1,1,206,44,1, +25,4,4,4,4,4,176,169,1,40,3844,3721,168,1,4,4,4,177,1,1, +1,1,1,1,1,33,227,170,1,1,176,1,3,21,19,132,120,1,1,176, +168,58,176,176,176,1,554,554,554,177,30,142,30,177,176,176,176,176,667,1, +22,1,168,169,679,679,43,211,170,1,162,26,158,1,1,176,4,4,4,4, +4,4,4,4,4,4,4,4,1,1,22,126,87,648,3,679,679,1,122,126, +1,1,3187,3038,3038,175,1,3,1,2542,2353,2353,2353,2353,21,110,1,23,1664,1664, +1664,1664,1664,1359,1359,1359,1359,1359,1359,1359,1359,85,1,33,187,233,20,1,176,152, +1,1,176,169,23,1126,1,1,2353,2148,2148,2148,2148,2148,41,183,1,3,26,16, +961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961, +961,961,961,961,961,961,961,961,961,961,961,33,233,828,1,19,1,176,110,29, +177,1359,1359,1359,1359,1359,1359,1359,1359,961,961,961,961,961,961,961,961,961,961,961, +961,961,961,961,193,1,1,143,150,1,3,679,679,23,2718,2718,2718,2542,141,39, +177,177,137,177,177,176,176,176,1,1,1,2353,2148,2148,2148,2148,2148,169,1,1194, +1,1,1,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961, +961,961,961,961,961,961,961,961,961,961,961,961,961,961,134,1,3,1,961,961, +961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961, +961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961, +961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961, +273,1,3,1,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961, +961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,273,1,3,1,1, +961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961, +961,961,961,961,961,961,961,961,690,668,690,668,690,668,131,816,3,679,679,1, +2353,2148,2148,2148,2148,2148,207,816,3,679,679,1,2542,2353,2353,2353,2353,177,29,1, +1359,1359,1359,1359,1359,1359,1359,1359,961,961,961,961,961,961,961,961,961,961,961,961, +961,961,961,148,1,3,1,1,1664,1664,1664,1664,1664,1359,1359,1359,1359,1359,1359,1359, +1359,157,1,23,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961, +961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,148,38,1,1664,1664, +1664,1664,1664,1359,1359,1359,1359,1359,1359,1359,1359,182,679,679,33,1664,1664,1664,1664,1664, +1664,1664,1664,1664,1359,1359,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,961,961,961,961,961,961,961,961,961,961,961,961, +961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,244, +1,3,19,1,1922,1922,1922,1922,1922,1922,1922,1664,27,158,177,176,176,177,177,177, +177,177,176,176,176,177,177,177,177,177,1,1,32,1359,1359,1359,1359,1359,1359,1359, +1359,1359,1359,961,961,961,961,961,961,961,961,961,961,961,167,1,1,1922,1922,1922, +1922,1922,1922,1922,1664,166,679,679,33,1359,1359,1359,1359,1359,961,961,961,961,961,961, +961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +3,1,1,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961, +961,961,961,961,961,961,961,961,961,961,961,690,668,690,668,690,668,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,18,39,1,1,3,1, +24,1922,1922,1922,1922,1664,1664,1664,1664,1664,129,675,3,1,23,1359,961,961,961,961, +961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961, +961,961,961,961,961,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,42,1,1359,1359,1359, +1359,1359,1359,1359,1359,1359,1359,961,961,961,961,961,961,961,961,961,961,961,124,480, +480,480,480,27,1359,1359,1359,1359,1359,1359,1359,1359,1359,1359,961,961,961,961,961,961, +961,961,961,961,961,134,1290,3,429,429,429,429,429,1,961,961,961,961,961,961, +961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961, +961,961,961,690,668,690,668,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,3,1,1,961,961, +961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,690,668, +690,668,690,668,690,668,690,668,690,668,690,668,690,668,690,668,690,668,690,668, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,33,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,887,3,23,18,1359,1359,1359,1359, +1359,1359,1359,1359,1359,1359,961,961,961,961,961,961,961,961,961,961,961,24,1,1, +1,24,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,17,10,1,3,24,23,961,961,961,961,961,961,961,961,961,961,961, +961,961,961,961,690,668,690,668,690,668,690,668,690,668,690,668,690,668,690,668, +690,668,690,668,690,668,690,668,690,668,690,668,690,668,690,668,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,36,1,42,28,1,1,1,961,961,961,961,961,961,961,961,961,690,668,690, +668,690,668,690,668,690,668,690,668,690,668,690,668,690,668,690,668,690,668,690, +668,690,668,690,668,690,668,690,668,690,668,690,668,690,668,690,668,690,668,690, +668,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,3,1,26,1359,1359,1359,1359,1359,1359,1359, +1359,1359,1359,1359,1359,1359,1359,961,961,961,17,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,55, +1,816,3,23,1,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961, +961,961,961,690,668,690,668,690,668,690,668,690,668,690,668,690,668,690,668,690, +668,690,668,690,668,690,668,690,668,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,3,1,23, +961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961, +961,961,961,961,961,961,961,961,961,961,961,1,32,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,26,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,3,679,679,21,1359,1359, +1359,1359,1359,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961, +961,961,961,961,39,39,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,675,3,1,1,961,961, +961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961, +961,961,961,961,961,961,961,961,961,4,4,4,4,4,4,4,1,3,1,1, +1359,1359,1359,1359,1359,1359,1359,1359,1359,1359,1359,1359,1359,961,961,961,961,961,4,4, +4,1,3,44,63,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961, +961,961,961,961,961,961,961,961,961,961,961,690,668,690,668,690,668,690,668,690, +668,4,4,4,4,4,4,4,4,4,1,1,35,961,961,961,961,961,961,961, +961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961, +961,961,961,961,4,4,4,4,4,4,4,4,4,1,1,30,961,961,961,961, +961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,690, +668,690,668,690,668,690,668,690,668,690,668,690,668,690,668,156,22,1,3,18, +1,1359,1359,1359,1359,1359,1359,1359,1359,961,961,961,961,961,961,961,961,961,961,961, +961,961,961,961,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,23,22,1,1,1,1,1,1,1,1,1,675,3, +679,679,22,1359,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961, +961,961,961,961,961,961,961,961,961,961,961,961,961,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,177,177,177,816,3,1,3187,3038,3038,961,961,961,961,961,961,961,961,961,961, +961,961,961,961,961,961,961,961,961,690,668,690,668,690,668,690,668,690,668,690, +668,690,668,690,668,690,668,690,668,690,668,690,668,1,1,1,18,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,176,176,176,176,176,176,176,177,1,3,1,1,2353,2148,2148,2148,2148, +2148,1,1,21,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,176,176,176,176,176,176,176,176,176, +176,192,176,1,1,1,1359,1359,1359,1359,1359,1359,1359,1359,1359,1359,1359,1359,961,961, +961,961,961,961,961,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,177,177,177,177, +177,177,177,177,177,21,1,1,45,961,961,961,961,961,961,961,961,961,961,961, +961,961,961,961,961,961,961,961,961,961,961,961,961,961,690,668,690,668,690,668, +690,668,690,668,690,668,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,177,177,177, +151,147,157,171,145,171,177,161,209,226,1290,3,1,22,961,961,961,961,961,961, +961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,690,668,690, +668,690,668,690,668,690,668,690,668,690,668,690,668,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961, +961,961,961,961,961,961,961,690,668,690,668,690,668,690,668,690,668,690,668,690, +668,690,668,690,668,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,30,1,16,1,3,1,1,1922,1664,1664,1664,1664,1664,1664,1664,1664,1664, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,176,177,177,177,177,177,177,176,176,176, +176,176,177,177,156,1,3,1,27,961,961,961,961,961,961,961,961,961,961,961, +961,690,668,690,668,690,668,690,668,690,668,690,668,690,668,690,668,690,668,690, +668,690,668,690,668,690,668,690,668,690,668,690,668,690,668,690,668,690,668,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,40, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,117,307,176,177,112,213,117,108,176,168,169,166,169,169,168,167,167, +1,3,1,1,961,961,961,961,961,961,961,961,961,961,961,961,961,690,668,690, +668,690,668,690,668,690,668,690,668,690,668,690,668,690,668,690,668,690,668,690, +668,690,668,690,668,690,668,690,668,690,668,690,668,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,179,177,177, +177,177,177,1,3,1,30,1359,1359,1359,1359,961,961,961,961,961,961,961,961,961, +961,961,961,961,961,961,961,961,961,961,961,961,961,961,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,191,1,29,35, +1359,1359,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961, +961,961,961,961,961,961,961,961,961,19,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961, +961,961,961,961,690,668,690,668,690,668,690,668,690,668,690,668,690,668,690,668, +690,668,690,668,690,668,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,816,3, +1,2542,2353,2353,2353,2353,961,961,961,961,961,961,961,961,961,961,690,668,690,668, +690,668,690,668,690,668,690,668,690,668,690,668,690,668,690,668,690,668,690,668, +690,668,690,668,690,668,690,668,690,668,690,668,690,668,690,668,690,668,762,112, +1,1,1,3187,3038,3038,961,961,961,961,961,961,961,961,961,961,961,961,961,961, +961,961,690,668,690,668,690,668,690,668,690,668,690,668,690,668,690,668,690,668, +690,668,690,668,690,668,690,668,690,668,690,668,1,1,1,1,1,1,1,1, +1,1,32,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +33,1,191,176,1,3,1,27,1664,1664,1664,1359,1359,1359,1359,1359,1359,1359,1359,1359, +1359,1359,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,675,3,1,1,1359,961,961,961,961,961, +961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961, +961,961,961,961,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,177, +177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,176, +176,176,176,176,176,816,3,18,22,961,961,961,961,961,961,961,961,961,961,961, +961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,690,668,690,668, +690,668,690,668,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,28,1,26,1,1,160,160,148,177, +177,675,3,1,1,1359,1359,1359,1359,1359,1359,1359,1359,1359,1359,1359,961,961,961,961, +961,961,961,961,961,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,38,28,1,1,1,1, +1,1,1,1,1,1,1,34,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,3844,3721,961,961,961,961,961,961,961,961, +961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961, +961,961,961,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2718,2718, +2718,2542,1359,1359,1359,1359,1359,1359,1359,1359,1359,961,961,961,961,961,961,961,961,961, +961,961,961,961,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,23,1,961,961,961,961,961,961,961,961,961,961,961, +961,961,961,961,961,961,961,961,961,961,961,690,668,690,668,690,668,690,668,690, +668,690,668,690,668,690,668,690,668,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1688,816,3,1,25,961,961,961,961, +961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,690,668, +690,668,690,668,690,668,690,668,690,668,690,668,690,668,690,668,1,1,1,1, +1,1,1,1,24,1,1,1,1,1,1,1,1,1,1,20,19,1,1,38, +27,1,1,1,1,1,1,16,1,1,38,38,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,177,177, +177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,176, +176,176,176,176,214,182,182,177,261,1,1,1,1,1,1,1,1,1,1,1, +1,20,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961, +961,961,961,961,961,690,668,690,668,690,668,690,668,690,668,690,668,690,668,690, +668,680,18,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +634,3,1,40,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961, +961,961,961,961,961,961,961,690,668,690,668,690,668,690,668,690,668,690,668,690, +668,690,668,1,1,1,1,1,40,30,1,29,1,1,1,34,1,27,1,1, +46,29,30,1,1,1,1,1,26,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,26,39,38,1,1,1,1,1,1,1,1,1, +1,1,40,41,733,1,1,1,1359,1359,1359,1359,1359,1359,961,961,961,961,961,961, +961,961,961,961,961,961,961,961,961,961,961,961,961,33,138,1,1,679,679,3844, +3721,1359,1359,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961, +961,961,961,961,961,961,961,961,961,961,23,168,884,1,679,679,1,1922,1922,1922, +1922,1664,1664,1664,1664,1664,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,130,130,1,1,19,1359,961,961,961,961,961,961, +961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961, +961,961,961,105,17,682,1,1,1,1359,1359,1359,1359,961,961,961,961,961,961,961, +961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,128,1117,26,1138, +3,1,3844,3721,1359,1359,1359,961,961,961,961,961,961,961,961,961,961,961,961,961, +961,961,961,961,961,961,961,961,961,961,961,961,143,28,1077,1,3,36,22,961, +961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,690,668,690,668,690, +668,690,668,690,668,690,668,690,668,690,668,690,668,690,668,690,668,690,668,690, +668,690,668,690,668,14,193,794,1,1,13,1359,1359,1359,1359,961,961,961,961,961, +961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,70,1, +176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,118,176, +176,176,176,176,90,176,176,176,176,176,176,634,3,1,2718,2718,2718,2542,961,961, +961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,690, +668,690,668,690,668,690,668,690,668,690,668,690,668,690,668,690,668,690,668,150, +28,702,1,3,18,19,1922,1922,1922,1922,1664,1664,1664,1664,1664,1,198,1212,1,679, +679,1,1359,1359,1359,1359,1359,1359,1359,1359,1359,961,961,961,961,961,961,961,961,961, +961,961,961,961,1,168,177,177,176,176,177,177,1138,3,1,2718,2718,2718,2542,961, +961,961,961,961,961,961,961,961,961,961,961,961,961,961,690,668,690,668,690,668, +690,668,690,668,690,668,690,668,690,668,690,668,690,668,690,668,690,668,690,668, +690,668,690,668,690,668,19,13,1,1,1,32,33,33,33,33,33,33,33,33, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,34,34,33,33,33,33,33,33,33,33,33,33,33,32,32,32,32,32,32, +32,32,32,32,32,32,16,27,186,186,186,186,186,186,186,186,186,186,186,186, +120,182,182,182,182,182,182,182,182,182,182,155,178,178,188,188,110,109,148,1, +3,679,679,23,961,961,961,961,961,961,961,961,961,961,961,961,961,961,690,668, +690,668,690,668,690,668,690,668,690,668,690,668,690,668,690,668,690,668,690,668, +690,668,690,668,690,668,690,668,690,668,690,668,24,771,50,27,27,30,30,30, +30,30,30,33,33,30,30,30,30,30,30,30,30,28,30,30,30,30,30,30, +30,22,34,34,16,675,3,1,1,961,961,961,961,961,961,961,961,961,961,961, +961,961,961,961,961,961,961,690,668,690,668,690,668,690,668,690,668,690,668,690, +668,690,668,690,668,690,668,690,668,690,668,690,668,22,151,1297,1,1,26,961, +961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961, +961,961,690,668,690,668,690,668,690,668,690,668,690,668,690,668,690,668,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,15,1,1,1,1,1,1, +18,37,1,1,1,19,1,39,41,168,1,1,3,554,554,554,1,1359,1359,1359, +1359,1359,1359,1359,1359,1359,1359,1359,1359,1359,1359,1359,961,168,1,674,675,3,34,3844, +3721,961,961,961,961,961,961,961,961,961,961,961,961,961,690,668,690,668,690,668, +690,668,690,668,690,668,690,668,690,668,690,668,690,668,690,668,690,668,690,668, +690,668,690,668,690,668,690,668,690,668,1,150,176,176,176,168,168,168,168,168, +168,168,168,168,86,1,25,961,961,961,961,961,961,961,961,961,961,961,961,961, +961,961,961,690,668,690,668,690,668,690,668,690,668,690,668,690,668,690,668,690, +668,690,668,690,668,690,668,690,668,690,668,690,668,24,1,169,169,169,169,164, +164,1,3,679,679,24,1359,1359,1359,961,961,961,961,961,961,961,961,961,961,961, +961,961,961,961,961,961,961,961,961,961,961,961,961,961,168,24,1096,1,1,1, +961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961, +961,961,961,690,668,690,668,690,668,690,668,690,668,690,668,690,668,690,668,168, +1,176,176,176,177,176,176,176,176,177,176,177,177,176,176,177,176,176,177,176, +177,176,176,155,168,168,168,168,168,168,168,168,168,168,167,169,169,168,170,1, +1,3844,3721,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961, +961,961,690,668,690,668,690,668,690,668,690,668,690,668,690,668,690,668,690,668, +690,668,690,668,690,668,169,37,1,675,3,1,1,961,961,961,961,961,961,961, +961,961,961,961,961,961,961,961,961,961,961,961,961,961,690,668,690,668,690,668, +690,668,690,668,690,668,690,668,690,668,690,668,690,668,169,1,177,177,177,177, +177,177,177,177,177,177,176,177,176,177,176,177,176,177,177,177,176,176,177,177, +177,1225,212,1,1,3187,3038,3038,961,961,961,961,961,961,961,961,961,961,961,961, +961,961,961,961,961,690,668,690,668,690,668,690,668,690,668,690,668,690,668,690, +668,690,668,690,668,690,668,690,668,690,668,690,668,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,168,1,1,33,27,30,1,27,33,40,1,1290,3,28,20,1359, +1359,1359,1359,1359,1359,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961, +961,961,961,961,160,1,176,177,177,156,99,1,1,24,961,961,961,961,961,961, +961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,690,668,690,668,690, +668,690,668,690,668,690,668,690,668,690,668,690,668,690,668,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,3,1,20,961,961,961,961,961,961,961,961, +961,961,690,668,690,668,690,668,690,668,690,668,690,668,690,668,690,668,690,668, +690,668,690,668,690,668,690,668,690,668,690,668,690,668,690,668,690,668,690,668, +690,668,690,668,169,1,499,675,3,1,1,961,961,961,961,961,961,961,961,961, +961,961,961,961,961,961,961,961,961,961,961,961,961,961,690,668,690,668,690,668, +690,668,690,668,690,668,690,668,690,668,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,151,887,3,1,1,961,961,961, +961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961, +961,961,961,961,961,961,961,690,668,168,26,176,177,177,176,176,176,176,176,176, +176,176,176,176,176,259,177,177,177,176,176,547,1,3844,3721,961,961,961,961,961, +961,961,961,961,961,961,961,961,961,961,961,961,690,668,690,668,690,668,690,668, +690,668,690,668,690,668,690,668,690,668,690,668,690,668,690,668,690,668,690,668, +168,1,1728,1138,3,1,3844,3721,961,961,961,961,961,961,961,961,961,961,961,961, +961,961,690,668,690,668,690,668,690,668,690,668,690,668,690,668,690,668,690,668, +690,668,690,668,690,668,690,668,690,668,690,668,690,668,690,668,23,126,885,151, +887,3,1,3844,3721,1359,961,961,961,961,961,961,961,961,961,961,961,961,961,961, +961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,168,1,1,1,1, +1359,1359,1359,1359,1359,1359,1359,961,961,961,961,961,961,961,961,961,961,961,961,961, +961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961, +961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,29,177,177,177,177, +177,176,176,176,177,176,176,177,176,177,177,176,177,176,177,176,177,177,177,177, +177,177,177,176,177,176,177,137,1290,3,1,961,961,961,961,961,961,961,961,961, +961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961, +961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961, +961,961,690,668,690,668,690,668,690,668,690,668,690,668,690,668,690,668,690,668, +690,668,690,668,178,17,170,142,135,157,228,176,143,146,177,184,224,171,108,151, +176,180,240,176,119,319,160,176,189,177,98,176,176,473,176,176,154,168,224,197, +169,168,169,169,168,168,168,188,168,169,168,168,168,168,138,198,169,169,208,172, +169,1,1,3844,3721,1359,1359,1359,961,961,961,961,961,961,961,961,961,961,961,961, +961,961,961,961,961,961,961,961,961,961,961,961,961,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1359,1359,1359,1359,1359,1359, +1359,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,136,21, +625,1,1,3844,3721,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961, +961,961,961,690,668,690,668,690,668,690,668,690,668,690,668,690,668,690,668,690, +668,690,668,690,668,690,668,690,668,169,1,985,1,3,25,32,961,961,961,961, +961,961,961,961,961,961,961,961,961,961,961,961,690,668,690,668,690,668,690,668, +690,668,690,668,690,668,690,668,690,668,690,668,690,668,690,668,690,668,690,668, +690,668,24,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,168,168,168,168,168, +168,168,168,169,169,169,169,164,164,1,1,1,1359,1359,1359,1359,1359,961,961,961, +961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,122,21, +1,634,3,1,1,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961, +961,961,961,961,690,668,690,668,690,668,690,668,690,668,690,668,690,668,690,668, +690,668,690,668,690,668,690,668,40,176,176,176,176,176,176,176,176,176,176,176, +176,176,176,176,176,176,176,176,177,177,176,176,176,176,176,177,176,177,177,176, +169,151,887,3,28,1,1359,1359,1359,961,961,961,961,961,961,961,961,961,961,961, +961,961,961,961,961,961,961,961,961,961,961,961,961,961,169,22,176,177,176,177, +176,176,176,177,177,177,176,177,177,176,176,713,1,3187,3038,3038,961,961,961,961, +961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,690,668,690,668, +690,668,690,668,690,668,690,668,690,668,690,668,690,668,690,668,690,668,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,168,1101,1,1,26,961,961,961,961,961,961, +961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,690, +668,690,668,690,668,690,668,690,668,690,668,119,28,893,1,679,679,1,961,961, +961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,690,668, +690,668,690,668,690,668,690,668,690,668,690,668,690,668,690,668,690,668,690,668, +1,739,1,1,1,1,1,1,13,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,169,168,169,166,168,169,166, +157,169,169,169,192,177,122,1,3,1,1,1359,1359,1359,1359,961,961,961,961,961, +961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,168,1, +1085,1138,3,1,3844,3721,961,961,961,961,961,961,961,961,961,961,961,961,961,961, +961,961,961,961,961,961,961,961,961,961,690,668,690,668,690,668,690,668,690,668, +690,668,690,668,168,1,1,1,1,1,961,961,961,961,961,961,961,961,961,961, +961,961,961,961,961,961,961,961,961,961,961,961,690,668,690,668,690,668,690,668, +690,668,690,668,690,668,690,668,690,668,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,176,176,177,177,176,176,177,176,177,176,176,176,176,176,176,176,176,176,177, +176,177,177,177,176,176,176,177,176,177,176,177,168,1,3,1,228,887,3,1, +1,961,961,961,961,961,961,961,961,961,961,690,668,690,668,690,668,690,668,690, +668,690,668,690,668,690,668,690,668,690,668,690,668,690,668,690,668,690,668,690, +668,690,668,690,668,690,668,690,668,690,668,690,668,168,1,176,176,176,176,176, +176,176,176,176,176,176,176,176,176,176,1,1,1,1359,1359,1359,1359,1359,961,961, +961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,1, +177,177,177,176,177,176,177,177,177,177,177,177,176,169,1,1,1,961,961,961, +961,961,961,961,690,668,690,668,690,668,690,668,690,668,690,668,690,668,690,668, +690,668,690,668,690,668,690,668,690,668,690,668,690,668,690,668,690,668,690,668, +690,668,690,668,690,668,690,668,690,668,690,668,169,55,177,177,176,176,176,177, +177,176,176,177,177,177,177,177,177,176,177,177,177,177,177,177,177,176,177,1, +1,1,2718,2718,2718,2542,961,961,961,961,961,961,961,961,961,961,961,961,961,961, +961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,168,1,1058, +1,30,1,1664,1664,1664,1664,1664,1359,1359,1359,1359,1359,1359,1359,1359,168,1,176,176, +177,177,176,177,144,856,997,3,679,679,1,961,961,961,961,961,961,961,961,961, +961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961, +690,668,690,668,168,1,176,177,177,176,177,177,177,176,176,177,177,177,176,176, +176,176,177,177,1,679,679,1,961,961,961,961,961,961,961,961,961,961,961,961, +961,690,668,690,668,690,668,690,668,690,668,690,668,690,668,690,668,690,668,690, +668,690,668,690,668,690,668,690,668,690,668,690,668,690,668,690,668,168,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,25,1,1,22,1943,1,1,3844,3721,961,961,961,961,961,961, +961,961,961,961,961,961,961,961,961,961,961,961,690,668,690,668,690,668,690,668, +690,668,690,668,690,668,690,668,690,668,690,668,690,668,690,668,690,668,169,21, +177,176,176,177,177,177,176,177,176,177,176,177,176,177,177,177,176,176,176,176, +176,176,177,177,1,1,3187,3038,3038,961,961,961,961,961,961,961,961,961,961,961, +961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961, +156,1,1,1372,1,2718,2718,2718,2542,961,961,961,961,961,961,961,961,961,961,961, +961,961,961,690,668,690,668,690,668,690,668,690,668,690,668,690,668,690,668,690, +668,690,668,690,668,690,668,690,668,690,668,690,668,690,668,690,668,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,3844,3721,961,961,961,961,961,961, +961,961,961,961,961,961,961,961,961,690,668,690,668,690,668,690,668,690,668,690, +668,690,668,690,668,690,668,690,668,690,668,690,668,690,668,690,668,690,668,690, +668,199,29,1092,168,169,169,169,169,169,168,168,169,169,168,168,168,168,168,169, +169,168,168,168,168,169,1,679,679,961,961,961,961,961,961,961,961,961,961,961, +961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961, +961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961, +961,690,668,690,668,690,668,690,668,690,668,690,668,690,668,690,668,690,668,690, +668,169,1,177,176,177,176,177,177,176,176,176,177,176,177,176,177,176,177,176, +176,176,176,176,177,176,176,177,177,176,176,176,176,176,597,1,3844,3721,961,961, +961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961, +961,961,961,961,961,961,690,668,690,668,690,668,218,39,176,177,177,176,177,177, +176,176,176,177,177,177,176,176,176,177,176,177,169,169,169,77,188,169,169,168, +168,168,168,169,169,169,168,210,210,174,168,168,1,1,1,961,961,961,961,961, +961,961,961,961,961,961,961,961,961,961,961,961,961,961,690,668,690,668,690,668, +690,668,690,668,690,668,690,668,690,668,690,668,690,668,690,668,690,668,132,1, +177,176,176,177,176,176,177,177,176,177,177,176,176,176,177,176,176,177,177,177, +176,176,177,177,177,177,1175,1,3844,3721,961,961,961,961,961,961,961,961,961,961, +961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,690,668,690,668,690, +668,690,668,690,668,690,668,145,20,176,176,176,176,176,176,176,177,176,177,177, +177,177,177,176,176,177,176,177,176,177,177,176,177,176,176,177,1,23,3187,3038, +3038,961,961,961,961,961,961,961,961,961,961,961,961,961,690,668,690,668,690,668, +690,668,690,668,690,668,690,668,690,668,690,668,690,668,690,668,690,668,690,668, +690,668,690,668,690,668,690,668,690,668,120,32,1,1,17,3187,3038,3038,961,961, +961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,690,668,690,668, +690,668,690,668,690,668,690,668,690,668,690,668,690,668,690,668,690,668,690,668, +690,668,169,27,177,177,177,177,177,176,176,177,176,177,176,177,177,176,177,177, +176,177,177,176,176,177,176,177,176,176,177,177,177,176,177,1,30,3844,3721,961, +961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,690,668,690,668, +690,668,690,668,690,668,690,668,690,668,690,668,690,668,690,668,690,668,690,668, +690,668,690,668,1,157,176,177,176,176,177,176,177,176,176,177,176,176,177,176, +177,176,176,176,176,176,177,176,176,176,177,176,177,176,176,177,176,1,1,24, +961,961,961,961,961,961,961,961,961,961,961,961,961,690,668,690,668,690,668,690, +668,690,668,690,668,690,668,690,668,690,668,690,668,690,668,690,668,690,668,690, +668,690,668,690,668,690,668,690,668,4,4,4,4,4,1,1,1,30,1,1359, +1359,1359,1359,1359,1359,1359,1359,1359,1359,961,961,961,961,961,961,961,961,961,961,961, +148,27,748,1,1,3187,3038,3038,1359,961,961,961,961,961,961,961,961,961,961,961, +961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,168,1, +1,1,32,1,961,961,961,961,961,961,961,961,961,961,961,961,961,961,690,668, +690,668,690,668,690,668,690,668,690,668,690,668,690,668,690,668,690,668,690,668, +690,668,690,668,690,668,690,668,690,668,690,668,169,1,1,822,1,3187,3038,3038, +961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961, +961,961,961,961,961,690,668,690,668,690,668,690,668,690,668,690,668,128,34,177, +177,176,176,177,176,176,177,176,177,177,177,176,177,177,176,177,177,177,176,176, +177,177,177,176,177,177,177,177,176,1098,181,1,679,679,961,961,961,961,961,961, +961,961,961,961,961,961,961,961,961,961,961,961,961,690,668,690,668,690,668,690, +668,690,668,690,668,690,668,690,668,690,668,690,668,690,668,690,668,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,177,176,176,177,176,176,176,176,177,176,177, +177,177,177,177,177,176,177,177,177,176,177,177,176,176,176,177,176,176,177,177, +168,856,1,997,3,1,1,961,961,961,961,961,961,961,961,961,961,961,961,961, +961,961,961,961,961,961,961,961,961,961,961,690,668,690,668,690,668,690,668,690, +668,690,668,690,668,1,168,177,177,177,176,177,177,177,176,177,177,177,176,177, +176,177,176,168,168,169,169,169,169,168,168,168,168,168,168,169,169,169,141,169, +169,169,169,113,1,1,1,961,961,961,961,961,961,961,961,961,961,961,961,961, +961,961,961,961,961,961,961,961,690,668,690,668,690,668,690,668,690,668,690,668, +690,668,690,668,690,668,690,668,169,1,177,177,176,176,176,177,176,177,177,177, +177,177,177,177,177,176,177,176,1,1,3844,3721,961,961,961,961,961,961,961,961, +961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,690,668,690,668,690, +668,690,668,690,668,690,668,690,668,690,668,23,161,177,177,177,177,176,176,177, +177,176,177,176,176,819,1,3187,3038,3038,961,961,961,961,961,961,961,961,961,961, +961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961, +690,668,169,1,177,176,177,177,176,176,177,177,176,176,176,177,177,177,177,1161, +45,3844,3721,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961, +961,690,668,690,668,690,668,690,668,690,668,690,668,690,668,690,668,690,668,690, +668,690,668,690,668,690,668,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1128,1, +22,1,1359,1359,1359,1359,1359,1359,1359,961,961,961,961,961,961,961,961,961,961,961, +961,961,961,961,961,961,168,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168, +168,168,168,168,168,168,168,168,168,168,1,1,3844,3721,1359,1359,1359,1359,1359,1359, +1359,1359,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,169,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,169,169,168,168,169,169,169,169,169,169,169,169,169, +169,169,169,169,169,169,169,169,168,168,168,168,168,169,169,169,1,679,679,3187, +3038,3038,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961, +961,961,961,690,668,690,668,690,668,690,668,690,668,690,668,690,668,690,668,690, +668,690,668,107,20,1,898,29,1,961,961,961,961,961,961,961,961,961,961,961, +961,961,961,961,961,961,961,961,961,961,961,690,668,690,668,690,668,690,668,690, +668,690,668,690,668,690,668,690,668,1,168,176,177,176,177,177,177,177,177,176, +177,176,176,177,176,176,176,856,144,997,3,1,23,961,961,961,961,961,961,961, +961,961,961,961,961,961,961,961,961,690,668,690,668,690,668,690,668,690,668,690, +668,690,668,690,668,690,668,690,668,690,668,690,668,690,668,690,668,690,668,124, +21,176,176,176,176,176,176,176,176,176,177,176,176,176,177,177,176,176,176,176, +176,176,176,164,176,176,176,177,176,172,176,177,22,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,168,168,193,168,168,168,168,168,168,168,168,168,168,168,115,168,168, +168,168,168,168,168,168,168,169,169,169,169,62,122,149,1,26,34,170,2,22, +176,1,131,2,1,32,244,170,2,1,25,160,156,2,28,1,3844,3721,144,2, +41,1,208,180,2,30,1,2718,2718,2718,2542,169,2,26,34,2718,2718,2718,2542,170, +2,1,1,2148,2148,2148,1922,1922,1922,1922,115,2,1,1,2718,2718,2718,2542,158,2, +1,3187,3038,3038,1922,1922,1922,1922,1664,1664,1664,1664,1664,154,2,1,3844,3721,2718,2718, +2718,2542,193,2,1,23,2353,2148,2148,2148,2148,2148,143,25,2,26,1,3187,3038,3038, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,2,1,1,2718,2718,2718,2542,169,1,2,27,1,3187, +3038,3038,202,37,2,1,3844,3721,1922,1922,1922,1922,1664,1664,1664,1664,1664,157,29,2, +1,1,2542,2353,2353,2353,2353,195,1,2,28,1,2542,2353,2353,2353,2353,147,1,2, +1,21,3187,3038,3038,186,1,2,1,26,3844,3721,169,25,1,2,679,679,3844,3721, +1922,1922,1922,1922,1922,1922,1922,1664,144,1,1,2,24,29,3187,3038,3038,121,1,2, +1,1,2718,2718,2718,2542,167,1,1,2,679,679,1,2542,2353,2353,2353,2353,151,725, +2,1,1,2542,2353,2353,2353,2353,129,788,2,33,3844,3721,2718,2718,2718,2542,175,32, +2,1,1,2718,2718,2718,2542,196,32,2,28,1,3187,3038,3038,161,1,1,2,36, +3844,3721,2718,2718,2718,2542,134,41,1295,2,1,3844,3721,2353,2148,2148,2148,2148,2148,161, +1,176,177,177,176,177,176,177,177,177,176,176,176,176,176,176,176,176,177,177, +177,176,176,176,177,177,176,176,177,176,2,1,3844,3721,2718,2718,2718,2542,128,1176, +1,28,56,42,39,22,24,41,28,1,1,27,27,29,29,29,30,30,30,30, +30,30,30,30,43,30,38,30,24,20,22,2,1,1,1922,1664,1664,1664,1664,1664, +1664,1664,1664,1664,126,35,1,786,132,1,1,3844,3721,1359,1359,961,961,961,961,961, +961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961, +961,961,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,168,168,168,169,169, +169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,132,169,169,169,169, +169,169,169,168,168,169,1,1,3187,3038,3038,961,961,961,961,961,961,961,961,961, +961,961,961,961,961,690,668,690,668,690,668,690,668,690,668,690,668,690,668,690, +668,690,668,690,668,690,668,690,668,690,668,690,668,690,668,690,668,690,668,168, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,176,176,176,176,176,176,176,176,176,176,177,176, +176,176,176,176,176,176,176,176,176,176,176,176,177,177,176,177,176,176,176,1, +1,1,1,26,30,41,1,168,168,168,168,168,168,168,168,168,168,168,168,168, +168,168,168,168,168,168,168,168,168,168,168,169,169,169,169,169,169,169,1,1, +24,961,961,961,961,961,961,961,961,961,961,961,961,961,961,690,668,690,668,690, +668,690,668,690,668,690,668,690,668,690,668,690,668,690,668,690,668,690,668,690, +668,690,668,690,668,690,668,690,668,22,169,889,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,169, +169,169,169,169,169,168,168,168,168,1,1,3187,3038,3038,1359,1359,1359,961,961,961, +961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961, +961,961,151,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,168,168,168,168, +168,168,168,168,168,168,168,168,168,170,170,1,1,1,566,566,566,566,566,566, +566,566,566,566,566,566,566,566,566,566,566,566,566,566,566,566,566,566,566,566, +566,566,566,566,566,566,566,566,566,566,566,566,566,566,566,566,566,566,566,566, +566,566,566,566,566,566,566,566,566,566,566,566,566,566,566,566,566,566,566,566, +566,566,566,566,566,566,566,566,566,566,566,566,566,566,566,566,566,566,566,566, +566,566,566,164,1,1,1,1,1,1,1,1,1,21,1,1,27,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,176,176,176,176,177, +176,177,176,176,177,176,177,177,176,177,177,177,177,176,176,177,177,176,176,176, +176,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,169,169,169,169,168,168,168,168,168,168,169, +169,168,168,168,168,168,1,34,1,2,1,1,2,1,1,2,1,50,177,4, +4,4,4,4,4,2,1,51,177,168,2,1,1,2,1,1,1922,1922,1922,1922, +1922,1922,1922,1664,111,2,1,1,1922,1922,1922,1922,1664,1664,1664,1664,1664,173,2,1, +1,2148,2148,2148,1922,1922,1922,1922,178,2,1,1,1664,1664,1664,1664,1664,1664,1664,1359, +1359,1359,1359,1359,203,2,33,1,2542,2353,2353,2353,2353,249,2,1,1,3844,3721,188, +2,1,3187,3038,3038,1359,1359,1359,1359,1359,961,961,961,961,961,961,961,961,961,961, +961,961,961,961,961,961,961,961,961,961,961,4,4,4,2,1,29,1359,1359,1359, +1359,1359,1359,1359,1359,1359,961,961,961,961,961,961,961,961,961,961,961,961,961,4, +4,4,2,23,3844,3721,1664,1664,1664,1664,1664,1359,1359,1359,1359,1359,1359,1359,1359,159, +32,2,1,1,1359,1359,1359,1359,1359,1359,1359,1359,1359,1359,1359,1359,961,961,961,961, +961,961,961,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,30,176,176,176,177,177,177, +176,176,176,176,176,177,177,177,176,176,185,2,679,679,3187,3038,3038,961,961,961, +961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961, +961,961,961,961,961,961,690,668,690,668,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,2,1,1,1922,1922,1922,1922,1664,1664,1664,1664,1664,4,4,4,2, +24,24,184,2,1,3844,3721,2148,2148,2148,1922,1922,1922,1922,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2, +1,1,1359,1359,1359,1359,1359,1359,1359,1359,961,961,961,961,961,961,961,961,961,961, +961,961,961,961,961,33,25,15,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,177,177,177,177,177, +177,177,177,177,177,177,177,177,177,177,176,176,176,176,176,176,176,176,176,176, +176,176,176,177,177,177,2,1,1,2542,2353,2353,2353,2353,4,4,4,2,1,3844, +3721,1664,1664,1664,1664,1664,1664,1664,1664,1664,1359,1359,19,168,1,2,1,23,1664,1664, +1664,1664,1664,1664,1664,1664,1664,1359,1359,23,143,1020,2,1,3844,3721,1359,1359,1359,1359, +1359,1359,1359,1359,1359,1359,1359,1359,1359,1359,1359,961,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,17,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,1,1,1359, +1359,1359,1359,1359,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961, +961,961,961,961,961,27,113,767,2,1,3187,3038,3038,1359,1359,1359,1359,961,961,961, +961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961, +1,169,176,177,177,177,176,176,177,2,1,35,1664,1664,1664,1359,1359,1359,1359,1359, +1359,1359,1359,1359,1359,1359,1,169,665,2,1,3187,3038,3038,961,961,961,961,961,961, +961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,690, +668,690,668,690,668,690,668,690,668,690,668,23,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177, +176,176,176,176,176,176,176,176,177,177,177,132,235,77,2,1,43,1359,1359,1359, +1359,1359,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961, +961,961,961,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,1,2718,2718,2718,2542, +961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961, +961,961,961,961,690,668,690,668,690,668,690,668,690,668,690,668,690,668,26,139, +177,177,177,177,177,176,177,177,177,177,177,177,177,176,176,177,176,176,2,1, +1,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,690, +668,690,668,690,668,690,668,690,668,690,668,690,668,690,668,690,668,690,668,690, +668,690,668,690,668,34,134,176,177,177,177,177,2,1,1,961,961,961,961,961, +961,961,961,961,961,961,961,961,961,961,961,961,961,690,668,690,668,690,668,690, +668,690,668,690,668,690,668,690,668,690,668,690,668,690,668,690,668,690,668,34, +134,176,176,177,177,177,177,177,177,177,177,2,38,35,961,961,961,961,961,961, +961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961, +690,668,690,668,690,668,690,668,690,668,1,168,176,176,176,177,176,176,176,176, +176,177,177,177,177,177,176,2,1,3187,3038,3038,961,961,961,961,961,961,961,961, +961,961,961,961,961,961,961,961,961,961,961,961,961,690,668,690,668,690,668,690, +668,690,668,690,668,690,668,690,668,690,668,690,668,1,168,176,176,177,177,177, +177,177,177,176,176,177,176,2,1,4,4,4,4,4,2,1,1,961,961,961, +961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961, +961,961,961,961,690,668,690,668,690,668,690,668,169,30,654,714,2,1,25,212, +2,1,1,2,679,679,1,3844,3721,169,1,1,1238,2,1,1,1922,1922,1922,1922, +1922,1922,1922,1664,33,186,1,1,2,679,679,1,3187,3038,3038,168,25,1,1,2, +1,1,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961, +961,961,961,961,961,961,961,961,961,961,961,961,961,169,1,52,1,2,1,39, +1359,1359,1359,1359,1359,1359,1359,1359,1359,1359,1359,1359,1359,1359,1359,961,168,1,1,169, +194,198,169,169,169,168,168,168,168,168,168,169,169,169,168,168,168,168,168,168, +169,169,169,169,169,169,169,169,169,1,1,1,1,1,1,1,1,1,1,1, +2,1,3844,3721,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961, +961,961,961,961,961,961,961,961,961,690,668,690,668,690,668,690,668,690,668,690, +668,169,1,831,890,144,2,37,1,171,128,2,42,1,3187,3038,3038,178,2,33, +24,176,124,2,679,679,22,1664,1664,1664,1664,1664,1359,1359,1359,1359,1359,1359,1359,1359, +120,1,2,38,38,2353,2148,2148,2148,2148,2148,214,2,33,34,3844,3721,137,22,2, +1,1,3187,3038,3038,148,27,2,1,3844,3721,1922,1922,1922,1922,1922,1922,1922,1664,217, +27,2,1,40,1664,1664,1664,1664,1664,1664,1664,1664,1664,1359,1359,134,25,2,40,1, +176,173,32,1131,2,1,34,3844,3721,202,1145,26,2,1,1,3844,3721,160,38,1065, +1,2,1,34,1664,1664,1664,1359,1359,1359,1359,1359,1359,1359,1359,1359,1359,1359,153,33, +222,229,145,177,176,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177, +177,177,177,176,176,176,176,176,68,2,24,1,3844,3721,168,1,1,1,2,1, +1,2718,2718,2718,2542,140,33,864,1,2,33,26,961,961,961,961,961,961,961,961, +961,961,961,961,961,961,961,961,961,961,961,690,668,690,668,690,668,690,668,690, +668,690,668,690,668,690,668,690,668,690,668,690,668,690,668,108,1,1,1,2, +1,1,2718,2718,2718,2542,201,26,981,1,2,3844,3721,3187,3038,3038,178,32,1558,1, +2,1,36,1664,1664,1664,1664,1664,1664,1664,1359,1359,1359,1359,1359,152,30,965,1,2, +1,35,1922,1922,1922,1922,1664,1664,1664,1664,1664,213,28,737,1,2,1,1,2353,2148, +2148,2148,2148,2148,123,20,810,1,2,1,1,2542,2353,2353,2353,2353,169,1,1317,1, +2,1,1,1664,1664,1664,1664,1664,1664,1664,1359,1359,1359,1359,1359,40,149,1,1,2, +33,1,1359,1359,1359,1359,961,961,961,961,961,961,961,961,961,961,961,961,961,961, +961,961,961,961,961,961,961,961,961,168,1,24,1,2,24,1,3844,3721,168,1, +841,1,2,38,22,2542,2353,2353,2353,2353,168,1,1,1,2,25,1,2542,2353,2353, +2353,2353,168,1,679,775,2,1,1,704,2,1,25,133,135,704,2,1,47,177, +252,704,2,1,28,2148,2148,2148,1922,1922,1922,1922,135,704,2,679,679,34,2542,2353, +2353,2353,2353,228,704,2,1,23,2718,2718,2718,2542,187,704,2,1,1,176,187,704, +2,1,1,1922,1922,1922,1922,1664,1664,1664,1664,1664,135,704,2,679,679,3187,3038,3038, +165,4,4,4,4,4,4,4,4,4,4,4,4,612,2,1,1,2353,2148,2148, +2148,2148,2148,121,704,2,18,15,2148,2148,2148,1922,1922,1922,1922,1,1,1,1,1, +1,1,1,38,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,37,35,1,704,2,679,679,1,2353,2148,2148,2148,2148,2148,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,177,177,177,177,177,177,176,176,176,176,177,177,782,2,1, +1,2718,2718,2718,2542,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,42,176,176,176,176, +176,176,176,177,177,177,177,704,2,1,1,1664,1664,1664,1664,1664,1664,1664,1359,1359, +1359,1359,1359,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,177,177,177,177,177,249,189, +204,186,163,704,2,1,3844,3721,2353,2148,2148,2148,2148,2148,24,161,704,2,1,3844, +3721,2353,2148,2148,2148,2148,2148,21,115,782,2,1,1,1922,1922,1922,1922,1664,1664,1664, +1664,1664,1,23,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,176,176,176,176,177,177,177, +177,177,176,176,176,176,176,177,177,177,177,177,704,2,1,3844,3721,2148,2148,2148, +1922,1922,1922,1922,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,176,176,176,176,176,176,176,177, +177,177,177,177,177,177,177,177,177,177,177,177,704,2,1,3187,3038,3038,2148,2148, +2148,1922,1922,1922,1922,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,176,176,176,176,176,176, +176,176,176,176,176,176,176,176,176,176,176,176,176,704,2,1,3844,3721,2542,2353, +2353,2353,2353,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,176,176,176,176,176,176,177,177,177, +177,177,177,176,176,176,176,176,176,176,176,176,176,176,176,177,177,177,782,2, +1,3844,3721,2718,2718,2718,2542,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,782,2,1,3187,3038,3038,2542,2353,2353,2353,2353, +30,30,30,30,30,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,176,176,176,176,176,176,287,177,177,177,177,177, +177,176,176,176,176,176,176,380,176,176,75,75,177,177,782,2,1,3844,3721,2718, +2718,2718,2542,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +177,177,177,782,2,1,3844,3721,1922,1922,1922,1922,1922,1922,1922,1664,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,9, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,782,2, +554,554,554,28,2542,2353,2353,2353,2353,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,30,1,1,1,52, +176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176, +176,176,176,176,176,176,704,2,1,3844,3721,1664,1664,1664,1664,1664,1359,1359,1359,1359, +1359,1359,1359,1359,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,2,1,36,1922,1922,1922,1922,1922,1922,1922,1664,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,40,35,35,231, +200,200,704,2,1,1,2148,2148,2148,1922,1922,1922,1922,168,1419,1,782,2,1,3844, +3721,2148,2148,2148,1922,1922,1922,1922,1,1,126,704,2,679,679,43,1922,1664,1664,1664, +1664,1664,1664,1664,1664,1664,169,1,176,176,177,177,177,177,176,176,176,176,176,176, +176,176,176,177,177,177,177,177,177,177,177,177,176,176,176,176,782,2,1,3844, +3721,2542,2353,2353,2353,2353,181,1170,19,1,2,1,34,1922,1922,1922,1922,1664,1664,1664, +1664,1664,216,38,176,176,176,176,176,176,177,177,176,176,177,46,187,188,2,25, +3844,3721,2353,2148,2148,2148,2148,2148,223,41,1276,1,2,1,59,2353,2148,2148,2148,2148, +2148,226,42,1248,670,2,1,3844,3721,1922,1922,1922,1922,1922,1922,1922,1664,38,1188,237, +1,2,679,679,3844,3721,2148,2148,2148,1922,1922,1922,1922,1096,36,196,1,2,1,3844, +3721,2718,2718,2718,2542,1190,38,205,1,2,1,22,2542,2353,2353,2353,2353,192,35,228, +228,177,177,177,177,177,176,176,176,176,176,176,176,176,177,177,177,177,177,177, +177,177,177,177,176,176,176,176,176,176,670,2,1,46,2542,2353,2353,2353,2353,219, +40,618,691,2,1,1,2718,2718,2718,2542,168,1,1622,1,2,1,29,2542,2353,2353, +2353,2353,145,33,177,177,176,176,176,176,176,176,176,176,176,177,177,177,177,177, +177,177,177,177,177,176,176,176,704,2,1,3844,3721,2148,2148,2148,1922,1922,1922,1922, +46,1447,253,670,2,1,25,2542,2353,2353,2353,2353,158,29,530,670,2,1,1,1922, +1664,1664,1664,1664,1664,1664,1664,1664,1664,169,30,467,691,2,1,27,242,168,33,1061, +691,2,1,29,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,169,32,1804,691,2, +1,51,2353,2148,2148,2148,2148,2148,169,1,1,691,2,24,3187,3038,3038,2353,2148,2148, +2148,2148,2148,169,1,1,670,2,1,27,1359,1359,1359,961,961,961,961,961,961,961, +961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,176,176, +176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,177, +177,177,177,177,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,14,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,38,691,2,1,1,1359,1359,1359,1359,961,961,961,961,961,961, +961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,168,1,1, +146,171,171,142,90,122,163,162,162,161,160,170,140,151,149,2,1,3844,3721,2353, +2148,2148,2148,2148,2148,168,1,1,125,81,168,168,196,196,167,167,167,133,168,168, +168,168,168,240,168,168,168,168,168,135,166,166,168,86,93,120,136,136,140,2, +1,24,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961, +961,961,961,961,961,961,961,961,961,961,961,690,668,690,668,168,1,1,787,2, +679,679,3844,3721,1664,1359,1359,1359,1359,1359,1359,1359,1359,1359,1359,1359,1359,1359,1359,168, +1,1,1,2,1,28,961,961,961,961,961,961,961,961,961,961,961,961,961,961, +961,961,961,961,961,961,961,961,961,961,961,961,961,961,690,668,690,668,690,668, +168,1,28,1072,2,1,1,961,961,961,961,961,961,961,961,961,961,961,961,961, +961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,127,33, +1346,832,120,2,1,3844,3721,1664,1664,1664,1664,1664,1664,1664,1359,1359,1359,1359,1359,168, +1,653,1,2,1,1,1922,1922,1922,1922,1664,1664,1664,1664,1664,168,1,1,1,2, +1,1,1922,1664,1664,1664,1664,1664,1664,1664,1664,1664,168,1,1,169,1130,2,1,1, +2353,2148,2148,2148,2148,2148,146,23,1130,2,1,1,2148,2148,2148,1922,1922,1922,1922,120, +21,1563,1130,2,1,23,3187,3038,3038,139,1130,2,35,1,2718,2718,2718,2542,168,1, +1,1,2,1,1,1922,1922,1922,1922,1664,1664,1664,1664,1664,168,1,1,781,158,2, +1,1,2542,2353,2353,2353,2353,168,39,600,534,153,2,210,210,174,168,168,169,169, +168,168,477,168,168,168,168,168,157,157,157,157,157,163,163,163,163,168,168,168, +142,142,169,179,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,27,1,38,48,1,1,1,1,648,1,1,1,22,1,1,1,1, +33,77,169,169,169,169,89,168,168,168,168,168,168,168,237,168,168,168,168,169, +169,169,169,169,169,169,169,168,168,170,169,169,1,1,1,1,1,1,2,26, +36,164,1,2,1,1,176,120,2,1,28,201,1,2,36,19,238,134,1,2, +35,1,3844,3721,178,1,2,23,1,204,145,1,2,47,1,2718,2718,2718,2542,159, +1,2,35,1,176,180,1,2,30,27,3187,3038,3038,182,1,2,1,1,3844,3721, +134,2,1,1,3844,3721,159,1,2,1,1,2718,2718,2718,2542,155,1,2,1,1, +3187,3038,3038,171,1,2,1,1,2718,2718,2718,2542,134,1,2,1,1,2148,2148,2148, +1922,1922,1922,1922,134,1,2,1,1,2718,2718,2718,2542,124,1,2,28,1,3187,3038, +3038,159,1,2,36,28,2353,2148,2148,2148,2148,2148,174,1,2,679,679,1,2542,2353, +2353,2353,2353,156,1,2,33,3844,3721,3187,3038,3038,180,1,2,27,25,2542,2353,2353, +2353,2353,154,1,2,27,1,177,28,168,1,2,1,1,1359,1359,1359,1359,1359,1359, +1359,1359,1359,1359,961,961,961,961,961,961,961,961,961,961,961,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,2,1,1,2542,2353,2353,2353,2353,22,22,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,29,1,1,1,2,1,1,3187,3038, +3038,198,1,1,2,33,1,2353,2148,2148,2148,2148,2148,144,29,1,2,1,1,2542, +2353,2353,2353,2353,159,22,1,2,1,1,1922,1922,1922,1922,1922,1922,1922,1664,36,36, +1,1,1,1,1,1,1,1,1,1,1,1,29,29,29,29,1,1,1,1, +1,1,1,1,1,1,2,1,1,2542,2353,2353,2353,2353,142,27,1,2,1,3844, +3721,2148,2148,2148,1922,1922,1922,1922,155,26,1,2,1,3187,3038,3038,1922,1922,1922,1922, +1664,1664,1664,1664,1664,134,24,1,2,1,1,2542,2353,2353,2353,2353,151,28,989,1, +2,1,1,2148,2148,2148,1922,1922,1922,1922,188,1,1,2,26,36,2148,2148,2148,1922, +1922,1922,1922,32,203,796,1,2,1,28,1922,1922,1922,1922,1922,1922,1922,1664,205,24, +757,1,2,1,34,2353,2148,2148,2148,2148,2148,130,25,1156,1,2,1,1,1664,1664, +1664,1359,1359,1359,1359,1359,1359,1359,1359,1359,1359,1359,199,30,764,1,2,57,1,176, +228,40,950,710,2,1,1,1664,1664,1664,1664,1664,1664,1664,1359,1359,1359,1359,1359,105, +719,27,710,2,1,1,176,168,1,1,210,710,2,32,46,2542,2353,2353,2353,2353, +168,1,1,710,2,1,23,3187,3038,3038,168,1,1,210,710,2,1,1,1922,1922, +1922,1922,1664,1664,1664,1664,1664,127,1,2,1,1,1922,1922,1922,1922,1664,1664,1664,1664, +1664,164,28,1,2,1,1,1922,1922,1922,1922,1922,1922,1922,1664,127,1,2,1,24, +2148,2148,2148,1922,1922,1922,1922,176,37,793,1,2,26,1,1922,1922,1922,1922,1922,1922, +1922,1664,129,1,2,33,1,2148,2148,2148,1922,1922,1922,1922,209,38,796,1,2,1, +27,1922,1664,1664,1664,1664,1664,1664,1664,1664,1664,157,1,2,1,1,1664,1664,1664,1664, +1664,1664,1664,1664,1664,1359,1359,154,24,658,1,2,30,28,1664,1664,1664,1664,1664,1359, +1359,1359,1359,1359,1359,1359,1359,179,25,1020,1,2,1,1,2148,2148,2148,1922,1922,1922, +1922,201,1,2,1,3844,3721,1664,1664,1664,1664,1664,1359,1359,1359,1359,1359,1359,1359,1359, +181,33,1,2,26,3844,3721,2353,2148,2148,2148,2148,2148,156,33,1,2,1,28,1922, +1922,1922,1922,1664,1664,1664,1664,1664,143,34,1,2,22,1,2353,2148,2148,2148,2148,2148, +168,1,1,172,957,2,26,3844,3721,1922,1922,1922,1922,1664,1664,1664,1664,1664,168,1, +1,123,957,2,32,1,1922,1922,1922,1922,1922,1922,1922,1664,127,28,614,186,957,2, +1,1,2148,2148,2148,1922,1922,1922,1922,119,24,709,957,2,1,1,2148,2148,2148,1922, +1922,1922,1922,168,1,957,2,32,3844,3721,1922,1664,1664,1664,1664,1664,1664,1664,1664,1664, +123,28,957,2,26,1,1664,1664,1664,1664,1664,1664,1664,1359,1359,1359,1359,1359,168,1, +1,135,796,2,24,1,1922,1922,1922,1922,1664,1664,1664,1664,1664,168,1,1,170,796, +2,30,3844,3721,1922,1922,1922,1922,1664,1664,1664,1664,1664,168,1,758,156,796,2,29, +35,1922,1922,1922,1922,1922,1922,1922,1664,194,23,707,743,2,1,1,2353,2148,2148,2148, +2148,2148,168,1,727,140,743,2,35,1,1922,1922,1922,1922,1664,1664,1664,1664,1664,134, +23,774,743,2,32,1,2542,2353,2353,2353,2353,201,1,743,2,23,3844,3721,1922,1922, +1922,1922,1664,1664,1664,1664,1664,154,30,743,2,1,1,2148,2148,2148,1922,1922,1922,1922, +126,20,743,2,28,3844,3721,2148,2148,2148,1922,1922,1922,1922,196,21,728,743,2,19, +23,1922,1922,1922,1922,1922,1922,1922,1664,132,23,832,743,2,1,1,1922,1922,1922,1922, +1922,1922,1922,1664,168,1,1,168,168,168,168,168,168,168,168,168,168,168,168,168, +168,168,168,168,168,168,168,168,168,175,168,168,168,168,168,168,168,236,162,2, +35,1,2148,2148,2148,1922,1922,1922,1922,168,1,643,1,2,30,1,3844,3721,168,1, +1,740,2,28,1,3187,3038,3038,168,1,1,1,2,52,1,2353,2148,2148,2148,2148, +2148,258,52,1276,1,2,1,28,2148,2148,2148,1922,1922,1922,1922,200,1,643,1,2, +32,1,2148,2148,2148,1922,1922,1922,1922,131,2,36,3844,3721,2542,2353,2353,2353,2353,168, +1,1477,1097,2,38,3844,3721,1922,1922,1922,1922,1922,1922,1922,1664,168,1,1,1,2, +1,48,2148,2148,2148,1922,1922,1922,1922,168,1,1,561,107,2,1,110,137,137,129, +135,153,166,192,189,133,162,153,153,153,153,123,115,109,165,205,162,177,178,178, +191,188,3,1,23,110,166,887,2,1,33,3187,3038,3038,193,887,2,1,29,121, +184,887,2,28,1,1922,1922,1922,1922,1664,1664,1664,1664,1664,150,1,621,1,2,1, +34,2542,2353,2353,2353,2353,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,21,774,2,1,1,1922,1664, +1664,1664,1664,1664,1664,1664,1664,1664,126,1,1,1,2,1,3844,3721,1359,1359,1359,1359, +1359,1359,1359,1359,1359,1359,1359,1359,1359,1359,1359,961,137,22,1084,1,2,1,2718,2718, +2718,2542,1664,1664,1664,1664,1664,1359,1359,1359,1359,1359,1359,1359,1359,130,21,899,887,2, +1,3187,3038,3038,1922,1922,1922,1922,1922,1922,1922,1664,116,35,1000,1,2,1,3187,3038, +3038,1664,1664,1664,1664,1664,1664,1664,1664,1664,1359,1359,121,24,853,887,2,1,3187,3038, +3038,1359,1359,1359,1359,1359,1359,1359,1359,1359,1359,1359,1359,1359,1359,961,961,961,129,32, +965,1,2,27,3844,3721,1359,1359,1359,1359,1359,1359,1359,1359,1359,1359,1359,1359,1359,1359, +961,961,961,143,26,627,152,887,2,1,3844,3721,1664,1664,1664,1664,1664,1664,1664,1664, +1664,1359,1359,146,27,884,887,2,1,1,1922,1664,1664,1664,1664,1664,1664,1664,1664,1664, +167,32,1126,1,2,28,3187,3038,3038,1664,1664,1664,1359,1359,1359,1359,1359,1359,1359,1359, +1359,1359,1359,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,18,33,1096,887,2,1,28, +1922,1664,1664,1664,1664,1664,1664,1664,1664,1664,22,137,176,177,177,177,177,177,176,176, +176,176,176,177,177,177,177,177,177,177,176,176,176,177,177,177,177,1,2,1, +1,1664,1359,1359,1359,1359,1359,1359,1359,1359,1359,1359,1359,1359,1359,1359,159,28,1208,1, +2,1,3844,3721,1359,1359,1359,1359,1359,1359,1359,1359,1359,1359,1359,1359,961,961,961,961, +961,961,961,179,35,1269,887,2,1,3844,3721,1664,1664,1664,1664,1664,1664,1664,1359,1359, +1359,1359,1359,177,22,920,1,2,21,3187,3038,3038,1664,1664,1664,1664,1664,1664,1664,1359, +1359,1359,1359,1359,226,29,919,887,2,1,1,1664,1664,1664,1664,1664,1664,1664,1664,1664, +1359,1359,146,39,640,887,2,24,3844,3721,1664,1664,1664,1664,1664,1359,1359,1359,1359,1359, +1359,1359,1359,169,1,176,176,176,177,177,177,176,177,177,177,129,1283,2,1,3187, +3038,3038,1359,1359,1359,1359,1359,1359,1359,1359,1359,1359,1359,1359,1359,1359,961,961,961,168, +1,1,1,2,29,3187,3038,3038,1664,1664,1664,1664,1664,1664,1664,1664,1664,1359,1359,168, +1,1339,1,2,1,3187,3038,3038,1664,1664,1664,1664,1664,1664,1664,1359,1359,1359,1359,1359, +138,29,744,1,2,1,1,1664,1664,1664,1664,1664,1664,1664,1664,1664,1359,1359,169,26, +1,1,2,1,3844,3721,1922,1664,1664,1664,1664,1664,1664,1664,1664,1664,169,34,701,1, +2,19,3844,3721,1664,1664,1664,1664,1664,1664,1664,1664,1664,1359,1359,169,1,1,682,2, +22,26,1922,1922,1922,1922,1664,1664,1664,1664,1664,168,1,1,774,2,27,1,1922,1922, +1922,1922,1664,1664,1664,1664,1664,168,1,1,774,2,1,3844,3721,1664,1664,1664,1664,1664, +1359,1359,1359,1359,1359,1359,1359,1359,168,1,176,177,176,177,176,176,177,176,123,193, +189,159,159,154,110,169,169,169,169,169,169,168,168,168,168,217,205,188,169,169, +169,191,198,46,167,386,2,137,156,153,102,216,133,126,119,214,213,147,159,158, +159,167,127,151,153,154,154,123,262,181,181,130,3,1,2542,2353,2353,2353,2353,1, +1,1,1,390,1,256,196,167,148,134,126,119,114,110,107,105,103,102,102,102, +102,102,103,105,107,110,114,119,126,134,148,167,196,256,1,0,-1); diff --git a/mapcode_fast_encode.php b/mapcode_fast_encode.php new file mode 100644 index 0000000..3e7d746 --- /dev/null +++ b/mapcode_fast_encode.php @@ -0,0 +1,717 @@ +