From 0cf5f41fda4c4a3bc53af6a59a1f835a52582057 Mon Sep 17 00:00:00 2001 From: Gregory Date: Wed, 3 May 2017 15:14:53 +0300 Subject: [PATCH 01/51] Fixed out_base bug Variable filename using in for tags uncompyle6 -o haven't worked argument -o haven't worked --- uncompyle6/main.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/uncompyle6/main.py b/uncompyle6/main.py index 4d72b4da..0bc8f80d 100644 --- a/uncompyle6/main.py +++ b/uncompyle6/main.py @@ -134,9 +134,9 @@ def main(in_base, out_base, files, codes, outfile=None, os.dup2(tee.stdin.fileno(), sys.stderr.fileno()) else: if filename.endswith('.pyc'): - outfile = os.path.join(out_base, filename[0:-1]) + outfileindir = os.path.join(out_base, filename[0:-1]) else: - outfile = os.path.join(out_base, filename) + '_dis' + outfileindir = os.path.join(out_base, filename) + '_dis' outstream = _get_outstream(outfile) # print(outfile, file=sys.stderr) From 93ec81673bef0586a3ab54941fc90916d2189652 Mon Sep 17 00:00:00 2001 From: Gregory Date: Wed, 3 May 2017 18:25:55 +0300 Subject: [PATCH 02/51] Some fix --- uncompyle6/main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/uncompyle6/main.py b/uncompyle6/main.py index 0bc8f80d..7d850316 100644 --- a/uncompyle6/main.py +++ b/uncompyle6/main.py @@ -137,7 +137,7 @@ def main(in_base, out_base, files, codes, outfile=None, outfileindir = os.path.join(out_base, filename[0:-1]) else: outfileindir = os.path.join(out_base, filename) + '_dis' - outstream = _get_outstream(outfile) + outstream = _get_outstream(outfileindir) # print(outfile, file=sys.stderr) # Try to uncompile the input file From dcaca278214aba57c328a896003b49b38ae0f46c Mon Sep 17 00:00:00 2001 From: rocky Date: Sat, 6 May 2017 07:25:01 -0400 Subject: [PATCH 03/51] fix PYTHON variable setting in test/Makefile --- test/Makefile | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/test/Makefile b/test/Makefile index 3d4f2ecb..6b997974 100644 --- a/test/Makefile +++ b/test/Makefile @@ -3,7 +3,7 @@ PHONY=check clean dist distclean test test-unit test-functional rmChangeLog clea GIT2CL ?= git2cl PYTHON ?= python -PYTHON_VERSION = $(shell $(PYTHON) -V | cut -d ' ' -f 2 | cut -d'.' -f1,2) +PYTHON_VERSION = $(shell $(PYTHON) -V 2>&1 | cut -d ' ' -f 2 | cut -d'.' -f1,2) NATIVE_CHECK = check-$(PYTHON_VERSION) # Set COMPILE='--compile' to force compilation before check @@ -16,11 +16,10 @@ check-short: # Run all tests check: - @$(PYTHON) -V && PYTHON_VERSION=`$(PYTHON) -V 2>&1 | cut -d ' ' -f 2 | cut -d'.' -f1,2`; \ - $(MAKE) check-$$PYTHON_VERSION + $(MAKE) check-$(PYTHON_VERSION) #: Run working tests from Python 2.6 or 2.7 -check-2.6 check-2.7: check-bytecode-2 check-bytecode-3 check-bytecode-1 check-2.7-ok +check-2.6 check-2.7: check-bytecode-2 check-bytecode-3 check-bytecode-1 check-native-short #: Run working tests from Python 3.0 check-3.0: check-bytecode From 1093ef5c5bbbb8487f4a75b51f36638863419f75 Mon Sep 17 00:00:00 2001 From: rocky Date: Sat, 6 May 2017 07:26:37 -0400 Subject: [PATCH 04/51] Get ready for release 2.9.11 --- ChangeLog | 667 ++++++++++++++---- NEWS | 6 + ...t_and.pyc => 06_list_ifnot_and.pyc-notyet} | Bin uncompyle6/version.py | 2 +- 4 files changed, 538 insertions(+), 137 deletions(-) rename test/bytecode_2.6/{06_list_ifnot_and.pyc => 06_list_ifnot_and.pyc-notyet} (100%) diff --git a/ChangeLog b/ChangeLog index 7887193c..c3ecbc04 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,402 @@ +2017-05-06 rocky + + * uncompyle6/version.py: Get ready for release 2.9.11 + +2017-05-06 rocky + + * test/Makefile: fix PYTHON variable setting in test/Makefile + +2017-05-06 rocky + + * test/simple_source/bug32/01_try_except_raise.py, + test/simple_source/bug32/03_if.py, uncompyle6/parsers/parse32.py, + uncompyle6/parsers/parse33.py: Fix more Python3.2 parser errors + +2017-05-05 rocky + + * uncompyle6/parsers/parse32.py, uncompyle6/scanners/scanner3.py: + Improve Python 3.2 decompilation ... by removing a lot of the control-flow labels of 3.3+ + +2017-05-05 rocky + + * .travis.yml: Try CI testing on Python 3.6 + +2017-05-02 rocky + + * test/simple_source/bug35/01_map_unpack.py, uncompyle6/parser.py, + uncompyle6/parsers/parse3.py, uncompyle6/parsers/parse35.py, + uncompyle6/semantics/pysource.py: Bang more on BUIlD_MAP_UNPACK there are still bugs. Note: {**{'x': 1}, **{'y': 2}} and {{'x': 1}, **{'y': 2}} generate the same Python 3.5+ bytecode. + +2017-05-02 rocky + + * test/simple_source/bug35/01_map_unpack.py, uncompyle6/parser.py, + uncompyle6/parsers/parse3.py, uncompyle6/parsers/parse35.py: + BUILD_MAP_UNPACK'ing of dictionaries in 3.5 + +2017-05-01 rocky + + * uncompyle6/semantics/pysource.py: Remove extra unpack *. Issue #98 + +2017-04-29 R. Bernstein + + * HISTORY.md: Update HISTORY.md + +2017-04-29 rocky + + * test/simple_source/bug35/01_map_unpack.py, + uncompyle6/parsers/parse35.py, uncompyle6/semantics/pysource.py: + Handle BUILD_MAP_UNPACK in a build_list + +2017-04-27 rocky + + * uncompyle6/semantics/pysource.py: A hacky way to get + CALL_FUNCTION_EX_KW to work. + +2017-04-26 rocky + + * uncompyle6/semantics/pysource.py: remove debug code + +2017-04-25 rocky + + * test/simple_source/bug36/01_call_function.py, + uncompyle6/parsers/parse36.py, uncompyle6/scanners/scanner36.py, + uncompyle6/semantics/pysource.py: Python 3.6 CALL_FUNCTION_EX first + attempt + +2017-04-22 rocky + + * uncompyle6/parser.py, uncompyle6/parsers/parse34.py: Reduse scope + of LOAD_ASSERT as expr to 3.4+ + +2017-04-22 rocky + + * uncompyle6/parser.py, uncompyle6/verify.py: LOAD_ASSERT can also + be an expr This may have the undesirable property that assert statements might + get tagged with equivalant low-level Python code that uses "raise + AssertionError", but so be it. Fixes #103 + +2017-04-22 R. Bernstein + + * HISTORY.md: Update HISTORY.md + +2017-04-22 R. Bernstein + + * HISTORY.md: Update HISTORY.md + +2017-04-22 rocky + + * history.md: history keeps gettting amended + +2017-04-22 rocky + + * readme.rst: document python 3.x status + +2017-04-22 rocky + + * test/simple_source/bug35/03_async_await.py, + uncompyle6/parsers/parse35.py, uncompyle6/semantics/pysource.py: add + await expr fixes #111 + +2017-04-22 rocky + + * : update test + +2017-04-22 rocky + + * test/simple_source/bug33/02_pos_args.py, + uncompyle6/parsers/parse3.py, uncompyle6/semantics/make_function.py: + 3.3+ bug in handling single kwarg after * towards fixing issue #110 + +2017-04-20 rocky + + * test/simple_source/bug35/02_async_for.py, + uncompyle6/parsers/parse35.py: add async for with pass statement fixes #109 + +2017-04-19 rocky + + * test/simple_source/bug35/03_while-if-break.py, + uncompyle6/parsers/parse3.py: 3.5 ifelsestmtl grammar bug. fixes #108 + +2017-04-18 rocky + + * test/simple_source/bug35/03_async_await.py, + uncompyle6/parsers/parse35.py: expand await stmt handling fixes #107 + +2017-04-18 rocky + + * test/simple_source/bug33/01_delete_deref.py, + uncompyle6/parsers/parse32.py, uncompyle6/semantics/pysource.py: add + delete_deref grammar rule fixes issue #106 + +2017-04-17 rocky + + * test/simple_source/bug36/01_extended_arg.py, + test/simple_source/bug36/01_if_file.py: rename test case to + something more appropriate + +2017-04-17 rocky + + * test/simple_source/bug36/01_if_file.py: fix botched test case thanks to zm908 for pointing this out + +2017-04-16 rocky + + * uncompyle6/parsers/parse3.py: comment on what's up with last + change + +2017-04-16 rocky + + * test/simple_source/bug22/03_if1.py, + test/simple_source/bug31/02_ifelse_comprehension.py, + uncompyle6/parsers/parse3.py: python 3.x ifelse in comprehension fixes issue #91 + +2017-04-16 rocky + + * : add 2.7 complex test + +2017-04-15 rocky + + * test/simple_source/bug35/01_map_unpack.py, + uncompyle6/semantics/pysource.py: correct bug in 3.5+ build_list + with unpack + +2017-04-15 r. bernstein + + * how-to-report-a-bug.md: update how-to-report-a-bug.md + +2017-04-15 r. bernstein + + * how-to-report-a-bug.md: update how-to-report-a-bug.md + +2017-04-15 rocky + + * test/simple_source/bug36/01_if_file.py, + uncompyle6/parsers/parse36.py: 3.6 generates wonky extended_arg in + expression fixes issue #102 + +2017-04-15 rocky + + * how-to-report-a-bug.md, manifest.in: add how to report a bug add test case for ... if 1 else ... + +2017-04-14 rocky + + * test/simple_source/bug35/01_map_unpack.py, + uncompyle6/parsers/parse3.py, uncompyle6/parsers/parse35.py, + uncompyle6/semantics/pysource.py: python 3.5+ build_unmap_pack rules towards addressing issue #98 + +2017-04-14 rocky + + * uncompyle6/scanners/scanner3.py: reduce adding return_end_if in + 3.5+ the whole control flow determination has to be redone in a less + haphazard way using real flow-control analysis. hopefully that's on + the way. in the meantime we have this hack. + +2017-04-14 rocky + + * test/simple_source/bug27+/03_if_1_else.py, + test/simple_source/bug27+/03_if_true_else.py: better names for a + test + +2017-04-13 rocky + + * test/simple_source/bug27+/03_if_true_else.py, + uncompyle6/parser.py, uncompyle6/parsers/parse3.py, + uncompyle6/semantics/consts.py: add if1else. fixes #101 + +2017-04-13 rocky + + * uncompyle6/parsers/parse3.py: in 3.x come_from should include + come_from_except + +2017-04-13 rocky + + * uncompyle6/parsers/parse35.py: towards fixing issue #92 + +2017-04-13 rocky + + * uncompyle6/parsers/parse23.py, uncompyle6/semantics/pysource.py: + add python 2.3 rule for "if 1: ..." fully fixes #97 for python 2.3. python 2.4 was fixed in a previous + commit. + +2017-04-12 rocky + + * uncompyle6/parsers/parse3.py, + uncompyle6/semantics/make_function.py: annotate args type need to be + expr's not constants + +2017-04-12 rocky + + * uncompyle6/parsers/parse24.py: handle python 2.4 "if 1...." + +2017-04-11 rocky + + * test/simple_source/bug31/04_def_annotate.py, + uncompyle6/semantics/fragments.py, + uncompyle6/semantics/make_function.py: bang on 3.x annotations + +2017-04-11 rocky + + * test/simple_source/bug31/04_def_annotate.py, + uncompyle6/parsers/parse3.py, uncompyle6/semantics/pysource.py: + towards fixing annotated decorator functions... and annotate functions + +2017-04-10 rocky + + * uncompyle6/parsers/parse2.py, uncompyle6/scanners/scanner27.py, + uncompyle6/semantics/check_ast.py, uncompyle6/semantics/pysource.py: + misc bugs parse2.py: restore accidently-removed while1stmt rule scanner27.py: + grammar typo check_ast: add while1else to list of looping constructs + pysource.py: call_function_var_kw_args with positional args rule is + different? + +2017-04-10 rocky + + * test/simple_source/stmts/02_while1else.py, + uncompyle6/parsers/parse2.py, uncompyle6/parsers/parse3.py, + uncompyle6/parsers/parse35.py: add more while1else grammar rules towards addressing issue #93 + +2017-04-09 rocky + + * : one more function_var test for 3.3 + +2017-04-09 rocky + + * test/simple_source/def/10_kw+pos_args-bug.py, + uncompyle6/parsers/parse3.py, uncompyle6/semantics/pysource.py: + another python 3.5 function_var bug fixes #94 + +2017-04-09 rocky + + * : commit 4199bc7f617e387fb03fc06939cd17366dc15c5e author: rocky + date: sun apr 9 05:30:45 2017 -0400 + +2017-04-03 rocky + + * : commit 6773a66b99d07e48290a77dbbbe3c71cc39c31ba author: rocky + date: mon apr 3 06:53:12 2017 -0400 + +2017-03-27 rocky + + * : commit a91cd716670be09d3cef34e1bb36a67f96f91712 author: rocky + date: mon mar 27 07:08:59 2017 -0400 + +2017-03-19 rocky + + * __pkginfo__.py: use more-recent xdis + +2017-03-15 rocky + + * history.md, test/simple_source/bug33/01_if_try_except.py: grammar + typo and add another test + +2017-03-12 rocky + + * uncompyle6/scanners/scanner3.py: python 3.0 doesn't have + pop_jump_if... + +2017-03-12 rocky + + * readme.rst: note problem in handling pathologically long lists + +2017-03-07 rocky + + * uncompyle6/scanners/scanner3.py: small cleanup - remove + pop_jump_tf + +2017-03-05 rocky + + * pytest/test_grammar.py, uncompyle6/parsers/parse3.py, + uncompyle6/parsers/parse33.py, uncompyle6/scanners/scanner3.py: more + accurate ranges of try blocks in 3.x + +2017-03-05 rocky + + * test/simple_source/bug33/01_try_except.py: more accurate ranges of + try blocks in 3.x + +2017-03-04 r. bernstein + + * : merge pull request #84 from + moagstar/property_based_test_function_call property based test function call + +2017-03-04 rocky + + * readme.rst: readme updates for 3.5 and 1.5 + +2017-03-04 rocky + + * test/simple_source/bug32/01_named_and_kwargs.py, + uncompyle6/parsers/parse3.py: bug found by hypothesis in creating + function calls + +2017-03-04 daniel bradburn + + * pytest/test_function_call.py: marked all function call tests as + failing until they pass across all python versions + +2017-03-04 daniel bradburn + + * pytest/test_function_call.py: added minimal examples for various + function call opcodes + +2017-03-04 daniel bradburn + + * pytest/test_function_call.py: added property based test for + verifying uncompylation of function calls. a number of minimal + examples for the various function call opcodes have been generated + with the majority marked as expected failure until python 3.6 opcode + support is complete. i'm hoping this will make it easier to figure + out what needs to be done to support the new opcodes and changed + semntics for function calls + +2017-03-03 daniel bradburn + + * pytest/test_function_call.py: reduced errors when generating + function call instances + +2017-03-03 daniel bradburn + + * pytest/test_function_call.py: added test file for function calls + +2017-03-03 daniel bradburn + + * .gitignore: added .idea to gitignore + +2017-03-03 daniel bradburn + + * .gitignore: added .venv to gitignore + +2017-03-01 rocky + + * uncompyle6/scanner.py, uncompyle6/scanners/scanner2.py, + uncompyle6/scanners/scanner3.py, uncompyle6/verify.py: come_from for + 3.x pop_except, dry with op_name() ... start adding come_froms for pop_except in preparation for getting + tryelse blocks correct. simpler opname access functions: - self.op_name(op) is self.opc.opname[op] - self.op_name_from_offset(offset) is + self.opc.opname[self.code[offset]] verify.py: not all offsets are ints + +2017-02-28 rocky + + * readme.rst, uncompyle6/parser.py, uncompyle6/parsers/parse26.py: + python 2.6 a == b or c == d == 3 grammar bug + +2017-02-28 rocky + + * : 2.6 a == b or x == y == z bug + +2017-02-28 rocky + + * test/simple_source/bug26/03_double_equals.py, + uncompyle6/semantics/consts.py: predidence of cmp_list: x == y == z the x, y, z should not have parenthesis around pairs of them (x == + y) or (y == z) + +2017-02-28 rocky + + * uncompyle6/parser.py, uncompyle6/parsers/parse27.py: python 2.7 + check jump targets of "and" + 2017-02-25 rocky - * uncompyle6/version.py: Get ready for release 2.9.10 + * ChangeLog, NEWS, __pkginfo__.py, uncompyle6/version.py: Get ready + for release 2.9.10 2017-02-25 rocky @@ -30,7 +426,7 @@ 2017-02-20 rocky - * uncompyle6/parsers/parse3.py, uncompyle6/parsers/parse35.py: + * uncompyle6/parsers/parse3.py, uncompyle6/parsers/parse35.py: Python 3.x needs more "while 1" grammar rules 2017-02-20 rocky @@ -160,7 +556,7 @@ 2017-01-15 rocky - * uncompyle6/parsers/parse3.py, uncompyle6/scanners/scanner3.py: + * uncompyle6/parsers/parse3.py, uncompyle6/scanners/scanner3.py: Handle 3.6 BUILD_CONST_KEYMAP 2017-01-15 rocky @@ -193,7 +589,7 @@ 2017-01-10 rocky * test/simple_source/bug35/03_double_star_unpack.py, - uncompyle6/parsers/parse3.py, uncompyle6/semantics/pysource.py: + uncompyle6/parsers/parse3.py, uncompyle6/semantics/pysource.py: Improve BUILD_xxx_UNPACK slightly 2017-01-09 rocky @@ -212,7 +608,7 @@ 2017-01-08 rocky - * uncompyle6/parsers/parse30.py, uncompyle6/scanners/scanner3.py: + * uncompyle6/parsers/parse30.py, uncompyle6/scanners/scanner3.py: Python 3.0 decompile bugs 2017-01-08 rocky @@ -243,7 +639,7 @@ 2017-01-07 rocky * test/simple_source/bug35/03_async_await.py, - uncompyle6/parsers/parse35.py, uncompyle6/semantics/pysource.py: + uncompyle6/parsers/parse35.py, uncompyle6/semantics/pysource.py: Start to add 3.5+ await and async 2017-01-07 rocky @@ -280,7 +676,7 @@ 2017-01-02 rocky - * uncompyle6/parsers/parse35.py, uncompyle6/scanners/scanner3.py: + * uncompyle6/parsers/parse35.py, uncompyle6/scanners/scanner3.py: Python 3.5 continue detection bug 2017-01-01 rocky @@ -290,7 +686,7 @@ 2017-01-01 rocky - * uncompyle6/parsers/parse35.py, uncompyle6/scanners/scanner3.py: + * uncompyle6/parsers/parse35.py, uncompyle6/scanners/scanner3.py: Towards fixing Python 3.5 return bugs 2017-01-01 rocky @@ -317,12 +713,12 @@ 2016-12-29 rocky - * uncompyle6/scanners/scanner2.py, uncompyle6/scanners/scanner3.py: + * uncompyle6/scanners/scanner2.py, uncompyle6/scanners/scanner3.py: dectect_structure() -> detect_control_flow() 2016-12-29 rocky - * uncompyle6/scanners/scanner2.py, uncompyle6/scanners/scanner3.py: + * uncompyle6/scanners/scanner2.py, uncompyle6/scanners/scanner3.py: DRY code and emitted Python 3 source * Python 3: break; continue -> break * Use variable in detect_structure for pre[rtarget] * Make Python 2 and Python 3 detect_structure more alie 2016-12-29 rocky @@ -359,7 +755,7 @@ 2016-12-27 rocky * uncompyle6/parsers/parse26.py, uncompyle6/scanners/scanner2.py, - uncompyle6/scanners/scanner26.py, uncompyle6/semantics/pysource.py: + uncompyle6/scanners/scanner26.py, uncompyle6/semantics/pysource.py: WIP : Add THEN to disambigute from "and" 2016-12-27 rocky @@ -404,7 +800,7 @@ uncompyle6/parsers/parse36.py, uncompyle6/scanners/scanner15.py, uncompyle6/scanners/scanner2.py, uncompyle6/scanners/scanner21.py, uncompyle6/scanners/scanner22.py, - uncompyle6/semantics/fragments.py, uncompyle6/semantics/pysource.py: + uncompyle6/semantics/fragments.py, uncompyle6/semantics/pysource.py: Lint 2016-12-24 rocky @@ -421,7 +817,7 @@ * uncompyle6/bin/pydisassemble.py, uncompyle6/bin/uncompile.py, uncompyle6/parsers/parse2.py, uncompyle6/parsers/parse25.py, uncompyle6/parsers/parse27.py, uncompyle6/parsers/parse3.py, - uncompyle6/scanners/scanner2.py, uncompyle6/scanners/scanner3.py: + uncompyle6/scanners/scanner2.py, uncompyle6/scanners/scanner3.py: Python flake8 crap Was testing realgud's C-x!8 (goto flake8 warning/error) 2016-12-18 rocky @@ -432,7 +828,7 @@ 2016-12-17 rocky - * uncompyle6/scanners/scanner2.py, uncompyle6/scanners/scanner25.py: + * uncompyle6/scanners/scanner2.py, uncompyle6/scanners/scanner25.py: show-asm on python2.5 is optional make scanner2 look a little more like scanner3 2016-12-16 rocky @@ -521,7 +917,7 @@ 2016-11-28 rocky - * uncompyle6/parsers/parse3.py, uncompyle6/parsers/parse36.py: + * uncompyle6/parsers/parse3.py, uncompyle6/parsers/parse36.py: Shorten Python3 grammars with + and * 2016-11-28 rocky @@ -560,7 +956,7 @@ 2016-11-24 rocky * uncompyle6/parsers/parse27.py, uncompyle6/scanners/scanner2.py, - uncompyle6/semantics/helper.py, uncompyle6/semantics/pysource.py: + uncompyle6/semantics/helper.py, uncompyle6/semantics/pysource.py: 2.7 grammar bug workaround. Fix docstring bug 2016-11-24 rocky @@ -570,7 +966,7 @@ 2016-11-24 rocky - * uncompyle6/parsers/parse3.py, uncompyle6/scanners/scanner2.py: + * uncompyle6/parsers/parse3.py, uncompyle6/scanners/scanner2.py: <2.7 "if" detection and dup Python 3 grammar rule 2016-11-23 rocky @@ -653,7 +1049,7 @@ 2016-11-20 rocky * pytest/test_fjt.py, uncompyle6/scanners/scanner2.py, - uncompyle6/scanners/scanner26.py, uncompyle6/scanners/scanner3.py: + uncompyle6/scanners/scanner26.py, uncompyle6/scanners/scanner3.py: Start to improve detect_structure for 2.7 and 2.x Add debug flag to find_jump_targets to show the structure we found. When there are control-flow bugs, it's often reflected here. scanner3.py: make code make more similar to 2.x code @@ -669,7 +1065,7 @@ 2016-11-16 rocky * test/simple_source/bug26/03_if_vs_and.py, uncompyle6/main.py, - uncompyle6/semantics/check_ast.py, uncompyle6/semantics/pysource.py: + uncompyle6/semantics/check_ast.py, uncompyle6/semantics/pysource.py: More AST checking Small fixes in output format 2016-11-15 rocky @@ -689,17 +1085,17 @@ 2016-11-14 rocky - * uncompyle6/parsers/parse26.py, uncompyle6/scanners/scanner2.py: + * uncompyle6/parsers/parse26.py, uncompyle6/scanners/scanner2.py: WIP remove COME_FROMs around ignore_if's 2016-11-14 rocky - * uncompyle6/parsers/parse26.py, uncompyle6/scanners/scanner2.py: + * uncompyle6/parsers/parse26.py, uncompyle6/scanners/scanner2.py: WIP remove COME_FROMs around ignore_if's 2016-11-14 rocky - * uncompyle6/scanners/scanner2.py, uncompyle6/scanners/scanner26.py: + * uncompyle6/scanners/scanner2.py, uncompyle6/scanners/scanner26.py: Show line numbers in 2.6 "after" asm .. start to understand some of the Python 2.6 bytecode parse failures. 2016-11-13 rocky @@ -735,7 +1131,7 @@ 2016-11-11 rocky * uncompyle6/parser.py, uncompyle6/semantics/check_ast.py, - uncompyle6/semantics/fragments.py, uncompyle6/semantics/pysource.py: + uncompyle6/semantics/fragments.py, uncompyle6/semantics/pysource.py: Revert augassign change but.. Make note of what's going on and add grammar test for bad situations we have in Python 2.6 (and perhaps others) @@ -755,7 +1151,7 @@ 2016-11-10 rocky * uncompyle6/main.py, uncompyle6/semantics/check_ast.py, - uncompyle6/semantics/fragments.py, uncompyle6/semantics/pysource.py: + uncompyle6/semantics/fragments.py, uncompyle6/semantics/pysource.py: Detect some erroneous decompilations Until we can actually prevent these in grammar rules, we will warn of improper decompilations. Also, we now stop when we hit a decompile error. Previously we were not. @@ -822,7 +1218,7 @@ 2016-10-30 rocky - * .gitignore, README.rst, test/simple_source/def/03_class_method.py: + * .gitignore, README.rst, test/simple_source/def/03_class_method.py: Note github unpyc3 and.. - Add source to bytecode_2.2/03_class_method.pyc - more ignore 2016-10-30 rocky @@ -851,20 +1247,20 @@ * pytest/test_grammar.py, uncompyle6/parsers/parse3.py, uncompyle6/parsers/parse31.py, uncompyle6/parsers/parse32.py, - uncompyle6/parsers/parse35.py, uncompyle6/semantics/pysource.py: + uncompyle6/parsers/parse35.py, uncompyle6/semantics/pysource.py: More complete annotate handling Still have a bit of work to do though. 2016-10-28 rocky * pytest/test_grammar.py, uncompyle6/parsers/parse3.py, uncompyle6/parsers/parse32.py, uncompyle6/parsers/parse33.py, - uncompyle6/parsers/parse34.py, uncompyle6/semantics/pysource.py: + uncompyle6/parsers/parse34.py, uncompyle6/semantics/pysource.py: Expand annotate return to Python 3.4 2016-10-28 rocky * pytest/test_grammar.py, uncompyle6/parsers/parse31.py, - uncompyle6/parsers/parse32.py, uncompyle6/semantics/pysource.py: + uncompyle6/parsers/parse32.py, uncompyle6/semantics/pysource.py: Expand annotate handling to 3.3 (and possibly 3.2) - DRY Python 3.1-3.3 grammar a little 2016-10-28 rocky @@ -878,7 +1274,7 @@ * test/simple_source/bug31/04_def_annotate.py, test/simple_source/bug31/04_def_attr.py, - uncompyle6/parsers/parse31.py, uncompyle6/semantics/pysource.py: + uncompyle6/parsers/parse31.py, uncompyle6/semantics/pysource.py: Clean and fix Python 3 annotate arg return 2016-10-26 rocky @@ -953,7 +1349,7 @@ 2016-10-20 moagstar * pytest/test_fstring.py, uncompyle6/parsers/parse3.py, - uncompyle6/parsers/parse36.py, uncompyle6/semantics/pysource.py: + uncompyle6/parsers/parse36.py, uncompyle6/semantics/pysource.py: further work on supporting single and multiple fstring decompilation 2016-10-20 rocky @@ -964,7 +1360,7 @@ 2016-10-19 moagstar * pytest/test_fstring.py, uncompyle6/parsers/parse3.py, - uncompyle6/parsers/parse36.py, uncompyle6/semantics/pysource.py: + uncompyle6/parsers/parse36.py, uncompyle6/semantics/pysource.py: urther work on fstrings for python 3.6 - there is a new opcode build_string which is used to improve fstring performance, but broke the fstring support in uncompyle @@ -1152,13 +1548,13 @@ 2016-10-05 rocky * uncompyle6/parser.py, uncompyle6/parsers/parse2.py, - uncompyle6/parsers/parse3.py, uncompyle6/scanners/scanner3.py: + uncompyle6/parsers/parse3.py, uncompyle6/scanners/scanner3.py: Python 3: "and" doesn't have optional come_from 2016-10-05 rocky * uncompyle6/parser.py, uncompyle6/parsers/parse2.py, - uncompyle6/parsers/parse3.py, uncompyle6/scanners/scanner3.py: + uncompyle6/parsers/parse3.py, uncompyle6/scanners/scanner3.py: Python 3: "and" doesn't have optional come_from 2016-10-05 rocky @@ -1188,7 +1584,7 @@ 2016-09-26 rocky * HISTORY.md, uncompyle6/parser.py, uncompyle6/parsers/parse2.py, - uncompyle6/parsers/parse3.py, uncompyle6/scanners/scanner3.py: + uncompyle6/parsers/parse3.py, uncompyle6/scanners/scanner3.py: Interval order COME_FROMs in Python3 This bug had possibly caused lots of grammar pollution which may need addressing. We want to process COME_FROMs to the same offset to be in *descending* order so we have the larger range or biggest @@ -1273,7 +1669,7 @@ 2016-09-21 rocky - * uncompyle6/scanners/scanner2.py, uncompyle6/scanners/scanner26.py: + * uncompyle6/scanners/scanner2.py, uncompyle6/scanners/scanner26.py: Python 2 & 3 scanner code ever so slightly closer 2016-09-21 rocky @@ -1283,7 +1679,7 @@ 2016-09-18 rocky * uncompyle6/scanners/scanner2.py, - uncompyle6/scanners/scanner26.py, uncompyle6/semantics/pysource.py: + uncompyle6/scanners/scanner26.py, uncompyle6/semantics/pysource.py: Small changes 2016-09-11 rocky @@ -1294,7 +1690,7 @@ 2016-09-11 rocky * test/bytecode_3.6/fstring.py, - test/bytecode_3.6/fstring_single.py, uncompyle6/parsers/parse35.py: + test/bytecode_3.6/fstring_single.py, uncompyle6/parsers/parse35.py: Tidy a bit 2016-09-09 rocky @@ -1308,7 +1704,7 @@ 2016-09-09 rocky - * uncompyle6/scanners/scanner2.py, uncompyle6/semantics/pysource.py: + * uncompyle6/scanners/scanner2.py, uncompyle6/semantics/pysource.py: ret_cond adjustment for < 2.7 and ... "<= 2.6" -> "< 2.7" since python 2.6's version is 2.6000001 2016-09-09 rocky @@ -1330,7 +1726,7 @@ 2016-09-08 rocky - * uncompyle6/parsers/parse3.py, uncompyle6/semantics/pysource.py: + * uncompyle6/parsers/parse3.py, uncompyle6/semantics/pysource.py: Python 3.0-3.2 *args processing 2016-09-08 rocky @@ -1366,7 +1762,7 @@ * uncompyle6/parsers/parse2.py, uncompyle6/parsers/parse26.py, uncompyle6/parsers/parse27.py, uncompyle6/scanners/scanner2.py, - uncompyle6/scanners/scanner26.py, uncompyle6/scanners/scanner3.py: + uncompyle6/scanners/scanner26.py, uncompyle6/scanners/scanner3.py: Python 2.6- try/except control flow detection 2016-09-04 rocky @@ -1441,19 +1837,19 @@ 2016-09-02 rocky * test/simple_source/bug26/06_return_pop.py, - uncompyle6/parsers/parse26.py, uncompyle6/scanners/scanner2.py: + uncompyle6/parsers/parse26.py, uncompyle6/scanners/scanner2.py: Python 2.6- bug: RETURN_ENDIF, POP_TOP .. POP_TOP should be excluded as a potentional statement beginning 2016-09-02 rocky * test/simple_source/bug33/02_named_and_kwargs.py, - uncompyle6/scanners/scanner2.py, uncompyle6/semantics/pysource.py: + uncompyle6/scanners/scanner2.py, uncompyle6/semantics/pysource.py: Fix Python 3.x named param and kwargs bug 2016-09-01 rocky * test/simple_source/bug26/04_while_and_stmt_one_line.py, - uncompyle6/scanners/scanner2.py, uncompyle6/scanners/scanner26.py: + uncompyle6/scanners/scanner2.py, uncompyle6/scanners/scanner26.py: 2.6- bug: while..and: stmt - on one line If 2.6 or before POP_BLOCK after a JUMP_IF_FALSE does not constitute a new statement. The POP_BLOCK is really part of the JUMP_IF_FALSE. In Python 2.7+ it's a single op. @@ -1461,7 +1857,7 @@ 2016-09-01 rocky * test/simple_source/bug26/02_except_as.py, - uncompyle6/parsers/parse26.py, uncompyle6/semantics/pysource.py: + uncompyle6/parsers/parse26.py, uncompyle6/semantics/pysource.py: Handle Python 2.6 and below "except , " 2016-08-31 rocky @@ -1603,7 +1999,7 @@ * README.rst, uncompyle6/parser.py, uncompyle6/parsers/parse22.py, uncompyle6/scanner.py, uncompyle6/scanners/scanner22.py, uncompyle6/scanners/scanner23.py, uncompyle6/scanners/scanner24.py, - uncompyle6/scanners/scanner25.py, uncompyle6/semantics/pysource.py: + uncompyle6/scanners/scanner25.py, uncompyle6/semantics/pysource.py: Start handling Python 2.2 bytecode and... Fix some bugs in Python 2.3-2.5 bytecode handling 2016-08-11 Omer Katz @@ -1672,7 +2068,7 @@ 2016-07-29 rocky * uncompyle6/parsers/parse35.py, uncompyle6/scanner.py, - uncompyle6/scanners/scanner3.py, uncompyle6/semantics/pysource.py: + uncompyle6/scanners/scanner3.py, uncompyle6/semantics/pysource.py: Fix 3.5 misclassifying RETURN_VALUE We use location of SETUP_EXCEPT instructions to disambiguate. 2016-07-28 Daniel Bradburn @@ -1771,7 +2167,7 @@ 2016-07-27 rocky - * uncompyle6/parsers/parse2.py, uncompyle6/semantics/pysource.py: + * uncompyle6/parsers/parse2.py, uncompyle6/semantics/pysource.py: Small code clean up 2016-07-26 rocky @@ -1799,7 +2195,7 @@ test/simple_source/bug_pypy27/03_try_return.py, uncompyle6/parser.py, uncompyle6/parsers/parse2.py, uncompyle6/parsers/parse27.py, uncompyle6/scanners/scanner2.py, - uncompyle6/scanners/scanner3.py, uncompyle6/semantics/pysource.py: + uncompyle6/scanners/scanner3.py, uncompyle6/semantics/pysource.py: More PyPy grammar rules * assert one and two-arg form * trystmt Simplify adding multiple grammar rules 2016-07-25 rocky @@ -1861,7 +2257,7 @@ * README.rst, test/simple_source/stmts/03_if_elif.py, uncompyle6/parsers/parse2.py, uncompyle6/parsers/parse27.py, uncompyle6/parsers/parse3.py, uncompyle6/scanners/scanner2.py, - uncompyle6/scanners/scanner3.py, uncompyle6/semantics/pysource.py: + uncompyle6/scanners/scanner3.py, uncompyle6/semantics/pysource.py: Handle PyPy JUMP_IF_NOT_DEBUG Update README.rst to note PyPY and reorganize a little 2016-07-25 rocky @@ -1883,7 +2279,7 @@ test/Makefile, test/test_pythonlib.py, uncompyle6/parsers/parse2.py, uncompyle6/parsers/parse3.py, uncompyle6/scanner.py, uncompyle6/scanners/scanner2.py, - uncompyle6/scanners/scanner3.py, uncompyle6/semantics/pysource.py: + uncompyle6/scanners/scanner3.py, uncompyle6/semantics/pysource.py: PyPy support * Use proper PYPY 32 opcodes * handle opcodes LOOKUP_METHOD and CALL_METHOD * Administrative stuff for PyPy 2016-07-24 Daniel Bradburn @@ -1903,19 +2299,19 @@ 2016-07-23 rocky * test/simple_source/bug27+/05_for_try_except.py, - uncompyle6/scanners/scanner2.py, uncompyle6/scanners/scanner27.py: + uncompyle6/scanners/scanner2.py, uncompyle6/scanners/scanner27.py: Another 2.7 'continue' detection bug 2016-07-23 rocky * test/simple_source/bug27+/05_for_try_except.py, - uncompyle6/scanners/scanner2.py, uncompyle6/scanners/scanner27.py: + uncompyle6/scanners/scanner2.py, uncompyle6/scanners/scanner27.py: Another 2.7 'continue' detection bug 2016-07-23 rocky * test/simple_source/bug27+/05_for_try_except.py, - uncompyle6/scanners/scanner2.py, uncompyle6/scanners/scanner27.py: + uncompyle6/scanners/scanner2.py, uncompyle6/scanners/scanner27.py: Another 2.7 'continue' detection bug 2016-07-23 rocky @@ -1964,7 +2360,7 @@ 2016-07-17 rocky - * pytest/testdata/if-2.7.right, pytest/testdata/ifelse-2.7.right: + * pytest/testdata/if-2.7.right, pytest/testdata/ifelse-2.7.right: Adjust test data for changed disasm output 2016-07-16 rocky @@ -1998,7 +2394,7 @@ 2016-07-14 rocky - * uncompyle6/parsers/parse3.py, uncompyle6/semantics/pysource.py: + * uncompyle6/parsers/parse3.py, uncompyle6/semantics/pysource.py: Attempt to get 3.5 RETURN_END_IF working This feels hacky and I'm not sure is quite right. Untili we understand better what to do though, we'll go with it. @@ -2069,7 +2465,7 @@ * test/simple_source/bug33/05_store_name.py, test/simple_source/comprehension/05_3x_set_comphension.py, - uncompyle6/parsers/parse3.py, uncompyle6/semantics/pysource.py: + uncompyle6/parsers/parse3.py, uncompyle6/semantics/pysource.py: Python 3.2 & 3.3 handle STORE_NAME better 2016-07-11 rocky @@ -2124,13 +2520,13 @@ 2016-07-10 rocky - * uncompyle6/parsers/parse3.py, uncompyle6/scanners/scanner3.py: + * uncompyle6/parsers/parse3.py, uncompyle6/scanners/scanner3.py: Bugs caused by 3.x jump_forward misclasification 2016-07-10 rocky * uncompyle6/parsers/parse3.py, uncompyle6/scanners/scanner2.py, - uncompyle6/scanners/scanner26.py, uncompyle6/scanners/scanner3.py: + uncompyle6/scanners/scanner26.py, uncompyle6/scanners/scanner3.py: Python 3 better CONTINUE op classification Also document what's up with JUMP_ABSOLUTE classification 2016-07-09 rocky @@ -2221,7 +2617,7 @@ * uncompyle6/scanners/scanner3.py, uncompyle6/scanners/scanner32.py, uncompyle6/scanners/scanner33.py, - uncompyle6/scanners/scanner34.py, uncompyle6/scanners/scanner35.py: + uncompyle6/scanners/scanner34.py, uncompyle6/scanners/scanner35.py: Python 3 code cleanup 2016-07-08 rocky @@ -2242,7 +2638,7 @@ 2016-07-08 rocky * uncompyle6/parsers/parse24.py, uncompyle6/scanners/scanner2.py, - uncompyle6/scanners/scanner24.py, uncompyle6/scanners/scanner26.py: + uncompyle6/scanners/scanner24.py, uncompyle6/scanners/scanner26.py: Python 2.4 generator expressions and gen_comp_body 2016-07-08 rocky @@ -2268,12 +2664,12 @@ 2016-07-08 rocky * test/simple_source/stmts/11_return_val.py, - uncompyle6/scanners/scanner2.py, uncompyle6/scanners/scanner26.py: + uncompyle6/scanners/scanner2.py, uncompyle6/scanners/scanner26.py: 2.5/2.6 RETURN_VALUE bug 2016-07-08 rocky - * uncompyle6/parsers/parse25.py, uncompyle6/parsers/parse26.py: + * uncompyle6/parsers/parse25.py, uncompyle6/parsers/parse26.py: 2.5/2.6 fn name clash fixes list conprehension problem 2016-07-08 rocky @@ -2315,7 +2711,7 @@ 2016-07-07 rocky - * uncompyle6/scanners/scanner2.py, uncompyle6/scanners/scanner26.py: + * uncompyle6/scanners/scanner2.py, uncompyle6/scanners/scanner26.py: <2.6 make sure jump back on loops is really "back" 2016-07-07 rocky @@ -2374,12 +2770,12 @@ * uncompyle6/parser.py, uncompyle6/parsers/parse26.py, uncompyle6/parsers/parse27.py, uncompyle6/parsers/parse3.py, - uncompyle6/scanners/scanner2.py, uncompyle6/scanners/scanner26.py: + uncompyle6/scanners/scanner2.py, uncompyle6/scanners/scanner26.py: Another 2.6 while stmt. Clean up grammar a little 2016-07-03 rocky - * uncompyle6/parsers/parse26.py, uncompyle6/scanners/scanner2.py: + * uncompyle6/parsers/parse26.py, uncompyle6/scanners/scanner2.py: 2.6 improper tagging of RETURN_END_IF 2016-07-02 rocky @@ -2416,7 +2812,7 @@ 2016-06-30 rocky * test/simple_source/stmts/06_for_break.py, - uncompyle6/parsers/parse26.py, uncompyle6/semantics/pysource.py: + uncompyle6/parsers/parse26.py, uncompyle6/semantics/pysource.py: More 2.6.9 bugs fixed * break loop parsing bug * ifelsestmt semantic-action bug in handling else 2016-06-30 rocky @@ -2433,7 +2829,7 @@ 2016-06-30 rocky * test/simple_source/comprehension/05_for_for.py, - uncompyle6/parsers/parse26.py, uncompyle6/semantics/pysource.py: + uncompyle6/parsers/parse26.py, uncompyle6/semantics/pysource.py: 2.6.9 list comprehension 2016-06-30 rocky @@ -2475,7 +2871,7 @@ 2016-06-28 rocky - * uncompyle6/parsers/parse26.py, uncompyle6/semantics/pysource.py: + * uncompyle6/parsers/parse26.py, uncompyle6/semantics/pysource.py: Weird 2.6.9 list comprehension 2016-06-28 rocky @@ -2492,7 +2888,7 @@ * uncompyle6/parser.py, uncompyle6/parsers/parse26.py, uncompyle6/parsers/parse27.py, uncompyle6/scanners/scanner2.py, - uncompyle6/scanners/scanner25.py, uncompyle6/scanners/scanner26.py: + uncompyle6/scanners/scanner25.py, uncompyle6/scanners/scanner26.py: Base 2.5 off of 2.6. Some other small bugs. 2016-06-27 rocky @@ -2502,7 +2898,7 @@ 2016-06-27 rocky - * uncompyle6/parsers/parse26.py, uncompyle6/semantics/pysource.py: + * uncompyle6/parsers/parse26.py, uncompyle6/semantics/pysource.py: 2.6 list comprehensions 2016-06-27 rocky @@ -2587,7 +2983,7 @@ 2016-06-22 rocky * test/simple_source/expression/05_yield_from.py, - uncompyle6/parsers/parse3.py, uncompyle6/semantics/pysource.py: + uncompyle6/parsers/parse3.py, uncompyle6/semantics/pysource.py: differing ways to do "yield from" in 3.3-3.5 2016-06-22 rocky @@ -2596,7 +2992,7 @@ uncompyle6/scanners/scanner2.py, uncompyle6/scanners/scanner23.py, uncompyle6/scanners/scanner25.py, uncompyle6/scanners/scanner26.py, uncompyle6/scanners/scanner27.py, - uncompyle6/semantics/fragments.py, uncompyle6/semantics/pysource.py: + uncompyle6/semantics/fragments.py, uncompyle6/semantics/pysource.py: Add Python 3.5 yield from and ... * fragments.py: Handle pass stmt sometimes * scanners: regularize Python 2 scanners some * test/test_pyenvlib.py: add python 3.5.1 option 2016-06-22 rocky @@ -2606,7 +3002,7 @@ 2016-06-22 rocky - * uncompyle6/parsers/parse3.py, uncompyle6/semantics/pysource.py: + * uncompyle6/parsers/parse3.py, uncompyle6/semantics/pysource.py: More 3.2 LOAD_CONST removal More python3 custom grammar DRYing 2016-06-22 rocky @@ -2618,7 +3014,7 @@ * test/simple_source/expression/05_lambda.py, test/simple_source/expression/10_lambda.py, - uncompyle6/parsers/parse3.py, uncompyle6/semantics/pysource.py: + uncompyle6/parsers/parse3.py, uncompyle6/semantics/pysource.py: Python 3.2 MAKE_FUNCTION adjustment 2016-06-22 rocky @@ -2637,18 +3033,18 @@ 2016-06-20 rocky - * uncompyle6/parsers/parse3.py, uncompyle6/semantics/pysource.py: + * uncompyle6/parsers/parse3.py, uncompyle6/semantics/pysource.py: Bang on Python 3.2 decompiling. 2016-06-20 rocky * uncompyle6/parsers/parse3.py, uncompyle6/scanner.py, - uncompyle6/scanners/scanner2.py, uncompyle6/scanners/scanner3.py: + uncompyle6/scanners/scanner2.py, uncompyle6/scanners/scanner3.py: Python 3 needs Python2's RETURN_END_IF Make python2 and python3 scanner look more the same 2016-06-20 rocky - * uncompyle6/parsers/parse3.py, uncompyle6/scanners/scanner3.py: + * uncompyle6/parsers/parse3.py, uncompyle6/scanners/scanner3.py: previous 2.7 class decorator bug fixed in 3.x 2016-06-20 rocky @@ -2680,7 +3076,7 @@ * test/simple_source/def/11_mkfunc_closure.py, uncompyle6/parsers/parse3.py, uncompyle6/scanners/scanner3.py, - uncompyle6/semantics/fragments.py, uncompyle6/semantics/pysource.py: + uncompyle6/semantics/fragments.py, uncompyle6/semantics/pysource.py: 3.x make closure kw args handling bug 2016-06-20 rocky @@ -2717,7 +3113,7 @@ * test/simple_source/comprehension/05_set_comprehension.py, uncompyle6/parsers/parse2.py, uncompyle6/parsers/parse3.py, uncompyle6/scanners/scanner27.py, - uncompyle6/semantics/fragments.py, uncompyle6/semantics/pysource.py: + uncompyle6/semantics/fragments.py, uncompyle6/semantics/pysource.py: 2.7 and 3.x bug in dict comprehensions 2016-06-19 rocky @@ -2735,7 +3131,7 @@ * test/simple_source/looping/08_while_except_bug.py, uncompyle6/parser.py, uncompyle6/parsers/parse2.py, - uncompyle6/parsers/parse3.py, uncompyle6/semantics/pysource.py: + uncompyle6/parsers/parse3.py, uncompyle6/semantics/pysource.py: Python 3 except clause parsing bug 2016-06-19 rocky @@ -2797,18 +3193,18 @@ * pytest/test_deparse.py, test/simple_source/comprehension/05_set_comprehension.py, uncompyle6/parser.py, uncompyle6/parsers/parse3.py, - uncompyle6/semantics/fragments.py, uncompyle6/semantics/pysource.py: + uncompyle6/semantics/fragments.py, uncompyle6/semantics/pysource.py: Fix python 3 set comprehension and ... Add a few set/list comprehension offsets for Python 3 2016-06-06 rocky * uncompyle6/parser.py, uncompyle6/parsers/astnode.py, - uncompyle6/semantics/fragments.py, uncompyle6/semantics/pysource.py: + uncompyle6/semantics/fragments.py, uncompyle6/semantics/pysource.py: small changes 2016-06-06 rocky - * uncompyle6/parsers/parse3.py, uncompyle6/semantics/fragments.py: + * uncompyle6/parsers/parse3.py, uncompyle6/semantics/fragments.py: include offset for starting listcomp 2016-06-03 rocky @@ -2830,7 +3226,7 @@ uncompyle6/scanners/scanner2.py, uncompyle6/scanners/scanner23.py, uncompyle6/scanners/scanner26.py, uncompyle6/scanners/scanner3.py, uncompyle6/scanners/scanner32.py, uncompyle6/scanners/scanner34.py, - uncompyle6/scanners/scanner35.py, uncompyle6/semantics/pysource.py: + uncompyle6/scanners/scanner35.py, uncompyle6/semantics/pysource.py: Limited support for Python 2.3 2016-06-03 rocky @@ -2928,7 +3324,7 @@ 2016-05-29 rocky * uncompyle6/scanners/scanner2.py, - uncompyle6/scanners/scanner25.py, uncompyle6/scanners/scanner26.py: + uncompyle6/scanners/scanner25.py, uncompyle6/scanners/scanner26.py: Bang again on Python 2.5 and 2.6 scanners 2016-05-29 rocky @@ -2940,7 +3336,7 @@ 2016-05-29 rocky * uncompyle6/scanners/scanner2.py, - uncompyle6/scanners/scanner26.py, uncompyle6/scanners/scanner27.py: + uncompyle6/scanners/scanner26.py, uncompyle6/scanners/scanner27.py: Start to DRY 2.6 scanner Note: can't use xdis 2.6 opcode until another xdis release. 2016-05-29 rocky @@ -2957,7 +3353,7 @@ * uncompyle6/scanners/scanner3.py, uncompyle6/scanners/scanner32.py, uncompyle6/scanners/scanner33.py, - uncompyle6/scanners/scanner34.py, uncompyle6/scanners/scanner35.py: + uncompyle6/scanners/scanner34.py, uncompyle6/scanners/scanner35.py: DRY scanners more 2016-05-28 rocky @@ -2972,7 +3368,7 @@ * test/simple_source/comprehension/06_list_ifnot.py, test/simple_source/comprehension/10-list-ifnot.py, uncompyle6/scanners/dis3.py, uncompyle6/scanners/scanner3.py, - uncompyle6/scanners/scanner35.py, uncompyle6/semantics/pysource.py: + uncompyle6/scanners/scanner35.py, uncompyle6/semantics/pysource.py: Remove dis3. Fix in 3.x list if not comprehension 2016-05-28 rocky @@ -2983,7 +3379,7 @@ 2016-05-28 rocky * uncompyle6/opcodes/opcode_32.py, uncompyle6/opcodes/opcode_33.py, - uncompyle6/opcodes/opcode_34.py, uncompyle6/scanners/scanner3.py: + uncompyle6/opcodes/opcode_34.py, uncompyle6/scanners/scanner3.py: Remove dup 3.x opcodes 2016-05-28 rocky @@ -2993,7 +3389,7 @@ 2016-05-28 rocky * uncompyle6/scanner.py, uncompyle6/scanners/scanner32.py, - uncompyle6/scanners/scanner33.py, uncompyle6/scanners/scanner34.py: + uncompyle6/scanners/scanner33.py, uncompyle6/scanners/scanner34.py: xdis for Python 3 opcodes 2016-05-28 rocky @@ -3095,7 +3491,7 @@ 2016-05-18 rocky * pytest/test_marsh.py, - test/simple_source/expression/06_frozenset.py, uncompyle6/marsh.py: + test/simple_source/expression/06_frozenset.py, uncompyle6/marsh.py: Handle marshal frozenset 2016-05-18 rocky @@ -3135,14 +3531,14 @@ 2016-05-17 rocky * pytest/test_marsh.py, - test/simple_source/expression/02_complex.py, uncompyle6/marsh.py: + test/simple_source/expression/02_complex.py, uncompyle6/marsh.py: Fix marshal bug in handling complex numbers 2016-05-17 rocky * Makefile, test/simple_source/def/09_class_closure.py, uncompyle6/parser.py, uncompyle6/parsers/parse3.py, - uncompyle6/semantics/fragments.py, uncompyle6/semantics/pysource.py: + uncompyle6/semantics/fragments.py, uncompyle6/semantics/pysource.py: Fix Python 3.x bugs * class definitions made via closures * Add "make check-short" to top-level * parse3.py: Python 3.3 uses STORE_LOGALS 2016-05-16 rocky @@ -3212,7 +3608,7 @@ * test/simple_source/expression/05_lambda.py, test/test_pyenvlib.py, uncompyle6/parsers/parse3.py, - uncompyle6/scanners/scanner3.py, uncompyle6/semantics/pysource.py: + uncompyle6/scanners/scanner3.py, uncompyle6/semantics/pysource.py: Fix bug in Python 3 lambda expression handling Some other small cleanup changes 2016-05-15 rocky @@ -3220,7 +3616,7 @@ * uncompyle6/bin/pydisassemble.py, uncompyle6/disas.py, uncompyle6/parser.py, uncompyle6/parsers/parse3.py, uncompyle6/scanners/scanner3.py, uncompyle6/scanners/scanner34.py, - uncompyle6/scanners/scanner35.py, uncompyle6/scanners/tok.py: + uncompyle6/scanners/scanner35.py, uncompyle6/scanners/tok.py: pydisassemble disassemble without grammar mangling Some other small cleanups as well 2016-05-15 rocky @@ -3260,7 +3656,7 @@ * uncompyle6/parsers/parse3.py, uncompyle6/scanners/scanner3.py, uncompyle6/scanners/scanner34.py, uncompyle6/scanners/scanner35.py, - uncompyle6/semantics/fragments.py, uncompyle6/semantics/pysource.py: + uncompyle6/semantics/fragments.py, uncompyle6/semantics/pysource.py: DRY scanner34 and scanner35 handle 3.0..3.4 build maps as key/value pairs 2016-05-15 rocky @@ -3332,7 +3728,7 @@ 2016-05-12 rocky * uncompyle6/scanners/scanner26.py, - uncompyle6/scanners/scanner27.py, uncompyle6/scanners/scanner35.py: + uncompyle6/scanners/scanner27.py, uncompyle6/scanners/scanner35.py: More small changes 2016-05-12 rocky @@ -3349,7 +3745,7 @@ * __pkginfo__.py, uncompyle6/parsers/parse2.py, uncompyle6/parsers/parse3.py, uncompyle6/scanners/scanner3.py, - uncompyle6/semantics/fragments.py, uncompyle6/semantics/pysource.py: + uncompyle6/semantics/fragments.py, uncompyle6/semantics/pysource.py: Misc fixups/cleanups * parse3.py Had botched if-for-else test by grammar addition * semantics/*.py: Show errorstack in failed parse when -g (requires sparck 1.2.0) * some optimization in scanner3 @@ -3363,7 +3759,7 @@ uncompyle6/parsers/parse3.py, uncompyle6/scanners/dis35.py, uncompyle6/scanners/scanner3.py, uncompyle6/scanners/scanner34.py, uncompyle6/scanners/scanner35.py, - uncompyle6/semantics/fragments.py, uncompyle6/semantics/pysource.py: + uncompyle6/semantics/fragments.py, uncompyle6/semantics/pysource.py: Redo make_function for *, arg main(*, file='foo') and things like that now work 2016-05-11 rocky @@ -3395,7 +3791,7 @@ 2016-05-09 rocky * test/simple_source/stmts/09_whiletrue_bug.py, - uncompyle6/parsers/parse3.py, uncompyle6/semantics/pysource.py: + uncompyle6/parsers/parse3.py, uncompyle6/semantics/pysource.py: Python 3 "while True" bug 2016-05-09 rocky @@ -3489,7 +3885,7 @@ * HISTORY.md, test/simple_source/branching/10_if_pass.py, uncompyle6/scanners/scanner26.py, uncompyle6/scanners/scanner27.py, - uncompyle6/scanners/scanner3.py, uncompyle6/scanners/scanner35.py: + uncompyle6/scanners/scanner3.py, uncompyle6/scanners/scanner35.py: Fix 3.5 if..pass bug Update HISTORY.MD to include Dan Pascu. Some minor doc corrections 2016-05-08 rocky @@ -3506,7 +3902,7 @@ * test/simple_source/expression/05_yield_from.py, uncompyle6/parsers/parse3.py, uncompyle6/scanners/scanner35.py, - uncompyle6/semantics/fragments.py, uncompyle6/semantics/pysource.py: + uncompyle6/semantics/fragments.py, uncompyle6/semantics/pysource.py: Handle Python 3 yield from Start dealing with MAKE_FUNCTION flags - not done yet. 2016-05-06 rocky @@ -3571,19 +3967,19 @@ 2016-05-05 rocky * test/simple_source/def/05_abc_class.py, - test/simple_source/def/06_classbug.py, uncompyle6/parsers/parse3.py: + test/simple_source/def/06_classbug.py, uncompyle6/parsers/parse3.py: Python 3.5 abc.py bug distilled 2016-05-05 rocky - * uncompyle6/scanners/dis35.py, uncompyle6/scanners/scanner35.py: + * uncompyle6/scanners/dis35.py, uncompyle6/scanners/scanner35.py: Add cross-Python-protable 3.5 dis module 2016-05-04 rocky * test/simple_source/stmts/05_with.py, uncompyle6/opcodes/opcode_35.py, uncompyle6/parser.py, - uncompyle6/parsers/parse3.py, uncompyle6/scanners/scanner35.py: + uncompyle6/parsers/parse3.py, uncompyle6/scanners/scanner35.py: Handle 3.5 with [as] scanner35.py: Fix a small variable-name typo 2016-05-03 rocky @@ -3593,7 +3989,7 @@ 2016-05-03 rocky * uncompyle6/scanners/scanner3.py, - uncompyle6/scanners/scanner34.py, uncompyle6/scanners/scanner35.py: + uncompyle6/scanners/scanner34.py, uncompyle6/scanners/scanner35.py: Don't repeat next_except_jump 2016-05-03 rocky @@ -3711,7 +4107,7 @@ * requirements.txt, uncompyle6/parser.py, uncompyle6/parsers/parse2.py, uncompyle6/parsers/parse3.py, - uncompyle6/semantics/fragments.py, uncompyle6/semantics/pysource.py: + uncompyle6/semantics/fragments.py, uncompyle6/semantics/pysource.py: spark -> spark_parser 2016-04-28 rocky @@ -3859,7 +4255,7 @@ 2016-01-02 rocky * uncompyle6/scanner.py, uncompyle6/scanners/scanner25.py, - uncompyle6/scanners/scanner26.py, uncompyle6/scanners/scanner27.py: + uncompyle6/scanners/scanner26.py, uncompyle6/scanners/scanner27.py: Make ScannerXX() initialization the same on Python 2.x and 3.x 2016-01-02 rocky @@ -3953,7 +4349,7 @@ 2015-12-31 rocky * test/simple_source/def/05_class.py, uncompyle6/parsers/parse3.py, - uncompyle6/semantics/fragments.py, uncompyle6/semantics/pysource.py: + uncompyle6/semantics/fragments.py, uncompyle6/semantics/pysource.py: Handle Python 3.3 > dotted class names 2015-12-30 rocky @@ -3976,7 +4372,7 @@ 2015-12-30 rocky - * uncompyle6/parsers/parse3.py, uncompyle6/semantics/pysource.py: + * uncompyle6/parsers/parse3.py, uncompyle6/semantics/pysource.py: Remove accidental schmutz. Try using pattr on 3.4 to get fn names 2015-12-30 rocky @@ -4023,7 +4419,7 @@ * test/simple_source/exception/25_try_except.py, test/test_pythonlib.py, uncompyle6/parsers/parse3.py, uncompyle6/scanners/scanner27.py, uncompyle6/scanners/scanner3.py, - uncompyle6/scanners/scanner34.py, uncompyle6/semantics/pysource.py: + uncompyle6/scanners/scanner34.py, uncompyle6/semantics/pysource.py: Towards Python3 getting try/except working more often. 2015-12-29 rocky @@ -4056,7 +4452,7 @@ * README.rst, test/Makefile, uncompyle6/opcodes/opcode_32.py, uncompyle6/opcodes/opcode_33.py, uncompyle6/opcodes/opcode_34.py, - uncompyle6/scanners/scanner3.py, uncompyle6/scanners/scanner32.py: + uncompyle6/scanners/scanner3.py, uncompyle6/scanners/scanner32.py: scanner3: Python 2.6 compatibility: change set initializations. Get rid of * import opcode_*: only a little of the much-needed larger cleanup Makefile: remove 3.x bytecode checking from Python 2.x for @@ -4075,7 +4471,7 @@ * uncompyle6/disas.py, uncompyle6/load.py, uncompyle6/main.py, uncompyle6/marsh.py, uncompyle6/scanners/scanner3.py, - uncompyle6/semantics/fragments.py, uncompyle6/semantics/pysource.py: + uncompyle6/semantics/fragments.py, uncompyle6/semantics/pysource.py: Add Python3 marshal codes and start to handle cross-version Python code object types, introducing scan.Code3 @@ -4125,7 +4521,7 @@ uncompyle6/scanners/scanner26.py, uncompyle6/scanners/scanner27.py, uncompyle6/scanners/scanner3.py, uncompyle6/scanners/scanner32.py, uncompyle6/scanners/scanner33.py, uncompyle6/scanners/scanner34.py, - uncompyle6/semantics/fragments.py, uncompyle6/semantics/pysource.py: + uncompyle6/semantics/fragments.py, uncompyle6/semantics/pysource.py: DRY Python3 scanner code. Some cross version handling fixed. Some Python 3.2 and 3.3 deparse fixes. @@ -4141,7 +4537,7 @@ uncompyle6/scanners/scanner26.py, uncompyle6/scanners/scanner27.py, uncompyle6/scanners/scanner3.py, uncompyle6/scanners/scanner32.py, uncompyle6/scanners/scanner33.py, uncompyle6/scanners/scanner34.py, - uncompyle6/semantics/fragments.py, uncompyle6/semantics/pysource.py: + uncompyle6/semantics/fragments.py, uncompyle6/semantics/pysource.py: DRY Python3 scanner code. Some cross version handling fixed. Some Python 3.2 and 3.3 deparse fixes. @@ -4205,7 +4601,7 @@ test/simple_source/stmts/15_assert.py, test/simple_source/stmts/15_for_if.py, uncompyle6/parsers/parse2.py, uncompyle6/parsers/parse3.py, - uncompyle6/scanners/scanner32.py, uncompyle6/scanners/scanner34.py: + uncompyle6/scanners/scanner32.py, uncompyle6/scanners/scanner34.py: Fix up looping by reinstating JUMP_ABSOLUTE -> JUMP_BACK or CONTINUE get jump offsets into jump attributes. Fix up 3.2 scanner paritally and use that in 3.4 for in cross version disassembly. @@ -4289,7 +4685,7 @@ * test/simple_source/simple_stmts/00_import.py, test/simple_source/simple_stmts/00_pass.py, - uncompyle6/parsers/parse3.py, uncompyle6/semantics/pysource.py: + uncompyle6/parsers/parse3.py, uncompyle6/semantics/pysource.py: Start Python3 class(superclass) handling 2015-12-23 rocky @@ -4323,7 +4719,7 @@ uncompyle6/opcodes/opcode_27.py, uncompyle6/opcodes/opcode_34.py, uncompyle6/parsers/astnode.py, uncompyle6/parsers/parse2.py, uncompyle6/parsers/parse3.py, uncompyle6/parsers/spark.py, - uncompyle6/semantics/fragments.py, uncompyle6/semantics/pysource.py: + uncompyle6/semantics/fragments.py, uncompyle6/semantics/pysource.py: Allow comments in grammar rules. Start working on Python3 class (not finished). More test organization. @@ -4407,7 +4803,7 @@ test/simple_source/misc/assign.py, test/simple_source/misc/assign_none_str.py, test/simple_source/simple_stmts/00_assign.py, - uncompyle6/parsers/parse3.py, uncompyle6/semantics/pysource.py: + uncompyle6/parsers/parse3.py, uncompyle6/semantics/pysource.py: Start Python3 execption handling 2015-12-21 rocky @@ -4553,7 +4949,7 @@ * test/Makefile, test/simple-source/misc/assign_none.py, test/simple-source/misc/assign_none_str.py, uncompyle6/marsh.py, - uncompyle6/scanners/scanner32.py, uncompyle6/scanners/scanner34.py: + uncompyle6/scanners/scanner32.py, uncompyle6/scanners/scanner34.py: Python 3 decompilation from Python2 2015-12-20 rocky @@ -4571,7 +4967,7 @@ 2015-12-20 rocky * Makefile, README.rst, test/Makefile, test/dis-compare.py, - uncompyle6/deparser.py, uncompyle6/disas.py, uncompyle6/walker.py: + uncompyle6/deparser.py, uncompyle6/disas.py, uncompyle6/walker.py: Go over makefiles to make "make check" work. walker, deparser: use zip_longest @@ -4641,7 +5037,7 @@ test/simple-source/precedence/left.py, test/simple-source/precedence/right.py, test/simple-source/precedence/structure.py, - uncompyle6/parsers/parse3.py, uncompyle6/scanners/scanner34.py: + uncompyle6/parsers/parse3.py, uncompyle6/scanners/scanner34.py: Python 3 bytecode handles opcodes with varargs (better). Decompiling assert works. Add more of the simple tests and their compiled bytecode. @@ -4683,7 +5079,7 @@ 2015-12-18 rocky - * test/simple-source/comprehension/forelse.py, uncompyle6/disas.py: + * test/simple-source/comprehension/forelse.py, uncompyle6/disas.py: disas.py: Do better for finding/turning a .py file into a .pyc file across supported versions of Python. Add for else list comprehension test @@ -4782,7 +5178,7 @@ 2015-12-17 rocky - * uncompyle6/opcodes/opcode_34.py, uncompyle6/parsers/parse3.py: + * uncompyle6/opcodes/opcode_34.py, uncompyle6/parsers/parse3.py: Python 3.4 correct grammar for some looping constructs 2015-12-17 rocky @@ -4817,14 +5213,14 @@ 2015-12-16 rocky * uncompyle6/deparser.py, uncompyle6/disas.py, - uncompyle6/parser.py, uncompyle6/scanner.py, uncompyle6/walker.py: + uncompyle6/parser.py, uncompyle6/scanner.py, uncompyle6/walker.py: Add LICENSE. Add demo programs and DRY code a little 2015-12-16 rocky * uncompyle6/opcodes/opcode_34.py, uncompyle6/scanner.py, uncompyle6/scanners/scanner25.py, uncompyle6/scanners/scanner26.py, - uncompyle6/scanners/scanner27.py, uncompyle6/scanners/scanner34.py: + uncompyle6/scanners/scanner27.py, uncompyle6/scanners/scanner34.py: On Python3.4 decompiling Python 3.4 instructions, use its built-in disassembler routines. In contrast to what was here, they most likely work! @@ -4881,7 +5277,7 @@ uncompyle6/deparser.py, uncompyle6/disas.py, uncompyle6/magics.py, uncompyle6/marsh.py, uncompyle6/scanners/scanner25.py, uncompyle6/scanners/scanner26.py, uncompyle6/scanners/scanner27.py, - uncompyle6/scanners/scanner32.py, uncompyle6/scanners/scanner34.py: + uncompyle6/scanners/scanner32.py, uncompyle6/scanners/scanner34.py: Split out marhsal and disassemble code and spell disassemble correctly. Fix some lint issues @@ -4966,7 +5362,7 @@ 2015-12-14 rocky - * uncompyle6/dparser.py, uncompyle6/parser.py, uncompyle6/walker.py: + * uncompyle6/dparser.py, uncompyle6/parser.py, uncompyle6/walker.py: uncompyle6/dparser -> uncompyle6/parser 2015-12-14 rocky @@ -5219,7 +5615,7 @@ * MANIFEST, MANIFEST.in, PKG-INFO, README.rst, uncompyle6/opcodes/opcode_23.py, uncompyle6/opcodes/opcode_26.py, uncompyle6/opcodes/opcode_27.py, uncompyle6/scanner25.py, - uncompyle6/scanner26.py, uncompyle6/spark.py, uncompyle6/verify.py: + uncompyle6/scanner26.py, uncompyle6/spark.py, uncompyle6/verify.py: Correct MANIFEST->MANIFEST.in more lint 2015-12-13 R. Bernstein @@ -5236,7 +5632,7 @@ uncompyle6/__init__.py, uncompyle6/disas.py, uncompyle6/opcodes/opcode_25.py, uncompyle6/opcodes/opcode_26.py, uncompyle6/scanner25.py, uncompyle6/scanner26.py, - uncompyle6/scanner34.py, uncompyle6/spark.py, uncompyle6/verify.py: + uncompyle6/scanner34.py, uncompyle6/spark.py, uncompyle6/verify.py: Make uncompyle6 run on Python3.4 and Python 2.7 We don't need our own disassembler. Python's will do fine @@ -5337,13 +5733,13 @@ * tox.ini, uncompyle-code.py, uncompyle6/dparser.py, uncompyle6/scanner25.py, uncompyle6/scanner27.py, - uncompyle6/scanner34.py, uncompyle6/spark.py, uncompyle6/walker.py: + uncompyle6/scanner34.py, uncompyle6/spark.py, uncompyle6/walker.py: Minimal disassemble, ast compile and deparse work on Python 3. Some linting 2015-12-12 rocky - * uncompyle6/dparser.py, uncompyle6/parser.py, uncompyle6/walker.py: + * uncompyle6/dparser.py, uncompyle6/parser.py, uncompyle6/walker.py: parser -> dparser so as not to conflict with python3's parser. 2015-12-12 rocky @@ -5362,7 +5758,7 @@ 2015-12-11 rocky - * uncompyle-code.py, uncompyle6/__init__.py, uncompyle6/walker.py: + * uncompyle-code.py, uncompyle6/__init__.py, uncompyle6/walker.py: python3 compatibiity and remove some flake8 warnings. 2015-12-11 rocky @@ -5440,7 +5836,7 @@ 2013-07-16 root * uncompyle2/__init__.py, uncompyle2/disas.py, - uncompyle2/magics.py, uncompyle2/scanner27.py, uncompyle2/walker.py: + uncompyle2/magics.py, uncompyle2/scanner27.py, uncompyle2/walker.py: marshal disassembly improvement 2013-06-20 Mysterie @@ -5525,7 +5921,7 @@ uncompyle2/opcode/opcode_27.py, uncompyle2/parser.py, uncompyle2/scanner.py, uncompyle2/scanner25.py, uncompyle2/scanner26.py, uncompyle2/scanner27.py, - uncompyle2/spark.py, uncompyle2/verify.py, uncompyle2/walker.py: + uncompyle2/spark.py, uncompyle2/verify.py, uncompyle2/walker.py: Cleaning code & patch 2012-09-22 Mysterie @@ -5630,4 +6026,3 @@ 2012-06-05 Mysterie * first commit - diff --git a/NEWS b/NEWS index cc30c15d..9c7ade5f 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,9 @@ +uncompyle6 2.9.11 2016-04-06 + +- Better support for Python 3.5+ BUILD_MAP_UNPACK +- Start 3.6 CALL_FUNCTION_EX support +- Many decompilation bug fixes. (Many more remain). See ChangeLog + uncompyle6 2.9.10 2016-02-25 - Python grammar rule fixes diff --git a/test/bytecode_2.6/06_list_ifnot_and.pyc b/test/bytecode_2.6/06_list_ifnot_and.pyc-notyet similarity index 100% rename from test/bytecode_2.6/06_list_ifnot_and.pyc rename to test/bytecode_2.6/06_list_ifnot_and.pyc-notyet diff --git a/uncompyle6/version.py b/uncompyle6/version.py index 5d5facdb..566e6123 100644 --- a/uncompyle6/version.py +++ b/uncompyle6/version.py @@ -1,3 +1,3 @@ # This file is suitable for sourcing inside bash as # well as importing into Python -VERSION='2.9.10' +VERSION='2.9.11' From 89d8a707786d2e64a166f40bf64ca44975f3e68b Mon Sep 17 00:00:00 2001 From: rocky Date: Sat, 6 May 2017 10:00:15 -0400 Subject: [PATCH 05/51] python 3.3 while True parsing bug --- uncompyle6/parsers/parse33.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/uncompyle6/parsers/parse33.py b/uncompyle6/parsers/parse33.py index c9f67712..1c1ee639 100644 --- a/uncompyle6/parsers/parse33.py +++ b/uncompyle6/parsers/parse33.py @@ -21,6 +21,9 @@ class Python33Parser(Python32Parser): iflaststmt ::= testexpr c_stmts_opt33 c_stmts_opt33 ::= JUMP_BACK JUMP_ABSOLUTE c_stmts_opt + whileTruestmt ::= SETUP_LOOP l_stmts JUMP_ABSOLUTE + JUMP_BACK COME_FROM_LOOP + # Python 3.5+ has jump optimization to remove the redundant # jump_excepts. But in 3.3 we need them added From 26e8de8532ebced89b502e7e53f3c8b785c03002 Mon Sep 17 00:00:00 2001 From: rocky Date: Sun, 7 May 2017 03:19:53 -0400 Subject: [PATCH 06/51] Fix improper COME_FROM_EXCEPT in Python 3.3+ --- uncompyle6/scanners/scanner3.py | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/uncompyle6/scanners/scanner3.py b/uncompyle6/scanners/scanner3.py index 30ecb9d0..31953266 100644 --- a/uncompyle6/scanners/scanner3.py +++ b/uncompyle6/scanners/scanner3.py @@ -135,6 +135,9 @@ class Scanner3(Scanner): # FIXME: remove the above in favor of: # self.varargs_ops = frozenset(self.opc.hasvargs) + def next_offset(self, op, offset): + return offset + self.op_size(op) + def ingest(self, co, classname=None, code_objects={}, show_asm=None): """ Pick out tokens from an uncompyle6 code object, and transform them, @@ -476,7 +479,7 @@ class Scanner3(Scanner): oparg = code[offset+1] else: oparg = code[offset+1] + code[offset+2] * 256 - next_offset = offset + self.op_size(op) + next_offset = self.next_offset(op, offset) if label is None: if op in op3.hasjrel and op != self.opc.FOR_ITER: @@ -911,14 +914,14 @@ class Scanner3(Scanner): end = self.restrict_to_parent(target, parent) self.fixed_jumps[offset] = end elif op == self.opc.POP_EXCEPT: - if self.version <= 3.5: - next_offset = offset+1 - else: - next_offset = offset+2 + next_offset = self.next_offset(op, offset) target = self.get_target(next_offset) if target > next_offset: - self.fixed_jumps[next_offset] = target - self.except_targets[target] = next_offset + next_op = code[next_offset] + if (self.opc.JUMP_ABSOLUTE == next_op and + END_FINALLY != code[self.next_offset(next_op, next_offset)]): + self.fixed_jumps[next_offset] = target + self.except_targets[target] = next_offset elif op == self.opc.SETUP_FINALLY: target = self.get_target(offset) From 50d875f6a6db554e12f6daf59762e405278f473f Mon Sep 17 00:00:00 2001 From: rocky Date: Sun, 7 May 2017 08:01:48 -0400 Subject: [PATCH 07/51] Small typo --- HOW-TO-REPORT-A-BUG.md | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/HOW-TO-REPORT-A-BUG.md b/HOW-TO-REPORT-A-BUG.md index ad192b12..7a2e1534 100644 --- a/HOW-TO-REPORT-A-BUG.md +++ b/HOW-TO-REPORT-A-BUG.md @@ -7,7 +7,7 @@ decompyle everything. This one probably does the best job of *any* Python decompiler. But it is a constant work in progress: Python keeps changing, and so does its code generation. I have found bugs in *every* Python decompiler I have tried. Even -those where authors/maintainers claim that they have used it on +those where authors/maintainers claim that they have used it on the entire Python standard library. And I don't mean that the program doesn't come out with the same Python source instructions, but that the program is *semantically* not equivalent. @@ -29,7 +29,7 @@ can figure out what OS you are running this on and what version of *uncomplye6* was used. Therefore, if you don't provide the input command and the output from that, please give: -* _uncompile6_ version used +* _uncompyle6_ version used * OS that you used this on * Python interpreter version used @@ -37,11 +37,16 @@ command and the output from that, please give: ### But I don't *have* the source code! Sure, I get it. No problem. There is Python assembly code on parse -errors, so simply by hand decompile that. To get a full disassembly, use pydisasm from the [xdis](https://pypi.python.org/pypi/xdis) package. Opcodes are described in the documentation for the [dis](https://docs.python.org/3.6/library/dis.html) module. +errors, so simply by hand decompile that. To get a full disassembly, +use pydisasm from the [xdis](https://pypi.python.org/pypi/xdis) +package. Opcodes are described in the documentation for +the [dis](https://docs.python.org/3.6/library/dis.html) module. ### But I don't *have* the source code and am incapable of figuring how how to do a hand disassembly! -Well, you could learn. No one is born into this world knowing how to disassemble Python bytecode. And as Richard Feynman once said, "What one fool can learn, so can another." +Well, you could learn. No one is born into this world knowing how to +disassemble Python bytecode. And as Richard Feynman once said, "What +one fool can learn, so can another." ## Narrowing the problem From 605721c99525e5ed394377c5a96817aefa81396c Mon Sep 17 00:00:00 2001 From: rocky Date: Sun, 7 May 2017 09:10:05 -0400 Subject: [PATCH 08/51] Python 3.x control-flow bug... "pass" statement inside "while True" --- test/bytecode_3.1/12_if_while_true_pass.pyc | Bin 0 -> 447 bytes test/bytecode_3.3/12_if_while_true_pass.pyc | Bin 0 -> 468 bytes .../looping/12_if_while_true_pass.py | 14 ++++++++++++++ uncompyle6/scanners/scanner3.py | 6 +----- 4 files changed, 15 insertions(+), 5 deletions(-) create mode 100644 test/bytecode_3.1/12_if_while_true_pass.pyc create mode 100644 test/bytecode_3.3/12_if_while_true_pass.pyc create mode 100644 test/simple_source/looping/12_if_while_true_pass.py diff --git a/test/bytecode_3.1/12_if_while_true_pass.pyc b/test/bytecode_3.1/12_if_while_true_pass.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0adaa83ab583ef536f285cc54e145084a519576c GIT binary patch literal 447 zcmbVG!Ab)$6r42LwYA0Dp1cZ+hb?**5%uJuB0ZD}vMjr?4Q{(>vcVSGTR+_Q(u(5I z2Q!(x$;+GPUcW2P&n5+al^}gbaDAc@*a5F31V%}VI)xS#N8ia(6QML|!vPv0rgk^*=EgmJjVyHQgj+nYc2?4?JY)t(z zaZ`V&h3DrcZ)U#p-D=iG?FXm>pAtDeHl2}3<^DkS1SUu(=;>i_@% literal 0 HcmV?d00001 diff --git a/test/simple_source/looping/12_if_while_true_pass.py b/test/simple_source/looping/12_if_while_true_pass.py new file mode 100644 index 00000000..cf3bd1c5 --- /dev/null +++ b/test/simple_source/looping/12_if_while_true_pass.py @@ -0,0 +1,14 @@ +# Python 3.3 pyclbr.py +# Note that Python 3 adds a lot of unecessary "continues" +# and puts that in for "pass" +def _readmodule(g, token, path): + for tokentype in g: + if g: + while True: + if token: + token = 1 + elif token: + pass + elif tokentype: + token = 7 + token = 10 diff --git a/uncompyle6/scanners/scanner3.py b/uncompyle6/scanners/scanner3.py index 31953266..e347bb6b 100644 --- a/uncompyle6/scanners/scanner3.py +++ b/uncompyle6/scanners/scanner3.py @@ -338,11 +338,7 @@ class Scanner3(Scanner): (next_opname not in ('END_FINALLY', 'POP_BLOCK', # Python 3.0 only uses POP_TOP 'POP_TOP'))): - if (self.version >= 3.4 or - (inst.offset not in self.not_continue) or - (tokens[-1].type == 'RETURN_VALUE')): - opname = 'CONTINUE' - pass + opname = 'CONTINUE' else: opname = 'JUMP_BACK' # FIXME: this is a hack to catch stuff like: From e10e184edaad411f149c6e3aed6ceb08d47ff9d9 Mon Sep 17 00:00:00 2001 From: rocky Date: Sun, 7 May 2017 09:13:50 -0400 Subject: [PATCH 09/51] --weak-verify on 3.3 with inclusion of last commit Note that the result is sematically equivalent, so it is is correct. --- test/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/Makefile b/test/Makefile index 6b997974..16aabd92 100644 --- a/test/Makefile +++ b/test/Makefile @@ -35,7 +35,7 @@ check-3.2: check-bytecode #: Run working tests from Python 3.3 check-3.3: check-bytecode - $(PYTHON) test_pythonlib.py --bytecode-3.3 --verify $(COMPILE) + $(PYTHON) test_pythonlib.py --bytecode-3.3 --weak-verify $(COMPILE) #: Run working tests from Python 3.4 check-3.4: check-bytecode check-3.4-ok check-2.7-ok From f8a40c1949dc1071cc27c26e19192cd4ca7a03a0 Mon Sep 17 00:00:00 2001 From: rocky Date: Sun, 7 May 2017 13:15:26 -0400 Subject: [PATCH 10/51] Reduce spurious "continue" statements --- uncompyle6/scanner.py | 3 +++ uncompyle6/scanners/scanner3.py | 3 --- uncompyle6/semantics/pysource.py | 19 +++++++++++++++++++ 3 files changed, 22 insertions(+), 3 deletions(-) diff --git a/uncompyle6/scanner.py b/uncompyle6/scanner.py index 824db86a..67ab4dbf 100755 --- a/uncompyle6/scanner.py +++ b/uncompyle6/scanner.py @@ -226,6 +226,9 @@ class Scanner(object): yield start start += self.op_size(self.code[start]) + def next_offset(self, op, offset): + return offset + self.op_size(op) + def op_size(self, op): """ Return size of operator with its arguments diff --git a/uncompyle6/scanners/scanner3.py b/uncompyle6/scanners/scanner3.py index e347bb6b..3f0f751c 100644 --- a/uncompyle6/scanners/scanner3.py +++ b/uncompyle6/scanners/scanner3.py @@ -135,9 +135,6 @@ class Scanner3(Scanner): # FIXME: remove the above in favor of: # self.varargs_ops = frozenset(self.opc.hasvargs) - def next_offset(self, op, offset): - return offset + self.op_size(op) - def ingest(self, co, classname=None, code_objects={}, show_asm=None): """ Pick out tokens from an uncompyle6 code object, and transform them, diff --git a/uncompyle6/semantics/pysource.py b/uncompyle6/semantics/pysource.py index b97c61b8..8f294182 100644 --- a/uncompyle6/semantics/pysource.py +++ b/uncompyle6/semantics/pysource.py @@ -519,6 +519,25 @@ class SourceWalker(GenericASTTraversal, object): node == AST('return_stmt', [AST('ret_expr', [NONE]), Token('RETURN_VALUE')])) + def n_continue_stmt(self, node): + if node[0] == 'CONTINUE': + t = node[0] + if not t.linestart: + # Artificially-added "continue" statements derived from JUMP_ABSOLUTE + # don't have line numbers associated with them. + # If this is a CONTINUE is to the same target as a JUMP_ABSOLUTE following it, + # then the "continue" can be suppressed. + op, offset = t.op, t.offset + next_offset = self.scanner.next_offset(op, offset) + scanner = self.scanner + code = scanner.code + next_inst = code[next_offset] + if (scanner.opc.opname[next_inst] == 'JUMP_ABSOLUTE' + and t.pattr == code[next_offset+1]): + # Suppress "continue" + self.prune() + self.default(node) + def n_return_stmt(self, node): if self.params['isLambda']: self.preorder(node[0]) From 449d74af5116aaaf59065c2600c1a5b017b041be Mon Sep 17 00:00:00 2001 From: rocky Date: Sun, 7 May 2017 13:30:26 -0400 Subject: [PATCH 11/51] More guarded CONTINUE deletion --- uncompyle6/semantics/pysource.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/uncompyle6/semantics/pysource.py b/uncompyle6/semantics/pysource.py index 8f294182..a0d1fd13 100644 --- a/uncompyle6/semantics/pysource.py +++ b/uncompyle6/semantics/pysource.py @@ -520,7 +520,7 @@ class SourceWalker(GenericASTTraversal, object): [AST('ret_expr', [NONE]), Token('RETURN_VALUE')])) def n_continue_stmt(self, node): - if node[0] == 'CONTINUE': + if self.version >= 3.0 and node[0] == 'CONTINUE': t = node[0] if not t.linestart: # Artificially-added "continue" statements derived from JUMP_ABSOLUTE From 9c0ef9fa6325ee1ef7b1ec86e3472f05d65f1c07 Mon Sep 17 00:00:00 2001 From: rocky Date: Mon, 8 May 2017 06:24:41 -0400 Subject: [PATCH 12/51] Try appveyor --- appveyor.yml | 77 +++++++++++++ appveyor/install.ps1 | 229 ++++++++++++++++++++++++++++++++++++++ appveyor/run_with_env.cmd | 87 +++++++++++++++ 3 files changed, 393 insertions(+) create mode 100644 appveyor.yml create mode 100644 appveyor/install.ps1 create mode 100644 appveyor/run_with_env.cmd diff --git a/appveyor.yml b/appveyor.yml new file mode 100644 index 00000000..24c1c7f6 --- /dev/null +++ b/appveyor.yml @@ -0,0 +1,77 @@ +environment: + global: + # SDK v7.0 MSVC Express 2008's SetEnv.cmd script will fail if the + # /E:ON and /V:ON options are not enabled in the batch script intepreter + # See: http://stackoverflow.com/a/13751649/163740 + CMD_IN_ENV: "cmd /E:ON /V:ON /C .\\appveyor\\run_with_env.cmd" + + matrix: + + # Pre-installed Python versions, which Appveyor may upgrade to + # a later point release. + # See: http://www.appveyor.com/docs/installed-software#python + + - PYTHON: "C:\\Python27" + PYTHON_VERSION: "2.7.x" + PYTHON_ARCH: "32" + + # - PYTHON: "C:\\Python27-x64" + # PYTHON_VERSION: "2.7.x" + # PYTHON_ARCH: "64" + + # - PYTHON: "C:\\Python26" + # PYTHON_VERSION: "2.6.x" + # PYTHON_ARCH: "32" + + # - PYTHON: "C:\\Python26-x64" + # PYTHON_VERSION: "2.6.x" + # PYTHON_ARCH: "64" + +install: + # We need wheel installed to build wheels + - "%PYTHON%\\python.exe -m pip install wheel nose" + + # Install Python (from the official .msi of http://python.org) and pip when + # not already installed. + - ps: if (-not(Test-Path($env:PYTHON))) { & appveyor\install.ps1 } + + # Prepend newly installed Python to the PATH of this build (this cannot be + # done from inside the powershell script as it would require to restart + # the parent CMD process). + - "SET PATH=%PYTHON%;%PYTHON%\\Scripts;%PATH%" + + # Check that we have the expected version and architecture for Python + - "python --version" + - "python -c \"import struct; print(struct.calcsize('P') * 8)\"" + + # Upgrade to the latest version of pip to avoid it displaying warnings + # about it being out of date. + - "pip install --disable-pip-version-check --user --upgrade pip" + + # Install the build dependencies of the project. If some dependencies contain + # compiled extensions and are not provided as pre-built wheel packages, + # pip will build them from source using the MSVC compiler matching the + # target Python version and architecture + - "%CMD_IN_ENV% pip install -r requirements.txt" + +build_script: + # Build the compiled extension + - "%CMD_IN_ENV% python setup.py build" + +test_script: + # Run the project tests + - "%CMD_IN_ENV% python test\test_pyenvlib.py --2.7.12 + +after_test: + # If tests are successful, create binary packages for the project. + - "%CMD_IN_ENV% python setup.py bdist_wininst" + - "%CMD_IN_ENV% python setup.py bdist_msi" + - ps: "ls dist" + +artifacts: + # Archive the generated packages in the ci.appveyor.com build report. + - path: dist\* + +#on_success: +# - TODO: upload the content of dist/*.whl to a public wheelhouse +# diff --git a/appveyor/install.ps1 b/appveyor/install.ps1 new file mode 100644 index 00000000..160ba55c --- /dev/null +++ b/appveyor/install.ps1 @@ -0,0 +1,229 @@ +# Sample script to install Python and pip under Windows +# Authors: Olivier Grisel, Jonathan Helmus, Kyle Kastner, and Alex Willmer +# License: CC0 1.0 Universal: http://creativecommons.org/publicdomain/zero/1.0/ + +$MINICONDA_URL = "http://repo.continuum.io/miniconda/" +$BASE_URL = "https://www.python.org/ftp/python/" +$GET_PIP_URL = "https://bootstrap.pypa.io/get-pip.py" +$GET_PIP_PATH = "C:\get-pip.py" + +$PYTHON_PRERELEASE_REGEX = @" +(?x) +(?\d+) +\. +(?\d+) +\. +(?\d+) +(?[a-z]{1,2}\d+) +"@ + + +function Download ($filename, $url) { + $webclient = New-Object System.Net.WebClient + + $basedir = $pwd.Path + "\" + $filepath = $basedir + $filename + if (Test-Path $filename) { + Write-Host "Reusing" $filepath + return $filepath + } + + # Download and retry up to 3 times in case of network transient errors. + Write-Host "Downloading" $filename "from" $url + $retry_attempts = 2 + for ($i = 0; $i -lt $retry_attempts; $i++) { + try { + $webclient.DownloadFile($url, $filepath) + break + } + Catch [Exception]{ + Start-Sleep 1 + } + } + if (Test-Path $filepath) { + Write-Host "File saved at" $filepath + } else { + # Retry once to get the error message if any at the last try + $webclient.DownloadFile($url, $filepath) + } + return $filepath +} + + +function ParsePythonVersion ($python_version) { + if ($python_version -match $PYTHON_PRERELEASE_REGEX) { + return ([int]$matches.major, [int]$matches.minor, [int]$matches.micro, + $matches.prerelease) + } + $version_obj = [version]$python_version + return ($version_obj.major, $version_obj.minor, $version_obj.build, "") +} + + +function DownloadPython ($python_version, $platform_suffix) { + $major, $minor, $micro, $prerelease = ParsePythonVersion $python_version + + if (($major -le 2 -and $micro -eq 0) ` + -or ($major -eq 3 -and $minor -le 2 -and $micro -eq 0) ` + ) { + $dir = "$major.$minor" + $python_version = "$major.$minor$prerelease" + } else { + $dir = "$major.$minor.$micro" + } + + if ($prerelease) { + if (($major -le 2) ` + -or ($major -eq 3 -and $minor -eq 1) ` + -or ($major -eq 3 -and $minor -eq 2) ` + -or ($major -eq 3 -and $minor -eq 3) ` + ) { + $dir = "$dir/prev" + } + } + + if (($major -le 2) -or ($major -le 3 -and $minor -le 4)) { + $ext = "msi" + if ($platform_suffix) { + $platform_suffix = ".$platform_suffix" + } + } else { + $ext = "exe" + if ($platform_suffix) { + $platform_suffix = "-$platform_suffix" + } + } + + $filename = "python-$python_version$platform_suffix.$ext" + $url = "$BASE_URL$dir/$filename" + $filepath = Download $filename $url + return $filepath +} + + +function InstallPython ($python_version, $architecture, $python_home) { + Write-Host "Installing Python" $python_version "for" $architecture "bit architecture to" $python_home + if (Test-Path $python_home) { + Write-Host $python_home "already exists, skipping." + return $false + } + if ($architecture -eq "32") { + $platform_suffix = "" + } else { + $platform_suffix = "amd64" + } + $installer_path = DownloadPython $python_version $platform_suffix + $installer_ext = [System.IO.Path]::GetExtension($installer_path) + Write-Host "Installing $installer_path to $python_home" + $install_log = $python_home + ".log" + if ($installer_ext -eq '.msi') { + InstallPythonMSI $installer_path $python_home $install_log + } else { + InstallPythonEXE $installer_path $python_home $install_log + } + if (Test-Path $python_home) { + Write-Host "Python $python_version ($architecture) installation complete" + } else { + Write-Host "Failed to install Python in $python_home" + Get-Content -Path $install_log + Exit 1 + } +} + + +function InstallPythonEXE ($exepath, $python_home, $install_log) { + $install_args = "/quiet InstallAllUsers=1 TargetDir=$python_home" + RunCommand $exepath $install_args +} + + +function InstallPythonMSI ($msipath, $python_home, $install_log) { + $install_args = "/qn /log $install_log /i $msipath TARGETDIR=$python_home" + $uninstall_args = "/qn /x $msipath" + RunCommand "msiexec.exe" $install_args + if (-not(Test-Path $python_home)) { + Write-Host "Python seems to be installed else-where, reinstalling." + RunCommand "msiexec.exe" $uninstall_args + RunCommand "msiexec.exe" $install_args + } +} + +function RunCommand ($command, $command_args) { + Write-Host $command $command_args + Start-Process -FilePath $command -ArgumentList $command_args -Wait -Passthru +} + + +function InstallPip ($python_home) { + $pip_path = $python_home + "\Scripts\pip.exe" + $python_path = $python_home + "\python.exe" + if (-not(Test-Path $pip_path)) { + Write-Host "Installing pip..." + $webclient = New-Object System.Net.WebClient + $webclient.DownloadFile($GET_PIP_URL, $GET_PIP_PATH) + Write-Host "Executing:" $python_path $GET_PIP_PATH + & $python_path $GET_PIP_PATH + } else { + Write-Host "pip already installed." + } +} + + +function DownloadMiniconda ($python_version, $platform_suffix) { + if ($python_version -eq "3.4") { + $filename = "Miniconda3-3.5.5-Windows-" + $platform_suffix + ".exe" + } else { + $filename = "Miniconda-3.5.5-Windows-" + $platform_suffix + ".exe" + } + $url = $MINICONDA_URL + $filename + $filepath = Download $filename $url + return $filepath +} + + +function InstallMiniconda ($python_version, $architecture, $python_home) { + Write-Host "Installing Python" $python_version "for" $architecture "bit architecture to" $python_home + if (Test-Path $python_home) { + Write-Host $python_home "already exists, skipping." + return $false + } + if ($architecture -eq "32") { + $platform_suffix = "x86" + } else { + $platform_suffix = "x86_64" + } + $filepath = DownloadMiniconda $python_version $platform_suffix + Write-Host "Installing" $filepath "to" $python_home + $install_log = $python_home + ".log" + $args = "/S /D=$python_home" + Write-Host $filepath $args + Start-Process -FilePath $filepath -ArgumentList $args -Wait -Passthru + if (Test-Path $python_home) { + Write-Host "Python $python_version ($architecture) installation complete" + } else { + Write-Host "Failed to install Python in $python_home" + Get-Content -Path $install_log + Exit 1 + } +} + + +function InstallMinicondaPip ($python_home) { + $pip_path = $python_home + "\Scripts\pip.exe" + $conda_path = $python_home + "\Scripts\conda.exe" + if (-not(Test-Path $pip_path)) { + Write-Host "Installing pip..." + $args = "install --yes pip" + Write-Host $conda_path $args + Start-Process -FilePath "$conda_path" -ArgumentList $args -Wait -Passthru + } else { + Write-Host "pip already installed." + } +} + +function main () { + InstallPython $env:PYTHON_VERSION $env:PYTHON_ARCH $env:PYTHON + InstallPip $env:PYTHON +} + +main diff --git a/appveyor/run_with_env.cmd b/appveyor/run_with_env.cmd new file mode 100644 index 00000000..3a250956 --- /dev/null +++ b/appveyor/run_with_env.cmd @@ -0,0 +1,87 @@ +:: To build extensions for 64 bit Python 3, we need to configure environment +:: variables to use the MSVC 2010 C++ compilers from GRMSDKX_EN_DVD.iso of: +:: MS Windows SDK for Windows 7 and .NET Framework 4 (SDK v7.1) +:: +:: To build extensions for 64 bit Python 2, we need to configure environment +:: variables to use the MSVC 2008 C++ compilers from GRMSDKX_EN_DVD.iso of: +:: MS Windows SDK for Windows 7 and .NET Framework 3.5 (SDK v7.0) +:: +:: 32 bit builds, and 64-bit builds for 3.5 and beyond, do not require specific +:: environment configurations. +:: +:: Note: this script needs to be run with the /E:ON and /V:ON flags for the +:: cmd interpreter, at least for (SDK v7.0) +:: +:: More details at: +:: https://github.com/cython/cython/wiki/64BitCythonExtensionsOnWindows +:: http://stackoverflow.com/a/13751649/163740 +:: +:: Author: Olivier Grisel +:: License: CC0 1.0 Universal: http://creativecommons.org/publicdomain/zero/1.0/ +:: +:: Notes about batch files for Python people: +:: +:: Quotes in values are literally part of the values: +:: SET FOO="bar" +:: FOO is now five characters long: " b a r " +:: If you don't want quotes, don't include them on the right-hand side. +:: +:: The CALL lines at the end of this file look redundant, but if you move them +:: outside of the IF clauses, they do not run properly in the SET_SDK_64==Y +:: case, I don't know why. +@ECHO OFF +SET COMMAND_TO_RUN=%* +SET WIN_SDK_ROOT=C:\Program Files\Microsoft SDKs\Windows +SET WIN_WDK=c:\Program Files (x86)\Windows Kits\10\Include\wdf + +:: Extract the major and minor versions, and allow for the minor version to be +:: more than 9. This requires the version number to have two dots in it. +SET MAJOR_PYTHON_VERSION=%PYTHON_VERSION:~0,1% +IF "%PYTHON_VERSION:~3,1%" == "." ( + SET MINOR_PYTHON_VERSION=%PYTHON_VERSION:~2,1% +) ELSE ( + SET MINOR_PYTHON_VERSION=%PYTHON_VERSION:~2,2% +) + +:: Based on the Python version, determine what SDK version to use, and whether +:: to set the SDK for 64-bit. +IF %MAJOR_PYTHON_VERSION% == 2 ( + SET WINDOWS_SDK_VERSION="v7.0" + SET SET_SDK_64=Y +) ELSE ( + IF %MAJOR_PYTHON_VERSION% == 3 ( + SET WINDOWS_SDK_VERSION="v7.1" + IF %MINOR_PYTHON_VERSION% LEQ 4 ( + SET SET_SDK_64=Y + ) ELSE ( + SET SET_SDK_64=N + IF EXIST "%WIN_WDK%" ( + :: See: https://connect.microsoft.com/VisualStudio/feedback/details/1610302/ + REN "%WIN_WDK%" 0wdf + ) + ) + ) ELSE ( + ECHO Unsupported Python version: "%MAJOR_PYTHON_VERSION%" + EXIT 1 + ) +) + +IF %PYTHON_ARCH% == 64 ( + IF %SET_SDK_64% == Y ( + ECHO Configuring Windows SDK %WINDOWS_SDK_VERSION% for Python %MAJOR_PYTHON_VERSION% on a 64 bit architecture + SET DISTUTILS_USE_SDK=1 + SET MSSdk=1 + "%WIN_SDK_ROOT%\%WINDOWS_SDK_VERSION%\Setup\WindowsSdkVer.exe" -q -version:%WINDOWS_SDK_VERSION% + "%WIN_SDK_ROOT%\%WINDOWS_SDK_VERSION%\Bin\SetEnv.cmd" /x64 /release + ECHO Executing: %COMMAND_TO_RUN% + call %COMMAND_TO_RUN% || EXIT 1 + ) ELSE ( + ECHO Using default MSVC build environment for 64 bit architecture + ECHO Executing: %COMMAND_TO_RUN% + call %COMMAND_TO_RUN% || EXIT 1 + ) +) ELSE ( + ECHO Using default MSVC build environment for 32 bit architecture + ECHO Executing: %COMMAND_TO_RUN% + call %COMMAND_TO_RUN% || EXIT 1 +) From a10914a6457aebf22d8af9f6286dc7ff15dcf544 Mon Sep 17 00:00:00 2001 From: rocky Date: Mon, 8 May 2017 06:30:48 -0400 Subject: [PATCH 13/51] appveyor take 2 --- appveyor.yml | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index 24c1c7f6..47cab67d 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -11,13 +11,13 @@ environment: # a later point release. # See: http://www.appveyor.com/docs/installed-software#python - - PYTHON: "C:\\Python27" - PYTHON_VERSION: "2.7.x" - PYTHON_ARCH: "32" - - # - PYTHON: "C:\\Python27-x64" + # - PYTHON: "C:\\Python27" # PYTHON_VERSION: "2.7.x" - # PYTHON_ARCH: "64" + # PYTHON_ARCH: "32" + + - PYTHON: "C:\\Python27-x64" + PYTHON_VERSION: "2.7.x" + PYTHON_ARCH: "64" # - PYTHON: "C:\\Python26" # PYTHON_VERSION: "2.6.x" @@ -29,7 +29,7 @@ environment: install: # We need wheel installed to build wheels - - "%PYTHON%\\python.exe -m pip install wheel nose" + - "%PYTHON%\\python.exe -m pip install wheel" # Install Python (from the official .msi of http://python.org) and pip when # not already installed. @@ -39,6 +39,7 @@ install: # done from inside the powershell script as it would require to restart # the parent CMD process). - "SET PATH=%PYTHON%;%PYTHON%\\Scripts;%PATH%" + - "SET HOME=." # Check that we have the expected version and architecture for Python - "python --version" @@ -60,7 +61,7 @@ build_script: test_script: # Run the project tests - - "%CMD_IN_ENV% python test\test_pyenvlib.py --2.7.12 + - "%CMD_IN_ENV% python test/test_pythonlib.py --2.7 --verify" after_test: # If tests are successful, create binary packages for the project. From 8d084ed3585607cc58a3f891b49034d916c0e2e8 Mon Sep 17 00:00:00 2001 From: rocky Date: Mon, 8 May 2017 06:58:12 -0400 Subject: [PATCH 14/51] pysource guard and another appveyor test --- appveyor.yml | 2 +- test/test_pyenvlib.py | 9 +++++++-- uncompyle6/semantics/pysource.py | 11 ++++++----- 3 files changed, 14 insertions(+), 8 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index 47cab67d..04ac8d77 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -61,7 +61,7 @@ build_script: test_script: # Run the project tests - - "%CMD_IN_ENV% python test/test_pythonlib.py --2.7 --verify" + - "%CMD_IN_ENV% python test/test_pyenvlib.py --native --weak-verify" after_test: # If tests are successful, create binary packages for the project. diff --git a/test/test_pyenvlib.py b/test/test_pyenvlib.py index a9bb408a..2cacdd4c 100755 --- a/test/test_pyenvlib.py +++ b/test/test_pyenvlib.py @@ -22,7 +22,7 @@ Step 2: Run the test: from __future__ import print_function from uncompyle6 import main, PYTHON3 -import os, time, shutil +import os, time, shutil, sys from fnmatch import fnmatch #----- configure this for your needs @@ -33,7 +33,7 @@ TEST_VERSIONS=('2.3.7', '2.4.6', '2.5.6', '2.6.9', '2.7.10', '2.7.11', '2.7.12', '2.7.13', '3.0.1', '3.1.5', '3.2.6', '3.3.5', '3.3.6', - '3.4.2', '3.5.1', '3.6.0') + '3.4.2', '3.5.1', '3.6.0', 'native') target_base = '/tmp/py-dis/' lib_prefix = os.path.join(os.environ['HOME'], '.pyenv/versions') @@ -54,6 +54,11 @@ for vers in TEST_VERSIONS: short_vers = vers[0:-2] test_options[vers] = (os.path.join(lib_prefix, vers, 'lib_pypy'), PYC, 'python-lib'+short_vers) + if vers == 'native': + short_vers = os.path.basename(sys.path[-1]) + test_options[vers] = (sys.path[-1], + PYC, short_vers) + else: short_vers = vers[:3] test_options[vers] = (os.path.join(lib_prefix, vers, 'lib', 'python'+short_vers), diff --git a/uncompyle6/semantics/pysource.py b/uncompyle6/semantics/pysource.py index a0d1fd13..e4d8666e 100644 --- a/uncompyle6/semantics/pysource.py +++ b/uncompyle6/semantics/pysource.py @@ -531,11 +531,12 @@ class SourceWalker(GenericASTTraversal, object): next_offset = self.scanner.next_offset(op, offset) scanner = self.scanner code = scanner.code - next_inst = code[next_offset] - if (scanner.opc.opname[next_inst] == 'JUMP_ABSOLUTE' - and t.pattr == code[next_offset+1]): - # Suppress "continue" - self.prune() + if next_offset < len(code): + next_inst = code[next_offset] + if (scanner.opc.opname[next_inst] == 'JUMP_ABSOLUTE' + and t.pattr == code[next_offset+1]): + # Suppress "continue" + self.prune() self.default(node) def n_return_stmt(self, node): From ca1679e636a6d2deef0658f9857ee0ddba9b17fe Mon Sep 17 00:00:00 2001 From: Daniel Bradburn Date: Wed, 10 May 2017 21:49:42 +0200 Subject: [PATCH 15/51] Added support for support for Python 3.6 CALL_FUNCTION_KW --- pytest/test_CALL_FUNCTION_KW.sh | 6 ++ pytest/test_function_call.py | 138 +++++++++++++++++++++---------- uncompyle6/parsers/parse3.py | 3 +- uncompyle6/parsers/parse36.py | 11 +++ uncompyle6/scanners/scanner36.py | 2 + uncompyle6/semantics/pysource.py | 14 ++++ 6 files changed, 128 insertions(+), 46 deletions(-) create mode 100644 pytest/test_CALL_FUNCTION_KW.sh diff --git a/pytest/test_CALL_FUNCTION_KW.sh b/pytest/test_CALL_FUNCTION_KW.sh new file mode 100644 index 00000000..5b3fe0ab --- /dev/null +++ b/pytest/test_CALL_FUNCTION_KW.sh @@ -0,0 +1,6 @@ +source ../.venv.3.6/bin/activate +py.test -k test_CALL_FUNCTION_KW +source ../.venv.3.5/bin/activate +py.test -k test_CALL_FUNCTION_KW +source ../.venv.2.7/bin/activate +py.test -k test_CALL_FUNCTION_KW \ No newline at end of file diff --git a/pytest/test_function_call.py b/pytest/test_function_call.py index 7b7b9729..099a208f 100644 --- a/pytest/test_function_call.py +++ b/pytest/test_function_call.py @@ -1,20 +1,24 @@ # std import string # 3rd party -from hypothesis import given, assume, strategies as st +from hypothesis import given, assume, example, settings, strategies as st import pytest # uncompyle from validate import validate_uncompyle +from test_fstring import expressions alpha = st.sampled_from(string.ascii_lowercase) numbers = st.sampled_from(string.digits) alphanum = st.sampled_from(string.ascii_lowercase + string.digits) -expressions = st.sampled_from([x for x in string.ascii_lowercase + string.digits] + ['x+1']) @st.composite -def function_calls(draw): +def function_calls(draw, + min_keyword_args=0, max_keyword_args=5, + min_positional_args=0, max_positional_args=5, + min_star_args=0, max_star_args=1, + min_double_star_args=0, max_double_star_args=1): """ Strategy factory for generating function calls. @@ -22,21 +26,49 @@ def function_calls(draw): :return: The function call text. """ - list1 = st.lists(alpha, min_size=0, max_size=1) - list3 = st.lists(alpha, min_size=0, max_size=3) + st_positional_args = st.lists( + alpha, + min_size=min_positional_args, + max_size=max_positional_args + ) + st_keyword_args = st.lists( + alpha, + min_size=min_keyword_args, + max_size=max_keyword_args + ) + st_star_args = st.lists( + alpha, + min_size=min_star_args, + max_size=max_star_args + ) + st_double_star_args = st.lists( + alpha, + min_size=min_double_star_args, + max_size=max_double_star_args + ) - positional_args = draw(list3) - named_args = [x + '=0' for x in draw(list3)] - star_args = ['*' + x for x in draw(list1)] - double_star_args = ['**' + x for x in draw(list1)] + positional_args = draw(st_positional_args) + keyword_args = draw(st_keyword_args) + st_values = st.lists( + expressions(), + min_size=len(keyword_args), + max_size=len(keyword_args) + ) + keyword_args = [ + x + '=' + e + for x, e in + zip(keyword_args, draw(st_values)) + ] + star_args = ['*' + x for x in draw(st_star_args)] + double_star_args = ['**' + x for x in draw(st_double_star_args)] - arguments = positional_args + named_args + star_args + double_star_args + arguments = positional_args + keyword_args + star_args + double_star_args draw(st.randoms()).shuffle(arguments) arguments = ','.join(arguments) function_call = 'fn({arguments})'.format(arguments=arguments) try: - # TODO: Figure out the exact rules for ordering of positional, named, + # TODO: Figure out the exact rules for ordering of positional, keyword, # star args, double star args and in which versions the various # types of arguments are supported so we don't need to check that the # expression compiles like this. @@ -46,9 +78,56 @@ def function_calls(draw): return function_call -@pytest.mark.xfail() -def test_CALL_FUNCTION(): - validate_uncompyle("fn(w,m,f)") +def test_function_no_args(): + validate_uncompyle("fn()") + + +def isolated_function_calls(which): + """ + Returns a strategy for generating function calls, but isolated to + particular types of arguments, for example only positional arguments. + + This can help reason about debugging errors in specific types of function + calls. + + :param which: One of 'keyword', 'positional', 'star', 'double_star' + + :return: Strategy for generating an function call isolated to specific + argument types. + """ + kwargs = dict( + max_keyword_args=0, + max_positional_args=0, + max_star_args=0, + max_double_star_args=0, + ) + kwargs['_'.join(('min', which, 'args'))] = 1 + kwargs['_'.join(('max', which, 'args'))] = 5 if 'star' not in which else 1 + return function_calls(**kwargs) + + +with settings(max_examples=25): + + @given(isolated_function_calls('positional')) + @example("fn(0)") + def test_function_positional_only(expr): + validate_uncompyle(expr) + + @given(isolated_function_calls('keyword')) + @example("fn(a=0)") + def test_function_call_keyword_only(expr): + validate_uncompyle(expr) + + @given(isolated_function_calls('star')) + @example("fn(*items)") + def test_function_call_star_only(expr): + validate_uncompyle(expr) + + @pytest.mark.xfail() + @given(isolated_function_calls('double_star')) + @example("fn(**{})") + def test_function_call_double_star_only(expr): + validate_uncompyle(expr) @pytest.mark.xfail() @@ -61,11 +140,6 @@ def test_BUILD_MAP_BUILD_MAP_UNPACK_WITH_CALL_BUILD_TUPLE_CALL_FUNCTION_EX(): validate_uncompyle("fn(a=0,**g)") -@pytest.mark.xfail() -def test_CALL_FUNCTION_KW(): - validate_uncompyle("fn(j=0)") - - @pytest.mark.xfail() def test_CALL_FUNCTION_EX(): validate_uncompyle("fn(*g,**j)") @@ -100,29 +174,3 @@ def test_BUILD_CONST_KEY_MAP_CALL_FUNCTION_EX(): @given(function_calls()) def test_function_call(function_call): validate_uncompyle(function_call) - - -examples = set() -generate_examples = False - - -@pytest.mark.skipif(not generate_examples, reason='not generating examples') -@given(function_calls()) -def test_generate_hypothesis(function_call): - examples.add(function_call) - - -@pytest.mark.skipif(not generate_examples, reason='not generating examples') -def test_generate_examples(): - import dis - example_opcodes = {} - for example in examples: - opcodes = tuple(sorted(set( - instruction.opname - for instruction in dis.Bytecode(example) - if instruction.opname not in ('LOAD_CONST', 'LOAD_NAME', 'RETURN_VALUE') - ))) - example_opcodes[opcodes] = example - for k, v in example_opcodes.items(): - print('def test_' + '_'.join(k) + '():\n validate_uncompyle("' + v + '")\n\n') - return diff --git a/uncompyle6/parsers/parse3.py b/uncompyle6/parsers/parse3.py index bef1f34b..624c780b 100644 --- a/uncompyle6/parsers/parse3.py +++ b/uncompyle6/parsers/parse3.py @@ -607,7 +607,8 @@ class Python3Parser(PythonParser): """, nop_func) continue elif opname in ('CALL_FUNCTION', 'CALL_FUNCTION_VAR', - 'CALL_FUNCTION_VAR_KW', 'CALL_FUNCTION_KW'): + 'CALL_FUNCTION_VAR_KW') \ + or opname.startswith('CALL_FUNCTION_KW'): self.custom_classfunc_rule(opname, token, customize) elif opname == 'LOAD_DICTCOMP': rule_pat = ("dictcomp ::= LOAD_DICTCOMP %sMAKE_FUNCTION_0 expr " diff --git a/uncompyle6/parsers/parse36.py b/uncompyle6/parsers/parse36.py index f93a86a8..dee9fcee 100644 --- a/uncompyle6/parsers/parse36.py +++ b/uncompyle6/parsers/parse36.py @@ -58,6 +58,17 @@ class Python36Parser(Python35Parser): """ % (fstring_expr_or_str_n, fstring_expr_or_str_n, "fstring_expr_or_str " * v) self.add_unique_doc_rules(rules_str, customize) + def custom_classfunc_rule(self, opname, token, customize): + + if opname.startswith('CALL_FUNCTION_KW'): + values = 'expr ' * token.attr + rule = 'call_function ::= expr kwargs_only_36 {token.type}'.format(**locals()) + self.add_unique_rule(rule, token.type, token.attr, customize) + rule = 'kwargs_only_36 ::= {values} LOAD_CONST'.format(**locals()) + self.add_unique_rule(rule, token.type, token.attr, customize) + else: + super(Python36Parser, self).custom_classfunc_rule(opname, token, customize) + class Python36ParserSingle(Python36Parser, PythonParserSingle): pass diff --git a/uncompyle6/scanners/scanner36.py b/uncompyle6/scanners/scanner36.py index 65ca0ba5..15265f12 100644 --- a/uncompyle6/scanners/scanner36.py +++ b/uncompyle6/scanners/scanner36.py @@ -28,6 +28,8 @@ class Scanner36(Scanner3): if t.op == self.opc.CALL_FUNCTION_EX and t.attr & 1: t.type = 'CALL_FUNCTION_EX_KW' pass + if t.op == self.opc.CALL_FUNCTION_KW: + t.type = 'CALL_FUNCTION_KW_{t.attr}'.format(**locals()) pass return tokens, customize diff --git a/uncompyle6/semantics/pysource.py b/uncompyle6/semantics/pysource.py index e4d8666e..2b9a0323 100644 --- a/uncompyle6/semantics/pysource.py +++ b/uncompyle6/semantics/pysource.py @@ -392,6 +392,7 @@ class SourceWalker(GenericASTTraversal, object): 'fstring_single': ( "f'{%c%{conversion}}'", 0), 'fstring_multi': ( "f'%c'", 0), 'func_args36': ( "%c(**", 0), + #'kwargs_only_36': ( "%c(**", 0), }) TABLE_R.update({ 'CALL_FUNCTION_EX': ('%c(*%P)', 0, (1, 2, ', ', 100)), @@ -413,6 +414,17 @@ class SourceWalker(GenericASTTraversal, object): self.default(node) self.n_fstring_single = n_fstring_single + def n_kwargs_only_36(node): + keys = node[-1].attr + num_kwargs = len(keys) + values = node[:num_kwargs] + for i, (key, value) in enumerate(zip(keys, values)): + self.write(key + '=') + self.preorder(value) + if i < num_kwargs: + self.write(',') + self.prune() + self.n_kwargs_only_36 = n_kwargs_only_36 return f = property(lambda s: s.params['f'], @@ -1800,6 +1812,8 @@ class SourceWalker(GenericASTTraversal, object): if k.startswith('CALL_METHOD'): # This happens in PyPy only TABLE_R[k] = ('%c(%P)', 0, (1, -1, ', ', 100)) + elif self.version >= 3.6 and k.startswith('CALL_FUNCTION_KW'): + TABLE_R[k] = ('%c(%P)', 0, (1, -1, ', ', 100)) elif op == 'CALL_FUNCTION': TABLE_R[k] = ('%c(%P)', 0, (1, -1, ', ', 100)) elif op in ('CALL_FUNCTION_VAR', From b952f56c445cf5b92000c72b799850076681064a Mon Sep 17 00:00:00 2001 From: Daniel Bradburn Date: Wed, 10 May 2017 22:36:28 +0200 Subject: [PATCH 16/51] Adding requirement for pytest >= 3.0 to fix strange INTERNALERROR in combination with hypothesis when using pytest 2.6.4 --- requirements-dev.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-dev.txt b/requirements-dev.txt index 804a075c..b7c5be83 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -1,4 +1,4 @@ -pytest +pytest>=3.0.0 flake8 hypothesis six \ No newline at end of file From 93437152a2145715ab22af37136daadc7a273bb0 Mon Sep 17 00:00:00 2001 From: Daniel Bradburn Date: Wed, 10 May 2017 22:52:49 +0200 Subject: [PATCH 17/51] Fixed bug in compiling double star arg only function calls where the closing parenthesis would be missed --- uncompyle6/semantics/pysource.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/uncompyle6/semantics/pysource.py b/uncompyle6/semantics/pysource.py index 2b9a0323..2b308212 100644 --- a/uncompyle6/semantics/pysource.py +++ b/uncompyle6/semantics/pysource.py @@ -397,7 +397,7 @@ class SourceWalker(GenericASTTraversal, object): TABLE_R.update({ 'CALL_FUNCTION_EX': ('%c(*%P)', 0, (1, 2, ', ', 100)), # Not quite right - 'CALL_FUNCTION_EX_KW': ('%c(**%C', 0, (2,3, ',')), + 'CALL_FUNCTION_EX_KW': ('%c(**%C)', 0, (2,3, ',')), }) FSTRING_CONVERSION_MAP = {1: '!s', 2: '!r', 3: '!a'} From 038692dbf964d21902cf37b2e0b4dac6a2b65461 Mon Sep 17 00:00:00 2001 From: Daniel Bradburn Date: Wed, 10 May 2017 22:57:48 +0200 Subject: [PATCH 18/51] Double star arg only test is no longer expected to fail --- pytest/test_function_call.py | 1 - 1 file changed, 1 deletion(-) diff --git a/pytest/test_function_call.py b/pytest/test_function_call.py index 099a208f..936c31ce 100644 --- a/pytest/test_function_call.py +++ b/pytest/test_function_call.py @@ -123,7 +123,6 @@ with settings(max_examples=25): def test_function_call_star_only(expr): validate_uncompyle(expr) - @pytest.mark.xfail() @given(isolated_function_calls('double_star')) @example("fn(**{})") def test_function_call_double_star_only(expr): From d540146d5a062c7b9bde53219123ec5575cca9f9 Mon Sep 17 00:00:00 2001 From: rocky Date: Thu, 11 May 2017 07:00:46 -0400 Subject: [PATCH 19/51] WIP: start 3.6 MAKE_FUNCTION handling --- uncompyle6/parsers/parse3.py | 5 ++- uncompyle6/scanners/scanner3.py | 46 ++++++++++++++++++++------- uncompyle6/semantics/make_function.py | 12 ++++++- 3 files changed, 50 insertions(+), 13 deletions(-) diff --git a/uncompyle6/parsers/parse3.py b/uncompyle6/parsers/parse3.py index 624c780b..589d68da 100644 --- a/uncompyle6/parsers/parse3.py +++ b/uncompyle6/parsers/parse3.py @@ -701,7 +701,10 @@ class Python3Parser(PythonParser): rule = 'unpack_list ::= ' + opname + ' designator' * token.attr elif opname_base.startswith('MAKE_FUNCTION'): # DRY with MAKE_CLOSURE - args_pos, args_kw, annotate_args = token.attr + if self.version < 3.6: + args_pos, args_kw, annotate_args = token.attr + else: + args_pos, args_kw, annotate_args, closure = token.attr rule_pat = ("genexpr ::= %sload_genexpr %%s%s expr " "GET_ITER CALL_FUNCTION_1" % ('pos_arg '* args_pos, opname)) diff --git a/uncompyle6/scanners/scanner3.py b/uncompyle6/scanners/scanner3.py index 3f0f751c..f3769fe7 100644 --- a/uncompyle6/scanners/scanner3.py +++ b/uncompyle6/scanners/scanner3.py @@ -130,6 +130,13 @@ class Scanner3(Scanner): varargs_ops.add(self.opc.CALL_METHOD) if self.version >= 3.6: varargs_ops.add(self.opc.BUILD_CONST_KEY_MAP) + # Below is in bit order, "defaultt = bit 0, closure = bit 3 + self.MAKE_FUNCTION_FLAGS = ( + ("default", 'D'), + ("keyword-only", "K"), + ("annotation", "A"), + ("closure", "C") + ) self.varargs_ops = frozenset(varargs_ops) # FIXME: remove the above in favor of: @@ -271,20 +278,37 @@ class Scanner3(Scanner): pattr = const pass elif opname in ('MAKE_FUNCTION', 'MAKE_CLOSURE'): - pos_args, name_pair_args, annotate_args = parse_fn_counts(inst.argval) - if name_pair_args > 0: - opname = '%s_N%d' % (opname, name_pair_args) - pass - if annotate_args > 0: - opname = '%s_A_%d' % (opname, annotate_args) - pass - opname = '%s_%d' % (opname, pos_args) - pattr = ("%d positional, %d keyword pair, %d annotated" % - (pos_args, name_pair_args, annotate_args)) + if self.version >= 3.6: + # 3.6+ doesn't have MAKE_CLOSURE, so opname == 'MAKE_CLOSURE' + flags = inst.argval + opname = 'MAKE_FUNCTION_%d' % (flags) + attr = [] + for tup in self.MAKE_FUNCTION_FLAGS: + bit = flags & 1 + if bit: + if pattr: + pattr += ", " + tup[0] + else: + pattr += tup[0] + attr.append(bit) + flags >>= 1 + attr = attr[:4] # remove last value: attr[5] == False + else: + pos_args, name_pair_args, annotate_args = parse_fn_counts(inst.argval) + pattr = ("%d positional, %d keyword pair, %d annotated" % + (pos_args, name_pair_args, annotate_args)) + if name_pair_args > 0: + opname = '%s_N%d' % (opname, name_pair_args) + pass + if annotate_args > 0: + opname = '%s_A_%d' % (opname, annotate_args) + pass + opname = '%s_%d' % (opname, pos_args) + attr = (pos_args, name_pair_args, annotate_args) tokens.append( Token( type_ = opname, - attr = (pos_args, name_pair_args, annotate_args), + attr = attr, pattr = pattr, offset = inst.offset, linestart = inst.starts_line, diff --git a/uncompyle6/semantics/make_function.py b/uncompyle6/semantics/make_function.py index 1ccefc83..d73b7b3b 100644 --- a/uncompyle6/semantics/make_function.py +++ b/uncompyle6/semantics/make_function.py @@ -461,7 +461,17 @@ def make_function3(self, node, isLambda, nested=1, codeNode=None): defparams = node[:args_node.attr[0]] pos_args, kw_args, annotate_argc = args_node.attr else: - defparams = node[:args_node.attr] + if self.version < 3.6: + defparams = node[:args_node.attr] + else: + default, kw, annotate, closure = args_node.attr + # FIXME: start here. + defparams = [] + # if default: + # defparams = node[-(2 + kw + annotate + closure)] + # else: + # defparams = [] + kw_args = 0 pass From 69fd1b33716e28d2b1cf5c6d9ac7d068c30039c9 Mon Sep 17 00:00:00 2001 From: Gregory Komagurov Date: Thu, 11 May 2017 19:43:14 +0300 Subject: [PATCH 20/51] Fix tests --- uncompyle6/main.py | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/uncompyle6/main.py b/uncompyle6/main.py index 7d850316..141eefce 100644 --- a/uncompyle6/main.py +++ b/uncompyle6/main.py @@ -106,6 +106,7 @@ def main(in_base, out_base, files, codes, outfile=None, return open(outfile, 'w') tot_files = okay_files = failed_files = verify_failed_files = 0 + current_outfile = outfile for filename in files: infile = os.path.join(in_base, filename) @@ -134,11 +135,11 @@ def main(in_base, out_base, files, codes, outfile=None, os.dup2(tee.stdin.fileno(), sys.stderr.fileno()) else: if filename.endswith('.pyc'): - outfileindir = os.path.join(out_base, filename[0:-1]) + current_outfile = os.path.join(out_base, filename[0:-1]) else: - outfileindir = os.path.join(out_base, filename) + '_dis' - outstream = _get_outstream(outfileindir) - # print(outfile, file=sys.stderr) + current_outfile = os.path.join(out_base, filename) + '_dis' + outstream = _get_outstream(current_outfile) + # print(current_outfile, file=sys.stderr) # Try to uncompile the input file try: @@ -157,16 +158,16 @@ def main(in_base, out_base, files, codes, outfile=None, raise # except: # failed_files += 1 - # if outfile: + # if current_outfile: # outstream.close() - # os.rename(outfile, outfile + '_failed') + # os.rename(current_outfile, current_outfile + '_failed') # else: # sys.stderr.write("\n# %s" % sys.exc_info()[1]) # sys.stderr.write("\n# Can't uncompile %s\n" % infile) else: # uncompile successful - if outfile: + if current_outfile: if do_linemaps: - mapping = line_number_mapping(infile, outfile) + mapping = line_number_mapping(infile, current_outfile) outstream.write("\n\n## Line number correspondences\n") import pprint s = pprint.pformat(mapping, indent=2, width=80) @@ -177,8 +178,8 @@ def main(in_base, out_base, files, codes, outfile=None, if do_verify: weak_verify = do_verify == 'weak' try: - msg = verify.compare_code_with_srcfile(infile, outfile, weak_verify=weak_verify) - if not outfile: + msg = verify.compare_code_with_srcfile(infile, current_outfile, weak_verify=weak_verify) + if not current_outfile: if not msg: print('\n# okay decompiling %s' % infile) okay_files += 1 @@ -187,7 +188,7 @@ def main(in_base, out_base, files, codes, outfile=None, except verify.VerifyCmpError as e: print(e) verify_failed_files += 1 - os.rename(outfile, outfile + '_unverified') + os.rename(current_outfile, current_outfile + '_unverified') sys.stderr.write("### Error Verifying %s\n" % filename) sys.stderr.write(str(e) + "\n") if not outfile: @@ -201,15 +202,15 @@ def main(in_base, out_base, files, codes, outfile=None, pass else: okay_files += 1 - if not outfile: + if not current_outfile: mess = '\n# okay decompiling' # mem_usage = __memUsage() print(mess, infile) - if outfile: + if current_outfile: sys.stdout.write("%s\r" % status_msg(do_verify, tot_files, okay_files, failed_files, verify_failed_files)) sys.stdout.flush() - if outfile: + if current_outfile: sys.stdout.write("\n") sys.stdout.flush() return (tot_files, okay_files, failed_files, verify_failed_files) From 4c2ca44818f21233247384b690531109104b1365 Mon Sep 17 00:00:00 2001 From: rocky Date: Fri, 12 May 2017 22:52:05 -0400 Subject: [PATCH 21/51] Bug in 2.7 decompiling ourself! Troublesome file was uncompyle6.semantics.pysource.engine() --- uncompyle6/parsers/parse27.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/uncompyle6/parsers/parse27.py b/uncompyle6/parsers/parse27.py index 3be0a4a7..d7392810 100644 --- a/uncompyle6/parsers/parse27.py +++ b/uncompyle6/parsers/parse27.py @@ -52,6 +52,8 @@ class Python27Parser(Python2Parser): come_froms ::= come_froms COME_FROM come_froms ::= COME_FROM + iflaststmtl ::= testexpr c_stmts_opt + _ifstmts_jump ::= c_stmts_opt JUMP_FORWARD come_froms bp_come_from ::= POP_BLOCK COME_FROM From 73857c831ba600bdb3e202479a8276b71de3e8f4 Mon Sep 17 00:00:00 2001 From: rocky Date: Sat, 13 May 2017 06:12:31 -0400 Subject: [PATCH 22/51] Typo --- uncompyle6/scanners/scanner3.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/uncompyle6/scanners/scanner3.py b/uncompyle6/scanners/scanner3.py index f3769fe7..00975cd9 100644 --- a/uncompyle6/scanners/scanner3.py +++ b/uncompyle6/scanners/scanner3.py @@ -130,7 +130,7 @@ class Scanner3(Scanner): varargs_ops.add(self.opc.CALL_METHOD) if self.version >= 3.6: varargs_ops.add(self.opc.BUILD_CONST_KEY_MAP) - # Below is in bit order, "defaultt = bit 0, closure = bit 3 + # Below is in bit order, "default = bit 0, closure = bit 3 self.MAKE_FUNCTION_FLAGS = ( ("default", 'D'), ("keyword-only", "K"), From a32c0e68ef42bf6ef666a17fecfb0a39bb8952c3 Mon Sep 17 00:00:00 2001 From: rocky Date: Sat, 13 May 2017 10:02:59 -0400 Subject: [PATCH 23/51] Bang on 3.6 MAKE_FUNCTION a bit more parse3.py, parse36.py: adding return_closure rule tags what's going on with this rule pysource.py: start changing semantic rules to support code changed by new make_function semantics README.rst: typo --- README.rst | 2 +- uncompyle6/parsers/parse3.py | 4 ++- uncompyle6/parsers/parse36.py | 2 ++ uncompyle6/semantics/pysource.py | 50 ++++++++++++++++++++++---------- 4 files changed, 41 insertions(+), 17 deletions(-) diff --git a/README.rst b/README.rst index 1cfcce86..4d8e4e42 100644 --- a/README.rst +++ b/README.rst @@ -168,7 +168,7 @@ See Also -------- * https://github.com/zrax/pycdc : supports all versions of Python and is written in C++. Support for later Python 3 versions is a bit lacking though. -* https://code.google.com/archive/p/unpyc3/ : supports Python 3.2 only. The above projects use a different decompiling technique what is used here. +* https://code.google.com/archive/p/unpyc3/ : supports Python 3.2 only. The above projects use a different decompiling technique than what is used here. * https://github.com/figment/unpyc3/ : fork of above, but supports Python 3.3 only. Include some fixes like supporting function annotations * The HISTORY_ file. diff --git a/uncompyle6/parsers/parse3.py b/uncompyle6/parsers/parse3.py index 589d68da..e4923696 100644 --- a/uncompyle6/parsers/parse3.py +++ b/uncompyle6/parsers/parse3.py @@ -334,7 +334,9 @@ class Python3Parser(PythonParser): def p_stmt3(self, args): """ - stmt ::= LOAD_CLOSURE RETURN_VALUE RETURN_LAST + stmt ::= return_closure + return_closure ::= LOAD_CLOSURE RETURN_VALUE RETURN_LAST + stmt ::= whileTruestmt ifelsestmt ::= testexpr c_stmts_opt JUMP_FORWARD else_suite _come_from """ diff --git a/uncompyle6/parsers/parse36.py b/uncompyle6/parsers/parse36.py index dee9fcee..92e41e2b 100644 --- a/uncompyle6/parsers/parse36.py +++ b/uncompyle6/parsers/parse36.py @@ -16,6 +16,8 @@ class Python36Parser(Python35Parser): def p_36misc(self, args): """ + return_closure ::= LOAD_CLOSURE DUP_TOP STORE_NAME RETURN_VALUE RETURN_LAST + expr ::= LOAD_NAME EXTENDED_ARG fstring_multi ::= fstring_expr_or_strs BUILD_STRING diff --git a/uncompyle6/semantics/pysource.py b/uncompyle6/semantics/pysource.py index 2b308212..4d7ed3de 100644 --- a/uncompyle6/semantics/pysource.py +++ b/uncompyle6/semantics/pysource.py @@ -424,7 +424,17 @@ class SourceWalker(GenericASTTraversal, object): if i < num_kwargs: self.write(',') self.prune() + return self.n_kwargs_only_36 = n_kwargs_only_36 + + def n_return_closure(node): + # Nothing should be output here + self.prune() + return + self.n_return_closure = n_return_closure + pass # version > 3.6 + pass # version > 3.4 + pass # version > 3.0 return f = property(lambda s: s.params['f'], @@ -1288,11 +1298,18 @@ class SourceWalker(GenericASTTraversal, object): if self.version > 3.0: if node == 'classdefdeco2': - currentclass = node[1][2].pattr + if self.version >= 3.6: + class_code = node[1][1].pattr + else: + class_code = node[1][2].pattr buildclass = node else: - currentclass = node[1][0].pattr - buildclass = node[0] + if self.version >= 3.6: + class_code = node[0][1][0].pattr + buildclass = node[0] + else: + class_code = node[1][0].pattr + buildclass = node[0] assert 'mkfunc' == buildclass[1] mkfunc = buildclass[1] @@ -1300,16 +1317,16 @@ class SourceWalker(GenericASTTraversal, object): if 3.0 <= self.version <= 3.2: for n in mkfunc: if hasattr(n, 'attr') and iscode(n.attr): - subclass = n.attr + subclass_code = n.attr break elif n == 'expr': - subclass = n[0].attr + subclass_code = n[0].attr pass pass else: for n in mkfunc: if hasattr(n, 'attr') and iscode(n.attr): - subclass = n.attr + subclass_code = n.attr break pass pass @@ -1321,10 +1338,10 @@ class SourceWalker(GenericASTTraversal, object): # Python 3.3 classes with closures work like this. # Note have to test before 3.2 case because # index -2 also has an attr. - subclass = load_closure[-3].attr + subclass_code = load_closure[-3].attr elif hasattr(load_closure[-2], 'attr'): # Python 3.2 works like this - subclass = load_closure[-2].attr + subclass_code = load_closure[-2].attr else: raise 'Internal Error n_classdef: cannot find class body' if hasattr(buildclass[3], '__len__'): @@ -1333,18 +1350,21 @@ class SourceWalker(GenericASTTraversal, object): subclass_info = buildclass[2] else: raise 'Internal Error n_classdef: cannot superclass name' + elif self.version >= 3.6 and node == 'classdefdeco2': + subclass_info = node + subclass_code = buildclass[1][0].attr else: - subclass = buildclass[1][0].attr + subclass_code = buildclass[1][0].attr subclass_info = node[0] else: buildclass = node if (node == 'classdefdeco2') else node[0] build_list = buildclass[1][0] if hasattr(buildclass[-3][0], 'attr'): - subclass = buildclass[-3][0].attr - currentclass = buildclass[0].pattr + subclass_code = buildclass[-3][0].attr + class_code = buildclass[0].pattr elif hasattr(node[0][0], 'pattr'): - subclass = buildclass[-3][1].attr - currentclass = node[0][0].pattr + subclass_code = buildclass[-3][1].attr + class_code = node[0][0].pattr else: raise 'Internal Error n_classdef: cannot find class name' @@ -1353,7 +1373,7 @@ class SourceWalker(GenericASTTraversal, object): else: self.write('\n\n') - self.currentclass = str(currentclass) + self.currentclass = str(class_code) self.write(self.indent, 'class ', self.currentclass) if self.version > 3.0: @@ -1364,7 +1384,7 @@ class SourceWalker(GenericASTTraversal, object): # class body self.indentMore() - self.build_class(subclass) + self.build_class(subclass_code) self.indentLess() self.currentclass = cclass From ff73efcf8eb367c9bfe3d6782eb74a5fbe9da30d Mon Sep 17 00:00:00 2001 From: rocky Date: Sat, 13 May 2017 11:39:19 -0400 Subject: [PATCH 24/51] Grammar rules for Python 3.6 MAKE_FUNCTION --- test/bytecode_3.6/11_classbug.pyc | Bin 0 -> 486 bytes uncompyle6/parsers/parse3.py | 12 ++++++++++++ 2 files changed, 12 insertions(+) create mode 100644 test/bytecode_3.6/11_classbug.pyc diff --git a/test/bytecode_3.6/11_classbug.pyc b/test/bytecode_3.6/11_classbug.pyc new file mode 100644 index 0000000000000000000000000000000000000000..cf63e8c8ea524498d503bcc3aed2f281d8b03aee GIT binary patch literal 486 zcmZWkJx{|h5Ix(eNGrM^1|%3*v$QI#2(dBIg-S?SPO0spqV$8<8H%#CQYH8kto$Xf z{0k=Tk}3?G^v-AB-Fwg1{eJKL^XlmX0KN%rL{!}o+$p7dFkr-vU}39LVdNtuN>ir| zb*S706&7d)Qn`njFf_f3Q?-W((unuM2~O-{ooC)YSfA-Ub564!2cHb)b7z!1cu~Pt zzQ{^cvQk?m$PMv`F;R6~xwb_iXfVWx^X1$lCQ(p2cOhD43mZDq%vqNzqkSSm7qJ#Z z{DPlLHzyw!-Ks3K9U40ujz&#?T0Rffn}Tgfw!#U-+xdU%gI2b~7FZK8^bi*-QxZ9b zW5m}o%bQM38Ttns+U7Z85fgcx5>Xs+-Q~o;V$|ZXsPE%MhRAQ|)7<%6Y${$0@lB(A JTkp~f`~r?8Z{q*} literal 0 HcmV?d00001 diff --git a/uncompyle6/parsers/parse3.py b/uncompyle6/parsers/parse3.py index e4923696..4b274e01 100644 --- a/uncompyle6/parsers/parse3.py +++ b/uncompyle6/parsers/parse3.py @@ -703,6 +703,18 @@ class Python3Parser(PythonParser): rule = 'unpack_list ::= ' + opname + ' designator' * token.attr elif opname_base.startswith('MAKE_FUNCTION'): # DRY with MAKE_CLOSURE + if self.version >= 3.6: + # The semantics of MAKE_FUNCTION in 3.6 are totally different from + # before. + args_pos, args_kw, annotate_args, closure = token.attr + stack_count = args_pos + args_kw + annotate_args + rule = ('mkfunc ::= %s%s%s%s' % + ('expr ' * stack_count, + 'load_closure ' * closure, + 'LOAD_CONST ' * 2, + opname)) + self.add_unique_rule(rule, opname, token.attr, customize) + continue if self.version < 3.6: args_pos, args_kw, annotate_args = token.attr else: From da884487d5158e896b4fe03813664fd9b6b5054f Mon Sep 17 00:00:00 2001 From: rocky Date: Sat, 13 May 2017 11:47:27 -0400 Subject: [PATCH 25/51] MAKE_FUNCTION_FLAGS can be a simpler tuple --- uncompyle6/scanners/scanner3.py | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/uncompyle6/scanners/scanner3.py b/uncompyle6/scanners/scanner3.py index 00975cd9..6b1f1032 100644 --- a/uncompyle6/scanners/scanner3.py +++ b/uncompyle6/scanners/scanner3.py @@ -131,12 +131,8 @@ class Scanner3(Scanner): if self.version >= 3.6: varargs_ops.add(self.opc.BUILD_CONST_KEY_MAP) # Below is in bit order, "default = bit 0, closure = bit 3 - self.MAKE_FUNCTION_FLAGS = ( - ("default", 'D'), - ("keyword-only", "K"), - ("annotation", "A"), - ("closure", "C") - ) + self.MAKE_FUNCTION_FLAGS = tuple(""" + default keyword-only annotation closure""".split()) self.varargs_ops = frozenset(varargs_ops) # FIXME: remove the above in favor of: From ea732acf496bc194c1344563106d1b6f3dc3880c Mon Sep 17 00:00:00 2001 From: rocky Date: Sat, 13 May 2017 17:29:20 -0400 Subject: [PATCH 26/51] In conjunction with MAKE_FUNCTION_FLAGS change... Switched from tuple to string, but forgot to change the code that uses this. --- uncompyle6/scanners/scanner3.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/uncompyle6/scanners/scanner3.py b/uncompyle6/scanners/scanner3.py index 6b1f1032..e2b36ad2 100644 --- a/uncompyle6/scanners/scanner3.py +++ b/uncompyle6/scanners/scanner3.py @@ -279,13 +279,13 @@ class Scanner3(Scanner): flags = inst.argval opname = 'MAKE_FUNCTION_%d' % (flags) attr = [] - for tup in self.MAKE_FUNCTION_FLAGS: + for flag in self.MAKE_FUNCTION_FLAGS: bit = flags & 1 if bit: if pattr: - pattr += ", " + tup[0] + pattr += ", " + flag else: - pattr += tup[0] + pattr += flag attr.append(bit) flags >>= 1 attr = attr[:4] # remove last value: attr[5] == False From 47977b3372f4a335a33713c5dd585f11ace7f195 Mon Sep 17 00:00:00 2001 From: rocky Date: Sun, 14 May 2017 11:41:12 -0400 Subject: [PATCH 27/51] Python 3.5 kw arg can be an expr Fixes Issue #95 --- test/bytecode_3.5/04_CALL_FUNCTION_VAR_KW.pyc | Bin 0 -> 325 bytes .../bug35/04_CALL_FUNCTION_VAR_KW.py | 7 +++++++ uncompyle6/parsers/parse3.py | 4 +++- 3 files changed, 10 insertions(+), 1 deletion(-) create mode 100644 test/bytecode_3.5/04_CALL_FUNCTION_VAR_KW.pyc create mode 100644 test/simple_source/bug35/04_CALL_FUNCTION_VAR_KW.py diff --git a/test/bytecode_3.5/04_CALL_FUNCTION_VAR_KW.pyc b/test/bytecode_3.5/04_CALL_FUNCTION_VAR_KW.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b9d565a1e5e578a05e87b10a603050dc1de75637 GIT binary patch literal 325 zcmWgR<>gW>mWbTPz`*brh~a=4$Z`PUVqqYW0z`}qDNGD4j0{m=Zm=e^Uosm|3Iy1p z*cnI{D*=fbW`-J8h8jkO8Wxbo8YYGs28JvKhCU|7S~i9nHilqLCcj&3#mO0|xrv&L zx7f1F6N}P|HQ8^m6sP8-MRDY&mL#SmmLwK20!@oz4M|MONxj7aQge$XFEKau7HbJe zXeC1t$nIZy#hJMUIjQl*`K3k4srpH!>Bgq|1}5>&jy^u|ZlQk8A)fwz@nMcZ@!sKj z1(mnBO7dYgFoE360VEh0nHkv_MVX2?fox4iFa> 8) & 0xff + args_kw = (token.attr >> 8) & 0xff + # args_ann = (token.attr >> 16) & 0x7FFF # Additional exprs for * and ** args: # 0 if neither @@ -498,7 +500,7 @@ class Python3Parser(PythonParser): # first LOAD_FAST, below are located. # Python 3.6+ replaces CALL_FUNCTION_VAR_KW with CALL_FUNCTION_EX if opname.endswith('KW'): - kw = 'LOAD_FAST ' + kw = 'expr ' else: kw = '' rule = ('call_function ::= expr expr ' + From b1e32c7cc54416d2c3e81a8903be4ce5e6d00e1c Mon Sep 17 00:00:00 2001 From: rocky Date: Sun, 14 May 2017 12:23:47 -0400 Subject: [PATCH 28/51] towards fixing a 3.5.CALL_FUNCTONI_VAR bug --- uncompyle6/semantics/pysource.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/uncompyle6/semantics/pysource.py b/uncompyle6/semantics/pysource.py index 4d7ed3de..acb83dd6 100644 --- a/uncompyle6/semantics/pysource.py +++ b/uncompyle6/semantics/pysource.py @@ -1850,6 +1850,9 @@ class SourceWalker(GenericASTTraversal, object): if self.version == 3.5: if str == '%c(%C, ': str = '%c(*%C, %c)' + elif str == '%c(%C': + str = '%c(*%C)' + # p2 = (1, -1, 100) else: str += '*%c)' entry = (str, 0, p2, -2) From 47b6a35abc4cea43b352e2441c5dbcfdb91de97e Mon Sep 17 00:00:00 2001 From: rocky Date: Mon, 15 May 2017 03:07:11 -0400 Subject: [PATCH 29/51] Bang on 3.6 MAKE_FUNCTION some more --- uncompyle6/parsers/parse3.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/uncompyle6/parsers/parse3.py b/uncompyle6/parsers/parse3.py index bb0471b7..56ce96d4 100644 --- a/uncompyle6/parsers/parse3.py +++ b/uncompyle6/parsers/parse3.py @@ -716,6 +716,11 @@ class Python3Parser(PythonParser): 'LOAD_CONST ' * 2, opname)) self.add_unique_rule(rule, opname, token.attr, customize) + rule_pat = ('mklambda ::= %s%sLOAD_LAMBDA %%s%s' % + (('pos_arg '* args_pos), + ('kwarg '* args_kw), + opname)) + self.add_make_function_rule(rule_pat, opname, token.attr, customize) continue if self.version < 3.6: args_pos, args_kw, annotate_args = token.attr From d1a695b2bd438b178a2a56e217244ccc098bb91d Mon Sep 17 00:00:00 2001 From: rocky Date: Mon, 15 May 2017 19:28:17 -0400 Subject: [PATCH 30/51] Reinstate 3.6 listcomp rule --- uncompyle6/parsers/parse3.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/uncompyle6/parsers/parse3.py b/uncompyle6/parsers/parse3.py index 56ce96d4..2a16c0bf 100644 --- a/uncompyle6/parsers/parse3.py +++ b/uncompyle6/parsers/parse3.py @@ -721,6 +721,9 @@ class Python3Parser(PythonParser): ('kwarg '* args_kw), opname)) self.add_make_function_rule(rule_pat, opname, token.attr, customize) + rule_pat = ("listcomp ::= %sLOAD_LISTCOMP %%s%s expr " + "GET_ITER CALL_FUNCTION_1" % ('expr ' * args_pos, opname)) + self.add_make_function_rule(rule_pat, opname, token.attr, customize) continue if self.version < 3.6: args_pos, args_kw, annotate_args = token.attr From 2ad40a5648a08836ed68304d29dda8f6b6649cfe Mon Sep 17 00:00:00 2001 From: rocky Date: Tue, 16 May 2017 00:22:48 -0400 Subject: [PATCH 31/51] Allow LOAD_CONST EXTENDED_ARG --- uncompyle6/parsers/parse36.py | 1 + uncompyle6/semantics/pysource.py | 16 +++++++++++++++- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/uncompyle6/parsers/parse36.py b/uncompyle6/parsers/parse36.py index 92e41e2b..2d429016 100644 --- a/uncompyle6/parsers/parse36.py +++ b/uncompyle6/parsers/parse36.py @@ -19,6 +19,7 @@ class Python36Parser(Python35Parser): return_closure ::= LOAD_CLOSURE DUP_TOP STORE_NAME RETURN_VALUE RETURN_LAST expr ::= LOAD_NAME EXTENDED_ARG + expr ::= LOAD_CONST EXTENDED_ARG fstring_multi ::= fstring_expr_or_strs BUILD_STRING fstring_expr_or_strs ::= fstring_expr_or_str+ diff --git a/uncompyle6/semantics/pysource.py b/uncompyle6/semantics/pysource.py index acb83dd6..01e101a3 100644 --- a/uncompyle6/semantics/pysource.py +++ b/uncompyle6/semantics/pysource.py @@ -1520,10 +1520,21 @@ class SourceWalker(GenericASTTraversal, object): values = node[:-2] # FIXME: Line numbers? for key, value in zip(keys, values): + self.write(sep) self.write(repr(key)) + line_number = self.line_number self.write(':') self.write(self.traverse(value[0])) - self.write(',') + sep = "," + if line_number != self.line_number: + sep += "\n" + self.indent + INDENT_PER_LEVEL[:-1] + line_number = self.line_number + else: + sep += " " + pass + pass + if sep.startswith(",\n"): + self.write(sep[1:]) pass pass else: @@ -1577,6 +1588,9 @@ class SourceWalker(GenericASTTraversal, object): if line_number != self.line_number: sep += "\n" + self.indent + " " line_number = self.line_number + pass + pass + pass if sep.startswith(",\n"): self.write(sep[1:]) self.write('}') From d2502f205e6ed0385e48dc7b3478cb03124c00ac Mon Sep 17 00:00:00 2001 From: rocky Date: Tue, 16 May 2017 06:03:57 -0400 Subject: [PATCH 32/51] extend use of EXTENDED_ARGS in 3.6 switching to a wordcode seems to have made opcode fields smaller so we need EXTENDED_ARG more? --- uncompyle6/parsers/parse36.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/uncompyle6/parsers/parse36.py b/uncompyle6/parsers/parse36.py index 2d429016..706e423f 100644 --- a/uncompyle6/parsers/parse36.py +++ b/uncompyle6/parsers/parse36.py @@ -16,6 +16,19 @@ class Python36Parser(Python35Parser): def p_36misc(self, args): """ + # For reasons I don't understnad the range of values in POP_JUMP_IF_FALSE + # got smaller and so EXTENDED_ARG needs to be used where it didn't before. + # Is this relevant to < 3.6 as well? + + jmp_false ::= EXTENDED_ARG POP_JUMP_IF_FALSE + jmp_true ::= EXTENDED_ARG POP_JUMP_IF_TRUE + _jump ::= EXTENDED_ARG JUMP_BACK + jump_back ::= EXTENDED_ARG JUMP_BACK + + for_block ::= l_stmts_opt opt_come_from_loop jump_back + + + # 3.6 redoes how return_closure works return_closure ::= LOAD_CLOSURE DUP_TOP STORE_NAME RETURN_VALUE RETURN_LAST expr ::= LOAD_NAME EXTENDED_ARG From 0ce804ae165c151a76d45d31d61d4d1d3f84c245 Mon Sep 17 00:00:00 2001 From: rocky Date: Tue, 16 May 2017 06:20:41 -0400 Subject: [PATCH 33/51] More EXTENDED_ARGS on 3.6 --- uncompyle6/parsers/parse36.py | 37 +++++++++++++++++++++++++++++++++-- 1 file changed, 35 insertions(+), 2 deletions(-) diff --git a/uncompyle6/parsers/parse36.py b/uncompyle6/parsers/parse36.py index 706e423f..af2c23e0 100644 --- a/uncompyle6/parsers/parse36.py +++ b/uncompyle6/parsers/parse36.py @@ -14,10 +14,40 @@ class Python36Parser(Python35Parser): super(Python36Parser, self).__init__(debug_parser) self.customized = {} + def p_loop_stmt3(self, args): + """ + # The range of values in arguments in 3.6 has been reduced from 2**16 to 2**8. + # As a result, EXTENDED_ARG needs to be used where it didn't before. + # Is this relevant to < 3.6 as well? + + + setup_loop ::= SETUP_LOOP + setup_loop ::= EXTENDED_ARG SETUP_LOOP + + forstmt ::= setup_loop expr _for designator for_block POP_BLOCK + opt_come_from_loop + + forelsestmt ::= setup_loop expr _for designator for_block POP_BLOCK else_suite + COME_FROM_LOOP + + forelselaststmt ::= setup_loop expr _for designator for_block POP_BLOCK else_suitec + COME_FROM_LOOP + + forelselaststmtl ::= setup_loop expr _for designator for_block POP_BLOCK else_suitel + COME_FROM_LOOP + + whilestmt ::= setup_loop testexpr l_stmts_opt COME_FROM jump_back POP_BLOCK + COME_FROM_LOOP + + whilestmt ::= setup_loop testexpr l_stmts_opt jump_back POP_BLOCK + COME_FROM_LOOP + """ + + def p_36misc(self, args): """ - # For reasons I don't understnad the range of values in POP_JUMP_IF_FALSE - # got smaller and so EXTENDED_ARG needs to be used where it didn't before. + # The range of values in arguments in 3.6 has been reduced from 2**16 to 2**8. + # As a result, EXTENDED_ARG needs to be used where it didn't before. # Is this relevant to < 3.6 as well? jmp_false ::= EXTENDED_ARG POP_JUMP_IF_FALSE @@ -25,6 +55,9 @@ class Python36Parser(Python35Parser): _jump ::= EXTENDED_ARG JUMP_BACK jump_back ::= EXTENDED_ARG JUMP_BACK + continue_stmt ::= EXTENDED_ARG CONTINUE + continue_stmt ::= EXTENDED_ARG CONTINUE_LOOP + for_block ::= l_stmts_opt opt_come_from_loop jump_back From 52b1f4d2b61f8d66d952dddb68023f3e62db1753 Mon Sep 17 00:00:00 2001 From: rocky Date: Tue, 16 May 2017 20:23:24 -0400 Subject: [PATCH 34/51] Fix broken CI on 3.6... Another grammar rule replacing SETUP_LOOP with setup_loop --- uncompyle6/parsers/parse36.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/uncompyle6/parsers/parse36.py b/uncompyle6/parsers/parse36.py index af2c23e0..60d55b75 100644 --- a/uncompyle6/parsers/parse36.py +++ b/uncompyle6/parsers/parse36.py @@ -41,6 +41,8 @@ class Python36Parser(Python35Parser): whilestmt ::= setup_loop testexpr l_stmts_opt jump_back POP_BLOCK COME_FROM_LOOP + + whileTruestmt ::= setup_loop l_stmts_opt JUMP_BACK POP_BLOCK COME_FROM_LOOP """ From 6991a637a245388aa08c611afb263365b9d6fd69 Mon Sep 17 00:00:00 2001 From: rocky Date: Wed, 17 May 2017 23:31:56 -0400 Subject: [PATCH 35/51] Small changes.... * __pkginfo__.py: Need spark parser 1.6.1 for corrected remove_rules() fn * parser36.py: remove replaced Python3 rules * scanner3.py: corrected comment. Thanks to moagstar here. * --- __pkginfo__.py | 2 +- uncompyle6/parsers/parse36.py | 23 +++++++++++++++++++++++ uncompyle6/scanners/scanner3.py | 2 +- 3 files changed, 25 insertions(+), 2 deletions(-) diff --git a/__pkginfo__.py b/__pkginfo__.py index a216d2d6..0d76896a 100644 --- a/__pkginfo__.py +++ b/__pkginfo__.py @@ -39,7 +39,7 @@ entry_points={ 'pydisassemble=uncompyle6.bin.pydisassemble:main', ]} ftp_url = None -install_requires = ['spark-parser >= 1.6.0, < 1.7.0', +install_requires = ['spark-parser >= 1.6.1, < 1.7.0', 'xdis >= 3.3.0, < 3.4.0'] license = 'MIT' mailing_list = 'python-debugger@googlegroups.com' diff --git a/uncompyle6/parsers/parse36.py b/uncompyle6/parsers/parse36.py index 60d55b75..3856beef 100644 --- a/uncompyle6/parsers/parse36.py +++ b/uncompyle6/parsers/parse36.py @@ -84,6 +84,29 @@ class Python36Parser(Python35Parser): def add_custom_rules(self, tokens, customize): super(Python36Parser, self).add_custom_rules(tokens, customize) + self.remove_rule(""" + forstmt ::= SETUP_LOOP expr _for designator for_block POP_BLOCK + opt_come_from_loop + + forelsestmt ::= SETUP_LOOP expr _for designator for_block POP_BLOCK else_suite + COME_FROM_LOOP + + forelselaststmt ::= SETUP_LOOP expr _for designator for_block POP_BLOCK else_suitec + COME_FROM_LOOP + + forelselaststmtl ::= SETUP_LOOP expr _for designator for_block POP_BLOCK else_suitel + COME_FROM_LOOP + + whilestmt ::= SETUP_LOOP testexpr l_stmts_opt COME_FROM jump_back POP_BLOCK + COME_FROM_LOOP + + whilestmt ::= SETUP_LOOP testexpr l_stmts_opt jump_back POP_BLOCK + COME_FROM_LOOP + + whileTruestmt ::= SETUP_LOOP l_stmts_opt JUMP_BACK POP_BLOCK COME_FROM_LOOP + COME_FROM_LOOP + """) + for i, token in enumerate(tokens): opname = token.type diff --git a/uncompyle6/scanners/scanner3.py b/uncompyle6/scanners/scanner3.py index e2b36ad2..486f8068 100644 --- a/uncompyle6/scanners/scanner3.py +++ b/uncompyle6/scanners/scanner3.py @@ -275,7 +275,7 @@ class Scanner3(Scanner): pass elif opname in ('MAKE_FUNCTION', 'MAKE_CLOSURE'): if self.version >= 3.6: - # 3.6+ doesn't have MAKE_CLOSURE, so opname == 'MAKE_CLOSURE' + # 3.6+ doesn't have MAKE_CLOSURE, so opname == 'MAKE_FUNCTION' flags = inst.argval opname = 'MAKE_FUNCTION_%d' % (flags) attr = [] From 94d1c6dfd3fe97849a3be03f7637243dd8460459 Mon Sep 17 00:00:00 2001 From: rocky Date: Thu, 18 May 2017 04:20:16 -0400 Subject: [PATCH 36/51] Enforce using xdis >=3.3.1 .. to pick up bug fixes to 3.6 in xdis --- __pkginfo__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/__pkginfo__.py b/__pkginfo__.py index 0d76896a..88740684 100644 --- a/__pkginfo__.py +++ b/__pkginfo__.py @@ -40,7 +40,7 @@ entry_points={ ]} ftp_url = None install_requires = ['spark-parser >= 1.6.1, < 1.7.0', - 'xdis >= 3.3.0, < 3.4.0'] + 'xdis >= 3.3.1, < 3.4.0'] license = 'MIT' mailing_list = 'python-debugger@googlegroups.com' modname = 'uncompyle6' From b4efa62fad0ddc42eaafc8f2695689879e1556da Mon Sep 17 00:00:00 2001 From: rocky Date: Fri, 19 May 2017 07:13:20 -0400 Subject: [PATCH 37/51] EXTENDED_ARG handling... get_target() wasn't taking into account EXTENDED_ARG before opcode. This is mostly relevant in Python 3.6 where the max size before needing EXTENDED_ARG has been reduced to 256, but theoretically possible in earlier versions. --- uncompyle6/parsers/parse36.py | 2 ++ uncompyle6/scanners/scanner3.py | 21 +++++++++++++++++---- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/uncompyle6/parsers/parse36.py b/uncompyle6/parsers/parse36.py index 3856beef..b30ef1c2 100644 --- a/uncompyle6/parsers/parse36.py +++ b/uncompyle6/parsers/parse36.py @@ -61,6 +61,8 @@ class Python36Parser(Python35Parser): continue_stmt ::= EXTENDED_ARG CONTINUE_LOOP for_block ::= l_stmts_opt opt_come_from_loop jump_back + cmp_list1 ::= expr DUP_TOP ROT_THREE COMPARE_OP + EXTENDED_ARG JUMP_IF_FALSE_OR_POP cmp_list2 COME_FROM # 3.6 redoes how return_closure works diff --git a/uncompyle6/scanners/scanner3.py b/uncompyle6/scanners/scanner3.py index 486f8068..846893e5 100644 --- a/uncompyle6/scanners/scanner3.py +++ b/uncompyle6/scanners/scanner3.py @@ -27,6 +27,7 @@ from array import array from uncompyle6.scanner import Scanner, op_has_argument from xdis.code import iscode +from xdis.util import code2num from xdis.bytecode import Bytecode from uncompyle6.scanner import Token, parse_fn_counts @@ -603,15 +604,27 @@ class Scanner3(Scanner): Get target offset for op located at given . """ op = self.code[offset] + rel_offset = 0 if self.version >= 3.6: target = self.code[offset+1] + arg_offset = 1 + extended_arg_mult = 1 << 8 if op in self.opc.hasjrel: - target += offset + 2 + rel_offset = offset + 2 else: target = self.code[offset+1] + self.code[offset+2] * 256 + arg_offset = 2 + extended_arg_mult = 1 << 16 if op in self.opc.hasjrel: - target += offset + 3 - + rel_offset = offset + 3 + pass + pass + target += rel_offset + prev_offset = self.prev_op[offset] + prev_op = code2num(self.code, prev_offset) + if prev_op == self.opc.EXTENDED_ARG: + target += (code2num(self.code, prev_offset + arg_offset) * extended_arg_mult) + pass return target def detect_control_flow(self, offset, targets): @@ -755,7 +768,7 @@ class Scanner3(Scanner): pre_rtarget = prev_op[rtarget] # Is it an "and" inside an "if" or "while" block - if op == self.opc.POP_JUMP_IF_FALSE: + if op == self.opc.POP_JUMP_IF_FALSE and self.version < 3.6: # Search for another POP_JUMP_IF_FALSE targetting the same op, # in current statement, starting from current offset, and filter From 9c846c309ef1a7fdc3709ea2be7059fbdb9b59a9 Mon Sep 17 00:00:00 2001 From: rocky Date: Fri, 19 May 2017 07:18:25 -0400 Subject: [PATCH 38/51] Bug in pypy JUMP_IF_NOT_DEBUG handling --- uncompyle6/parsers/parse3.py | 1 + 1 file changed, 1 insertion(+) diff --git a/uncompyle6/parsers/parse3.py b/uncompyle6/parsers/parse3.py index 2a16c0bf..fe96b8d0 100644 --- a/uncompyle6/parsers/parse3.py +++ b/uncompyle6/parsers/parse3.py @@ -641,6 +641,7 @@ class Python3Parser(PythonParser): opname, token.attr, customize) continue elif opname == 'JUMP_IF_NOT_DEBUG': + v = token.attr self.add_unique_rule( "stmt ::= assert_pypy", opname, v, customize) self.add_unique_rule( From 3084ac20e923ab2f90cd953c1a114673a17ea494 Mon Sep 17 00:00:00 2001 From: rocky Date: Fri, 19 May 2017 07:52:31 -0400 Subject: [PATCH 39/51] Another attempt at getting get_target() correct --- uncompyle6/scanners/scanner3.py | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/uncompyle6/scanners/scanner3.py b/uncompyle6/scanners/scanner3.py index 846893e5..2ee573a7 100644 --- a/uncompyle6/scanners/scanner3.py +++ b/uncompyle6/scanners/scanner3.py @@ -27,7 +27,6 @@ from array import array from uncompyle6.scanner import Scanner, op_has_argument from xdis.code import iscode -from xdis.util import code2num from xdis.bytecode import Bytecode from uncompyle6.scanner import Token, parse_fn_counts @@ -620,11 +619,14 @@ class Scanner3(Scanner): pass pass target += rel_offset - prev_offset = self.prev_op[offset] - prev_op = code2num(self.code, prev_offset) - if prev_op == self.opc.EXTENDED_ARG: - target += (code2num(self.code, prev_offset + arg_offset) * extended_arg_mult) - pass + + if offset > 0: + prev_offset = self.prev_op[offset] + prev_op = self.code[prev_offset] + if prev_op == self.opc.EXTENDED_ARG: + target += (self.code[prev_offset + arg_offset] + * extended_arg_mult) + pass return target def detect_control_flow(self, offset, targets): From 2a47f0309fcda3b5a3cbc99af07620bda5331380 Mon Sep 17 00:00:00 2001 From: rocky Date: Fri, 19 May 2017 15:36:53 -0400 Subject: [PATCH 40/51] Fix EXTENDED_ARG for long lists, sets, maps --- test/simple_source/expression/06_huge_list.py | 1123 +++++++++++++++++ uncompyle6/parsers/parse3.py | 6 + uncompyle6/semantics/pysource.py | 2 +- 3 files changed, 1130 insertions(+), 1 deletion(-) create mode 100644 test/simple_source/expression/06_huge_list.py diff --git a/test/simple_source/expression/06_huge_list.py b/test/simple_source/expression/06_huge_list.py new file mode 100644 index 00000000..6dcd97d0 --- /dev/null +++ b/test/simple_source/expression/06_huge_list.py @@ -0,0 +1,1123 @@ +# We have more than 1<<16 elements +[ + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +] diff --git a/uncompyle6/parsers/parse3.py b/uncompyle6/parsers/parse3.py index fe96b8d0..9193b573 100644 --- a/uncompyle6/parsers/parse3.py +++ b/uncompyle6/parsers/parse3.py @@ -627,6 +627,12 @@ class Python3Parser(PythonParser): self.custom_build_class_rule(opname, i, token, tokens, customize) elif opname_base in ('BUILD_LIST', 'BUILD_TUPLE', 'BUILD_SET'): v = token.attr + if self.version >= 3.6: + extended_arg = 1 << 8 + else: + extended_arg = 1 << 16 + if v >= extended_arg: + opname = "EXTENDED_ARG %s" % opname rule = ('build_list ::= ' + 'expr1024 ' * int(v//1024) + 'expr32 ' * int((v//32) % 32) + 'expr ' * (v % 32) + opname) diff --git a/uncompyle6/semantics/pysource.py b/uncompyle6/semantics/pysource.py index 01e101a3..8a7f5fee 100644 --- a/uncompyle6/semantics/pysource.py +++ b/uncompyle6/semantics/pysource.py @@ -1646,7 +1646,7 @@ class SourceWalker(GenericASTTraversal, object): sep = '' for elem in flat_elems: - if elem == 'ROT_THREE': + if elem in ('ROT_THREE', 'EXTENDED_ARG'): continue assert elem == 'expr' line_number = self.line_number From 49fd4305057d1a115d2f32906ea6e56ddac34b31 Mon Sep 17 00:00:00 2001 From: rocky Date: Fri, 19 May 2017 19:29:22 -0400 Subject: [PATCH 41/51] EXTENDED_ARG is implemented in 2.6 --- uncompyle6/scanners/scanner26.py | 1 - 1 file changed, 1 deletion(-) diff --git a/uncompyle6/scanners/scanner26.py b/uncompyle6/scanners/scanner26.py index f649e739..65992a3f 100755 --- a/uncompyle6/scanners/scanner26.py +++ b/uncompyle6/scanners/scanner26.py @@ -178,7 +178,6 @@ class Scanner26(scan.Scanner2): oparg = self.get_argument(offset) + extended_arg extended_arg = 0 if op == self.opc.EXTENDED_ARG: - raise NotImplementedError extended_arg = oparg * scan.L65536 continue if op in self.opc.hasconst: From 2ab7aa2f48b261e213421b050150a7ad9ced5793 Mon Sep 17 00:00:00 2001 From: rocky Date: Fri, 19 May 2017 22:06:18 -0400 Subject: [PATCH 42/51] Simplify EXTENDED_ARG on 3.x We largely remove them and fold them itno the next op. MAKE_FUNCTION though before 3.6 is an exception as that indicates an annotated function --- uncompyle6/parsers/parse3.py | 18 +++++--- uncompyle6/parsers/parse36.py | 74 --------------------------------- uncompyle6/scanners/scanner3.py | 50 ++++++++++++---------- 3 files changed, 41 insertions(+), 101 deletions(-) diff --git a/uncompyle6/parsers/parse3.py b/uncompyle6/parsers/parse3.py index 9193b573..6844a7ea 100644 --- a/uncompyle6/parsers/parse3.py +++ b/uncompyle6/parsers/parse3.py @@ -627,12 +627,6 @@ class Python3Parser(PythonParser): self.custom_build_class_rule(opname, i, token, tokens, customize) elif opname_base in ('BUILD_LIST', 'BUILD_TUPLE', 'BUILD_SET'): v = token.attr - if self.version >= 3.6: - extended_arg = 1 << 8 - else: - extended_arg = 1 << 16 - if v >= extended_arg: - opname = "EXTENDED_ARG %s" % opname rule = ('build_list ::= ' + 'expr1024 ' * int(v//1024) + 'expr32 ' * int((v//32) % 32) + 'expr ' * (v % 32) + opname) @@ -764,7 +758,18 @@ class Python3Parser(PythonParser): ('pos_arg ' * args_pos, opname)) self.add_unique_rule(rule, opname, token.attr, customize) if opname.startswith('MAKE_FUNCTION_A'): + if self.version >= 3.6: + rule = ('mkfunc_annotate ::= %s%sannotate_tuple LOAD_CONST LOAD_CONST %s' % + (('pos_arg ' * (args_pos)), + ('call_function ' * (annotate_args-1)), opname)) + self.add_unique_rule(rule, opname, token.attr, customize) + rule = ('mkfunc_annotate ::= %s%sannotate_tuple LOAD_CONST LOAD_CONST %s' % + (('pos_arg ' * (args_pos)), + ('annotate_arg ' * (annotate_args-1)), opname)) if self.version >= 3.3: + # Normally we remove EXTENDED_ARG from the opcodes, but in the case of + # annotated functions can use the EXTENDED_ARG tuple to signal we have an annotated function. + # Yes this is a little hacky rule = ('mkfunc_annotate ::= %s%sannotate_tuple LOAD_CONST LOAD_CONST EXTENDED_ARG %s' % (('pos_arg ' * (args_pos)), ('call_function ' * (annotate_args-1)), opname)) @@ -773,6 +778,7 @@ class Python3Parser(PythonParser): (('pos_arg ' * (args_pos)), ('annotate_arg ' * (annotate_args-1)), opname)) else: + # See above comment about use of EXTENDED_ARG rule = ('mkfunc_annotate ::= %s%sannotate_tuple LOAD_CONST EXTENDED_ARG %s' % (('pos_arg ' * (args_pos)), ('annotate_arg ' * (annotate_args-1)), opname)) diff --git a/uncompyle6/parsers/parse36.py b/uncompyle6/parsers/parse36.py index b30ef1c2..1b4c8022 100644 --- a/uncompyle6/parsers/parse36.py +++ b/uncompyle6/parsers/parse36.py @@ -14,63 +14,12 @@ class Python36Parser(Python35Parser): super(Python36Parser, self).__init__(debug_parser) self.customized = {} - def p_loop_stmt3(self, args): - """ - # The range of values in arguments in 3.6 has been reduced from 2**16 to 2**8. - # As a result, EXTENDED_ARG needs to be used where it didn't before. - # Is this relevant to < 3.6 as well? - - - setup_loop ::= SETUP_LOOP - setup_loop ::= EXTENDED_ARG SETUP_LOOP - - forstmt ::= setup_loop expr _for designator for_block POP_BLOCK - opt_come_from_loop - - forelsestmt ::= setup_loop expr _for designator for_block POP_BLOCK else_suite - COME_FROM_LOOP - - forelselaststmt ::= setup_loop expr _for designator for_block POP_BLOCK else_suitec - COME_FROM_LOOP - - forelselaststmtl ::= setup_loop expr _for designator for_block POP_BLOCK else_suitel - COME_FROM_LOOP - - whilestmt ::= setup_loop testexpr l_stmts_opt COME_FROM jump_back POP_BLOCK - COME_FROM_LOOP - - whilestmt ::= setup_loop testexpr l_stmts_opt jump_back POP_BLOCK - COME_FROM_LOOP - - whileTruestmt ::= setup_loop l_stmts_opt JUMP_BACK POP_BLOCK COME_FROM_LOOP - """ - def p_36misc(self, args): """ - # The range of values in arguments in 3.6 has been reduced from 2**16 to 2**8. - # As a result, EXTENDED_ARG needs to be used where it didn't before. - # Is this relevant to < 3.6 as well? - - jmp_false ::= EXTENDED_ARG POP_JUMP_IF_FALSE - jmp_true ::= EXTENDED_ARG POP_JUMP_IF_TRUE - _jump ::= EXTENDED_ARG JUMP_BACK - jump_back ::= EXTENDED_ARG JUMP_BACK - - continue_stmt ::= EXTENDED_ARG CONTINUE - continue_stmt ::= EXTENDED_ARG CONTINUE_LOOP - - for_block ::= l_stmts_opt opt_come_from_loop jump_back - cmp_list1 ::= expr DUP_TOP ROT_THREE COMPARE_OP - EXTENDED_ARG JUMP_IF_FALSE_OR_POP cmp_list2 COME_FROM - - # 3.6 redoes how return_closure works return_closure ::= LOAD_CLOSURE DUP_TOP STORE_NAME RETURN_VALUE RETURN_LAST - expr ::= LOAD_NAME EXTENDED_ARG - expr ::= LOAD_CONST EXTENDED_ARG - fstring_multi ::= fstring_expr_or_strs BUILD_STRING fstring_expr_or_strs ::= fstring_expr_or_str+ @@ -86,29 +35,6 @@ class Python36Parser(Python35Parser): def add_custom_rules(self, tokens, customize): super(Python36Parser, self).add_custom_rules(tokens, customize) - self.remove_rule(""" - forstmt ::= SETUP_LOOP expr _for designator for_block POP_BLOCK - opt_come_from_loop - - forelsestmt ::= SETUP_LOOP expr _for designator for_block POP_BLOCK else_suite - COME_FROM_LOOP - - forelselaststmt ::= SETUP_LOOP expr _for designator for_block POP_BLOCK else_suitec - COME_FROM_LOOP - - forelselaststmtl ::= SETUP_LOOP expr _for designator for_block POP_BLOCK else_suitel - COME_FROM_LOOP - - whilestmt ::= SETUP_LOOP testexpr l_stmts_opt COME_FROM jump_back POP_BLOCK - COME_FROM_LOOP - - whilestmt ::= SETUP_LOOP testexpr l_stmts_opt jump_back POP_BLOCK - COME_FROM_LOOP - - whileTruestmt ::= SETUP_LOOP l_stmts_opt JUMP_BACK POP_BLOCK COME_FROM_LOOP - COME_FROM_LOOP - """) - for i, token in enumerate(tokens): opname = token.type diff --git a/uncompyle6/scanners/scanner3.py b/uncompyle6/scanners/scanner3.py index 2ee573a7..04a24c67 100644 --- a/uncompyle6/scanners/scanner3.py +++ b/uncompyle6/scanners/scanner3.py @@ -208,9 +208,12 @@ class Scanner3(Scanner): jump_targets = self.find_jump_targets(show_asm) last_op_was_break = False - for inst in bytecode: + extended_arg = 0 + for i, inst in enumerate(bytecode): argval = inst.argval + if isinstance(argval, int): + argval += extended_arg if inst.offset in jump_targets: jump_idx = 0 # We want to process COME_FROMs to the same offset to be in *descending* @@ -247,12 +250,28 @@ class Scanner3(Scanner): pass - pattr = inst.argrepr + pattr = inst.argrepr opname = inst.opname - op = inst.opcode + op = inst.opcode + + has_arg = op_has_argument(op, self.opc) + if has_arg: + extended_arg = 0 + if op == self.opc.EXTENDED_ARG: + if self.version < 3.6: + extended_arg = argval * (1<<16) + else: + extended_arg = argval * (1<<8) + + # Normally we remove EXTENDED_ARG from the + # opcodes, but in the case of annotated functions + # can use the EXTENDED_ARG tuple to signal we have + # an annotated function. + if not bs[i+1].opname.startswith("MAKE_FUNCTION"): + continue if opname in ['LOAD_CONST']: - const = inst.argval + const = argval if iscode(const): if const.co_name == '': opname = 'LOAD_LAMBDA' @@ -276,7 +295,7 @@ class Scanner3(Scanner): elif opname in ('MAKE_FUNCTION', 'MAKE_CLOSURE'): if self.version >= 3.6: # 3.6+ doesn't have MAKE_CLOSURE, so opname == 'MAKE_FUNCTION' - flags = inst.argval + flags = argval opname = 'MAKE_FUNCTION_%d' % (flags) attr = [] for flag in self.MAKE_FUNCTION_FLAGS: @@ -315,7 +334,7 @@ class Scanner3(Scanner): ) continue elif op in self.varargs_ops: - pos_args = inst.argval + pos_args = argval if self.is_pypy and not pos_args and opname == 'BUILD_MAP': opname = 'BUILD_MAP_n' else: @@ -327,9 +346,9 @@ class Scanner3(Scanner): customize[opname] = 0 elif opname == 'UNPACK_EX': # FIXME: try with scanner and parser by - # changing inst.argval - before_args = inst.argval & 0xFF - after_args = (inst.argval >> 8) & 0xff + # changing argval + before_args = argval & 0xFF + after_args = (argval >> 8) & 0xff pattr = "%d before vararg, %d after" % (before_args, after_args) argval = (before_args, after_args) opname = '%s_%d+%d' % (opname, before_args, after_args) @@ -346,7 +365,7 @@ class Scanner3(Scanner): # comprehensions we might sometimes classify JUMP_BACK # as CONTINUE, but that's okay since we add a grammar # rule for that. - pattr = inst.argval + pattr = argval target = self.get_target(inst.offset) if target <= inst.offset: next_opname = self.opname[self.code[inst.offset+3]] @@ -606,27 +625,16 @@ class Scanner3(Scanner): rel_offset = 0 if self.version >= 3.6: target = self.code[offset+1] - arg_offset = 1 - extended_arg_mult = 1 << 8 if op in self.opc.hasjrel: rel_offset = offset + 2 else: target = self.code[offset+1] + self.code[offset+2] * 256 - arg_offset = 2 - extended_arg_mult = 1 << 16 if op in self.opc.hasjrel: rel_offset = offset + 3 pass pass target += rel_offset - if offset > 0: - prev_offset = self.prev_op[offset] - prev_op = self.code[prev_offset] - if prev_op == self.opc.EXTENDED_ARG: - target += (self.code[prev_offset + arg_offset] - * extended_arg_mult) - pass return target def detect_control_flow(self, offset, targets): From d3794ec9af3768b2daf418cdc91c81e300067756 Mon Sep 17 00:00:00 2001 From: rocky Date: Sat, 20 May 2017 07:40:59 -0400 Subject: [PATCH 43/51] More explicit about 3.5 UNMAP_PACK Have to reduce 3.5 bytecode testing for now, code is more solid. --- ... 02_build_map_unpack_with_call.pyc-notyet} | Bin ...k.pyc => 03_double_star_unpack.pyc-notyet} | Bin ...break.pyc => 03_while-if-break.pyc-notyet} | Bin uncompyle6/parsers/parse3.py | 10 ++++++++- uncompyle6/semantics/pysource.py | 20 ++++++++++++------ 5 files changed, 22 insertions(+), 8 deletions(-) rename test/bytecode_3.5/{02_build_map_unpack_with_call.pyc => 02_build_map_unpack_with_call.pyc-notyet} (100%) rename test/bytecode_3.5/{03_double_star_unpack.pyc => 03_double_star_unpack.pyc-notyet} (100%) rename test/bytecode_3.5/{03_while-if-break.pyc => 03_while-if-break.pyc-notyet} (100%) diff --git a/test/bytecode_3.5/02_build_map_unpack_with_call.pyc b/test/bytecode_3.5/02_build_map_unpack_with_call.pyc-notyet similarity index 100% rename from test/bytecode_3.5/02_build_map_unpack_with_call.pyc rename to test/bytecode_3.5/02_build_map_unpack_with_call.pyc-notyet diff --git a/test/bytecode_3.5/03_double_star_unpack.pyc b/test/bytecode_3.5/03_double_star_unpack.pyc-notyet similarity index 100% rename from test/bytecode_3.5/03_double_star_unpack.pyc rename to test/bytecode_3.5/03_double_star_unpack.pyc-notyet diff --git a/test/bytecode_3.5/03_while-if-break.pyc b/test/bytecode_3.5/03_while-if-break.pyc-notyet similarity index 100% rename from test/bytecode_3.5/03_while-if-break.pyc rename to test/bytecode_3.5/03_while-if-break.pyc-notyet diff --git a/uncompyle6/parsers/parse3.py b/uncompyle6/parsers/parse3.py index 6844a7ea..d3cca70d 100644 --- a/uncompyle6/parsers/parse3.py +++ b/uncompyle6/parsers/parse3.py @@ -625,6 +625,14 @@ class Python3Parser(PythonParser): self.add_make_function_rule(rule_pat, opname, token.attr, customize) elif opname == 'LOAD_BUILD_CLASS': self.custom_build_class_rule(opname, i, token, tokens, customize) + elif opname.startswith('BUILD_LIST_UNPACK'): + v = token.attr + rule = ('build_list_unpack ::= ' + 'expr1024 ' * int(v//1024) + + 'expr32 ' * int((v//32) % 32) + + 'expr ' * (v % 32) + opname) + self.add_unique_rule(rule, opname, token.attr, customize) + rule = 'expr ::= build_list_unpack' + self.add_unique_rule(rule, opname, token.attr, customize) elif opname_base in ('BUILD_LIST', 'BUILD_TUPLE', 'BUILD_SET'): v = token.attr rule = ('build_list ::= ' + 'expr1024 ' * int(v//1024) + @@ -680,7 +688,7 @@ class Python3Parser(PythonParser): self.add_unique_rule(rule, opname, token.attr, customize) rule = ('unmap_dict ::= ' + ('mapexpr ' * token.attr) + - ' BUILD_MAP_UNPACK') + 'BUILD_MAP_UNPACK') else: rule = kvlist_n + ' ::= ' + 'expr ' * (token.attr*2) self.add_unique_rule(rule, opname, token.attr, customize) diff --git a/uncompyle6/semantics/pysource.py b/uncompyle6/semantics/pysource.py index 8a7f5fee..ef72fc0c 100644 --- a/uncompyle6/semantics/pysource.py +++ b/uncompyle6/semantics/pysource.py @@ -359,6 +359,9 @@ class SourceWalker(GenericASTTraversal, object): self.prune() self.n_async_call_function = n_async_call_function + self.n_build_list_unpack = self.n_build_list + + def n_funcdef(node): code_node = node[0][1] if (code_node == 'LOAD_CONST' and iscode(code_node.attr) @@ -1613,6 +1616,13 @@ class SourceWalker(GenericASTTraversal, object): # will assume that if the text ends in *. last_was_star = self.f.getvalue().endswith('*') + if lastnodetype.endswith('UNPACK'): + # FIXME: need to handle range of BUILD_LIST_UNPACK + have_star = True + # endchar = '' + else: + have_star = False + if lastnodetype.startswith('BUILD_LIST'): self.write('['); endchar = ']' elif lastnodetype.startswith('BUILD_TUPLE'): @@ -1624,11 +1634,7 @@ class SourceWalker(GenericASTTraversal, object): elif lastnodetype.startswith('ROT_TWO'): self.write('('); endchar = ')' else: - raise 'Internal Error: n_build_list expects list, tuple, set, or unpack' - have_star = False - if lastnodetype.endswith('UNPACK'): - # FIXME: need to handle range of BUILD_LIST_UNPACK - have_star = True + raise TypeError('Internal Error: n_build_list expects list, tuple, set, or unpack') flat_elems = [] for elem in node: @@ -1854,7 +1860,7 @@ class SourceWalker(GenericASTTraversal, object): 'CALL_FUNCTION_VAR_KW', 'CALL_FUNCTION_KW'): if v == 0: str = '%c(%C' # '%C' is a dummy here ... - p2 = (0, 0, None) # .. because of this + p2 = (0, -1, None) # .. because of this else: str = '%c(%C, ' p2 = (1, -2, ', ') @@ -1866,7 +1872,7 @@ class SourceWalker(GenericASTTraversal, object): str = '%c(*%C, %c)' elif str == '%c(%C': str = '%c(*%C)' - # p2 = (1, -1, 100) + p2 = (1, -1, 100) else: str += '*%c)' entry = (str, 0, p2, -2) From 5ebb731c046434406b0d9dbfbcb69280a74c1a06 Mon Sep 17 00:00:00 2001 From: rocky Date: Sat, 20 May 2017 07:50:41 -0400 Subject: [PATCH 44/51] Worse results. Revert some of the last changes --- uncompyle6/semantics/pysource.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/uncompyle6/semantics/pysource.py b/uncompyle6/semantics/pysource.py index ef72fc0c..85d5e60c 100644 --- a/uncompyle6/semantics/pysource.py +++ b/uncompyle6/semantics/pysource.py @@ -1860,7 +1860,7 @@ class SourceWalker(GenericASTTraversal, object): 'CALL_FUNCTION_VAR_KW', 'CALL_FUNCTION_KW'): if v == 0: str = '%c(%C' # '%C' is a dummy here ... - p2 = (0, -1, None) # .. because of this + p2 = (0, 0, None) # .. because of this else: str = '%c(%C, ' p2 = (1, -2, ', ') @@ -1872,7 +1872,7 @@ class SourceWalker(GenericASTTraversal, object): str = '%c(*%C, %c)' elif str == '%c(%C': str = '%c(*%C)' - p2 = (1, -1, 100) + # p2 = (1, -1, 100) else: str += '*%c)' entry = (str, 0, p2, -2) From d93b7a9eae9a0b5c17ddf998f1d270baca03b778 Mon Sep 17 00:00:00 2001 From: rocky Date: Sun, 21 May 2017 04:44:11 -0400 Subject: [PATCH 45/51] Correct EXTENDED_ARG handling on Python 3.6... where it can appear several times and xdis may handle it as well. It possibly in other versions bug since EXTENDED_ARG is used so rarely there because it has such a high value 1<<16, it's hard to test and determine that. --- uncompyle6/scanners/scanner3.py | 45 +++++++++++++++++++-------------- 1 file changed, 26 insertions(+), 19 deletions(-) diff --git a/uncompyle6/scanners/scanner3.py b/uncompyle6/scanners/scanner3.py index 04a24c67..5f29fadf 100644 --- a/uncompyle6/scanners/scanner3.py +++ b/uncompyle6/scanners/scanner3.py @@ -138,6 +138,13 @@ class Scanner3(Scanner): # FIXME: remove the above in favor of: # self.varargs_ops = frozenset(self.opc.hasvargs) + def extended_arg_val(self, val): + if self.version < 3.6: + return val * (1<<16) + else: + return val * (1<<8) + + def ingest(self, co, classname=None, code_objects={}, show_asm=None): """ Pick out tokens from an uncompyle6 code object, and transform them, @@ -212,8 +219,25 @@ class Scanner3(Scanner): for i, inst in enumerate(bytecode): argval = inst.argval - if isinstance(argval, int): - argval += extended_arg + op = inst.opcode + has_arg = op_has_argument(op, self.opc) + if has_arg: + if op == self.opc.EXTENDED_ARG: + extended_arg += self.extended_arg_val(argval) + + # Normally we remove EXTENDED_ARG from the + # opcodes, but in the case of annotated functions + # can use the EXTENDED_ARG tuple to signal we have + # an annotated function. + if not bs[i+1].opname.startswith("MAKE_FUNCTION"): + continue + + if isinstance(argval, int) and extended_arg: + min_extended= self.extended_arg_val(1) + if argval < min_extended: + argval += extended_arg + extended_arg = 0 + if inst.offset in jump_targets: jump_idx = 0 # We want to process COME_FROMs to the same offset to be in *descending* @@ -252,23 +276,6 @@ class Scanner3(Scanner): pattr = inst.argrepr opname = inst.opname - op = inst.opcode - - has_arg = op_has_argument(op, self.opc) - if has_arg: - extended_arg = 0 - if op == self.opc.EXTENDED_ARG: - if self.version < 3.6: - extended_arg = argval * (1<<16) - else: - extended_arg = argval * (1<<8) - - # Normally we remove EXTENDED_ARG from the - # opcodes, but in the case of annotated functions - # can use the EXTENDED_ARG tuple to signal we have - # an annotated function. - if not bs[i+1].opname.startswith("MAKE_FUNCTION"): - continue if opname in ['LOAD_CONST']: const = argval From cf3c07e047106ab47ea9c7ae7832e2e08f877f9a Mon Sep 17 00:00:00 2001 From: rocky Date: Tue, 23 May 2017 06:10:31 -0400 Subject: [PATCH 46/51] Add fuzzy offset deparse lookup --- uncompyle6/semantics/fragments.py | 64 ++++++++++++++++++++++++++++++- uncompyle6/semantics/pysource.py | 9 +---- 2 files changed, 65 insertions(+), 8 deletions(-) diff --git a/uncompyle6/semantics/fragments.py b/uncompyle6/semantics/fragments.py index 48cd3cbf..39b57fb2 100644 --- a/uncompyle6/semantics/fragments.py +++ b/uncompyle6/semantics/fragments.py @@ -1790,6 +1790,36 @@ def deparse_code(version, co, out=StringIO(), showasm=False, showast=False, return deparsed +from bisect import bisect_right +def find_gt(a, x): + 'Find leftmost value greater than x' + i = bisect_right(a, x) + if i != len(a): + return a[i] + raise ValueError + +def deparse_code_around_offset(name, offset, version, co, out=StringIO(), + showasm=False, showast=False, + showgrammar=False, is_pypy=False): + """ + Like deparse_code(), but given a function/module name and + offset, finds the node closest to offset. If offset is not an instruction boundary, + we raise an IndexError. + """ + deparsed = deparse_code(version, co, out, showasm, showast, showgrammar, is_pypy) + if (name, offset) in deparsed.offsets.keys(): + # This is the easy case + return deparsed.offsets[name, offset] + + valid_offsets = [t for t in deparsed.offsets if isinstance(t[1], int)] + offset_list = sorted([t[1] for t in valid_offsets if t[0] == name]) + + # FIXME: should check for branching? + found_offset = find_gt(offset_list, offset) + deparsed.offsets[name, offset] = deparsed.offsets[name, found_offset] + return deparsed + + if __name__ == '__main__': def deparse_test(co, is_pypy=IS_PYPY): @@ -1821,6 +1851,35 @@ if __name__ == '__main__': pass return + def deparse_test_around(offset, name, co, is_pypy=IS_PYPY): + sys_version = sys.version_info.major + (sys.version_info.minor / 10.0) + walk = deparse_code_around_offset(name, offset, sys_version, co, showasm=False, showast=False, + showgrammar=False, is_pypy=IS_PYPY) + print("deparsed source") + print(walk.text, "\n") + print('------------------------') + for name, offset in sorted(walk.offsets.keys(), + key=lambda x: str(x[0])): + print("name %s, offset %s" % (name, offset)) + nodeInfo = walk.offsets[name, offset] + node = nodeInfo.node + extractInfo = walk.extract_node_info(node) + print("code: %s" % node.type) + # print extractInfo + print(extractInfo.selectedText) + print(extractInfo.selectedLine) + print(extractInfo.markerLine) + extractInfo, p = walk.extract_parent_info(node) + if extractInfo: + print("Contained in...") + print(extractInfo.selectedLine) + print(extractInfo.markerLine) + print("code: %s" % p.type) + print('=' * 40) + pass + pass + return + def get_code_for_fn(fn): return fn.__code__ @@ -1840,6 +1899,9 @@ if __name__ == '__main__': # check_args(['3', '5']) # deparse_test(get_code_for_fn(gcd)) - deparse_test(get_code_for_fn(test)) + # deparse_test(get_code_for_fn(test)) # deparse_test(get_code_for_fn(FragmentsWalker.fixup_offsets)) + # deparse_test(get_code_for_fn(FragmentsWalker.n_build_list)) + print('=' * 30) + deparse_test_around(408, 'n_build_list', get_code_for_fn(FragmentsWalker.n_build_list)) # deparse_test(inspect.currentframe().f_code) diff --git a/uncompyle6/semantics/pysource.py b/uncompyle6/semantics/pysource.py index 85d5e60c..c2f9718c 100644 --- a/uncompyle6/semantics/pysource.py +++ b/uncompyle6/semantics/pysource.py @@ -1741,12 +1741,8 @@ class SourceWalker(GenericASTTraversal, object): typ = m.group('type') or '{' node = startnode - try: - if m.group('child'): - node = node[int(m.group('child'))] - except: - print(node.__dict__) - raise + if m.group('child'): + node = node[int(m.group('child'))] if typ == '%': self.write('%') elif typ == '+': @@ -1821,7 +1817,6 @@ class SourceWalker(GenericASTTraversal, object): try: self.write(eval(expr, d, d)) except: - print(node) raise m = escape.search(fmt, i) self.write(fmt[i:]) From 9eee4eccd7877f2d379d913b5a3b03bd4f0de8d5 Mon Sep 17 00:00:00 2001 From: rocky Date: Tue, 23 May 2017 19:00:06 -0400 Subject: [PATCH 47/51] Fix bug in a 3.6 class name. --- uncompyle6/semantics/pysource.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/uncompyle6/semantics/pysource.py b/uncompyle6/semantics/pysource.py index c2f9718c..8c3d1935 100644 --- a/uncompyle6/semantics/pysource.py +++ b/uncompyle6/semantics/pysource.py @@ -1302,16 +1302,16 @@ class SourceWalker(GenericASTTraversal, object): if self.version > 3.0: if node == 'classdefdeco2': if self.version >= 3.6: - class_code = node[1][1].pattr + class_name = node[1][1].pattr else: - class_code = node[1][2].pattr + class_name = node[1][2].pattr buildclass = node else: if self.version >= 3.6: - class_code = node[0][1][0].pattr + class_name = node[0][1][0].attr.co_name buildclass = node[0] else: - class_code = node[1][0].pattr + class_name = node[1][0].pattr buildclass = node[0] assert 'mkfunc' == buildclass[1] @@ -1364,10 +1364,10 @@ class SourceWalker(GenericASTTraversal, object): build_list = buildclass[1][0] if hasattr(buildclass[-3][0], 'attr'): subclass_code = buildclass[-3][0].attr - class_code = buildclass[0].pattr + class_name = buildclass[0].pattr elif hasattr(node[0][0], 'pattr'): subclass_code = buildclass[-3][1].attr - class_code = node[0][0].pattr + class_name = node[0][0].pattr else: raise 'Internal Error n_classdef: cannot find class name' @@ -1376,7 +1376,7 @@ class SourceWalker(GenericASTTraversal, object): else: self.write('\n\n') - self.currentclass = str(class_code) + self.currentclass = str(class_name) self.write(self.indent, 'class ', self.currentclass) if self.version > 3.0: From 7257ba41c5d20974d9e4c6b23c7135e08a4c0ecd Mon Sep 17 00:00:00 2001 From: rocky Date: Tue, 23 May 2017 21:02:06 -0400 Subject: [PATCH 48/51] Fix up retreiving "async" property on 3.6 --- uncompyle6/semantics/pysource.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/uncompyle6/semantics/pysource.py b/uncompyle6/semantics/pysource.py index 8c3d1935..550d791f 100644 --- a/uncompyle6/semantics/pysource.py +++ b/uncompyle6/semantics/pysource.py @@ -363,9 +363,14 @@ class SourceWalker(GenericASTTraversal, object): def n_funcdef(node): - code_node = node[0][1] - if (code_node == 'LOAD_CONST' and iscode(code_node.attr) - and code_node.attr.co_flags & COMPILER_FLAG_BIT['COROUTINE']): + if self.version == 3.6: + code_node = node[0][0] + else: + code_node = node[0][1] + + is_code = hasattr(code_node, 'attr') and iscode(code_node.attr) + if (is_code and + (code_node.attr.co_flags & COMPILER_FLAG_BIT['COROUTINE'])): self.engine(('\n\n%|async def %c\n', -2), node) else: self.engine(('\n\n%|def %c\n', -2), node) From 394120bb1a48bff686cdd2dd3c2e7aeba53a6a37 Mon Sep 17 00:00:00 2001 From: rocky Date: Tue, 23 May 2017 21:10:14 -0400 Subject: [PATCH 49/51] Fix up 3.6 unmapexpr --- uncompyle6/semantics/pysource.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/uncompyle6/semantics/pysource.py b/uncompyle6/semantics/pysource.py index 550d791f..6c476ac3 100644 --- a/uncompyle6/semantics/pysource.py +++ b/uncompyle6/semantics/pysource.py @@ -346,7 +346,7 @@ class SourceWalker(GenericASTTraversal, object): 'async_with_as_stmt': ( '%|async with %c as %c:\n%+%c%-', 0, 6, 7), 'unmap_dict': ( '{**%C}', (0, -1, ', **') ), - 'unmapexpr': ( '{**%c}', 0), + # 'unmapexpr': ( '{**%c}', 0), # done by n_unmapexpr }) def n_async_call_function(node): @@ -385,8 +385,6 @@ class SourceWalker(GenericASTTraversal, object): self.f.write(', **') pass pass - if version >= 3.6: - self.f.write(')') self.prune() pass self.n_unmapexpr = n_unmapexpr From cbbf64ccd07cde7fe0dd5e9ce75201b300970bdd Mon Sep 17 00:00:00 2001 From: rocky Date: Tue, 30 May 2017 01:25:33 -0400 Subject: [PATCH 50/51] Python 3.6 makefunction handling for fragments --- uncompyle6/semantics/fragments.py | 130 +----------------------------- 1 file changed, 1 insertion(+), 129 deletions(-) diff --git a/uncompyle6/semantics/fragments.py b/uncompyle6/semantics/fragments.py index 39b57fb2..effe8e34 100644 --- a/uncompyle6/semantics/fragments.py +++ b/uncompyle6/semantics/fragments.py @@ -500,7 +500,7 @@ class FragmentsWalker(pysource.SourceWalker, object): self.write(func_name) self.indentMore() - self.make_function(node, isLambda=False, code=code) + self.make_function(node, isLambda=False, codeNode=code) self.set_pos_info(node, start, len(self.f.getvalue())) @@ -1581,134 +1581,6 @@ class FragmentsWalker(pysource.SourceWalker, object): self.set_pos_info(last_node, startnode_start, self.last_finish) return - def make_function(self, node, isLambda, nested=1, code=None): - """Dump function defintion, doc string, and function body.""" - - def build_param(ast, name, default): - """build parameters: - - handle defaults - - handle format tuple parameters - """ - if self.version < 3.0: - # if formal parameter is a tuple, the paramater name - # starts with a dot (eg. '.1', '.2') - if name.startswith('.'): - # replace the name with the tuple-string - name = self.get_tuple_parameter(ast, name) - pass - pass - - if default: - maybe_show_ast_param_default(self.showast, name, default) - result = '%s=' % name - old_last_finish = self.last_finish - self.last_finish = len(result) - value = self.traverse(default, indent='') - self.last_finish = old_last_finish - result += value - if result[-2:] == '= ': # default was 'LOAD_CONST None' - result += 'None' - return result - else: - return name - - # MAKE_FUNCTION_... or MAKE_CLOSURE_... - assert node[-1].type.startswith('MAKE_') - - args_node = node[-1] - if isinstance(args_node.attr, tuple): - if self.version <= 3.3 and len(node) > 2 and node[-3] != 'LOAD_LAMBDA': - # positional args are after kwargs - defparams = node[1:args_node.attr[0]+1] - else: - # positional args are before kwargs - defparams = node[:args_node.attr[0]] - pos_args, kw_args, annotate_argc = args_node.attr - else: - defparams = node[:args_node.attr] - kw_args, annotate_argc = (0, 0) - pass - - if self.version > 3.0 and isLambda and iscode(node[-3].attr): - code = node[-3].attr - else: - code = code.attr - - assert iscode(code) - code = Code(code, self.scanner, self.currentclass) - - # add defaults values to parameter names - argc = code.co_argcount - paramnames = list(code.co_varnames[:argc]) - - # defaults are for last n parameters, thus reverse - paramnames.reverse(); defparams.reverse() - - try: - ast = self.build_ast(code._tokens, - code._customize, - isLambda = isLambda, - noneInNames = ('None' in code.co_names)) - except ParserError as p: - self.write(str(p)) - self.ERROR = p - return - - # build parameters - - params = [build_param(ast, name, default) for - name, default in zip_longest(paramnames, defparams, fillvalue=None)] - - params.reverse() # back to correct order - - if code_has_star_arg(code): - params.append('*%s' % code.co_varnames[argc]) - argc += 1 - if code_has_star_star_arg(code): - params.append('**%s' % code.co_varnames[argc]) - argc += 1 - - # dump parameter list (with default values) - indent = self.indent - if isLambda: - self.write("lambda ", ", ".join(params)) - else: - self.write("(", ", ".join(params)) - # self.println(indent, '#flags:\t', int(code.co_flags)) - - if kw_args > 0: - if argc > 0: - self.write(", *, ") - else: - self.write("*, ") - for n in node: - if n == 'pos_arg': - continue - self.preorder(n) - break - pass - - if isLambda: - self.write(": ") - else: - self.println("):") - - if len(code.co_consts)>0 and code.co_consts[0] is not None and not isLambda: # ugly - # docstring exists, dump it - print_docstring(self, indent, code.co_consts[0]) - - code._tokens = None # save memory - assert ast == 'stmts' - - all_globals = find_all_globals(ast, set()) - for g in ((all_globals & self.mod_globs) | find_globals(ast, set())): - self.println(self.indent, 'global ', g) - self.mod_globs -= all_globals - rn = ('None' in code.co_names) and not find_none(ast) - self.gen_source(ast, code.co_name, code._customize, isLambda=isLambda, - returnNone=rn) - code._tokens = None; code._customize = None # save memory - @classmethod def _get_mapping(cls, node): return MAP.get(node, MAP_DIRECT_FRAGMENT) From ad98fae3d4b0b83f65b15da8201e33c0ee6dab17 Mon Sep 17 00:00:00 2001 From: rocky Date: Tue, 30 May 2017 01:26:52 -0400 Subject: [PATCH 51/51] Get ready for release 2.10.0 --- ChangeLog | 692 ++++++++++++++++++++++++++++-------------- NEWS | 20 ++ uncompyle6/version.py | 2 +- 3 files changed, 490 insertions(+), 224 deletions(-) diff --git a/ChangeLog b/ChangeLog index c3ecbc04..73a4da3c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,243 @@ +2017-05-30 rocky + + * uncompyle6/version.py: Get ready for release 2.10.0 + +2017-05-30 rocky + + * uncompyle6/semantics/fragments.py: Python 3.6 makefunction + handling for fragments + +2017-05-23 rocky + + * uncompyle6/semantics/pysource.py: Fix up 3.6 unmapexpr + +2017-05-23 rocky + + * uncompyle6/semantics/pysource.py: Fix up retreiving "async" + property on 3.6 + +2017-05-23 rocky + + * uncompyle6/semantics/pysource.py: Fix bug in a 3.6 class name. + +2017-05-23 rocky + + * uncompyle6/semantics/fragments.py, + uncompyle6/semantics/pysource.py: Add fuzzy offset deparse lookup + +2017-05-21 rocky + + * uncompyle6/scanners/scanner3.py: Correct EXTENDED_ARG handling on + Python 3.6... where it can appear several times and xdis may handle it as well. + It possibly in other versions bug since EXTENDED_ARG is used so + rarely there because it has such a high value 1<<16, it's hard to + test and determine that. + +2017-05-20 rocky + + * uncompyle6/semantics/pysource.py: Worse results. Revert some of + the last changes + +2017-05-20 rocky + + * uncompyle6/parsers/parse3.py, uncompyle6/semantics/pysource.py: + More explicit about 3.5 UNMAP_PACK Have to reduce 3.5 bytecode testing for now, code is more solid. + +2017-05-19 rocky + + * uncompyle6/parsers/parse3.py, uncompyle6/parsers/parse36.py, + uncompyle6/scanners/scanner3.py: Simplify EXTENDED_ARG on 3.x We largely remove them and fold them itno the next op. + MAKE_FUNCTION though before 3.6 is an exception as that indicates an + annotated function + +2017-05-19 rocky + + * uncompyle6/scanners/scanner26.py: EXTENDED_ARG is implemented in + 2.6 + +2017-05-19 rocky + + * test/simple_source/expression/06_huge_list.py, + uncompyle6/parsers/parse3.py, uncompyle6/semantics/pysource.py: Fix + EXTENDED_ARG for long lists, sets, maps + +2017-05-19 rocky + + * uncompyle6/scanners/scanner3.py: Another attempt at getting + get_target() correct + +2017-05-19 rocky + + * uncompyle6/parsers/parse3.py: Bug in pypy JUMP_IF_NOT_DEBUG + handling + +2017-05-19 rocky + + * uncompyle6/parsers/parse36.py, uncompyle6/scanners/scanner3.py: + EXTENDED_ARG handling... get_target() wasn't taking into account EXTENDED_ARG before opcode. This is mostly relevant in Python 3.6 where the max size before + needing EXTENDED_ARG has been reduced to 256, but theoretically + possible in earlier versions. + +2017-05-18 rocky + + * __pkginfo__.py: Enforce using xdis >=3.3.1 .. to pick up bug fixes to 3.6 in xdis + +2017-05-17 rocky + + * __pkginfo__.py, uncompyle6/parsers/parse36.py, + uncompyle6/scanners/scanner3.py: Small changes.... * __pkginfo__.py: Need spark parser 1.6.1 for corrected + remove_rules() fn * parser36.py: remove replaced Python3 rules * scanner3.py: corrected comment. Thanks to moagstar here. * + +2017-05-16 rocky + + * uncompyle6/parsers/parse36.py: Fix broken CI on 3.6... Another grammar rule replacing SETUP_LOOP with setup_loop + +2017-05-16 rocky + + * uncompyle6/parsers/parse36.py: More EXTENDED_ARGS on 3.6 + +2017-05-16 rocky + + * uncompyle6/parsers/parse36.py: extend use of EXTENDED_ARGS in 3.6 switching to a wordcode seems to have made opcode fields smaller so + we need EXTENDED_ARG more? + +2017-05-16 rocky + + * uncompyle6/parsers/parse36.py, uncompyle6/semantics/pysource.py: + Allow LOAD_CONST EXTENDED_ARG + +2017-05-15 rocky + + * uncompyle6/parsers/parse3.py: Reinstate 3.6 listcomp rule + +2017-05-15 rocky + + * uncompyle6/parsers/parse3.py: Bang on 3.6 MAKE_FUNCTION some more + +2017-05-14 rocky + + * uncompyle6/semantics/pysource.py: towards fixing a + 3.5.CALL_FUNCTONI_VAR bug + +2017-05-14 rocky + + * test/simple_source/bug35/04_CALL_FUNCTION_VAR_KW.py, + uncompyle6/parsers/parse3.py: Python 3.5 kw arg can be an expr Fixes Issue #95 + +2017-05-14 R. Bernstein + + * : Merge pull request #117 from rocky/3.6-MAKE_FUNCTION 3.6 make function + +2017-05-13 rocky + + * uncompyle6/scanners/scanner3.py: MAKE_FUNCTION_FLAGS can be a + simpler tuple + +2017-05-13 rocky + + * uncompyle6/parsers/parse3.py: Grammar rules for Python 3.6 + MAKE_FUNCTION + +2017-05-13 rocky + + * README.rst, uncompyle6/parsers/parse3.py, + uncompyle6/parsers/parse36.py, uncompyle6/semantics/pysource.py: + Bang on 3.6 MAKE_FUNCTION a bit more parse3.py, parse36.py: adding return_closure rule tags what's going + on with this rule pysource.py: start changing semantic rules to support code changed + by new make_function semantics README.rst: typo + +2017-05-13 rocky + + * uncompyle6/scanners/scanner3.py: Typo + +2017-05-12 rocky + + * uncompyle6/parsers/parse27.py: Bug in 2.7 decompiling ourself! Troublesome file was uncompyle6.semantics.pysource.engine() + +2017-05-11 R. Bernstein + + * : Merge pull request #113 from grkov90/patch-1 Fixed out_base bug + +2017-05-11 rocky + + * uncompyle6/parsers/parse3.py, uncompyle6/scanners/scanner3.py, + uncompyle6/semantics/make_function.py: WIP: start 3.6 MAKE_FUNCTION + handling + +2017-05-11 Daniel Bradburn + + * : Merge pull request #116 from moagstar/function_call_keyword_only Added support for Python 3.6 CALL_FUNCTION_KW + +2017-05-10 Daniel Bradburn + + * uncompyle6/semantics/pysource.py: Fixed bug in compiling double + star arg only function calls where the closing parenthesis would be + missed + +2017-05-10 Daniel Bradburn + + * requirements-dev.txt: Adding requirement for pytest >= 3.0 to fix + strange INTERNALERROR in combination with hypothesis when using + pytest 2.6.4 + +2017-05-10 Daniel Bradburn + + * pytest/test_CALL_FUNCTION_KW.sh, pytest/test_function_call.py, + uncompyle6/parsers/parse3.py, uncompyle6/parsers/parse36.py, + uncompyle6/scanners/scanner36.py, uncompyle6/semantics/pysource.py: + Added support for support for Python 3.6 CALL_FUNCTION_KW + +2017-05-08 rocky + + * appveyor.yml, test/test_pyenvlib.py, + uncompyle6/semantics/pysource.py: pysource guard and another + appveyor test + +2017-05-08 rocky + + * appveyor.yml: appveyor take 2 + +2017-05-08 rocky + + * appveyor.yml, appveyor/install.ps1, appveyor/run_with_env.cmd: Try + appveyor + +2017-05-07 rocky + + * uncompyle6/semantics/pysource.py: More guarded CONTINUE deletion + +2017-05-07 rocky + + * uncompyle6/scanner.py, uncompyle6/scanners/scanner3.py, + uncompyle6/semantics/pysource.py: Reduce spurious "continue" + statements + +2017-05-07 rocky + + * test/Makefile: --weak-verify on 3.3 with inclusion of last commit Note that the result is sematically equivalent, so it is is correct. + +2017-05-07 rocky + + * test/simple_source/looping/12_if_while_true_pass.py, + uncompyle6/scanners/scanner3.py: Python 3.x control-flow bug... "pass" statement inside "while True" + +2017-05-07 rocky + + * HOW-TO-REPORT-A-BUG.md: Small typo + +2017-05-07 rocky + + * uncompyle6/scanners/scanner3.py: Fix improper COME_FROM_EXCEPT in + Python 3.3+ + 2017-05-06 rocky - * uncompyle6/version.py: Get ready for release 2.9.11 + * uncompyle6/parsers/parse33.py: python 3.3 while True parsing bug + +2017-05-06 rocky + + * ChangeLog, NEWS, uncompyle6/version.py: Get ready for release + 2.9.11 2017-05-06 rocky @@ -14,13 +251,21 @@ 2017-05-05 rocky - * uncompyle6/parsers/parse32.py, uncompyle6/scanners/scanner3.py: + * uncompyle6/parsers/parse32.py, uncompyle6/scanners/scanner3.py: Improve Python 3.2 decompilation ... by removing a lot of the control-flow labels of 3.3+ 2017-05-05 rocky * .travis.yml: Try CI testing on Python 3.6 +2017-05-03 Gregory + + * uncompyle6/main.py: Some fix + +2017-05-03 Gregory + + * uncompyle6/main.py: Fixed out_base bug Variable filename using in for tags uncompyle6 -o haven't worked argument -o haven't worked + 2017-05-02 rocky * test/simple_source/bug35/01_map_unpack.py, uncompyle6/parser.py, @@ -30,7 +275,7 @@ 2017-05-02 rocky * test/simple_source/bug35/01_map_unpack.py, uncompyle6/parser.py, - uncompyle6/parsers/parse3.py, uncompyle6/parsers/parse35.py: + uncompyle6/parsers/parse3.py, uncompyle6/parsers/parse35.py: BUILD_MAP_UNPACK'ing of dictionaries in 3.5 2017-05-01 rocky @@ -44,7 +289,7 @@ 2017-04-29 rocky * test/simple_source/bug35/01_map_unpack.py, - uncompyle6/parsers/parse35.py, uncompyle6/semantics/pysource.py: + uncompyle6/parsers/parse35.py, uncompyle6/semantics/pysource.py: Handle BUILD_MAP_UNPACK in a build_list 2017-04-27 rocky @@ -85,136 +330,136 @@ 2017-04-22 rocky - * history.md: history keeps gettting amended + * HISTORY.md: History keeps gettting amended 2017-04-22 rocky - * readme.rst: document python 3.x status + * README.rst: Document Python 3.x status 2017-04-22 rocky * test/simple_source/bug35/03_async_await.py, - uncompyle6/parsers/parse35.py, uncompyle6/semantics/pysource.py: add - await expr fixes #111 + uncompyle6/parsers/parse35.py, uncompyle6/semantics/pysource.py: Add + await expr Fixes #111 2017-04-22 rocky - * : update test + * : Update test 2017-04-22 rocky * test/simple_source/bug33/02_pos_args.py, - uncompyle6/parsers/parse3.py, uncompyle6/semantics/make_function.py: - 3.3+ bug in handling single kwarg after * towards fixing issue #110 + uncompyle6/parsers/parse3.py, uncompyle6/semantics/make_function.py: + 3.3+ bug in handling single kwarg after * Towards fixing issue #110 2017-04-20 rocky * test/simple_source/bug35/02_async_for.py, - uncompyle6/parsers/parse35.py: add async for with pass statement fixes #109 + uncompyle6/parsers/parse35.py: Add async for with pass statement Fixes #109 2017-04-19 rocky * test/simple_source/bug35/03_while-if-break.py, - uncompyle6/parsers/parse3.py: 3.5 ifelsestmtl grammar bug. fixes #108 + uncompyle6/parsers/parse3.py: 3.5 ifelsestmtl grammar bug. Fixes #108 2017-04-18 rocky * test/simple_source/bug35/03_async_await.py, - uncompyle6/parsers/parse35.py: expand await stmt handling fixes #107 + uncompyle6/parsers/parse35.py: Expand await stmt handling Fixes #107 2017-04-18 rocky * test/simple_source/bug33/01_delete_deref.py, - uncompyle6/parsers/parse32.py, uncompyle6/semantics/pysource.py: add - delete_deref grammar rule fixes issue #106 + uncompyle6/parsers/parse32.py, uncompyle6/semantics/pysource.py: Add + DELETE_DEREF grammar rule Fixes Issue #106 2017-04-17 rocky * test/simple_source/bug36/01_extended_arg.py, - test/simple_source/bug36/01_if_file.py: rename test case to + test/simple_source/bug36/01_if_file.py: Rename test case to something more appropriate 2017-04-17 rocky - * test/simple_source/bug36/01_if_file.py: fix botched test case thanks to zm908 for pointing this out + * test/simple_source/bug36/01_if_file.py: Fix botched test case Thanks to Zm908 for pointing this out 2017-04-16 rocky - * uncompyle6/parsers/parse3.py: comment on what's up with last + * uncompyle6/parsers/parse3.py: Comment on what's up with last change 2017-04-16 rocky * test/simple_source/bug22/03_if1.py, test/simple_source/bug31/02_ifelse_comprehension.py, - uncompyle6/parsers/parse3.py: python 3.x ifelse in comprehension fixes issue #91 + uncompyle6/parsers/parse3.py: Python 3.x ifelse in comprehension Fixes Issue #91 2017-04-16 rocky - * : add 2.7 complex test + * : Add 2.7 complex test 2017-04-15 rocky * test/simple_source/bug35/01_map_unpack.py, - uncompyle6/semantics/pysource.py: correct bug in 3.5+ build_list - with unpack + uncompyle6/semantics/pysource.py: Correct bug in 3.5+ build_list + with UNPACK -2017-04-15 r. bernstein +2017-04-15 R. Bernstein - * how-to-report-a-bug.md: update how-to-report-a-bug.md + * HOW-TO-REPORT-A-BUG.md: Update HOW-TO-REPORT-A-BUG.md -2017-04-15 r. bernstein +2017-04-15 R. Bernstein - * how-to-report-a-bug.md: update how-to-report-a-bug.md + * HOW-TO-REPORT-A-BUG.md: Update HOW-TO-REPORT-A-BUG.md 2017-04-15 rocky * test/simple_source/bug36/01_if_file.py, - uncompyle6/parsers/parse36.py: 3.6 generates wonky extended_arg in - expression fixes issue #102 + uncompyle6/parsers/parse36.py: 3.6 generates Wonky EXTENDED_ARG in + expression Fixes Issue #102 2017-04-15 rocky - * how-to-report-a-bug.md, manifest.in: add how to report a bug add test case for ... if 1 else ... + * HOW-TO-REPORT-A-BUG.md, MANIFEST.in: Add how to report a bug Add test case for ... if 1 else ... 2017-04-14 rocky * test/simple_source/bug35/01_map_unpack.py, uncompyle6/parsers/parse3.py, uncompyle6/parsers/parse35.py, - uncompyle6/semantics/pysource.py: python 3.5+ build_unmap_pack rules towards addressing issue #98 + uncompyle6/semantics/pysource.py: Python 3.5+ BUILD_UNMAP_PACK rules Towards addressing Issue #98 2017-04-14 rocky - * uncompyle6/scanners/scanner3.py: reduce adding return_end_if in - 3.5+ the whole control flow determination has to be redone in a less - haphazard way using real flow-control analysis. hopefully that's on - the way. in the meantime we have this hack. + * uncompyle6/scanners/scanner3.py: Reduce adding RETURN_END_IF in + 3.5+ The whole control flow determination has to be redone in a less + haphazard way using real flow-control analysis. Hopefully that's on + the way. In the meantime we have this hack. 2017-04-14 rocky * test/simple_source/bug27+/03_if_1_else.py, - test/simple_source/bug27+/03_if_true_else.py: better names for a + test/simple_source/bug27+/03_if_true_else.py: Better names for a test 2017-04-13 rocky * test/simple_source/bug27+/03_if_true_else.py, uncompyle6/parser.py, uncompyle6/parsers/parse3.py, - uncompyle6/semantics/consts.py: add if1else. fixes #101 + uncompyle6/semantics/consts.py: Add if1else. Fixes #101 2017-04-13 rocky - * uncompyle6/parsers/parse3.py: in 3.x come_from should include - come_from_except + * uncompyle6/parsers/parse3.py: In 3.x come_from should include + COME_FROM_EXCEPT 2017-04-13 rocky - * uncompyle6/parsers/parse35.py: towards fixing issue #92 + * uncompyle6/parsers/parse35.py: Towards fixing issue #92 2017-04-13 rocky - * uncompyle6/parsers/parse23.py, uncompyle6/semantics/pysource.py: - add python 2.3 rule for "if 1: ..." fully fixes #97 for python 2.3. python 2.4 was fixed in a previous + * uncompyle6/parsers/parse23.py, uncompyle6/semantics/pysource.py: + Add Python 2.3 rule for "if 1: ..." Fully fixes #97 for Python 2.3. Python 2.4 was fixed in a previous commit. 2017-04-12 rocky @@ -225,158 +470,158 @@ 2017-04-12 rocky - * uncompyle6/parsers/parse24.py: handle python 2.4 "if 1...." + * uncompyle6/parsers/parse24.py: Handle Python 2.4 "if 1...." 2017-04-11 rocky * test/simple_source/bug31/04_def_annotate.py, uncompyle6/semantics/fragments.py, - uncompyle6/semantics/make_function.py: bang on 3.x annotations + uncompyle6/semantics/make_function.py: Bang on 3.x annotations 2017-04-11 rocky * test/simple_source/bug31/04_def_annotate.py, - uncompyle6/parsers/parse3.py, uncompyle6/semantics/pysource.py: - towards fixing annotated decorator functions... and annotate functions + uncompyle6/parsers/parse3.py, uncompyle6/semantics/pysource.py: + Towards fixing annotated decorator functions... and annotate functions 2017-04-10 rocky * uncompyle6/parsers/parse2.py, uncompyle6/scanners/scanner27.py, - uncompyle6/semantics/check_ast.py, uncompyle6/semantics/pysource.py: - misc bugs parse2.py: restore accidently-removed while1stmt rule scanner27.py: + uncompyle6/semantics/check_ast.py, uncompyle6/semantics/pysource.py: + Misc bugs parse2.py: restore accidently-removed while1stmt rule scanner27.py: grammar typo check_ast: add while1else to list of looping constructs - pysource.py: call_function_var_kw_args with positional args rule is + pysource.py: CALL_FUNCTION_VAR_KW_ARGS with positional args rule is different? 2017-04-10 rocky * test/simple_source/stmts/02_while1else.py, uncompyle6/parsers/parse2.py, uncompyle6/parsers/parse3.py, - uncompyle6/parsers/parse35.py: add more while1else grammar rules towards addressing issue #93 + uncompyle6/parsers/parse35.py: Add more while1else grammar rules Towards addressing issue #93 2017-04-09 rocky - * : one more function_var test for 3.3 + * : One more FUNCTION_VAR test for 3.3 2017-04-09 rocky * test/simple_source/def/10_kw+pos_args-bug.py, - uncompyle6/parsers/parse3.py, uncompyle6/semantics/pysource.py: - another python 3.5 function_var bug fixes #94 + uncompyle6/parsers/parse3.py, uncompyle6/semantics/pysource.py: + Another Python 3.5 FUNCTION_VAR bug Fixes #94 2017-04-09 rocky - * : commit 4199bc7f617e387fb03fc06939cd17366dc15c5e author: rocky - date: sun apr 9 05:30:45 2017 -0400 + * : commit 4199bc7f617e387fb03fc06939cd17366dc15c5e Author: rocky + Date: Sun Apr 9 05:30:45 2017 -0400 2017-04-03 rocky - * : commit 6773a66b99d07e48290a77dbbbe3c71cc39c31ba author: rocky - date: mon apr 3 06:53:12 2017 -0400 + * : commit 6773a66b99d07e48290a77dbbbe3c71cc39c31ba Author: rocky + Date: Mon Apr 3 06:53:12 2017 -0400 2017-03-27 rocky - * : commit a91cd716670be09d3cef34e1bb36a67f96f91712 author: rocky - date: mon mar 27 07:08:59 2017 -0400 + * : commit a91cd716670be09d3cef34e1bb36a67f96f91712 Author: rocky + Date: Mon Mar 27 07:08:59 2017 -0400 2017-03-19 rocky - * __pkginfo__.py: use more-recent xdis + * __pkginfo__.py: Use more-recent xdis 2017-03-15 rocky - * history.md, test/simple_source/bug33/01_if_try_except.py: grammar + * HISTORY.md, test/simple_source/bug33/01_if_try_except.py: grammar typo and add another test 2017-03-12 rocky - * uncompyle6/scanners/scanner3.py: python 3.0 doesn't have - pop_jump_if... + * uncompyle6/scanners/scanner3.py: Python 3.0 doesn't have + POP_JUMP_IF... 2017-03-12 rocky - * readme.rst: note problem in handling pathologically long lists + * README.rst: Note problem in handling pathologically long lists 2017-03-07 rocky - * uncompyle6/scanners/scanner3.py: small cleanup - remove - pop_jump_tf + * uncompyle6/scanners/scanner3.py: Small cleanup - remove + POP_JUMP_TF 2017-03-05 rocky * pytest/test_grammar.py, uncompyle6/parsers/parse3.py, - uncompyle6/parsers/parse33.py, uncompyle6/scanners/scanner3.py: more + uncompyle6/parsers/parse33.py, uncompyle6/scanners/scanner3.py: More accurate ranges of try blocks in 3.x 2017-03-05 rocky - * test/simple_source/bug33/01_try_except.py: more accurate ranges of + * test/simple_source/bug33/01_try_except.py: More accurate ranges of try blocks in 3.x -2017-03-04 r. bernstein +2017-03-04 R. Bernstein - * : merge pull request #84 from - moagstar/property_based_test_function_call property based test function call + * : Merge pull request #84 from + moagstar/property_based_test_function_call Property based test function call 2017-03-04 rocky - * readme.rst: readme updates for 3.5 and 1.5 + * README.rst: README updates for 3.5 and 1.5 2017-03-04 rocky * test/simple_source/bug32/01_named_and_kwargs.py, - uncompyle6/parsers/parse3.py: bug found by hypothesis in creating + uncompyle6/parsers/parse3.py: Bug found by hypothesis in creating function calls -2017-03-04 daniel bradburn +2017-03-04 Daniel Bradburn * pytest/test_function_call.py: marked all function call tests as failing until they pass across all python versions -2017-03-04 daniel bradburn +2017-03-04 Daniel Bradburn * pytest/test_function_call.py: added minimal examples for various function call opcodes -2017-03-04 daniel bradburn +2017-03-04 Daniel Bradburn * pytest/test_function_call.py: added property based test for - verifying uncompylation of function calls. a number of minimal + verifying uncompylation of function calls. A number of minimal examples for the various function call opcodes have been generated with the majority marked as expected failure until python 3.6 opcode - support is complete. i'm hoping this will make it easier to figure + support is complete. I'm hoping this will make it easier to figure out what needs to be done to support the new opcodes and changed semntics for function calls -2017-03-03 daniel bradburn +2017-03-03 Daniel Bradburn * pytest/test_function_call.py: reduced errors when generating function call instances -2017-03-03 daniel bradburn +2017-03-03 Daniel Bradburn * pytest/test_function_call.py: added test file for function calls -2017-03-03 daniel bradburn +2017-03-03 Daniel Bradburn * .gitignore: added .idea to gitignore -2017-03-03 daniel bradburn +2017-03-03 Daniel Bradburn * .gitignore: added .venv to gitignore 2017-03-01 rocky * uncompyle6/scanner.py, uncompyle6/scanners/scanner2.py, - uncompyle6/scanners/scanner3.py, uncompyle6/verify.py: come_from for - 3.x pop_except, dry with op_name() ... start adding come_froms for pop_except in preparation for getting - tryelse blocks correct. simpler opname access functions: - self.op_name(op) is self.opc.opname[op] - self.op_name_from_offset(offset) is + uncompyle6/scanners/scanner3.py, uncompyle6/verify.py: COME_FROM for + 3.x POP_EXCEPT, DRY with op_name() ... Start adding COME_FROMs for POP_EXCEPT in preparation for getting + tryelse blocks correct. Simpler opname access functions: - self.op_name(op) is self.opc.opname[op] - self.op_name_from_offset(offset) is self.opc.opname[self.code[offset]] verify.py: not all offsets are ints 2017-02-28 rocky - * readme.rst, uncompyle6/parser.py, uncompyle6/parsers/parse26.py: - python 2.6 a == b or c == d == 3 grammar bug + * README.rst, uncompyle6/parser.py, uncompyle6/parsers/parse26.py: + Python 2.6 a == b or c == d == 3 grammar bug 2017-02-28 rocky @@ -385,12 +630,12 @@ 2017-02-28 rocky * test/simple_source/bug26/03_double_equals.py, - uncompyle6/semantics/consts.py: predidence of cmp_list: x == y == z the x, y, z should not have parenthesis around pairs of them (x == + uncompyle6/semantics/consts.py: Predidence of cmp_list: x == y == z The x, y, z should not have parenthesis around pairs of them (x == y) or (y == z) 2017-02-28 rocky - * uncompyle6/parser.py, uncompyle6/parsers/parse27.py: python 2.7 + * uncompyle6/parser.py, uncompyle6/parsers/parse27.py: Python 2.7 check jump targets of "and" 2017-02-25 rocky @@ -426,7 +671,7 @@ 2017-02-20 rocky - * uncompyle6/parsers/parse3.py, uncompyle6/parsers/parse35.py: + * uncompyle6/parsers/parse3.py, uncompyle6/parsers/parse35.py: Python 3.x needs more "while 1" grammar rules 2017-02-20 rocky @@ -556,7 +801,7 @@ 2017-01-15 rocky - * uncompyle6/parsers/parse3.py, uncompyle6/scanners/scanner3.py: + * uncompyle6/parsers/parse3.py, uncompyle6/scanners/scanner3.py: Handle 3.6 BUILD_CONST_KEYMAP 2017-01-15 rocky @@ -589,7 +834,7 @@ 2017-01-10 rocky * test/simple_source/bug35/03_double_star_unpack.py, - uncompyle6/parsers/parse3.py, uncompyle6/semantics/pysource.py: + uncompyle6/parsers/parse3.py, uncompyle6/semantics/pysource.py: Improve BUILD_xxx_UNPACK slightly 2017-01-09 rocky @@ -608,7 +853,7 @@ 2017-01-08 rocky - * uncompyle6/parsers/parse30.py, uncompyle6/scanners/scanner3.py: + * uncompyle6/parsers/parse30.py, uncompyle6/scanners/scanner3.py: Python 3.0 decompile bugs 2017-01-08 rocky @@ -639,7 +884,7 @@ 2017-01-07 rocky * test/simple_source/bug35/03_async_await.py, - uncompyle6/parsers/parse35.py, uncompyle6/semantics/pysource.py: + uncompyle6/parsers/parse35.py, uncompyle6/semantics/pysource.py: Start to add 3.5+ await and async 2017-01-07 rocky @@ -676,7 +921,7 @@ 2017-01-02 rocky - * uncompyle6/parsers/parse35.py, uncompyle6/scanners/scanner3.py: + * uncompyle6/parsers/parse35.py, uncompyle6/scanners/scanner3.py: Python 3.5 continue detection bug 2017-01-01 rocky @@ -686,7 +931,7 @@ 2017-01-01 rocky - * uncompyle6/parsers/parse35.py, uncompyle6/scanners/scanner3.py: + * uncompyle6/parsers/parse35.py, uncompyle6/scanners/scanner3.py: Towards fixing Python 3.5 return bugs 2017-01-01 rocky @@ -713,12 +958,12 @@ 2016-12-29 rocky - * uncompyle6/scanners/scanner2.py, uncompyle6/scanners/scanner3.py: + * uncompyle6/scanners/scanner2.py, uncompyle6/scanners/scanner3.py: dectect_structure() -> detect_control_flow() 2016-12-29 rocky - * uncompyle6/scanners/scanner2.py, uncompyle6/scanners/scanner3.py: + * uncompyle6/scanners/scanner2.py, uncompyle6/scanners/scanner3.py: DRY code and emitted Python 3 source * Python 3: break; continue -> break * Use variable in detect_structure for pre[rtarget] * Make Python 2 and Python 3 detect_structure more alie 2016-12-29 rocky @@ -755,7 +1000,7 @@ 2016-12-27 rocky * uncompyle6/parsers/parse26.py, uncompyle6/scanners/scanner2.py, - uncompyle6/scanners/scanner26.py, uncompyle6/semantics/pysource.py: + uncompyle6/scanners/scanner26.py, uncompyle6/semantics/pysource.py: WIP : Add THEN to disambigute from "and" 2016-12-27 rocky @@ -800,7 +1045,7 @@ uncompyle6/parsers/parse36.py, uncompyle6/scanners/scanner15.py, uncompyle6/scanners/scanner2.py, uncompyle6/scanners/scanner21.py, uncompyle6/scanners/scanner22.py, - uncompyle6/semantics/fragments.py, uncompyle6/semantics/pysource.py: + uncompyle6/semantics/fragments.py, uncompyle6/semantics/pysource.py: Lint 2016-12-24 rocky @@ -817,7 +1062,7 @@ * uncompyle6/bin/pydisassemble.py, uncompyle6/bin/uncompile.py, uncompyle6/parsers/parse2.py, uncompyle6/parsers/parse25.py, uncompyle6/parsers/parse27.py, uncompyle6/parsers/parse3.py, - uncompyle6/scanners/scanner2.py, uncompyle6/scanners/scanner3.py: + uncompyle6/scanners/scanner2.py, uncompyle6/scanners/scanner3.py: Python flake8 crap Was testing realgud's C-x!8 (goto flake8 warning/error) 2016-12-18 rocky @@ -828,7 +1073,7 @@ 2016-12-17 rocky - * uncompyle6/scanners/scanner2.py, uncompyle6/scanners/scanner25.py: + * uncompyle6/scanners/scanner2.py, uncompyle6/scanners/scanner25.py: show-asm on python2.5 is optional make scanner2 look a little more like scanner3 2016-12-16 rocky @@ -917,7 +1162,7 @@ 2016-11-28 rocky - * uncompyle6/parsers/parse3.py, uncompyle6/parsers/parse36.py: + * uncompyle6/parsers/parse3.py, uncompyle6/parsers/parse36.py: Shorten Python3 grammars with + and * 2016-11-28 rocky @@ -956,7 +1201,7 @@ 2016-11-24 rocky * uncompyle6/parsers/parse27.py, uncompyle6/scanners/scanner2.py, - uncompyle6/semantics/helper.py, uncompyle6/semantics/pysource.py: + uncompyle6/semantics/helper.py, uncompyle6/semantics/pysource.py: 2.7 grammar bug workaround. Fix docstring bug 2016-11-24 rocky @@ -966,7 +1211,7 @@ 2016-11-24 rocky - * uncompyle6/parsers/parse3.py, uncompyle6/scanners/scanner2.py: + * uncompyle6/parsers/parse3.py, uncompyle6/scanners/scanner2.py: <2.7 "if" detection and dup Python 3 grammar rule 2016-11-23 rocky @@ -1049,7 +1294,7 @@ 2016-11-20 rocky * pytest/test_fjt.py, uncompyle6/scanners/scanner2.py, - uncompyle6/scanners/scanner26.py, uncompyle6/scanners/scanner3.py: + uncompyle6/scanners/scanner26.py, uncompyle6/scanners/scanner3.py: Start to improve detect_structure for 2.7 and 2.x Add debug flag to find_jump_targets to show the structure we found. When there are control-flow bugs, it's often reflected here. scanner3.py: make code make more similar to 2.x code @@ -1065,7 +1310,7 @@ 2016-11-16 rocky * test/simple_source/bug26/03_if_vs_and.py, uncompyle6/main.py, - uncompyle6/semantics/check_ast.py, uncompyle6/semantics/pysource.py: + uncompyle6/semantics/check_ast.py, uncompyle6/semantics/pysource.py: More AST checking Small fixes in output format 2016-11-15 rocky @@ -1085,17 +1330,17 @@ 2016-11-14 rocky - * uncompyle6/parsers/parse26.py, uncompyle6/scanners/scanner2.py: + * uncompyle6/parsers/parse26.py, uncompyle6/scanners/scanner2.py: WIP remove COME_FROMs around ignore_if's 2016-11-14 rocky - * uncompyle6/parsers/parse26.py, uncompyle6/scanners/scanner2.py: + * uncompyle6/parsers/parse26.py, uncompyle6/scanners/scanner2.py: WIP remove COME_FROMs around ignore_if's 2016-11-14 rocky - * uncompyle6/scanners/scanner2.py, uncompyle6/scanners/scanner26.py: + * uncompyle6/scanners/scanner2.py, uncompyle6/scanners/scanner26.py: Show line numbers in 2.6 "after" asm .. start to understand some of the Python 2.6 bytecode parse failures. 2016-11-13 rocky @@ -1131,7 +1376,7 @@ 2016-11-11 rocky * uncompyle6/parser.py, uncompyle6/semantics/check_ast.py, - uncompyle6/semantics/fragments.py, uncompyle6/semantics/pysource.py: + uncompyle6/semantics/fragments.py, uncompyle6/semantics/pysource.py: Revert augassign change but.. Make note of what's going on and add grammar test for bad situations we have in Python 2.6 (and perhaps others) @@ -1151,7 +1396,7 @@ 2016-11-10 rocky * uncompyle6/main.py, uncompyle6/semantics/check_ast.py, - uncompyle6/semantics/fragments.py, uncompyle6/semantics/pysource.py: + uncompyle6/semantics/fragments.py, uncompyle6/semantics/pysource.py: Detect some erroneous decompilations Until we can actually prevent these in grammar rules, we will warn of improper decompilations. Also, we now stop when we hit a decompile error. Previously we were not. @@ -1218,7 +1463,7 @@ 2016-10-30 rocky - * .gitignore, README.rst, test/simple_source/def/03_class_method.py: + * .gitignore, README.rst, test/simple_source/def/03_class_method.py: Note github unpyc3 and.. - Add source to bytecode_2.2/03_class_method.pyc - more ignore 2016-10-30 rocky @@ -1247,20 +1492,20 @@ * pytest/test_grammar.py, uncompyle6/parsers/parse3.py, uncompyle6/parsers/parse31.py, uncompyle6/parsers/parse32.py, - uncompyle6/parsers/parse35.py, uncompyle6/semantics/pysource.py: + uncompyle6/parsers/parse35.py, uncompyle6/semantics/pysource.py: More complete annotate handling Still have a bit of work to do though. 2016-10-28 rocky * pytest/test_grammar.py, uncompyle6/parsers/parse3.py, uncompyle6/parsers/parse32.py, uncompyle6/parsers/parse33.py, - uncompyle6/parsers/parse34.py, uncompyle6/semantics/pysource.py: + uncompyle6/parsers/parse34.py, uncompyle6/semantics/pysource.py: Expand annotate return to Python 3.4 2016-10-28 rocky * pytest/test_grammar.py, uncompyle6/parsers/parse31.py, - uncompyle6/parsers/parse32.py, uncompyle6/semantics/pysource.py: + uncompyle6/parsers/parse32.py, uncompyle6/semantics/pysource.py: Expand annotate handling to 3.3 (and possibly 3.2) - DRY Python 3.1-3.3 grammar a little 2016-10-28 rocky @@ -1274,7 +1519,7 @@ * test/simple_source/bug31/04_def_annotate.py, test/simple_source/bug31/04_def_attr.py, - uncompyle6/parsers/parse31.py, uncompyle6/semantics/pysource.py: + uncompyle6/parsers/parse31.py, uncompyle6/semantics/pysource.py: Clean and fix Python 3 annotate arg return 2016-10-26 rocky @@ -1349,7 +1594,7 @@ 2016-10-20 moagstar * pytest/test_fstring.py, uncompyle6/parsers/parse3.py, - uncompyle6/parsers/parse36.py, uncompyle6/semantics/pysource.py: + uncompyle6/parsers/parse36.py, uncompyle6/semantics/pysource.py: further work on supporting single and multiple fstring decompilation 2016-10-20 rocky @@ -1360,7 +1605,7 @@ 2016-10-19 moagstar * pytest/test_fstring.py, uncompyle6/parsers/parse3.py, - uncompyle6/parsers/parse36.py, uncompyle6/semantics/pysource.py: + uncompyle6/parsers/parse36.py, uncompyle6/semantics/pysource.py: urther work on fstrings for python 3.6 - there is a new opcode build_string which is used to improve fstring performance, but broke the fstring support in uncompyle @@ -1548,13 +1793,13 @@ 2016-10-05 rocky * uncompyle6/parser.py, uncompyle6/parsers/parse2.py, - uncompyle6/parsers/parse3.py, uncompyle6/scanners/scanner3.py: + uncompyle6/parsers/parse3.py, uncompyle6/scanners/scanner3.py: Python 3: "and" doesn't have optional come_from 2016-10-05 rocky * uncompyle6/parser.py, uncompyle6/parsers/parse2.py, - uncompyle6/parsers/parse3.py, uncompyle6/scanners/scanner3.py: + uncompyle6/parsers/parse3.py, uncompyle6/scanners/scanner3.py: Python 3: "and" doesn't have optional come_from 2016-10-05 rocky @@ -1584,7 +1829,7 @@ 2016-09-26 rocky * HISTORY.md, uncompyle6/parser.py, uncompyle6/parsers/parse2.py, - uncompyle6/parsers/parse3.py, uncompyle6/scanners/scanner3.py: + uncompyle6/parsers/parse3.py, uncompyle6/scanners/scanner3.py: Interval order COME_FROMs in Python3 This bug had possibly caused lots of grammar pollution which may need addressing. We want to process COME_FROMs to the same offset to be in *descending* order so we have the larger range or biggest @@ -1669,7 +1914,7 @@ 2016-09-21 rocky - * uncompyle6/scanners/scanner2.py, uncompyle6/scanners/scanner26.py: + * uncompyle6/scanners/scanner2.py, uncompyle6/scanners/scanner26.py: Python 2 & 3 scanner code ever so slightly closer 2016-09-21 rocky @@ -1679,7 +1924,7 @@ 2016-09-18 rocky * uncompyle6/scanners/scanner2.py, - uncompyle6/scanners/scanner26.py, uncompyle6/semantics/pysource.py: + uncompyle6/scanners/scanner26.py, uncompyle6/semantics/pysource.py: Small changes 2016-09-11 rocky @@ -1690,7 +1935,7 @@ 2016-09-11 rocky * test/bytecode_3.6/fstring.py, - test/bytecode_3.6/fstring_single.py, uncompyle6/parsers/parse35.py: + test/bytecode_3.6/fstring_single.py, uncompyle6/parsers/parse35.py: Tidy a bit 2016-09-09 rocky @@ -1704,7 +1949,7 @@ 2016-09-09 rocky - * uncompyle6/scanners/scanner2.py, uncompyle6/semantics/pysource.py: + * uncompyle6/scanners/scanner2.py, uncompyle6/semantics/pysource.py: ret_cond adjustment for < 2.7 and ... "<= 2.6" -> "< 2.7" since python 2.6's version is 2.6000001 2016-09-09 rocky @@ -1726,7 +1971,7 @@ 2016-09-08 rocky - * uncompyle6/parsers/parse3.py, uncompyle6/semantics/pysource.py: + * uncompyle6/parsers/parse3.py, uncompyle6/semantics/pysource.py: Python 3.0-3.2 *args processing 2016-09-08 rocky @@ -1762,7 +2007,7 @@ * uncompyle6/parsers/parse2.py, uncompyle6/parsers/parse26.py, uncompyle6/parsers/parse27.py, uncompyle6/scanners/scanner2.py, - uncompyle6/scanners/scanner26.py, uncompyle6/scanners/scanner3.py: + uncompyle6/scanners/scanner26.py, uncompyle6/scanners/scanner3.py: Python 2.6- try/except control flow detection 2016-09-04 rocky @@ -1837,19 +2082,19 @@ 2016-09-02 rocky * test/simple_source/bug26/06_return_pop.py, - uncompyle6/parsers/parse26.py, uncompyle6/scanners/scanner2.py: + uncompyle6/parsers/parse26.py, uncompyle6/scanners/scanner2.py: Python 2.6- bug: RETURN_ENDIF, POP_TOP .. POP_TOP should be excluded as a potentional statement beginning 2016-09-02 rocky * test/simple_source/bug33/02_named_and_kwargs.py, - uncompyle6/scanners/scanner2.py, uncompyle6/semantics/pysource.py: + uncompyle6/scanners/scanner2.py, uncompyle6/semantics/pysource.py: Fix Python 3.x named param and kwargs bug 2016-09-01 rocky * test/simple_source/bug26/04_while_and_stmt_one_line.py, - uncompyle6/scanners/scanner2.py, uncompyle6/scanners/scanner26.py: + uncompyle6/scanners/scanner2.py, uncompyle6/scanners/scanner26.py: 2.6- bug: while..and: stmt - on one line If 2.6 or before POP_BLOCK after a JUMP_IF_FALSE does not constitute a new statement. The POP_BLOCK is really part of the JUMP_IF_FALSE. In Python 2.7+ it's a single op. @@ -1857,7 +2102,7 @@ 2016-09-01 rocky * test/simple_source/bug26/02_except_as.py, - uncompyle6/parsers/parse26.py, uncompyle6/semantics/pysource.py: + uncompyle6/parsers/parse26.py, uncompyle6/semantics/pysource.py: Handle Python 2.6 and below "except , " 2016-08-31 rocky @@ -1999,7 +2244,7 @@ * README.rst, uncompyle6/parser.py, uncompyle6/parsers/parse22.py, uncompyle6/scanner.py, uncompyle6/scanners/scanner22.py, uncompyle6/scanners/scanner23.py, uncompyle6/scanners/scanner24.py, - uncompyle6/scanners/scanner25.py, uncompyle6/semantics/pysource.py: + uncompyle6/scanners/scanner25.py, uncompyle6/semantics/pysource.py: Start handling Python 2.2 bytecode and... Fix some bugs in Python 2.3-2.5 bytecode handling 2016-08-11 Omer Katz @@ -2068,7 +2313,7 @@ 2016-07-29 rocky * uncompyle6/parsers/parse35.py, uncompyle6/scanner.py, - uncompyle6/scanners/scanner3.py, uncompyle6/semantics/pysource.py: + uncompyle6/scanners/scanner3.py, uncompyle6/semantics/pysource.py: Fix 3.5 misclassifying RETURN_VALUE We use location of SETUP_EXCEPT instructions to disambiguate. 2016-07-28 Daniel Bradburn @@ -2167,7 +2412,7 @@ 2016-07-27 rocky - * uncompyle6/parsers/parse2.py, uncompyle6/semantics/pysource.py: + * uncompyle6/parsers/parse2.py, uncompyle6/semantics/pysource.py: Small code clean up 2016-07-26 rocky @@ -2195,7 +2440,7 @@ test/simple_source/bug_pypy27/03_try_return.py, uncompyle6/parser.py, uncompyle6/parsers/parse2.py, uncompyle6/parsers/parse27.py, uncompyle6/scanners/scanner2.py, - uncompyle6/scanners/scanner3.py, uncompyle6/semantics/pysource.py: + uncompyle6/scanners/scanner3.py, uncompyle6/semantics/pysource.py: More PyPy grammar rules * assert one and two-arg form * trystmt Simplify adding multiple grammar rules 2016-07-25 rocky @@ -2257,7 +2502,7 @@ * README.rst, test/simple_source/stmts/03_if_elif.py, uncompyle6/parsers/parse2.py, uncompyle6/parsers/parse27.py, uncompyle6/parsers/parse3.py, uncompyle6/scanners/scanner2.py, - uncompyle6/scanners/scanner3.py, uncompyle6/semantics/pysource.py: + uncompyle6/scanners/scanner3.py, uncompyle6/semantics/pysource.py: Handle PyPy JUMP_IF_NOT_DEBUG Update README.rst to note PyPY and reorganize a little 2016-07-25 rocky @@ -2279,7 +2524,7 @@ test/Makefile, test/test_pythonlib.py, uncompyle6/parsers/parse2.py, uncompyle6/parsers/parse3.py, uncompyle6/scanner.py, uncompyle6/scanners/scanner2.py, - uncompyle6/scanners/scanner3.py, uncompyle6/semantics/pysource.py: + uncompyle6/scanners/scanner3.py, uncompyle6/semantics/pysource.py: PyPy support * Use proper PYPY 32 opcodes * handle opcodes LOOKUP_METHOD and CALL_METHOD * Administrative stuff for PyPy 2016-07-24 Daniel Bradburn @@ -2299,19 +2544,19 @@ 2016-07-23 rocky * test/simple_source/bug27+/05_for_try_except.py, - uncompyle6/scanners/scanner2.py, uncompyle6/scanners/scanner27.py: + uncompyle6/scanners/scanner2.py, uncompyle6/scanners/scanner27.py: Another 2.7 'continue' detection bug 2016-07-23 rocky * test/simple_source/bug27+/05_for_try_except.py, - uncompyle6/scanners/scanner2.py, uncompyle6/scanners/scanner27.py: + uncompyle6/scanners/scanner2.py, uncompyle6/scanners/scanner27.py: Another 2.7 'continue' detection bug 2016-07-23 rocky * test/simple_source/bug27+/05_for_try_except.py, - uncompyle6/scanners/scanner2.py, uncompyle6/scanners/scanner27.py: + uncompyle6/scanners/scanner2.py, uncompyle6/scanners/scanner27.py: Another 2.7 'continue' detection bug 2016-07-23 rocky @@ -2360,7 +2605,7 @@ 2016-07-17 rocky - * pytest/testdata/if-2.7.right, pytest/testdata/ifelse-2.7.right: + * pytest/testdata/if-2.7.right, pytest/testdata/ifelse-2.7.right: Adjust test data for changed disasm output 2016-07-16 rocky @@ -2394,7 +2639,7 @@ 2016-07-14 rocky - * uncompyle6/parsers/parse3.py, uncompyle6/semantics/pysource.py: + * uncompyle6/parsers/parse3.py, uncompyle6/semantics/pysource.py: Attempt to get 3.5 RETURN_END_IF working This feels hacky and I'm not sure is quite right. Untili we understand better what to do though, we'll go with it. @@ -2465,7 +2710,7 @@ * test/simple_source/bug33/05_store_name.py, test/simple_source/comprehension/05_3x_set_comphension.py, - uncompyle6/parsers/parse3.py, uncompyle6/semantics/pysource.py: + uncompyle6/parsers/parse3.py, uncompyle6/semantics/pysource.py: Python 3.2 & 3.3 handle STORE_NAME better 2016-07-11 rocky @@ -2520,13 +2765,13 @@ 2016-07-10 rocky - * uncompyle6/parsers/parse3.py, uncompyle6/scanners/scanner3.py: + * uncompyle6/parsers/parse3.py, uncompyle6/scanners/scanner3.py: Bugs caused by 3.x jump_forward misclasification 2016-07-10 rocky * uncompyle6/parsers/parse3.py, uncompyle6/scanners/scanner2.py, - uncompyle6/scanners/scanner26.py, uncompyle6/scanners/scanner3.py: + uncompyle6/scanners/scanner26.py, uncompyle6/scanners/scanner3.py: Python 3 better CONTINUE op classification Also document what's up with JUMP_ABSOLUTE classification 2016-07-09 rocky @@ -2617,7 +2862,7 @@ * uncompyle6/scanners/scanner3.py, uncompyle6/scanners/scanner32.py, uncompyle6/scanners/scanner33.py, - uncompyle6/scanners/scanner34.py, uncompyle6/scanners/scanner35.py: + uncompyle6/scanners/scanner34.py, uncompyle6/scanners/scanner35.py: Python 3 code cleanup 2016-07-08 rocky @@ -2638,7 +2883,7 @@ 2016-07-08 rocky * uncompyle6/parsers/parse24.py, uncompyle6/scanners/scanner2.py, - uncompyle6/scanners/scanner24.py, uncompyle6/scanners/scanner26.py: + uncompyle6/scanners/scanner24.py, uncompyle6/scanners/scanner26.py: Python 2.4 generator expressions and gen_comp_body 2016-07-08 rocky @@ -2664,12 +2909,12 @@ 2016-07-08 rocky * test/simple_source/stmts/11_return_val.py, - uncompyle6/scanners/scanner2.py, uncompyle6/scanners/scanner26.py: + uncompyle6/scanners/scanner2.py, uncompyle6/scanners/scanner26.py: 2.5/2.6 RETURN_VALUE bug 2016-07-08 rocky - * uncompyle6/parsers/parse25.py, uncompyle6/parsers/parse26.py: + * uncompyle6/parsers/parse25.py, uncompyle6/parsers/parse26.py: 2.5/2.6 fn name clash fixes list conprehension problem 2016-07-08 rocky @@ -2711,7 +2956,7 @@ 2016-07-07 rocky - * uncompyle6/scanners/scanner2.py, uncompyle6/scanners/scanner26.py: + * uncompyle6/scanners/scanner2.py, uncompyle6/scanners/scanner26.py: <2.6 make sure jump back on loops is really "back" 2016-07-07 rocky @@ -2770,12 +3015,12 @@ * uncompyle6/parser.py, uncompyle6/parsers/parse26.py, uncompyle6/parsers/parse27.py, uncompyle6/parsers/parse3.py, - uncompyle6/scanners/scanner2.py, uncompyle6/scanners/scanner26.py: + uncompyle6/scanners/scanner2.py, uncompyle6/scanners/scanner26.py: Another 2.6 while stmt. Clean up grammar a little 2016-07-03 rocky - * uncompyle6/parsers/parse26.py, uncompyle6/scanners/scanner2.py: + * uncompyle6/parsers/parse26.py, uncompyle6/scanners/scanner2.py: 2.6 improper tagging of RETURN_END_IF 2016-07-02 rocky @@ -2812,7 +3057,7 @@ 2016-06-30 rocky * test/simple_source/stmts/06_for_break.py, - uncompyle6/parsers/parse26.py, uncompyle6/semantics/pysource.py: + uncompyle6/parsers/parse26.py, uncompyle6/semantics/pysource.py: More 2.6.9 bugs fixed * break loop parsing bug * ifelsestmt semantic-action bug in handling else 2016-06-30 rocky @@ -2829,7 +3074,7 @@ 2016-06-30 rocky * test/simple_source/comprehension/05_for_for.py, - uncompyle6/parsers/parse26.py, uncompyle6/semantics/pysource.py: + uncompyle6/parsers/parse26.py, uncompyle6/semantics/pysource.py: 2.6.9 list comprehension 2016-06-30 rocky @@ -2871,7 +3116,7 @@ 2016-06-28 rocky - * uncompyle6/parsers/parse26.py, uncompyle6/semantics/pysource.py: + * uncompyle6/parsers/parse26.py, uncompyle6/semantics/pysource.py: Weird 2.6.9 list comprehension 2016-06-28 rocky @@ -2888,7 +3133,7 @@ * uncompyle6/parser.py, uncompyle6/parsers/parse26.py, uncompyle6/parsers/parse27.py, uncompyle6/scanners/scanner2.py, - uncompyle6/scanners/scanner25.py, uncompyle6/scanners/scanner26.py: + uncompyle6/scanners/scanner25.py, uncompyle6/scanners/scanner26.py: Base 2.5 off of 2.6. Some other small bugs. 2016-06-27 rocky @@ -2898,7 +3143,7 @@ 2016-06-27 rocky - * uncompyle6/parsers/parse26.py, uncompyle6/semantics/pysource.py: + * uncompyle6/parsers/parse26.py, uncompyle6/semantics/pysource.py: 2.6 list comprehensions 2016-06-27 rocky @@ -2983,7 +3228,7 @@ 2016-06-22 rocky * test/simple_source/expression/05_yield_from.py, - uncompyle6/parsers/parse3.py, uncompyle6/semantics/pysource.py: + uncompyle6/parsers/parse3.py, uncompyle6/semantics/pysource.py: differing ways to do "yield from" in 3.3-3.5 2016-06-22 rocky @@ -2992,7 +3237,7 @@ uncompyle6/scanners/scanner2.py, uncompyle6/scanners/scanner23.py, uncompyle6/scanners/scanner25.py, uncompyle6/scanners/scanner26.py, uncompyle6/scanners/scanner27.py, - uncompyle6/semantics/fragments.py, uncompyle6/semantics/pysource.py: + uncompyle6/semantics/fragments.py, uncompyle6/semantics/pysource.py: Add Python 3.5 yield from and ... * fragments.py: Handle pass stmt sometimes * scanners: regularize Python 2 scanners some * test/test_pyenvlib.py: add python 3.5.1 option 2016-06-22 rocky @@ -3002,7 +3247,7 @@ 2016-06-22 rocky - * uncompyle6/parsers/parse3.py, uncompyle6/semantics/pysource.py: + * uncompyle6/parsers/parse3.py, uncompyle6/semantics/pysource.py: More 3.2 LOAD_CONST removal More python3 custom grammar DRYing 2016-06-22 rocky @@ -3014,7 +3259,7 @@ * test/simple_source/expression/05_lambda.py, test/simple_source/expression/10_lambda.py, - uncompyle6/parsers/parse3.py, uncompyle6/semantics/pysource.py: + uncompyle6/parsers/parse3.py, uncompyle6/semantics/pysource.py: Python 3.2 MAKE_FUNCTION adjustment 2016-06-22 rocky @@ -3033,18 +3278,18 @@ 2016-06-20 rocky - * uncompyle6/parsers/parse3.py, uncompyle6/semantics/pysource.py: + * uncompyle6/parsers/parse3.py, uncompyle6/semantics/pysource.py: Bang on Python 3.2 decompiling. 2016-06-20 rocky * uncompyle6/parsers/parse3.py, uncompyle6/scanner.py, - uncompyle6/scanners/scanner2.py, uncompyle6/scanners/scanner3.py: + uncompyle6/scanners/scanner2.py, uncompyle6/scanners/scanner3.py: Python 3 needs Python2's RETURN_END_IF Make python2 and python3 scanner look more the same 2016-06-20 rocky - * uncompyle6/parsers/parse3.py, uncompyle6/scanners/scanner3.py: + * uncompyle6/parsers/parse3.py, uncompyle6/scanners/scanner3.py: previous 2.7 class decorator bug fixed in 3.x 2016-06-20 rocky @@ -3076,7 +3321,7 @@ * test/simple_source/def/11_mkfunc_closure.py, uncompyle6/parsers/parse3.py, uncompyle6/scanners/scanner3.py, - uncompyle6/semantics/fragments.py, uncompyle6/semantics/pysource.py: + uncompyle6/semantics/fragments.py, uncompyle6/semantics/pysource.py: 3.x make closure kw args handling bug 2016-06-20 rocky @@ -3113,7 +3358,7 @@ * test/simple_source/comprehension/05_set_comprehension.py, uncompyle6/parsers/parse2.py, uncompyle6/parsers/parse3.py, uncompyle6/scanners/scanner27.py, - uncompyle6/semantics/fragments.py, uncompyle6/semantics/pysource.py: + uncompyle6/semantics/fragments.py, uncompyle6/semantics/pysource.py: 2.7 and 3.x bug in dict comprehensions 2016-06-19 rocky @@ -3131,7 +3376,7 @@ * test/simple_source/looping/08_while_except_bug.py, uncompyle6/parser.py, uncompyle6/parsers/parse2.py, - uncompyle6/parsers/parse3.py, uncompyle6/semantics/pysource.py: + uncompyle6/parsers/parse3.py, uncompyle6/semantics/pysource.py: Python 3 except clause parsing bug 2016-06-19 rocky @@ -3193,18 +3438,18 @@ * pytest/test_deparse.py, test/simple_source/comprehension/05_set_comprehension.py, uncompyle6/parser.py, uncompyle6/parsers/parse3.py, - uncompyle6/semantics/fragments.py, uncompyle6/semantics/pysource.py: + uncompyle6/semantics/fragments.py, uncompyle6/semantics/pysource.py: Fix python 3 set comprehension and ... Add a few set/list comprehension offsets for Python 3 2016-06-06 rocky * uncompyle6/parser.py, uncompyle6/parsers/astnode.py, - uncompyle6/semantics/fragments.py, uncompyle6/semantics/pysource.py: + uncompyle6/semantics/fragments.py, uncompyle6/semantics/pysource.py: small changes 2016-06-06 rocky - * uncompyle6/parsers/parse3.py, uncompyle6/semantics/fragments.py: + * uncompyle6/parsers/parse3.py, uncompyle6/semantics/fragments.py: include offset for starting listcomp 2016-06-03 rocky @@ -3226,7 +3471,7 @@ uncompyle6/scanners/scanner2.py, uncompyle6/scanners/scanner23.py, uncompyle6/scanners/scanner26.py, uncompyle6/scanners/scanner3.py, uncompyle6/scanners/scanner32.py, uncompyle6/scanners/scanner34.py, - uncompyle6/scanners/scanner35.py, uncompyle6/semantics/pysource.py: + uncompyle6/scanners/scanner35.py, uncompyle6/semantics/pysource.py: Limited support for Python 2.3 2016-06-03 rocky @@ -3324,7 +3569,7 @@ 2016-05-29 rocky * uncompyle6/scanners/scanner2.py, - uncompyle6/scanners/scanner25.py, uncompyle6/scanners/scanner26.py: + uncompyle6/scanners/scanner25.py, uncompyle6/scanners/scanner26.py: Bang again on Python 2.5 and 2.6 scanners 2016-05-29 rocky @@ -3336,7 +3581,7 @@ 2016-05-29 rocky * uncompyle6/scanners/scanner2.py, - uncompyle6/scanners/scanner26.py, uncompyle6/scanners/scanner27.py: + uncompyle6/scanners/scanner26.py, uncompyle6/scanners/scanner27.py: Start to DRY 2.6 scanner Note: can't use xdis 2.6 opcode until another xdis release. 2016-05-29 rocky @@ -3353,7 +3598,7 @@ * uncompyle6/scanners/scanner3.py, uncompyle6/scanners/scanner32.py, uncompyle6/scanners/scanner33.py, - uncompyle6/scanners/scanner34.py, uncompyle6/scanners/scanner35.py: + uncompyle6/scanners/scanner34.py, uncompyle6/scanners/scanner35.py: DRY scanners more 2016-05-28 rocky @@ -3368,7 +3613,7 @@ * test/simple_source/comprehension/06_list_ifnot.py, test/simple_source/comprehension/10-list-ifnot.py, uncompyle6/scanners/dis3.py, uncompyle6/scanners/scanner3.py, - uncompyle6/scanners/scanner35.py, uncompyle6/semantics/pysource.py: + uncompyle6/scanners/scanner35.py, uncompyle6/semantics/pysource.py: Remove dis3. Fix in 3.x list if not comprehension 2016-05-28 rocky @@ -3379,7 +3624,7 @@ 2016-05-28 rocky * uncompyle6/opcodes/opcode_32.py, uncompyle6/opcodes/opcode_33.py, - uncompyle6/opcodes/opcode_34.py, uncompyle6/scanners/scanner3.py: + uncompyle6/opcodes/opcode_34.py, uncompyle6/scanners/scanner3.py: Remove dup 3.x opcodes 2016-05-28 rocky @@ -3389,7 +3634,7 @@ 2016-05-28 rocky * uncompyle6/scanner.py, uncompyle6/scanners/scanner32.py, - uncompyle6/scanners/scanner33.py, uncompyle6/scanners/scanner34.py: + uncompyle6/scanners/scanner33.py, uncompyle6/scanners/scanner34.py: xdis for Python 3 opcodes 2016-05-28 rocky @@ -3491,7 +3736,7 @@ 2016-05-18 rocky * pytest/test_marsh.py, - test/simple_source/expression/06_frozenset.py, uncompyle6/marsh.py: + test/simple_source/expression/06_frozenset.py, uncompyle6/marsh.py: Handle marshal frozenset 2016-05-18 rocky @@ -3531,14 +3776,14 @@ 2016-05-17 rocky * pytest/test_marsh.py, - test/simple_source/expression/02_complex.py, uncompyle6/marsh.py: + test/simple_source/expression/02_complex.py, uncompyle6/marsh.py: Fix marshal bug in handling complex numbers 2016-05-17 rocky * Makefile, test/simple_source/def/09_class_closure.py, uncompyle6/parser.py, uncompyle6/parsers/parse3.py, - uncompyle6/semantics/fragments.py, uncompyle6/semantics/pysource.py: + uncompyle6/semantics/fragments.py, uncompyle6/semantics/pysource.py: Fix Python 3.x bugs * class definitions made via closures * Add "make check-short" to top-level * parse3.py: Python 3.3 uses STORE_LOGALS 2016-05-16 rocky @@ -3608,7 +3853,7 @@ * test/simple_source/expression/05_lambda.py, test/test_pyenvlib.py, uncompyle6/parsers/parse3.py, - uncompyle6/scanners/scanner3.py, uncompyle6/semantics/pysource.py: + uncompyle6/scanners/scanner3.py, uncompyle6/semantics/pysource.py: Fix bug in Python 3 lambda expression handling Some other small cleanup changes 2016-05-15 rocky @@ -3616,7 +3861,7 @@ * uncompyle6/bin/pydisassemble.py, uncompyle6/disas.py, uncompyle6/parser.py, uncompyle6/parsers/parse3.py, uncompyle6/scanners/scanner3.py, uncompyle6/scanners/scanner34.py, - uncompyle6/scanners/scanner35.py, uncompyle6/scanners/tok.py: + uncompyle6/scanners/scanner35.py, uncompyle6/scanners/tok.py: pydisassemble disassemble without grammar mangling Some other small cleanups as well 2016-05-15 rocky @@ -3656,7 +3901,7 @@ * uncompyle6/parsers/parse3.py, uncompyle6/scanners/scanner3.py, uncompyle6/scanners/scanner34.py, uncompyle6/scanners/scanner35.py, - uncompyle6/semantics/fragments.py, uncompyle6/semantics/pysource.py: + uncompyle6/semantics/fragments.py, uncompyle6/semantics/pysource.py: DRY scanner34 and scanner35 handle 3.0..3.4 build maps as key/value pairs 2016-05-15 rocky @@ -3728,7 +3973,7 @@ 2016-05-12 rocky * uncompyle6/scanners/scanner26.py, - uncompyle6/scanners/scanner27.py, uncompyle6/scanners/scanner35.py: + uncompyle6/scanners/scanner27.py, uncompyle6/scanners/scanner35.py: More small changes 2016-05-12 rocky @@ -3745,7 +3990,7 @@ * __pkginfo__.py, uncompyle6/parsers/parse2.py, uncompyle6/parsers/parse3.py, uncompyle6/scanners/scanner3.py, - uncompyle6/semantics/fragments.py, uncompyle6/semantics/pysource.py: + uncompyle6/semantics/fragments.py, uncompyle6/semantics/pysource.py: Misc fixups/cleanups * parse3.py Had botched if-for-else test by grammar addition * semantics/*.py: Show errorstack in failed parse when -g (requires sparck 1.2.0) * some optimization in scanner3 @@ -3759,7 +4004,7 @@ uncompyle6/parsers/parse3.py, uncompyle6/scanners/dis35.py, uncompyle6/scanners/scanner3.py, uncompyle6/scanners/scanner34.py, uncompyle6/scanners/scanner35.py, - uncompyle6/semantics/fragments.py, uncompyle6/semantics/pysource.py: + uncompyle6/semantics/fragments.py, uncompyle6/semantics/pysource.py: Redo make_function for *, arg main(*, file='foo') and things like that now work 2016-05-11 rocky @@ -3791,7 +4036,7 @@ 2016-05-09 rocky * test/simple_source/stmts/09_whiletrue_bug.py, - uncompyle6/parsers/parse3.py, uncompyle6/semantics/pysource.py: + uncompyle6/parsers/parse3.py, uncompyle6/semantics/pysource.py: Python 3 "while True" bug 2016-05-09 rocky @@ -3885,7 +4130,7 @@ * HISTORY.md, test/simple_source/branching/10_if_pass.py, uncompyle6/scanners/scanner26.py, uncompyle6/scanners/scanner27.py, - uncompyle6/scanners/scanner3.py, uncompyle6/scanners/scanner35.py: + uncompyle6/scanners/scanner3.py, uncompyle6/scanners/scanner35.py: Fix 3.5 if..pass bug Update HISTORY.MD to include Dan Pascu. Some minor doc corrections 2016-05-08 rocky @@ -3902,7 +4147,7 @@ * test/simple_source/expression/05_yield_from.py, uncompyle6/parsers/parse3.py, uncompyle6/scanners/scanner35.py, - uncompyle6/semantics/fragments.py, uncompyle6/semantics/pysource.py: + uncompyle6/semantics/fragments.py, uncompyle6/semantics/pysource.py: Handle Python 3 yield from Start dealing with MAKE_FUNCTION flags - not done yet. 2016-05-06 rocky @@ -3967,19 +4212,19 @@ 2016-05-05 rocky * test/simple_source/def/05_abc_class.py, - test/simple_source/def/06_classbug.py, uncompyle6/parsers/parse3.py: + test/simple_source/def/06_classbug.py, uncompyle6/parsers/parse3.py: Python 3.5 abc.py bug distilled 2016-05-05 rocky - * uncompyle6/scanners/dis35.py, uncompyle6/scanners/scanner35.py: + * uncompyle6/scanners/dis35.py, uncompyle6/scanners/scanner35.py: Add cross-Python-protable 3.5 dis module 2016-05-04 rocky * test/simple_source/stmts/05_with.py, uncompyle6/opcodes/opcode_35.py, uncompyle6/parser.py, - uncompyle6/parsers/parse3.py, uncompyle6/scanners/scanner35.py: + uncompyle6/parsers/parse3.py, uncompyle6/scanners/scanner35.py: Handle 3.5 with [as] scanner35.py: Fix a small variable-name typo 2016-05-03 rocky @@ -3989,7 +4234,7 @@ 2016-05-03 rocky * uncompyle6/scanners/scanner3.py, - uncompyle6/scanners/scanner34.py, uncompyle6/scanners/scanner35.py: + uncompyle6/scanners/scanner34.py, uncompyle6/scanners/scanner35.py: Don't repeat next_except_jump 2016-05-03 rocky @@ -4107,7 +4352,7 @@ * requirements.txt, uncompyle6/parser.py, uncompyle6/parsers/parse2.py, uncompyle6/parsers/parse3.py, - uncompyle6/semantics/fragments.py, uncompyle6/semantics/pysource.py: + uncompyle6/semantics/fragments.py, uncompyle6/semantics/pysource.py: spark -> spark_parser 2016-04-28 rocky @@ -4255,7 +4500,7 @@ 2016-01-02 rocky * uncompyle6/scanner.py, uncompyle6/scanners/scanner25.py, - uncompyle6/scanners/scanner26.py, uncompyle6/scanners/scanner27.py: + uncompyle6/scanners/scanner26.py, uncompyle6/scanners/scanner27.py: Make ScannerXX() initialization the same on Python 2.x and 3.x 2016-01-02 rocky @@ -4349,7 +4594,7 @@ 2015-12-31 rocky * test/simple_source/def/05_class.py, uncompyle6/parsers/parse3.py, - uncompyle6/semantics/fragments.py, uncompyle6/semantics/pysource.py: + uncompyle6/semantics/fragments.py, uncompyle6/semantics/pysource.py: Handle Python 3.3 > dotted class names 2015-12-30 rocky @@ -4372,7 +4617,7 @@ 2015-12-30 rocky - * uncompyle6/parsers/parse3.py, uncompyle6/semantics/pysource.py: + * uncompyle6/parsers/parse3.py, uncompyle6/semantics/pysource.py: Remove accidental schmutz. Try using pattr on 3.4 to get fn names 2015-12-30 rocky @@ -4419,7 +4664,7 @@ * test/simple_source/exception/25_try_except.py, test/test_pythonlib.py, uncompyle6/parsers/parse3.py, uncompyle6/scanners/scanner27.py, uncompyle6/scanners/scanner3.py, - uncompyle6/scanners/scanner34.py, uncompyle6/semantics/pysource.py: + uncompyle6/scanners/scanner34.py, uncompyle6/semantics/pysource.py: Towards Python3 getting try/except working more often. 2015-12-29 rocky @@ -4452,7 +4697,7 @@ * README.rst, test/Makefile, uncompyle6/opcodes/opcode_32.py, uncompyle6/opcodes/opcode_33.py, uncompyle6/opcodes/opcode_34.py, - uncompyle6/scanners/scanner3.py, uncompyle6/scanners/scanner32.py: + uncompyle6/scanners/scanner3.py, uncompyle6/scanners/scanner32.py: scanner3: Python 2.6 compatibility: change set initializations. Get rid of * import opcode_*: only a little of the much-needed larger cleanup Makefile: remove 3.x bytecode checking from Python 2.x for @@ -4471,7 +4716,7 @@ * uncompyle6/disas.py, uncompyle6/load.py, uncompyle6/main.py, uncompyle6/marsh.py, uncompyle6/scanners/scanner3.py, - uncompyle6/semantics/fragments.py, uncompyle6/semantics/pysource.py: + uncompyle6/semantics/fragments.py, uncompyle6/semantics/pysource.py: Add Python3 marshal codes and start to handle cross-version Python code object types, introducing scan.Code3 @@ -4521,7 +4766,7 @@ uncompyle6/scanners/scanner26.py, uncompyle6/scanners/scanner27.py, uncompyle6/scanners/scanner3.py, uncompyle6/scanners/scanner32.py, uncompyle6/scanners/scanner33.py, uncompyle6/scanners/scanner34.py, - uncompyle6/semantics/fragments.py, uncompyle6/semantics/pysource.py: + uncompyle6/semantics/fragments.py, uncompyle6/semantics/pysource.py: DRY Python3 scanner code. Some cross version handling fixed. Some Python 3.2 and 3.3 deparse fixes. @@ -4537,7 +4782,7 @@ uncompyle6/scanners/scanner26.py, uncompyle6/scanners/scanner27.py, uncompyle6/scanners/scanner3.py, uncompyle6/scanners/scanner32.py, uncompyle6/scanners/scanner33.py, uncompyle6/scanners/scanner34.py, - uncompyle6/semantics/fragments.py, uncompyle6/semantics/pysource.py: + uncompyle6/semantics/fragments.py, uncompyle6/semantics/pysource.py: DRY Python3 scanner code. Some cross version handling fixed. Some Python 3.2 and 3.3 deparse fixes. @@ -4601,7 +4846,7 @@ test/simple_source/stmts/15_assert.py, test/simple_source/stmts/15_for_if.py, uncompyle6/parsers/parse2.py, uncompyle6/parsers/parse3.py, - uncompyle6/scanners/scanner32.py, uncompyle6/scanners/scanner34.py: + uncompyle6/scanners/scanner32.py, uncompyle6/scanners/scanner34.py: Fix up looping by reinstating JUMP_ABSOLUTE -> JUMP_BACK or CONTINUE get jump offsets into jump attributes. Fix up 3.2 scanner paritally and use that in 3.4 for in cross version disassembly. @@ -4685,7 +4930,7 @@ * test/simple_source/simple_stmts/00_import.py, test/simple_source/simple_stmts/00_pass.py, - uncompyle6/parsers/parse3.py, uncompyle6/semantics/pysource.py: + uncompyle6/parsers/parse3.py, uncompyle6/semantics/pysource.py: Start Python3 class(superclass) handling 2015-12-23 rocky @@ -4719,7 +4964,7 @@ uncompyle6/opcodes/opcode_27.py, uncompyle6/opcodes/opcode_34.py, uncompyle6/parsers/astnode.py, uncompyle6/parsers/parse2.py, uncompyle6/parsers/parse3.py, uncompyle6/parsers/spark.py, - uncompyle6/semantics/fragments.py, uncompyle6/semantics/pysource.py: + uncompyle6/semantics/fragments.py, uncompyle6/semantics/pysource.py: Allow comments in grammar rules. Start working on Python3 class (not finished). More test organization. @@ -4803,7 +5048,7 @@ test/simple_source/misc/assign.py, test/simple_source/misc/assign_none_str.py, test/simple_source/simple_stmts/00_assign.py, - uncompyle6/parsers/parse3.py, uncompyle6/semantics/pysource.py: + uncompyle6/parsers/parse3.py, uncompyle6/semantics/pysource.py: Start Python3 execption handling 2015-12-21 rocky @@ -4949,7 +5194,7 @@ * test/Makefile, test/simple-source/misc/assign_none.py, test/simple-source/misc/assign_none_str.py, uncompyle6/marsh.py, - uncompyle6/scanners/scanner32.py, uncompyle6/scanners/scanner34.py: + uncompyle6/scanners/scanner32.py, uncompyle6/scanners/scanner34.py: Python 3 decompilation from Python2 2015-12-20 rocky @@ -4967,7 +5212,7 @@ 2015-12-20 rocky * Makefile, README.rst, test/Makefile, test/dis-compare.py, - uncompyle6/deparser.py, uncompyle6/disas.py, uncompyle6/walker.py: + uncompyle6/deparser.py, uncompyle6/disas.py, uncompyle6/walker.py: Go over makefiles to make "make check" work. walker, deparser: use zip_longest @@ -5037,7 +5282,7 @@ test/simple-source/precedence/left.py, test/simple-source/precedence/right.py, test/simple-source/precedence/structure.py, - uncompyle6/parsers/parse3.py, uncompyle6/scanners/scanner34.py: + uncompyle6/parsers/parse3.py, uncompyle6/scanners/scanner34.py: Python 3 bytecode handles opcodes with varargs (better). Decompiling assert works. Add more of the simple tests and their compiled bytecode. @@ -5079,7 +5324,7 @@ 2015-12-18 rocky - * test/simple-source/comprehension/forelse.py, uncompyle6/disas.py: + * test/simple-source/comprehension/forelse.py, uncompyle6/disas.py: disas.py: Do better for finding/turning a .py file into a .pyc file across supported versions of Python. Add for else list comprehension test @@ -5178,7 +5423,7 @@ 2015-12-17 rocky - * uncompyle6/opcodes/opcode_34.py, uncompyle6/parsers/parse3.py: + * uncompyle6/opcodes/opcode_34.py, uncompyle6/parsers/parse3.py: Python 3.4 correct grammar for some looping constructs 2015-12-17 rocky @@ -5213,14 +5458,14 @@ 2015-12-16 rocky * uncompyle6/deparser.py, uncompyle6/disas.py, - uncompyle6/parser.py, uncompyle6/scanner.py, uncompyle6/walker.py: + uncompyle6/parser.py, uncompyle6/scanner.py, uncompyle6/walker.py: Add LICENSE. Add demo programs and DRY code a little 2015-12-16 rocky * uncompyle6/opcodes/opcode_34.py, uncompyle6/scanner.py, uncompyle6/scanners/scanner25.py, uncompyle6/scanners/scanner26.py, - uncompyle6/scanners/scanner27.py, uncompyle6/scanners/scanner34.py: + uncompyle6/scanners/scanner27.py, uncompyle6/scanners/scanner34.py: On Python3.4 decompiling Python 3.4 instructions, use its built-in disassembler routines. In contrast to what was here, they most likely work! @@ -5277,7 +5522,7 @@ uncompyle6/deparser.py, uncompyle6/disas.py, uncompyle6/magics.py, uncompyle6/marsh.py, uncompyle6/scanners/scanner25.py, uncompyle6/scanners/scanner26.py, uncompyle6/scanners/scanner27.py, - uncompyle6/scanners/scanner32.py, uncompyle6/scanners/scanner34.py: + uncompyle6/scanners/scanner32.py, uncompyle6/scanners/scanner34.py: Split out marhsal and disassemble code and spell disassemble correctly. Fix some lint issues @@ -5362,7 +5607,7 @@ 2015-12-14 rocky - * uncompyle6/dparser.py, uncompyle6/parser.py, uncompyle6/walker.py: + * uncompyle6/dparser.py, uncompyle6/parser.py, uncompyle6/walker.py: uncompyle6/dparser -> uncompyle6/parser 2015-12-14 rocky @@ -5615,7 +5860,7 @@ * MANIFEST, MANIFEST.in, PKG-INFO, README.rst, uncompyle6/opcodes/opcode_23.py, uncompyle6/opcodes/opcode_26.py, uncompyle6/opcodes/opcode_27.py, uncompyle6/scanner25.py, - uncompyle6/scanner26.py, uncompyle6/spark.py, uncompyle6/verify.py: + uncompyle6/scanner26.py, uncompyle6/spark.py, uncompyle6/verify.py: Correct MANIFEST->MANIFEST.in more lint 2015-12-13 R. Bernstein @@ -5632,7 +5877,7 @@ uncompyle6/__init__.py, uncompyle6/disas.py, uncompyle6/opcodes/opcode_25.py, uncompyle6/opcodes/opcode_26.py, uncompyle6/scanner25.py, uncompyle6/scanner26.py, - uncompyle6/scanner34.py, uncompyle6/spark.py, uncompyle6/verify.py: + uncompyle6/scanner34.py, uncompyle6/spark.py, uncompyle6/verify.py: Make uncompyle6 run on Python3.4 and Python 2.7 We don't need our own disassembler. Python's will do fine @@ -5733,13 +5978,13 @@ * tox.ini, uncompyle-code.py, uncompyle6/dparser.py, uncompyle6/scanner25.py, uncompyle6/scanner27.py, - uncompyle6/scanner34.py, uncompyle6/spark.py, uncompyle6/walker.py: + uncompyle6/scanner34.py, uncompyle6/spark.py, uncompyle6/walker.py: Minimal disassemble, ast compile and deparse work on Python 3. Some linting 2015-12-12 rocky - * uncompyle6/dparser.py, uncompyle6/parser.py, uncompyle6/walker.py: + * uncompyle6/dparser.py, uncompyle6/parser.py, uncompyle6/walker.py: parser -> dparser so as not to conflict with python3's parser. 2015-12-12 rocky @@ -5758,7 +6003,7 @@ 2015-12-11 rocky - * uncompyle-code.py, uncompyle6/__init__.py, uncompyle6/walker.py: + * uncompyle-code.py, uncompyle6/__init__.py, uncompyle6/walker.py: python3 compatibiity and remove some flake8 warnings. 2015-12-11 rocky @@ -5836,7 +6081,7 @@ 2013-07-16 root * uncompyle2/__init__.py, uncompyle2/disas.py, - uncompyle2/magics.py, uncompyle2/scanner27.py, uncompyle2/walker.py: + uncompyle2/magics.py, uncompyle2/scanner27.py, uncompyle2/walker.py: marshal disassembly improvement 2013-06-20 Mysterie @@ -5921,7 +6166,7 @@ uncompyle2/opcode/opcode_27.py, uncompyle2/parser.py, uncompyle2/scanner.py, uncompyle2/scanner25.py, uncompyle2/scanner26.py, uncompyle2/scanner27.py, - uncompyle2/spark.py, uncompyle2/verify.py, uncompyle2/walker.py: + uncompyle2/spark.py, uncompyle2/verify.py, uncompyle2/walker.py: Cleaning code & patch 2012-09-22 Mysterie @@ -6026,3 +6271,4 @@ 2012-06-05 Mysterie * first commit + diff --git a/NEWS b/NEWS index 9c7ade5f..d32a93ea 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,23 @@ +uncompyle6 2.10.0 2016-05-30 Elaine Gordon + +- Add fuzzy offset deparse lookup +- 3.6 bugfixes + - fix EXTENDED_ARGS handling (and in 2.6 and others) + - semantic routine make_function fragments.py + - MAKE_FUNCTION handling + - CALL_FUNCTION_EX handling + - async property on defs + - support for CALL_FUNCTION_KW (moagstar) +- 3.5+ UNMAP_PACK and BUILD_UNMAP_PACK handling +- 3.5 FUNCTION_VAR bug +- 3.x pass statement insdie while True +- Improve 3.2 decompilation +- Fixed -o argument processing (Gregrory) +- Reduce scope of LOAD_ASSERT as expr to 3.4+ +- "await" statement fixes +- 2.3, 2.4 "if 1 .." fixes +- 3.x annotation fixes + uncompyle6 2.9.11 2016-04-06 - Better support for Python 3.5+ BUILD_MAP_UNPACK diff --git a/uncompyle6/version.py b/uncompyle6/version.py index 566e6123..37bd89e2 100644 --- a/uncompyle6/version.py +++ b/uncompyle6/version.py @@ -1,3 +1,3 @@ # This file is suitable for sourcing inside bash as # well as importing into Python -VERSION='2.9.11' +VERSION='2.10.0'