[med-svn] [python-dendropy] 02/08: Imported Upstream version 4.1.0+dfsg

Sascha Steinbiss satta at debian.org
Sun Jul 31 20:15:28 UTC 2016


This is an automated email from the git hooks/post-receive script.

satta pushed a commit to branch master
in repository python-dendropy.

commit 5b9f5b056a98eab0e0f03f06d6c3696559578063
Author: Sascha Steinbiss <satta at debian.org>
Date:   Sun Jul 31 18:35:32 2016 +0000

    Imported Upstream version 4.1.0+dfsg
---
 CHANGES.rst                                        |   33 +
 DendroPy.egg-info/PKG-INFO                         |    6 +-
 DendroPy.egg-info/SOURCES.txt                      |   38 +
 PKG-INFO                                           |    6 +-
 README.rst                                         |    2 +-
 applications/sumtrees/sumtrees.py                  |  246 +++-
 dendropy/__init__.py                               |   24 +-
 dendropy/calculate/combinatorics.py                |   71 +
 dendropy/calculate/phylogeneticdistance.py         | 1526 ++++++++++++++++++++
 dendropy/calculate/popgenstat.py                   |   20 +-
 dendropy/calculate/probability.py                  |   37 +-
 dendropy/calculate/statistics.py                   |   10 +
 dendropy/calculate/treecompare.py                  |  324 ++++-
 dendropy/calculate/treemeasure.py                  |  126 +-
 dendropy/calculate/treesum.py                      |    6 +-
 dendropy/dataio/fastawriter.py                     |    6 +-
 dendropy/dataio/ioservice.py                       |   25 +-
 dendropy/dataio/newickreader.py                    |   79 +-
 dendropy/dataio/newickwriter.py                    |  103 +-
 dendropy/dataio/newickyielder.py                   |    5 +-
 dendropy/dataio/nexmlreader.py                     |   12 +-
 dendropy/dataio/nexmlwriter.py                     |   24 +-
 dendropy/dataio/nexmlyielder.py                    |    5 +-
 dendropy/dataio/nexusprocessing.py                 |   11 +-
 dendropy/dataio/nexusreader.py                     |   86 +-
 dendropy/dataio/nexuswriter.py                     |  127 +-
 dendropy/dataio/nexusyielder.py                    |    1 +
 dendropy/dataio/phylipreader.py                    |   30 +-
 dendropy/dataio/phylipwriter.py                    |   37 +-
 dendropy/dataio/xmlprocessing.py                   |    5 +-
 dendropy/datamodel/basemodel.py                    |   27 +-
 dendropy/datamodel/charmatrixmodel.py              |  256 ++--
 dendropy/datamodel/charstatemodel.py               |   38 +-
 dendropy/datamodel/datasetmodel.py                 |   25 +-
 dendropy/datamodel/taxonmodel.py                   |  159 +-
 dendropy/datamodel/treecollectionmodel.py          |  277 ++--
 dendropy/datamodel/treemodel.py                    | 1341 ++++++++++++-----
 dendropy/interop/entrez.py                         |    5 +-
 dendropy/interop/paup.py                           |   31 +-
 dendropy/interop/rstats.py                         |   99 +-
 dendropy/interop/seqgen.py                         |    4 -
 dendropy/legacy/ncbi.py                            |    7 +-
 dendropy/legacy/treecalc.py                        |   10 +-
 dendropy/model/birthdeath.py                       |   17 +-
 dendropy/model/coalescent.py                       |   33 +-
 dendropy/model/discrete.py                         |    8 +-
 dendropy/model/parsimony.py                        |   14 +-
 dendropy/model/protractedspeciation.py             | 1015 ++++++++++---
 dendropy/model/reconcile.py                        |   12 +-
 dendropy/model/treeshape.py                        |    5 +-
 dendropy/simulate/popgensim.py                     |    4 -
 .../benchmark_newick_light_tree_parser.py          |    5 +-
 .../test/benchmark/benchmark_newick_tree_parser.py |    4 -
 dendropy/test/data/chars/community.data.tsv        |    6 +
 dendropy/test/data/other/community.data.tsv        |    6 +
 ...mmunity.data.weighted.unnormalized.ses.mntd.csv |    6 +
 ...ommunity.data.weighted.unnormalized.ses.mpd.csv |    6 +
 dendropy/test/data/other/hiv1.distances.csv        |  194 +++
 .../test/data/other/hiv1.node-to-node-dists.csv    |  386 +++++
 .../other/hiv1.unweighted.node-to-node-dists.csv   |  386 +++++
 .../data/other/laurasiatherian.distances.ml.csv    |   48 +
 .../other/pythonidae.mle.node-to-node-dists.csv    |   65 +
 ...ythonidae.mle.unweighted.node-to-node-dists.csv |   65 +
 .../data/other/pythonidae.mle.unweighted.pdm.csv   |   34 +
 .../data/other/pythonidae.mle.weighted.pdm.csv     |   34 +
 .../test/data/other/saitou_and_nei_1987_table1.csv |    9 +
 dendropy/test/data/other/wpnjex.csv                |    6 +
 dendropy/test/data/other/wpupgmaex.csv             |    6 +
 dendropy/test/data/trees/community.tree.newick     |    1 +
 dendropy/test/data/trees/hiv1.newick               |    2 +-
 dendropy/test/data/trees/hiv1.nexus                |  197 +--
 .../trees/pythonidae.mle.numbered-nodes.newick     |    2 +
 dendropy/test/support/compare_and_validate.py      |    5 +-
 dendropy/test/support/dendropytest.py              |    6 +-
 dendropy/test/support/pathmap.py                   |   11 +
 dendropy/test/test_dataio_tokenizer.py             |    5 +-
 dendropy/test/test_datamodel_bipartitions.py       |    4 -
 dendropy/test/test_datamodel_charmatrix.py         |   20 +-
 dendropy/test/test_datamodel_split_bitmasks.py     |    6 +-
 dendropy/test/test_fitch.py                        |    4 -
 dendropy/test/test_phylogenetic_distance_matrix.py |  854 +++++++++++
 dendropy/test/test_protractedspeciation.py         |  317 ++++
 .../test/test_tree_calculations_and_metrics.py     |  143 +-
 .../test/test_tree_operations_and_manipulations.py |  154 +-
 dendropy/test/test_tree_shape_kernel.py            |  291 ++++
 dendropy/utility/bitprocessing.py                  |    4 +-
 dendropy/utility/cli.py                            |    2 +-
 dendropy/utility/container.py                      |  269 +++-
 dendropy/utility/error.py                          |   36 +-
 dendropy/utility/textprocessing.py                 |   19 +
 dendropy/utility/vcsinfo.py                        |    7 +-
 91 files changed, 8147 insertions(+), 1896 deletions(-)

diff --git a/CHANGES.rst b/CHANGES.rst
index 3b25227..f886225 100644
--- a/CHANGES.rst
+++ b/CHANGES.rst
@@ -1,3 +1,36 @@
+Release 4.1.0 (Pending)
+-----------------------
+
+New or Updated Features
+^^^^^^^^^^^^^^^^^^^^^^^
+
+    -   [SumTrees]: tip-dating/non-contemporaneous tip age assignment using the "``--tip-ages``" argument (http://dendropy.org/programs/sumtrees.html#setting-the-node-ages-of-the-summary-trees).
+    -   [SumTrees]: "``--min-clade-freq``" applies to all summary targets (i.e., not just consensus trees, but user-specified as well as, e.g. MCCT trees).
+    -   Fast, flexible, and powerful tree and subtree cloning, extracting only nodes/taxa of interest (http://dendropy.org/primer/treemanips.html#extracting-trees-and-subtrees-from-an-existing-tree).
+    -   Neighbor-joining and UPGMA trees (http://dendropy.org/primer/phylogenetic_distances.html#generating-distance-trees-from-a-phylogeneticdistancematrix-object).
+    -   The new (actually, warmed-over) PhylogeneticDistanceMatrix to manage various "within-tree" distances, such patristic distances, or the ecological statistics described below (http://dendropy.org/primer/phylogenetic_distances.html#creating-a-phylogeneticdistancematrix-object).
+    -   Added phylogenetic community ecology statistic calculations: Mean Pairwise Distance (MPD), Mean Nearest Taxon Distance (MNTD), Standardized Effect Size MPD and MNTD, equivalent to -1 * NRI and -1 * NTI (http://dendropy.org/primer/phylogenetic_distances.html#phylogenetic-community-statistics).
+    -   Added DataTable class to manage community ecology (as well as more general classes of) data.
+    -   Implementation of the Protracted Speciation model: a Birth-Death process with explicit modeling of speciation-as-a-process rather than speciation-as-an-event by incorporating the lag between speciation initiation and speciation completion.
+    -   NEWICK terminating semicolon requirement relaxation.
+    -   Some more refined node filtering/dropping.
+    -   Return list of nodes dropped when filtering out leaves.
+    -   Force max/min ages when calculating node ages; and beginning of support for setting node ages by function.
+    -   Implementation of Tree.find_nodes() to return collection of nodes that match instaed of just the first one.
+
+Bug Fixes
+^^^^^^^^^
+
+    -   Handle sequence comparison where there are no non-ignored sites in common.
+    -   Update string type checking to handle unicode etc. under Python 2.
+    -   Exclusion of trees from data set reads actually works.
+    -   Actually implement symbol to state (alphabet) identity coercion in derived classes.
+    -   Pop out inner classes to enable pickling.
+    -   Several bugs, mostly caused by leftovers of DendroPy3 code.
+    -   Made group_ranges work properly with unordered iterables.
+    -   Make PHYLIP writing work correctly with missing taxa.
+
+
 Release 4.0.3
 -------------
 
diff --git a/DendroPy.egg-info/PKG-INFO b/DendroPy.egg-info/PKG-INFO
index 4a4f556..4c951b6 100644
--- a/DendroPy.egg-info/PKG-INFO
+++ b/DendroPy.egg-info/PKG-INFO
@@ -1,6 +1,6 @@
 Metadata-Version: 1.1
 Name: DendroPy
-Version: 4.0.3
+Version: 4.1.0
 Summary: A Python library for phylogenetics and phylogenetic computing: reading, writing, simulation, processing and manipulation of phylogenetic trees (phylogenies) and characters.
 Home-page: http://packages.python.org/DendroPy/
 Author: Jeet Sukumaran and Mark T. Holder
@@ -70,7 +70,7 @@ Description: .. image:: https://raw.githubusercontent.com/jeetsukumaran/DendroPy
         
             or::
         
-                DENDROPY_PAUP_EXECUTABLE_PATH=/usr/local/bin/paup python -m unittest
+                DENDROPY_PAUP_EXECUTABLE_PATH=/usr/local/bin/paup python -m dendropy.test
         
             If this variable is not set or set to "NONE", then any tests that rely on
             PAUP* will NOT be run.
@@ -115,7 +115,7 @@ Description: .. image:: https://raw.githubusercontent.com/jeetsukumaran/DendroPy
         Current Release
         ===============
         
-        The current release of DendroPy is version 4.0.3 (development-master-55d1251, 2015-07-29 01:05:56).
+        The current release of DendroPy is version 4.1.0 (development-master-715b4cc, 2016-03-13 15:21:37).
         
         
 Keywords: phylogenetics phylogeny phylogenies phylogeography evolution evolutionary biology systematics coalescent population genetics phyloinformatics bioinformatics
diff --git a/DendroPy.egg-info/SOURCES.txt b/DendroPy.egg-info/SOURCES.txt
index 6d8b71e..681ac04 100644
--- a/DendroPy.egg-info/SOURCES.txt
+++ b/DendroPy.egg-info/SOURCES.txt
@@ -15,7 +15,9 @@ applications/sumtrees/sumtrees.py
 dendropy/__init__.py
 dendropy/__main__.py
 dendropy/calculate/__init__.py
+dendropy/calculate/combinatorics.py
 dendropy/calculate/mathfn.py
+dendropy/calculate/phylogeneticdistance.py
 dendropy/calculate/popgenstat.py
 dendropy/calculate/probability.py
 dendropy/calculate/statistics.py
@@ -145,12 +147,15 @@ dendropy/test/test_datamodel_treearray.py
 dendropy/test/test_fitch.py
 dendropy/test/test_parsimony_scoring.py
 dendropy/test/test_paup.py
+dendropy/test/test_phylogenetic_distance_matrix.py
 dendropy/test/test_popgenstat.py
+dendropy/test/test_protractedspeciation.py
 dendropy/test/test_statistics.py
 dendropy/test/test_tree_calculations_and_metrics.py
 dendropy/test/test_tree_from_splits.py
 dendropy/test/test_tree_operations_and_manipulations.py
 dendropy/test/test_tree_reconciliation_and_discordance.py
+dendropy/test/test_tree_shape_kernel.py
 dendropy/test/test_tree_split_compatibility.py
 dendropy/test/test_tree_summarization_and_consensus.py
 dendropy/test/benchmark/__init__.py
@@ -174,6 +179,7 @@ dendropy/test/data/chars/caenophidia_mos.chars.nexus
 dendropy/test/data/chars/caenophidia_mos.chars.txt
 dendropy/test/data/chars/cetaceans.nex
 dendropy/test/data/chars/codons.nexml
+dendropy/test/data/chars/community.data.tsv
 dendropy/test/data/chars/crotaphytus_bicinctores.cytb.aligned.nexml
 dendropy/test/data/chars/crotaphytus_bicinctores.nd2.aligned.nexml
 dendropy/test/data/chars/interleaved-charsets-all.nex
@@ -251,6 +257,20 @@ dendropy/test/data/mixed/geospiza.nex
 dendropy/test/data/mixed/multitaxa_mesquite.nex
 dendropy/test/data/mixed/reference_single_taxonset_dataset.nex
 dendropy/test/data/mixed/standard-test-mixed.1.basic.nexus
+dendropy/test/data/other/community.data.tsv
+dendropy/test/data/other/community.data.weighted.unnormalized.ses.mntd.csv
+dendropy/test/data/other/community.data.weighted.unnormalized.ses.mpd.csv
+dendropy/test/data/other/hiv1.distances.csv
+dendropy/test/data/other/hiv1.node-to-node-dists.csv
+dendropy/test/data/other/hiv1.unweighted.node-to-node-dists.csv
+dendropy/test/data/other/laurasiatherian.distances.ml.csv
+dendropy/test/data/other/pythonidae.mle.node-to-node-dists.csv
+dendropy/test/data/other/pythonidae.mle.unweighted.node-to-node-dists.csv
+dendropy/test/data/other/pythonidae.mle.unweighted.pdm.csv
+dendropy/test/data/other/pythonidae.mle.weighted.pdm.csv
+dendropy/test/data/other/saitou_and_nei_1987_table1.csv
+dendropy/test/data/other/wpnjex.csv
+dendropy/test/data/other/wpupgmaex.csv
 dendropy/test/data/splits/cetaceans.mb.no-clock.mcmc.trees.is-rooted-False.use-tree-weights-False.burnin-0.splits.txt
 dendropy/test/data/splits/cetaceans.mb.no-clock.mcmc.trees.is-rooted-False.use-tree-weights-False.burnin-150.splits.txt
 dendropy/test/data/splits/cetaceans.mb.no-clock.mcmc.trees.is-rooted-False.use-tree-weights-None.burnin-0.splits.txt
@@ -512,6 +532,7 @@ dendropy/test/data/trees/cetaceans.raxml.bootstraps.weighted-01.trees
 dendropy/test/data/trees/cetaceans.raxml.bootstraps.weighted-02.trees
 dendropy/test/data/trees/cetaceans.raxml.bootstraps.weighted-03.trees
 dendropy/test/data/trees/cetaceans.taxa.nex
+dendropy/test/data/trees/community.tree.newick
 dendropy/test/data/trees/curated-with-translate-block-and-internal-taxa.nex
 dendropy/test/data/trees/curated-with-translate-block-and-no-taxa-block-and-untranslated-internal-taxa.nex
 dendropy/test/data/trees/curated-with-translate-block-and-no-taxa-block.nex
@@ -608,6 +629,7 @@ dendropy/test/data/trees/pythonidae.mlboots.newick.tre
 dendropy/test/data/trees/pythonidae.mlboots.nexus.tre
 dendropy/test/data/trees/pythonidae.mle.newick
 dendropy/test/data/trees/pythonidae.mle.nex
+dendropy/test/data/trees/pythonidae.mle.numbered-nodes.newick
 dendropy/test/data/trees/pythonidae.random.bd0301.midpoint-rooted.tre
 dendropy/test/data/trees/pythonidae.random.bd0301.randomly-rooted.tre
 dendropy/test/data/trees/pythonidae.random.bd0301.tre
@@ -711,6 +733,14 @@ doc/source/examples/paup_estimate_tree_ml.py
 doc/source/examples/paup_estimate_tree_nj.py
 doc/source/examples/pbhg.py
 doc/source/examples/pdm.py
+doc/source/examples/pdm_mpd0.py
+doc/source/examples/pdm_mpd1.py
+doc/source/examples/pdm_nj_tree.py
+doc/source/examples/pdm_ses1.py
+doc/source/examples/pdm_ses2.py
+doc/source/examples/pdm_ses3.py
+doc/source/examples/pdm_tns1.py
+doc/source/examples/pdm_upgma_tree.py
 doc/source/examples/pgstats1.py
 doc/source/examples/pic1.py
 doc/source/examples/pic2.py
@@ -745,6 +775,7 @@ doc/source/examples/pythonidae.mb.run4.t
 doc/source/examples/pythonidae.mcmc-con.nex
 doc/source/examples/pythonidae.mcmc.nex
 doc/source/examples/pythonidae.mle.nex
+doc/source/examples/pythonidae.mle.weighted.pdm.csv
 doc/source/examples/pythonidae.nex
 doc/source/examples/pythonidae.random.bd0301.tre
 doc/source/examples/pythonidae_combined.nex
@@ -781,10 +812,15 @@ doc/source/examples/taxon_labels2b.py
 doc/source/examples/taxon_labels3.py
 doc/source/examples/taxon_labels4.py
 doc/source/examples/to_outgroup_position.py
+doc/source/examples/tree_clone_and_prune_vs_extract.py
 doc/source/examples/tree_copy1.py
 doc/source/examples/tree_copy2.py
 doc/source/examples/tree_evolve_char1.py
 doc/source/examples/tree_evolve_char2.py
+doc/source/examples/tree_extract1.py
+doc/source/examples/tree_extract2.py
+doc/source/examples/tree_extract3.py
+doc/source/examples/tree_extract4.py
 doc/source/examples/tree_iter1.py
 doc/source/examples/tree_iter2.py
 doc/source/examples/tree_length_crit.py
@@ -807,6 +843,7 @@ doc/source/library/datasetmodel.rst
 doc/source/library/discrete.rst
 doc/source/library/index.rst
 doc/source/library/parsimony.rst
+doc/source/library/phylogeneticdistance.rst
 doc/source/library/popgensim.rst
 doc/source/library/popgenstat.rst
 doc/source/library/probability.rst
@@ -829,6 +866,7 @@ doc/source/primer/genbank.rst
 doc/source/primer/index.rst
 doc/source/primer/paup.rst
 doc/source/primer/phylogenetic_character_analyses.rst
+doc/source/primer/phylogenetic_distances.rst
 doc/source/primer/popgenstats.rst
 doc/source/primer/raxml.rst
 doc/source/primer/reading_and_writing.rst
diff --git a/PKG-INFO b/PKG-INFO
index 4a4f556..4c951b6 100644
--- a/PKG-INFO
+++ b/PKG-INFO
@@ -1,6 +1,6 @@
 Metadata-Version: 1.1
 Name: DendroPy
-Version: 4.0.3
+Version: 4.1.0
 Summary: A Python library for phylogenetics and phylogenetic computing: reading, writing, simulation, processing and manipulation of phylogenetic trees (phylogenies) and characters.
 Home-page: http://packages.python.org/DendroPy/
 Author: Jeet Sukumaran and Mark T. Holder
@@ -70,7 +70,7 @@ Description: .. image:: https://raw.githubusercontent.com/jeetsukumaran/DendroPy
         
             or::
         
-                DENDROPY_PAUP_EXECUTABLE_PATH=/usr/local/bin/paup python -m unittest
+                DENDROPY_PAUP_EXECUTABLE_PATH=/usr/local/bin/paup python -m dendropy.test
         
             If this variable is not set or set to "NONE", then any tests that rely on
             PAUP* will NOT be run.
@@ -115,7 +115,7 @@ Description: .. image:: https://raw.githubusercontent.com/jeetsukumaran/DendroPy
         Current Release
         ===============
         
-        The current release of DendroPy is version 4.0.3 (development-master-55d1251, 2015-07-29 01:05:56).
+        The current release of DendroPy is version 4.1.0 (development-master-715b4cc, 2016-03-13 15:21:37).
         
         
 Keywords: phylogenetics phylogeny phylogenies phylogeography evolution evolutionary biology systematics coalescent population genetics phyloinformatics bioinformatics
diff --git a/README.rst b/README.rst
index afc6c74..7193ce5 100644
--- a/README.rst
+++ b/README.rst
@@ -62,7 +62,7 @@ Testing
 
     or::
 
-        DENDROPY_PAUP_EXECUTABLE_PATH=/usr/local/bin/paup python -m unittest
+        DENDROPY_PAUP_EXECUTABLE_PATH=/usr/local/bin/paup python -m dendropy.test
 
     If this variable is not set or set to "NONE", then any tests that rely on
     PAUP* will NOT be run.
diff --git a/applications/sumtrees/sumtrees.py b/applications/sumtrees/sumtrees.py
index f82380d..2d8393d 100755
--- a/applications/sumtrees/sumtrees.py
+++ b/applications/sumtrees/sumtrees.py
@@ -34,9 +34,8 @@ import platform
 import socket
 import math
 import csv
+import json
 
-if not (sys.version_info.major >= 3 and sys.version_info.minor >= 4):
-    from dendropy.utility.filesys import pre_py34_open as open
 try:
     # Python 3
     import queue
@@ -46,6 +45,8 @@ except ImportError:
 import multiprocessing
 
 import dendropy
+if not (sys.version_info.major >= 3 and sys.version_info.minor >= 4):
+    from dendropy.utility.filesys import pre_py34_open as open
 from dendropy.utility import cli
 from dendropy.utility import constants
 from dendropy.utility import error
@@ -59,9 +60,7 @@ from dendropy.utility import textprocessing
 
 _program_name = "SumTrees"
 _program_subtitle = "Phylogenetic Tree Summarization"
-_program_date = "Jan 31 2015"
-# _program_version = "{} ({})".format(dendropy.__version__, _program_date)
-_program_version = "4.0.0 ({})".format(_program_date)
+_program_version = dendropy.__version__
 _program_author = "Jeet Sukumaran and Mark T. Holder"
 _program_contact = "jeetsukumaran at gmail.com"
 _program_copyright = """\
@@ -172,6 +171,7 @@ class TreeAnalysisWorker(multiprocessing.Process):
             ignore_node_ages,
             use_tree_weights,
             ultrametricity_precision,
+            taxon_label_age_map,
             log_frequency,
             messenger,
             messenger_lock,
@@ -192,6 +192,7 @@ class TreeAnalysisWorker(multiprocessing.Process):
         self.ignore_node_ages = ignore_node_ages
         self.use_tree_weights = use_tree_weights
         self.ultrametricity_precision = ultrametricity_precision
+        self.taxon_label_age_map = taxon_label_age_map
         self.log_frequency = log_frequency
         self.messenger = messenger
         self.messenger_lock = messenger_lock
@@ -203,6 +204,7 @@ class TreeAnalysisWorker(multiprocessing.Process):
                 ignore_node_ages=self.ignore_node_ages,
                 use_tree_weights=self.use_tree_weights,
                 ultrametricity_precision=self.ultrametricity_precision,
+                taxon_label_age_map=self.taxon_label_age_map,
                 )
         self.tree_array.worker_name = self.name
         self.num_tasks_received = 0
@@ -289,6 +291,7 @@ class TreeProcessor(object):
             ignore_node_ages,
             use_tree_weights,
             ultrametricity_precision,
+            taxon_label_age_map,
             num_processes,
             log_frequency,
             messenger,
@@ -300,6 +303,7 @@ class TreeProcessor(object):
         self.ignore_node_ages = ignore_node_ages
         self.use_tree_weights = use_tree_weights
         self.ultrametricity_precision = ultrametricity_precision
+        self.taxon_label_age_map = taxon_label_age_map
         self.num_processes = num_processes
         self.log_frequency = log_frequency
         self.messenger = messenger
@@ -359,6 +363,7 @@ class TreeProcessor(object):
                 ignore_node_ages=self.ignore_node_ages,
                 use_tree_weights=self.use_tree_weights,
                 ultrametricity_precision=self.ultrametricity_precision,
+                taxon_label_age_map=self.taxon_label_age_map,
                 )
         _read_into_tree_array(
                 tree_array=tree_array,
@@ -430,6 +435,7 @@ class TreeProcessor(object):
                     ignore_node_ages=self.ignore_node_ages,
                     use_tree_weights=self.use_tree_weights,
                     ultrametricity_precision=self.ultrametricity_precision,
+                    taxon_label_age_map=self.taxon_label_age_map,
                     messenger=self.messenger,
                     messenger_lock=messenger_lock,
                     log_frequency=self.log_frequency,
@@ -525,7 +531,7 @@ def _write_trees(trees,
 ##############################################################################
 ## Front-End
 
-def citation(args):
+def print_citation(args):
     show_splash(dest=sys.stdout)
     sys.exit(0)
 
@@ -555,7 +561,7 @@ labels and branch lengths the mean across all trees, dropping the first 200
 trees in each file as a burn-in, and saving the result to "``result.tre``"::
 
     $ sumtrees.py \\
-            --summary-tree consensus \\
+            --summary-target consensus \\
             --min-clade-freq=0.95 \\
             --edges mean-length \\
             --burnin=200 \\
@@ -568,7 +574,7 @@ product of posterior probabilities, you can specify 'mcct' for the
 '--summary-tree' option:
 
     $ sumtrees.py \\
-            --summary-tree mcct \\
+            --summary-target mcct \\
             --min-clade-freq=0.95 \\
             --edges mean-length \\
             --burnin=200 \\
@@ -580,7 +586,7 @@ If the input trees are ultrametric and you want to set the node ages to the
 median node age, set the '--edges' argument to 'median-age':
 
     $ sumtrees.py \\
-            --summary-tree mcct \\
+            --summary-target mcct \\
             --edges median-age \\
             --burnin=200 \\
             --output=result.tre \\
@@ -655,10 +661,6 @@ def main():
             action="store_false",
             default=None,
             help="Treat source trees as unrooted.")
-    source_options.add_argument("-v", "--ultrametricity-precision", "--edge-weight-epsilon", "--branch-length-epsilon",
-            type=float,
-            default=constants.DEFAULT_ULTRAMETRICITY_PRECISION,
-            help="Precision to use when validating ultrametricity (default: %(default)s; specify '0' to disable validation).")
     source_options.add_argument("--weighted-trees",
             action="store_true",
             default=False,
@@ -674,7 +676,12 @@ def main():
                 "Do not convert unprotected (unquoted) underscores to spaces"
                 " when reading NEXUS/NEWICK format trees."
                 ))
-    source_options.add_argument("--taxon-name-filepath",
+    source_options.add_argument("-v", "--ultrametricity-precision", "--edge-weight-epsilon", "--branch-length-epsilon",
+            type=float,
+            default=constants.DEFAULT_ULTRAMETRICITY_PRECISION,
+            help="Precision to use when validating ultrametricity (default: %(default)s; specify '0' to disable validation).")
+    source_options.add_argument(
+            "--taxon-name-filepath", "--taxon-names-filepath",
             metavar="FILEPATH",
             default=None,
             help=(
@@ -694,6 +701,57 @@ def main():
                 " providing the taxon names via this option can avoid"
                 " these issues."
                 ))
+    source_options.add_argument("--tip-ages", "--tip-ages-filepath",
+            dest="tip_ages_filepath",
+            metavar="FILEPATH",
+            default=None,
+            help=(
+                "Path to file providing ages (i.e., time from present) of"
+                " tips. For format of this file, see '--tip-age-format'."
+                " If not specified, or for any taxon omitted from the data,"
+                " an age of 0.0 will be assumed."
+                ))
+    source_options.add_argument("--tip-ages-format",
+            dest="tip_ages_format",
+            default="tsv",
+            choices=["tsv", "csv", "json",],
+            metavar="FORMAT",
+            help=cli.CustomFormatter.format_definition_list_help(
+                    preamble=
+                        (
+                        "Format of the tip date data (default: '%(default)s'):"
+                        ),
+                    definitions=
+                        (
+                            ("'tsv'",
+                                "A tab-delimited file. This should consist of two columns"
+                                " separated by tabs. The first column lists the taxon labels"
+                                " (matching the taxon label of the input trees EXACTLY)"
+                                " and the second column lists the ages of the"
+                                " corresponding tips."
+                            ),
+                            ("'csv'",
+                                "A comma-delimited file. This should consist of two columns"
+                                " separated by commas. The first column lists the taxon labels"
+                                " (matching the taxon label of the input trees EXACTLY)"
+                                " and the second column lists the ages of the"
+                                " corresponding tips."
+                            ),
+                            ("'json'",
+                                "A JSON file. This should specify a single"
+                                " dictionary at the top-level with keys being taxon"
+                                " labels (matching the taxon labels of the input "
+                                " trees EXACTLY) and values being the ages of the "
+                                " corresponding tips."
+                            ),
+                        )
+                ))
+    source_options.add_argument("--no-trim-tip-age-labels",
+            action="store_false",
+            default=True,
+            help="By default, whitespace will be trimmed from the labels"
+                 " found in the tip ages data source. Specifing this option"
+                 " suppresses this.")
 
     target_tree_options = parser.add_argument_group("Target Tree Topology Options")
     target_tree_options.add_argument(
@@ -738,23 +796,34 @@ def main():
                                 "posterior probabilities.              "
                             ),
                             ("'msct'",
-                                "The maximum clade credibility tree.   "
+                                "The maximum sum of clade credibilities tree.   "
                                 "The tree from the source set that     "
-                                "maximizes the *product* of clade      "
+                                "maximizes the *sum* of clade      "
                                 "posterior probabilities.              "
                             ),
                         )
                 ))
     target_tree_supplemental_options = parser.add_argument_group("Target Tree Supplemental Options")
-    target_tree_supplemental_options.add_argument("-f", "--min-consensus-freq", "--min-freq", "--min-clade-freq",
+    target_tree_supplemental_options.add_argument("-f", "--min-clade-freq", "--min-freq", "--min-split-freq", "--min-consensus-freq",
+            dest="min_clade_freq",
             type=float,
-            default=constants.GREATER_THAN_HALF,
+            # default=constants.GREATER_THAN_HALF,
+            default=None,
             metavar="#.##",
             help=(
-                "If using a consensus tree summarization strategy, then "
-                "this is the minimum frequency or probability for a clade "
-                "or a split to be included in the resulting tree "
-                "(default: > 0.5)."))
+                "Minimum frequency or "
+                "probability for a clade or a split to be included in "
+                "the summary target trees. "
+                "If user-defined or non-consensus trees are specified "
+                "as summary targets "
+                "and a explicit value is provided for this argument, "
+                "then clades with support values below this threshold "
+                "will be collapsed. "
+                "If a consensus tree summary target is specified, "
+                "then clades with support values below this threshold "
+                "will not be included, and this threshold takes on a "
+                "default value of greater than 0.5 if not explicitly "
+                "specified."))
     target_tree_supplemental_options.add_argument("--allow-unknown-target-tree-taxa",
             action="store_true",
             default=False,
@@ -763,6 +832,18 @@ def main():
                 " previously encountered in source trees or defined in"
                 " the taxon discovery file."
                 ))
+    # target_tree_supplemental_options.add_argument(
+    #         "--collapse-edges-with-less-than-minimum-support",
+    #         dest="collapse_edges_with_less_than_minimum_support",
+    #         action="store_true",
+    #         default=False,
+    #         help=(
+    #             "Collapse edges that have support values less than that specifed "
+    #             "by '-f', '--min-freq'. By default, the '--min-freq' option "
+    #             "only applies for consensus tree summary targets. Specifying "
+    #             "this option will apply it to all other types of summary targets "
+    #             "including user-specified target trees."
+    #             ))
 
     target_tree_rooting_options = parser.add_argument_group("Target Tree Rooting Options")
     target_tree_rooting_options.add_argument("--root-target-at-outgroup",
@@ -1055,10 +1136,11 @@ def main():
             action="store_true",
             default=False,
             help="Show help information for program and exit.")
-    information_options.add_argument("--citation",
+    information_options.add_argument("--version","--citation",
+            dest="citation",
             action="store_true",
             default=False,
-            help="Show citation information for program and exit.")
+            help="Show version and citation information for program and exit.")
     information_options.add_argument("--usage-examples",
             action="store_true",
             default=False,
@@ -1080,7 +1162,8 @@ def main():
     ## Information (Only) Operations
 
     if args.citation:
-        citation(args)
+        print_citation(args)
+        sys.exit(0)
 
     if not args.quiet:
         show_splash()
@@ -1242,6 +1325,66 @@ def main():
         args.summarize_node_ages = True
 
     ######################################################################
+    ## Tip Ages
+
+    if args.tip_ages_filepath is None:
+        taxon_label_age_map = None
+    else:
+        if not args.summarize_node_ages:
+            messenger.error("Tip age data file specified, but node ages are not going be analyzed."
+                            " Specify '--summarize-node-ages' or '--edges=mean-age' or --edges=median-age'"
+                            " to analyze node ages.")
+            sys.exit(1)
+        tip_ages_filepath = os.path.expanduser(os.path.expandvars(args.tip_ages_filepath))
+        messenger.info("Tip ages will be read from: '{}'".format(tip_ages_filepath))
+        with open(tip_ages_filepath, "r") as src:
+            if args.tip_ages_format == "csv" or args.tip_ages_format == "tsv":
+                raw_tip_data_map = collections.OrderedDict()
+                if args.tip_ages_format == "csv":
+                    delimiter=","
+                    delimiter_desc = "',' (comma)"
+                else:
+                    delimiter="\t"
+                    delimiter_desc = "'\\t' (the tab character)"
+                csv_reader = csv.reader(src, delimiter=delimiter)
+                for row_idx, row in enumerate(csv_reader):
+                    try:
+                        taxon_label, age = row
+                    except ValueError as e:
+                        messenger.error("Tip age data file '{}', line {}: error reading columns. Perhaps wrong delimiter was specified? Expecting {} as a delimiter. Use '--tip-ages-format' to change this.".format(
+                            tip_ages_filepath, row_idx, delimiter_desc))
+                        sys.exit(1)
+                    try:
+                        raw_tip_data_map[taxon_label] = float(age)
+                    except ValueError as e:
+                        messenger.error("Tip age data file '{}', line {} (label = '{}'): invalid age value: {}".format(
+                            tip_ages_filepath, row_idx, taxon_label, age))
+                        sys.exit(1)
+            elif args.tip_ages_format == "json":
+                raw_tip_data_map = collections.OrderedDict(json.load(src))
+            else:
+                messenger.error("Unrecognized or unsupported format for tip age data: '{}'".format(args.tip_ages_format))
+                sys.exit(1)
+        taxon_label_age_map = {}
+        for taxon_label in raw_tip_data_map:
+            try:
+                age = float(raw_tip_data_map[taxon_label])
+            except ValueError:
+                messenger.error("Tip age data file '{}': taxon with label '{}': invalid value for age: {}".format(
+                    tip_ages_filepath, taxon_label, raw_tip_data_map[taxon_label]))
+                sys.exit(1)
+            if not args.no_trim_tip_age_labels:
+                taxon_label = taxon_label.strip()
+            if args.input_format in ("nexus/newick", "nexus", "newick"):
+                if not args.preserve_underscores:
+                    if not (
+                            (taxon_label[0] == taxon_label[-1] == "'")
+                            or (taxon_label[0] == taxon_label[-1] == '"')
+                            ):
+                        taxon_label = taxon_label.replace("_", " ")
+            taxon_label_age_map[taxon_label] = age
+
+    ######################################################################
     ## Ultrametricity Precision
 
     if args.ultrametricity_precision == 0:
@@ -1249,7 +1392,6 @@ def main():
         # API uses 0
         args.ultrametricity_precision = -1
 
-
     ######################################################################
     ## Output File Setup
 
@@ -1366,6 +1508,7 @@ def main():
             ignore_node_ages=not args.summarize_node_ages,
             use_tree_weights=args.weighted_trees,
             ultrametricity_precision=args.ultrametricity_precision,
+            taxon_label_age_map=taxon_label_age_map,
             num_processes=num_processes,
             log_frequency=args.log_frequency if not args.quiet else 0,
             messenger=messenger,
@@ -1417,6 +1560,21 @@ def main():
         sys.exit(1)
     analysis_time_end = datetime.datetime.now()
     analysis_time_delta =  analysis_time_end-analysis_time_start
+
+    ### Validate/match taxa with tip ages
+    ### We do this here so as to avoid reporting a "job complete"
+    ### if there are errors
+    if taxon_label_age_map:
+        taxon_age_map = {}
+        for taxon_label, age in taxon_label_age_map.items():
+            taxon = tree_array.taxon_namespace.get_taxon(taxon_label)
+            if taxon is None:
+                messenger.error("Unable to find taxon with label matching tip data label '{}' in the taxon namespace: {}".format(
+                    taxon_label,
+                    [t.label for t in tree_array.taxon_namespace]))
+                sys.exit(1)
+            taxon_age_map[taxon] = taxon_label_age_map[taxon_label]
+
     messenger.info("Analysis of source trees completed in: {}".format(timeprocessing.pretty_timedelta(analysis_time_delta),
         wrap=False,
         ))
@@ -1459,6 +1617,18 @@ def main():
         _bulleted_message_and_log("{} unique splits out of a total of {} splits".format(num_unique_splits, int(num_splits)))
         _bulleted_message_and_log("{} unique non-trivial splits counted out of a total of non-trivial {} splits".format(num_nt_unique_splits, int(num_nt_splits)))
 
+    ###  tip ages
+    if not taxon_label_age_map:
+        pass
+        # _message_and_log("All tips assumed to be contemporaneous with age of 0.0")
+    else:
+        _message_and_log("Tips assigned the following ages for node age analysis:")
+        taxon_labels = [taxon.label for taxon in tree_array.taxon_namespace]
+        max_taxon_label_length = max([len(x) for x in taxon_labels])
+        taxon_age_template = "{{:>{}}} : {{}}".format(max_taxon_label_length)
+        for taxon in tree_array.taxon_namespace:
+            _bulleted_message_and_log(taxon_age_template.format(taxon.label, taxon_label_age_map.get(taxon.label, 0.0)))
+
     ### build target tree(s)
     target_trees = dendropy.TreeList(taxon_namespace=tree_array.taxon_namespace)
     if target_tree_filepath is None:
@@ -1470,8 +1640,12 @@ def main():
         if args.summary_target is None:
             args.summary_target = "consensus"
         if args.summary_target == "consensus":
-            tree = tree_array.consensus_tree(min_freq=args.min_consensus_freq, summarize_splits=False)
-            msg = "Summarized onto consensus tree with minimum clade frequency threshold of {}:".format(args.min_consensus_freq)
+            if args.min_clade_freq is None:
+                min_freq = constants.GREATER_THAN_HALF
+            else:
+                min_freq = args.min_clade_freq
+            tree = tree_array.consensus_tree(min_freq=min_freq, summarize_splits=False)
+            msg = "Summarized onto consensus tree with minimum clade frequency threshold of {}:".format(min_freq)
         elif args.summary_target == "mcct" or args.summary_target == "mcc":
             tree = tree_array.maximum_product_of_split_support_tree(
                     include_external_splits=args.include_external_splits_when_scoring_clade_credibility_tree,
@@ -1484,8 +1658,8 @@ def main():
             msg = "Summarized onto Maximum Sum of Credibilities Tree (i.e., tree given in sources that maximizes the sum of clade credibilities{}):".format(coda)
         else:
             raise ValueError(args.summary_target)
-        target_trees.append(tree)
         _message_and_log(msg, wrap=True)
+        target_trees.append(tree)
     else:
         try:
             if not args.allow_unknown_target_tree_taxa:
@@ -1525,8 +1699,17 @@ def main():
             msg = "Summarizing onto {} target trees".format(len(target_trees))
         else:
             msg = "Summarizing onto target tree".format(len(target_trees))
+        target_trees.append(tree)
         msg += " defined in '{}':".format(target_tree_filepath)
         _message_and_log(msg, wrap=False)
+    # if args.collapse_edges_with_less_than_minimum_support and args.summary_target != "consensus":
+    if args.min_clade_freq is not None and args.summary_target != "consensus":
+        msg = "Collapsing clades or splits with support frequency less than {}".format(args.min_clade_freq)
+        for tree in target_trees:
+            tree_array.collapse_edges_with_less_than_minimum_support(
+                    tree=tree,
+                    min_freq=args.min_clade_freq,)
+        _message_and_log(msg, wrap=False)
 
     ###  rooting
 
@@ -1666,11 +1849,8 @@ def main():
         summarization_metainfo.append("Program Information")
         summarization_metainfo.append("-------------------")
         summarization_metainfo.append("{} {} by {}".format(_program_name, _program_version, _program_author))
-        summarization_metainfo.append("Using {}, located at: '{}'".format(dendropy.description(), dendropy.homedir()))
-        python_version = sys.version.replace("\n", "").replace("[", "(").replace("]",")")
-        summarization_metainfo.append("Running under Python {}, located at: '{}'".format(python_version, sys.executable))
+        summarization_metainfo.append(dendropy.description_text())
 
-        summarization_metainfo.append("")
         summarization_metainfo.append("Execution Information")
         summarization_metainfo.append("---------------------")
         try:
diff --git a/dendropy/__init__.py b/dendropy/__init__.py
index 040cb50..bf5ee5a 100644
--- a/dendropy/__init__.py
+++ b/dendropy/__init__.py
@@ -43,19 +43,27 @@ from dendropy.datamodel.charstatemodel import BINARY_STATE_ALPHABET
 from dendropy.datamodel.charstatemodel import RESTRICTION_SITES_STATE_ALPHABET
 from dendropy.datamodel.charstatemodel import INFINITE_SITES_STATE_ALPHABET
 from dendropy.datamodel.charstatemodel import new_standard_state_alphabet
-from dendropy.datamodel.charmatrixmodel import CharacterMatrix
 from dendropy.datamodel.charmatrixmodel import CharacterDataSequence
+from dendropy.datamodel.charmatrixmodel import CharacterMatrix
+from dendropy.datamodel.charmatrixmodel import DnaCharacterDataSequence
 from dendropy.datamodel.charmatrixmodel import DnaCharacterMatrix
-from dendropy.datamodel.charmatrixmodel import RnaCharacterMatrix
+from dendropy.datamodel.charmatrixmodel import NucleotideCharacterDataSequence
 from dendropy.datamodel.charmatrixmodel import NucleotideCharacterMatrix
+from dendropy.datamodel.charmatrixmodel import RnaCharacterDataSequence
+from dendropy.datamodel.charmatrixmodel import RnaCharacterMatrix
+from dendropy.datamodel.charmatrixmodel import ProteinCharacterDataSequence
 from dendropy.datamodel.charmatrixmodel import ProteinCharacterMatrix
+from dendropy.datamodel.charmatrixmodel import RestrictionSitesCharacterDataSequence
 from dendropy.datamodel.charmatrixmodel import RestrictionSitesCharacterMatrix
+from dendropy.datamodel.charmatrixmodel import InfiniteSitesCharacterDataSequence
 from dendropy.datamodel.charmatrixmodel import InfiniteSitesCharacterMatrix
+from dendropy.datamodel.charmatrixmodel import StandardCharacterDataSequence
 from dendropy.datamodel.charmatrixmodel import StandardCharacterMatrix
+from dendropy.datamodel.charmatrixmodel import ContinuousCharacterDataSequence
 from dendropy.datamodel.charmatrixmodel import ContinuousCharacterMatrix
+from dendropy.calculate.phylogeneticdistance import PhylogeneticDistanceMatrix
 from dendropy.datamodel.datasetmodel import DataSet
 from dendropy.utility.error import ImmutableTaxonNamespaceError
-from dendropy.utility.error import DataError
 from dendropy.utility.error import DataParseError
 from dendropy.utility.error import UnsupportedSchemaError
 from dendropy.utility.error import UnspecifiedSchemaError
@@ -94,8 +102,8 @@ import collections
 version_info = collections.namedtuple("dendropy_version_info",
         ["major", "minor", "micro", "releaselevel"])(
                 major=4,
-                minor=0,
-                micro=3,
+                minor=1,
+                micro=0,
                 releaselevel=""
                 )
 __project__ = "DendroPy"
@@ -157,6 +165,12 @@ def description(dest=None):
             fieldnamewidth=max_fieldname_len + 2,
             fieldvalue=fieldvalue))
 
+def description_text():
+    from dendropy.utility.textprocessing import StringIO
+    s = StringIO()
+    description(s)
+    return s.getvalue()
+
 def citation_info(include_preamble=True, width=76):
     import textwrap
     citation_lines = []
diff --git a/dendropy/calculate/combinatorics.py b/dendropy/calculate/combinatorics.py
new file mode 100644
index 0000000..3c2354a
--- /dev/null
+++ b/dendropy/calculate/combinatorics.py
@@ -0,0 +1,71 @@
+#! /usr/bin/env python
+
+##############################################################################
+##  DendroPy Phylogenetic Computing Library.
+##
+##  Copyright 2010-2015 Jeet Sukumaran and Mark T. Holder.
+##  All rights reserved.
+##
+##  See "LICENSE.rst" for terms and conditions of usage.
+##
+##  If you use this work or any portion thereof in published work,
+##  please cite it as:
+##
+##     Sukumaran, J. and M. T. Holder. 2010. DendroPy: a Python library
+##     for phylogenetic computing. Bioinformatics 26: 1569-1571.
+##
+##############################################################################
+
+"""
+Combinatoric and related functionCombinatoric and related functions.
+"""
+
+import math
+
+def factorial(num):
+    """factorial(n): return the factorial of the integer num.
+    factorial(0) = 1
+    factorial(n) with n<0 is -factorial(abs(n))
+    """
+    result = 1
+    for i in range(1, abs(num)+1):
+        result *= i
+    return result
+
+def choose(population, sample):
+    """
+    Returns  ``population`` choose ``sample``, given
+    by: n! / k!(n-k)!, where n == ``population`` and
+    k == ``sample``.
+    """
+    if sample > population:
+        return 0
+    s = max(sample, population - sample)
+    assert s <= population
+    assert population > -1
+    if s == population:
+        return 1
+    numerator = 1
+    denominator = 1
+    for i in range(s+1, population + 1):
+        numerator *= i
+        denominator *= (i - s)
+    return numerator/denominator
+
+def num_edges_on_tree(num_leaves, is_rooted=True):
+    if is_rooted:
+        return (2 * num_leaves) - 2
+    else:
+        return (2 * num_leaves) - 3
+
+def num_internal_nodes_on_tree(num_leaves, is_rooted=True):
+    if is_rooted:
+        return num_leaves - 1
+    else:
+        return num_leaves - 2
+
+def num_internal_edges_on_tree(num_leaves, is_rooted=True):
+    if is_rooted:
+        return num_leaves - 2
+    else:
+        return num_leaves - 3
diff --git a/dendropy/calculate/phylogeneticdistance.py b/dendropy/calculate/phylogeneticdistance.py
new file mode 100644
index 0000000..1b36f78
--- /dev/null
+++ b/dendropy/calculate/phylogeneticdistance.py
@@ -0,0 +1,1526 @@
+#! /usr/bin/env python
+
+##############################################################################
+##  DendroPy Phylogenetic Computing Library.
+##
+##  Copyright 2010-2015 Jeet Sukumaran and Mark T. Holder.
+##  All rights reserved.
+##
+##  See "LICENSE.rst" for terms and conditions of usage.
+##
+##  If you use this work or any portion thereof in published work,
+##  please cite it as:
+##
+##     Sukumaran, J. and M. T. Holder. 2010. DendroPy: a Python library
+##     for phylogenetic computing. Bioinformatics 26: 1569-1571.
+##
+##############################################################################
+
+"""
+Taxon-to-taxon phylogenetic distances.
+"""
+
+import math
+import collections
+import csv
+from dendropy.calculate import statistics
+from dendropy.utility import GLOBAL_RNG
+from dendropy.utility import container
+from dendropy.utility import error
+import dendropy
+
+class PhylogeneticDistanceMatrix(object):
+    """
+    Calculates and maintains patristic distance information of taxa on a tree.
+    """
+
+    @classmethod
+    def from_tree(cls, tree):
+        """
+        Creates and returns a |PhylogeneticDistanceMatrix| based
+        on the given tree.
+
+        Note that this creates a "snapshot" of the current state of the tree.
+        Subsequent changes to the tree will not be reflected in
+        |PhylogeneticDistanceMatrix| instances previously created.
+
+        Also note that syntactically you may prefer to use::
+
+            pdm = tree.phylogenetic_distance_matrix()
+
+        instead of::
+
+            pdm = PhylogeneticDistanceMatrix.from_tree(tree)
+
+        Parameters
+        ----------
+        tree : a |Tree| instance
+            The |Tree| from which to get the phylogenetic distances.
+
+        Returns
+        -------
+        pdm : A |PhylogeneticDistanceMatrix| instance
+
+        Examples
+        --------
+
+        ::
+
+            import dendropy
+            tree = dendropy.Tree.get(path="tree.nex",
+                    schema="nexus")
+            pdm1 = dendropy.PhylogeneticDistanceMatrix.from_tree(tree)
+
+            # following is equivalent to above and probably preferred:
+            pdm2 = tree.phylogenetic_distance_matrix()
+
+        """
+        pdm = cls()
+        pdm.compile_from_tree(tree=tree)
+        return pdm
+
+    @classmethod
+    def from_csv(cls,
+            src,
+            taxon_namespace=None,
+            is_allow_new_taxa=None,
+            is_first_row_column_names=True,
+            is_first_column_row_names=True,
+            default_data_type=float,
+            label_transform_fn=None,
+            **csv_reader_kwargs
+            ):
+        """
+        Instantiates a new PhylogeneticDistanceMatrix instance with data
+        from an external source.
+
+        Parameters
+        ----------
+        src : file or file-like
+            Source of data. This is a token delimited-file (e.g., a
+            comma-delimited or tab-delimited file) providing a table which
+            lists taxon labels in both rows and columns. The cells of the table
+            are numeric (typically real) values that indicate the distance
+            between the taxa of the current row and column. Note that *only*
+            the upper right section of the table is considered. The diagonals
+            values are typically zeroes and, in either case, ignored along with
+            the lower diagonal. Despite being ignored by the
+            PhylogeneticDistanceMatrix object, the values are parsed by the
+            underlying reader and thus have to be valid numerical values.
+        taxon_namespace : |TaxonNamespace| instance
+            The taxon namespace with which to manage taxa. If this has
+            not already been pre-populated with the taxon names, then
+            ``is_allow_new_taxa`` should be set to |True|.
+        is_allow_new_taxa : bool
+            If |False|: we do *not* expect to encounter any new taxa in the
+            data file, and it is an error if we do. If |True|: we do expect to
+            encounter new taxa in the data file. The default value of this
+            depends on the value passed to ``taxon_namespace``. If
+            ``taxon_namespace`` is ``None`` or an empty |TaxonNamespace|
+            instance, then unless explicitly set to |False|,
+            ``is_allow_new_taxa`` will default to |True|: allowing of creation
+            of new taxa corresponding to labels found in the data source. On
+            the other hand, if ``taxon_namespace`` is not None and its value is
+            a |TaxonNamespace| instance with at least one taxon, unless
+            explicitly set to |True|, ``is_allow_new_taxa`` will default to
+            |False|, and it will be an error if taxon labels are found in the
+            data source that do not correspond (exactly) to |Taxon| objects
+            defined in the taxon namespace.  This is to err on the side of
+            caution, to avoid (or rather, highlight) problems due to incorrect
+            or mismatching labels between the data source and the current taxon
+            namespace.
+        is_first_row_column_names : bool
+            By default |True|: assumes that first row lists the taxon names.
+            Set to |False| if there is no header row.
+        is_first_column_row_names : bool
+            By default |True|: assumes that first column lists the taxon names.
+            Set to |False| if there is now row name column.
+        label_transform_fn : function object
+            If not None, this should be a function object that takes a string
+            as an argument and returns another string. This function will be
+            applied to row and column labels before they are matched to taxon
+            labels in the |TaxonNamespace| instance given by
+            ``taxon_namespace``.
+        \*\*csv_reader_kwargs : keyword arguments
+            This arguments will be passed to the underlying CSV reader.
+            The most important one is probably 'delimiter'.
+
+        Returns
+        -------
+        pdm : A |PhylogeneticDistanceMatrix| instance
+
+        Examples
+        --------
+
+        ::
+
+            import dendropy
+            pdm1 = dendropy.PhylogeneticDistanceMatrix.from_csv(
+                    src=open("data.csv"),
+                    delimiter=",")
+            pdm2 = dendropy.PhylogeneticDistanceMatrix.from_csv(
+                    src=open("data.tsv"),
+                    delimiter="\t")
+
+        """
+        if taxon_namespace is None:
+            taxon_namespace = dendropy.TaxonNamespace()
+        if len(taxon_namespace) == 0 and is_allow_new_taxa is None:
+            is_allow_new_taxa = True
+        old_taxon_namespace_mutability = taxon_namespace.is_mutable
+        taxon_namespace.is_mutable = is_allow_new_taxa
+        data_table = container.DataTable.from_csv(
+                src,
+                is_first_row_column_names=is_first_row_column_names,
+                is_first_column_row_names=is_first_column_row_names,
+                default_data_type=default_data_type,
+                label_transform_fn=label_transform_fn,
+                **csv_reader_kwargs
+                )
+        if not is_first_row_column_names and not is_first_column_row_names:
+            distances = {}
+            seen_row_labels = set()
+            seen_row_taxa_labels = set()
+            for i1, t1_label in enumerate(data_table.row_name_iter()):
+                if len(taxon_namespace) <= i1:
+                    t1 = taxon_namespace.require_taxon(label=t1_label)
+                else:
+                    t1 = taxon_namespace[i1]
+                seen_row_labels.add(t1_label)
+                assert t1.label not in seen_row_taxa_labels
+                seen_row_taxa_labels.add(t1.label)
+                distances[t1] = {}
+                for i2, t2_label in enumerate(data_table.column_name_iter()):
+                    if t2_label in seen_row_labels:
+                        continue
+                    if len(taxon_namespace) <= i2:
+                        t2 = taxon_namespace.require_taxon(label=t2_label)
+                    else:
+                        t2 = taxon_namespace[i2]
+                    distances[t1][t2] = data_table[t1_label, t2_label]
+        else:
+            distances = {}
+            seen_taxa = set()
+            taxa = []
+            if is_first_column_row_names:
+                name_iter = data_table.row_name_iter()
+            else:
+                name_iter = data_table.column_name_iter()
+            for label in name_iter:
+                t1 = taxon_namespace.require_taxon(label=label)
+                assert t1 not in seen_taxa
+                seen_taxa.add(t1)
+                taxa.append(t1)
+            seen_row_taxa = set()
+            for i1, t1 in enumerate(taxa):
+                assert t1 in seen_taxa
+                seen_row_taxa.add(t1)
+                distances[t1] = {}
+                for i2, t2 in enumerate(taxa):
+                    if t2 in seen_row_taxa:
+                        continue
+                    distances[t1][t2] = data_table[i1, i2]
+        # else:
+            # raise NotImplementedError()
+
+        taxon_namespace.is_mutable = old_taxon_namespace_mutability
+        pdm = cls()
+        pdm.compile_from_dict(
+                distances=distances,
+                taxon_namespace=taxon_namespace)
+        return pdm
+
+    def __init__(self):
+        self.clear()
+
+    def clear(self):
+        self.taxon_namespace = None
+        self._mapped_taxa = set()
+        self._all_distinct_mapped_taxa_pairs = set()
+        self._tree_length = None
+        self._num_edges = None
+        self._taxon_phylogenetic_distances = {}
+        self._taxon_phylogenetic_path_steps = {}
+        self._mrca = {}
+
+    def compile_from_tree(self, tree):
+        """
+        Calculates the distances. Note that the path length (in number of
+        steps) between taxa that span the root will be off by one if
+        the tree is unrooted.
+        """
+        self.clear()
+        self.taxon_namespace = tree.taxon_namespace
+        # for i1, t1 in enumerate(self.taxon_namespace):
+        #     self._taxon_phylogenetic_distances[t1] = {}
+        #     self._taxon_phylogenetic_path_steps[t1] = {}
+        #     self._mrca[t1] = {}
+        self._tree_length = 0.0
+        self._num_edges = 0
+        for node in tree.postorder_node_iter():
+            try:
+                self._tree_length += node.edge.length
+            except TypeError: # None for edge length
+                pass
+            self._num_edges += 1
+            children = node.child_nodes()
+            if len(children) == 0:
+                node.desc_paths = {node : (0,0)}
+            else:
+                node.desc_paths = {}
+                for cidx1, c1 in enumerate(children):
+                    for desc1, (desc1_plen, desc1_psteps) in c1.desc_paths.items():
+                        node.desc_paths[desc1] = (desc1_plen + c1.edge.length, desc1_psteps + 1)
+                        assert desc1.taxon is not None
+                        if desc1.taxon not in self._taxon_phylogenetic_distances:
+                            self._mapped_taxa.add(desc1.taxon)
+                            self._taxon_phylogenetic_distances[desc1.taxon] = {}
+                            self._taxon_phylogenetic_distances[desc1.taxon][desc1.taxon] = 0.0
+                            self._taxon_phylogenetic_path_steps[desc1.taxon] = {}
+                            self._taxon_phylogenetic_path_steps[desc1.taxon][desc1.taxon] = 0
+                            self._mrca[desc1.taxon] = {desc1.taxon: desc1}
+                        for c2 in children[cidx1+1:]:
+                            for desc2, (desc2_plen, desc2_psteps) in c2.desc_paths.items():
+                                self._mapped_taxa.add(desc2.taxon)
+                                self._mrca[desc1.taxon][desc2.taxon] = c1.parent_node
+                                # self._all_distinct_mapped_taxa_pairs.add( tuple([desc1.taxon, desc2.taxon]) )
+                                self._all_distinct_mapped_taxa_pairs.add( frozenset([desc1.taxon, desc2.taxon]) )
+                                pat_dist = node.desc_paths[desc1][0] + desc2_plen + c2.edge.length
+                                self._taxon_phylogenetic_distances[desc1.taxon][desc2.taxon] = pat_dist
+                                path_steps = node.desc_paths[desc1][1] + desc2_psteps + 1
+                                self._taxon_phylogenetic_path_steps[desc1.taxon][desc2.taxon] = path_steps
+                    del(c1.desc_paths)
+        self._mirror_lookups()
+        # assert self._tree_length == tree.length()
+
+    def compile_from_dict(self, distances, taxon_namespace):
+        self.clear()
+        self.taxon_namespace = taxon_namespace
+        for t1 in distances:
+            self._mapped_taxa.add(t1)
+            self._taxon_phylogenetic_distances[t1] = {}
+            for t2 in distances[t1]:
+                self._taxon_phylogenetic_distances[t1][t2] = distances[t1][t2]
+        self._mirror_lookups()
+
+    def _mirror_lookups(self):
+        for ddata in (
+                self._taxon_phylogenetic_distances,
+                self._taxon_phylogenetic_path_steps,
+                self._mrca,
+                ):
+            for taxon1 in ddata:
+                for taxon2 in ddata[taxon1]:
+                    # assert taxon1 is not taxon2
+                    if taxon2 not in ddata:
+                        ddata[taxon2] = {}
+                    ddata[taxon2][taxon1] = ddata[taxon1][taxon2]
+
+    def __eq__(self, o):
+        if self.taxon_namespace is not o.taxon_namespace:
+            return False
+        return (True
+                and (self._mapped_taxa == o._mapped_taxa)
+                and (self._all_distinct_mapped_taxa_pairs == o._all_distinct_mapped_taxa_pairs)
+                and (self._taxon_phylogenetic_distances == o._taxon_phylogenetic_distances)
+                and (self._taxon_phylogenetic_path_steps == o._taxon_phylogenetic_path_steps)
+                and (self._mrca == o._mrca)
+                and (self._tree_length == o._tree_length)
+                and (self._num_edges == o._num_edges)
+                )
+
+    def __hash__(self):
+        return id(self)
+
+    def __call__(self, taxon1, taxon2):
+        return self.patristic_distance(taxon1, taxon2)
+
+    def __copy__(self):
+        return self.clone()
+
+    def __iter__(self):
+        for taxon in self._taxon_phylogenetic_distances:
+            yield taxon
+
+    def clone(self):
+        o = self.__class__()
+        o.taxon_namespace = self.taxon_namespace
+        o._mapped_taxa = set(self._mapped_taxa)
+        o._all_distinct_mapped_taxa_pairs = set(self._all_distinct_mapped_taxa_pairs)
+        o._tree_length = self._tree_length
+        o._num_edges = self._num_edges
+        for src, dest in (
+                (self._taxon_phylogenetic_distances, o._taxon_phylogenetic_distances,),
+                (self._taxon_phylogenetic_path_steps, o._taxon_phylogenetic_path_steps,),
+                (self._mrca, o._mrca,),
+                ):
+            for t1 in src:
+                dest[t1] = {}
+                for t2 in src[t1]:
+                    dest[t1][t2] = src[t1][t2]
+        return o
+
+    def mrca(self, taxon1, taxon2):
+        """
+        Returns MRCA of two taxon objects.
+        """
+        return self._mrca[taxon1][taxon2]
+
+    def distance(self,
+            taxon1,
+            taxon2,
+            is_weighted_edge_distances=True,
+            is_normalize_by_tree_size=False):
+        """
+        Returns distance between taxon1 and taxon2.
+        """
+        if is_weighted_edge_distances:
+            return self.patristic_distance(taxon1, taxon2, is_normalize_by_tree_size=is_normalize_by_tree_size)
+        else:
+            return self.path_edge_count(taxon1, taxon2, is_normalize_by_tree_size=is_normalize_by_tree_size)
+
+    def patristic_distance(self, taxon1, taxon2, is_normalize_by_tree_size=False):
+        """
+        Returns patristic distance between two taxon objects.
+        """
+        if taxon1 is taxon2:
+            return 0.0
+        d = self._taxon_phylogenetic_distances[taxon1][taxon2]
+        if is_normalize_by_tree_size:
+            return d / self._tree_length
+        else:
+            return d
+
+    def path_edge_count(self, taxon1, taxon2, is_normalize_by_tree_size=False):
+        """
+        Returns the number of edges between two taxon objects.
+        """
+        if taxon1 is taxon2:
+            return 0
+        d = self._taxon_phylogenetic_path_steps[taxon1][taxon2]
+        if is_normalize_by_tree_size:
+            return float(d) / self._num_edges
+        else:
+            return d
+
+    def distances(self,
+            is_weighted_edge_distances=True,
+            is_normalize_by_tree_size=False):
+        """
+        Returns list of patristic distances.
+        """
+        dmatrix, normalization_factor = self._get_distance_matrix_and_normalization_factor(
+                is_weighted_edge_distances=is_weighted_edge_distances,
+                is_normalize_by_tree_size=is_normalize_by_tree_size,
+                )
+        results = []
+        for t1, t2 in self._all_distinct_mapped_taxa_pairs:
+            results.append(dmatrix[t1][t2]/normalization_factor)
+        return results
+
+    def max_pairwise_distance_taxa(self,
+            is_weighted_edge_distances=True):
+        if is_weighted_edge_distances:
+            dists = self._taxon_phylogenetic_distances
+        else:
+            dists = self._taxon_phylogenetic_path_steps
+        max_dist = None
+        max_dist_taxa = None
+        for t1, t2 in self._all_distinct_mapped_taxa_pairs:
+            pat_dist = dists[t1][t2]
+            if max_dist is None or pat_dist > max_dist:
+                max_dist = pat_dist
+                max_dist_taxa = (t1, t2)
+        return max_dist_taxa
+
+    def sum_of_distances(self,
+            is_weighted_edge_distances=True,
+            is_normalize_by_tree_size=False):
+        """
+        Returns sum of patristic distances on tree.
+        """
+        return sum(self.distances(is_weighted_edge_distances=is_weighted_edge_distances,is_normalize_by_tree_size=is_normalize_by_tree_size))
+
+    def taxon_iter(self, filter_fn=None):
+        """
+        Iterates over taxa in matrix. Note that this could be a subset of the taxa in
+        the associated taxon namespace.
+        """
+        for t1 in self._mapped_taxa:
+            if not filter_fn or filter_fn(t1):
+                yield t1
+
+    def distinct_taxon_pair_iter(self, filter_fn=None):
+        """
+        Iterates over all distinct pairs of taxa in matrix.
+        """
+        for t1, t2 in self._all_distinct_mapped_taxa_pairs:
+            if not filter_fn or (filter_fn(t1) and filter_fn(t2)):
+                yield t1, t2
+
+    def mean_pairwise_distance(self,
+            filter_fn=None,
+            is_weighted_edge_distances=True,
+            is_normalize_by_tree_size=False):
+        """
+        Calculates the phylogenetic ecology statistic "MPD"[1,2] for the tree
+        (only considering taxa for which ``filter_fn`` returns True when
+        applied if ``filter_fn`` is specified).
+
+        The mean pairwise distance (mpd) is given by:
+
+            .. math::
+                mpd = \\frac{ \\sum_{i}^{n} \\sum_{j}^{n} \\delta_{i,j} }{n \\choose 2},
+
+        where :math:`i \\neq j`, :math:`\\delta_{i,j}` is the phylogenetic
+        distance between species :math:`i` and :math:`j`, and :math:`n` is the number
+        of species in the sample.
+
+        Parameters
+        ----------
+        filter_fn : function object or None
+            If |None|, then all leaves will be considered. Otherwise should
+            be a function object that takes a Taxon instance as an argument and
+            returns |True| if it is to be included in the calculation or
+            |False| otherwise.
+            In trees sampled from multiple communites, ``filter_fn`` can be
+            used to restrict the calculation to only one community based on
+            some criteria.
+        is_weighted_edge_distances : bool
+            If |True| then the edge-weighted distance, i.e., considering edge
+            lengths, is returned. Otherwise the the path steps or the number of
+            edges rather then the sum of is_weighted_edge_distances edges, connecting two
+            taxa is considered.
+        is_normalize_by_tree_size : bool
+            If |True| then the results are normalized by the total tree length
+            or steps/edges (depending on whether edge-weighted or unweighted
+            distances are used, respectively). Otherwise, raw distances are
+            used.
+
+        Returns
+        -------
+        mpd : float
+            The Mean Pairwise Distance (MPD) statistic for the daata.
+
+        Examples
+        --------
+
+        ::
+
+            import dendropy
+            tree = dendropy.Tree.get(path="data.nex",
+                    schema="nexus")
+            pdm = dendropy.PhylogeneticDistanceMatrix(tree)
+
+            # consider all tips
+            mpd1 = pdm.mean_pairwise_distance()
+
+            # only tips within the same community, based on the node annotation
+            # "community"
+            mpds_by_community = {}
+            for community_label in ("1", "2", "3",):
+                filter_fn = lambda x: x.annotations["community"] == community_label
+                mpd = pdm.mean_pairwise_distance(filter_fn=filter_fn)
+                mpds_by_community[community_label] = mpd
+
+        References
+        ----------
+
+        [1] Webb, C.O. 2000. Exploring the phylogenetic structure of
+        ecological communities: An example for rainforest trees. The
+        American Naturalist 156: 145-155.
+
+        [2] Swenson, N.G. Functional and Phylogenetic Ecology in R.
+
+
+        """
+        comparison_regime = self.distinct_taxon_pair_iter(filter_fn=filter_fn)
+        return self._calculate_mean_pairwise_distance(
+                comparison_regime=comparison_regime,
+                is_weighted_edge_distances=is_weighted_edge_distances,
+                is_normalize_by_tree_size=is_normalize_by_tree_size,
+                )
+
+    def mean_nearest_taxon_distance(self,
+            filter_fn=None,
+            is_weighted_edge_distances=True,
+            is_normalize_by_tree_size=False):
+        """
+        Calculates the phylogenetic ecology statistic "MNTD"[1,2] for the tree
+        (only considering taxa for which ``filter_fn`` returns True when
+        applied if ``filter_fn`` is specified).
+
+        The mean nearest taxon distance (mntd) is given by:
+
+            .. math::
+                mntd = \\frac{ \\sum_{i}^{n} min(\\delta_{i,j}) }{n},
+
+        where :math:`i \\neq j`, :math:`\\delta_{i,j}` is the phylogenetic
+        distance between species :math:`i` and :math:`j`, and :math:`n` is the number
+        of species in the sample.
+
+        Parameters
+        ----------
+        filter_fn : function object or None
+            If |None|, then all leaves will be considered. Otherwise should
+            be a function object that takes a Taxon instance as an argument and
+            returns |True| if it is to be included in the calculation or
+            |False| otherwise.
+            In trees sampled from multiple communites, ``filter_fn`` can be
+            used to restrict the calculation to only one community based on
+            some criteria.
+        is_weighted_edge_distances : bool
+            If |True| then the edge-weighted distance, i.e., considering edge
+            lengths, is returned. Otherwise the the path steps or the number of
+            edges rather then the sum of is_weighted_edge_distances edges, connecting two
+            taxa is considered.
+        is_normalize_by_tree_size : bool
+            If |True| then the results are normalized by the total tree length
+            or steps/edges (depending on whether edge-weighted or unweighted
+            distances are used, respectively). Otherwise, raw distances are
+            used.
+
+        Returns
+        -------
+        mntd : float
+            The Mean Nearest Taxon Distance (MNTD) statistic for the daata.
+
+        Examples
+        --------
+
+        ::
+
+            import dendropy
+            tree = dendropy.Tree.get(path="data.nex",
+                    schema="nexus")
+            pdm = dendropy.PhylogeneticDistanceMatrix(tree)
+
+            # consider all tips
+            mntd = pdm.mean_nearest_taxon_distance()
+
+            # only tips within the same community, based on the node annotation
+            # "community"
+            mntds_by_community = {}
+            for community_label in ("1", "2", "3",):
+                filter_fn = lambda x: x.annotations["community"] == community_label
+                mntd = pdm.mean_pairwise_distance(filter_fn=filter_fn)
+                mntds_by_community[community_label] = mntd
+
+        References
+        ----------
+
+        [1] Webb, C.O. 2000. Exploring the phylogenetic structure of
+        ecological communities: An example for rainforest trees. The
+        American Naturalist 156: 145-155.
+
+        [2] Swenson, N.G. Functional and Phylogenetic Ecology in R.
+
+        """
+        comparison_regime = self._get_taxon_to_all_other_taxa_comparisons(filter_fn=filter_fn)
+        return self._calculate_mean_nearest_taxon_distance(
+                comparison_regime=comparison_regime,
+                is_weighted_edge_distances=is_weighted_edge_distances,
+                is_normalize_by_tree_size=is_normalize_by_tree_size,)
+
+    def standardized_effect_size_mean_pairwise_distance(self,
+            assemblage_memberships,
+            num_randomization_replicates=1000,
+            is_weighted_edge_distances=True,
+            is_normalize_by_tree_size=False,
+            is_skip_single_taxon_assemblages=False,
+            null_model_type="taxa.label",
+            rng=None):
+        """
+        Returns the standardized effect size value for the MPD statistic under
+        a null model under various community compositions.
+
+        The S.E.S. is given by:
+
+            .. math::
+                SES(statistic) = \\frac{observed - mean(model_{null})}{sd(model_{null})}
+
+        This removes any bias associated with the decrease in variance in the
+        MPD statistic value as species richness increases to the point where
+        communities become saturated. Equivalent to -1 times the Nearest
+        Relative Index (NRI) when using phylogenetic distances.
+
+        In contrast to the function calculating the non-standardized effect
+        size version of this statistic, which uses filter function to specify
+        the subset of taxa to be considerd, here a collection of (multiple)
+        sets of taxa constituting a community is specified. This to allow
+        calculation of the null model statistic across all community sets for
+        each randomization replicate.
+
+        Parameters
+        ----------
+        assemblage_memberships : iterable of iterable of |Taxon| objects
+            A collection of collections, e.g. a list of sets, with the elements
+            of each set being |Taxon| instances. Each set specifies the
+            composition of a community. The standardized effect size of this
+            statistic will be calculated for each community as specified by a
+            set of |Taxon| instances.
+        num_randomization_replicates : int
+            Number of randomization replicates.
+        is_weighted_edge_distances: bool
+            If ``True`` then edge lengths will be considered for distances.
+            Otherwise, just the number of edges.
+
+        Returns
+        -------
+        r : list of results
+            A list of results, with each result corresponding to a community
+            set given in ``assemblage_memberships``. Each result consists of a named
+            tuple with the following elements:
+
+                -   obs       : the observed value of the statistic
+                -   null_model_mean : the mean value of the statistic under the null
+                                model
+                -   null_model_sd   : the standard deviation of the statistic under
+                                the null model
+                -   z         : the standardized effect value of the statistic
+                                (= SES as defined in [1] above)
+                -   p         : the p-value of the observed value of the
+
+        Examples
+        --------
+
+        ::
+
+            import dendropy
+            tree = dendropy.Tree.get_from_path(
+                    src="data/community.tree.newick",
+                    schema="newick",
+                    rooting="force-rooted")
+            pdm = tree.phylogenetic_distance_matrix()
+            assemblage_membership_definitions = pdm.assemblage_membership_definitions_from_csv("data/comm1.csv")
+            results = pdm.standardized_effect_size_mean_pairwise_distance(assemblage_memberships=assemblage_membership_definitions.values())
+            print(results)
+
+        """
+        if assemblage_memberships is None:
+            assemblage_memberships = [ set(self._mapped_taxa) ]
+        comparison_regimes = []
+        for idx, assemblage_membership in enumerate(assemblage_memberships):
+            if len(assemblage_membership) == 1:
+                if is_skip_single_taxon_assemblages:
+                    continue
+                else:
+                    raise error.SingleTaxonAssemblageException("{}: {}".format(idx, assemblage_membership))
+            filter_fn = lambda taxon: taxon in assemblage_membership
+            comparison_regime = list(self.distinct_taxon_pair_iter(filter_fn=filter_fn))
+            comparison_regimes.append(comparison_regime)
+        results = self._calculate_standardized_effect_size(
+                statisticf_name="_calculate_mean_pairwise_distance",
+                is_weighted_edge_distances=is_weighted_edge_distances,
+                is_normalize_by_tree_size=is_normalize_by_tree_size,
+                comparison_regimes=comparison_regimes,
+                null_model_type=null_model_type,
+                num_randomization_replicates=num_randomization_replicates,
+                rng=rng)
+        return results
+
+    def standardized_effect_size_mean_nearest_taxon_distance(self,
+            assemblage_memberships,
+            num_randomization_replicates=1000,
+            is_weighted_edge_distances=True,
+            is_normalize_by_tree_size=False,
+            is_skip_single_taxon_assemblages=False,
+            null_model_type="taxa.label",
+            rng=None):
+        """
+        Returns the standardized effect size value for the MNTD statistic under
+        a null model under various community compositions.
+
+        The S.E.S. is given by:
+
+            .. math::
+                SES(statistic) = \\frac{observed - mean(model_{null})}{sd(model_{null})}
+
+        This removes any bias associated with the decrease in variance in the
+        MPD statistic value as species richness increases to the point where
+        communities become saturated. Equivalent to -1 times the Nearest Taxon
+        Index when using phylogenetic distances.
+
+        In contrast to the function calculating the non-standardized effect
+        size version of this statistic, which uses filter function to specify
+        the subset of taxa to be considerd, here a collection of (multiple)
+        sets of taxa constituting a community is specified. This to allow
+        calculation of the null model statistic across all community sets for
+        each randomization replicate.
+
+        Parameters
+        ----------
+        assemblage_memberships : iterable of iterable of |Taxon| objects
+            A collection of collections, e.g. a list of sets, with the elements
+            of each set being |Taxon| instances. Each set specifies the
+            composition of a community. The standardized effect size of this
+            statistic will be calculated for each community as specified by a
+            set of |Taxon| instances.
+        num_randomization_replicates : int
+            Number of randomization replicates.
+        is_weighted_edge_distances: bool
+            If ``True`` then edge lengths will be considered for distances.
+            Otherwise, just the number of edges.
+
+        Returns
+        -------
+        r : list of results
+            A list of results, with each result corresponding to a community
+            set given in ``assemblage_memberships``. Each result consists of a named
+            tuple with the following elements:
+
+                -   obs       : the observed value of the statistic
+                -   null_model_mean : the mean value of the statistic under the null
+                                model
+                -   null_model_sd   : the standard deviation of the statistic under
+                                the null model
+                -   z         : the standardized effect value of the statistic
+                                (= SES as defined in [1] above)
+                -   p         : the p-value of the observed value of the
+                                statistic under the null model.
+        Examples
+        --------
+
+        ::
+
+            import dendropy
+            tree = dendropy.Tree.get_from_path(
+                    src="data/community.tree.newick",
+                    schema="newick",
+                    rooting="force-rooted")
+            pdm = dendropy.PhylogeneticDistanceMatrix.from_tree(tree)
+            assemblage_memberships = pdm.assemblage_membership_definitions_from_csv("data/comm1.csv")
+            results = pdm.standardized_effect_size_mean_nearest_taxon_distance(assemblage_memberships=assemblage_memberships)
+            print(results)
+
+        """
+        if assemblage_memberships is None:
+            assemblage_memberships = [ set(self._mapped_taxa) ]
+        comparison_regimes = []
+        for idx, assemblage_membership in enumerate(assemblage_memberships):
+            if len(assemblage_membership) == 1:
+                if is_skip_single_taxon_assemblages:
+                    continue
+                else:
+                    raise error.SingleTaxonAssemblageException("{}: {}".format(idx, assemblage_membership))
+            filter_fn = lambda taxon: taxon in assemblage_membership
+            comparison_regime = self._get_taxon_to_all_other_taxa_comparisons(filter_fn=filter_fn)
+            comparison_regimes.append(comparison_regime)
+        results = self._calculate_standardized_effect_size(
+                statisticf_name="_calculate_mean_nearest_taxon_distance",
+                comparison_regimes=comparison_regimes,
+                is_weighted_edge_distances=is_weighted_edge_distances,
+                is_normalize_by_tree_size=is_normalize_by_tree_size,
+                null_model_type=null_model_type,
+                num_randomization_replicates=num_randomization_replicates,
+                rng=rng)
+        return results
+
+    def shuffle_taxa(self,
+            is_shuffle_phylogenetic_distances=True,
+            is_shuffle_phylogenetic_path_steps=True,
+            is_shuffle_mrca=True,
+            rng=None):
+        """
+        Randomly shuffles taxa in-situ.
+        """
+        if rng is None:
+            rng = GLOBAL_RNG
+        reordered_taxa = list(self._mapped_taxa)
+        rng.shuffle(reordered_taxa)
+        current_to_shuffled_taxon_map = dict(zip(self._mapped_taxa, reordered_taxa))
+        to_shuffle = []
+        if is_shuffle_phylogenetic_distances:
+            to_shuffle.append("_taxon_phylogenetic_distances")
+        if is_shuffle_phylogenetic_path_steps:
+            to_shuffle.append("_taxon_phylogenetic_path_steps")
+        if is_shuffle_mrca:
+            to_shuffle.append("_mrca")
+        for attr_name in to_shuffle:
+            src = getattr(self, attr_name)
+            dest = {}
+
+            ## 5m8.076s
+            # for t1, t2 in self._all_distinct_mapped_taxa_pairs:
+            #     x1 = current_to_shuffled_taxon_map[t1]
+            #     x2 = current_to_shuffled_taxon_map[t2]
+            #     d = src[t1][t2]
+            #     try:
+            #         dest[x1][x2] = d
+            #     except KeyError:
+            #         dest[x1] = {x2: d}
+            #         if t1 in src[t1]:
+            #             dest[x1][x1] = src[t1][t1]
+            #     try:
+            #         dest[x2][x1] = d
+            #     except KeyError:
+            #         dest[x2] = {x1: d}
+            #         if t2 in src[t2]:
+            #             dest[x2][x2] = src[t2][t2]
+            # setattr(self, attr_name, dest)
+
+            # 4m48.025s
+            for t1 in src:
+                x1 = current_to_shuffled_taxon_map[t1]
+                dest[x1] = {}
+                for t2 in src[t1]:
+                    x2 = current_to_shuffled_taxon_map[t2]
+                    dest[x1][x2] = src[t1][t2]
+            setattr(self, attr_name, dest)
+
+        return current_to_shuffled_taxon_map
+
+    def nj_tree(self,
+            is_weighted_edge_distances=True,
+            tree_factory=None,
+            ):
+        """
+        Returns an Neighbor-Joining (NJ) tree based on the distances in the matrix.
+
+        Calculates and returns a tree under the Neighbor-Joining algorithm of
+        Saitou and Nei (1987) for the data in the matrix.
+
+        Parameters
+        ----------
+        is_weighted_edge_distances: bool
+            If ``True`` then edge lengths will be considered for distances.
+            Otherwise, just the number of edges.
+
+        Returns
+        -------
+        t : |Tree|
+            A |Tree| instance corresponding to the Neighbor-Joining (NJ) tree
+            for this data.
+
+        Examples
+        --------
+
+        ::
+
+            import dendropy
+
+            # Read data from a CSV file into a PhylogeneticDistanceMatrix
+            # object
+            with open("distance_matrix.csv") as src:
+                pdm = dendropy.PhylogeneticDistanceMatrix.from_csv(
+                        src,
+                        is_first_row_column_names=True,
+                        is_first_column_row_names=True,
+                        is_allow_new_taxa=True,
+                        delimiter=",",
+                        )
+
+            # Calculate the tree
+            nj_tree = pdm.nj_tree()
+
+            # Print it
+            print(nj_tree.as_string("nexus"))
+
+
+        References
+        ----------
+        Saitou, N. and Nei, M. (1987) The neighbor-joining method: a new method
+        for reconstructing phylogenetic trees. Molecular Biology and Evolution,
+        4: 406-425.
+
+        """
+
+        if is_weighted_edge_distances:
+            original_dmatrix = self._taxon_phylogenetic_distances
+        else:
+            original_dmatrix = self._taxon_phylogenetic_path_steps
+        if tree_factory is None:
+            tree_factory = dendropy.Tree
+        tree = tree_factory(taxon_namespace=self.taxon_namespace)
+
+        # initialize node pool
+        node_pool = []
+        for t1 in self._mapped_taxa:
+            nd = tree.node_factory()
+            nd.taxon = t1
+            nd._nj_distances = {}
+            node_pool.append(nd)
+
+        # initialize factor
+        n = len(self._mapped_taxa)
+
+        # cache calculations
+        for nd1 in node_pool:
+            nd1._nj_xsub = 0.0
+            for nd2 in node_pool:
+                if nd1 is nd2:
+                    continue
+                d = original_dmatrix[nd1.taxon][nd2.taxon]
+                nd1._nj_distances[nd2] = d
+                nd1._nj_xsub += d
+
+        while n > 1:
+
+            # calculate the Q-matrix
+            min_q = None
+            nodes_to_join = None
+            for idx1, nd1 in enumerate(node_pool[:-1]):
+                for idx2, nd2 in enumerate(node_pool[idx1+1:]):
+                    v1 = (n - 2) * nd1._nj_distances[nd2]
+                    qvalue = v1 - nd1._nj_xsub - nd2._nj_xsub
+                    if min_q is None or qvalue < min_q:
+                        min_q = qvalue
+                        nodes_to_join = (nd1, nd2)
+
+            # create the new node
+            new_node = tree.node_factory()
+
+            # attach it to the tree
+            for node_to_join in nodes_to_join:
+                new_node.add_child(node_to_join)
+                node_pool.remove(node_to_join)
+
+            # calculate the distances for the new node
+            new_node._nj_distances = {}
+            new_node._nj_xsub = 0.0
+            for node in node_pool:
+                # actual node-to-node distances
+                v1 = 0.0
+                for node_to_join in nodes_to_join:
+                    v1 += node._nj_distances[node_to_join]
+                v3 = nodes_to_join[0]._nj_distances[nodes_to_join[1]]
+                dist = 0.5 * (v1 - v3)
+                new_node._nj_distances[node] = dist
+                node._nj_distances[new_node] = dist
+
+                # Adjust/recalculate the values needed for the Q-matrix
+                # calculations
+                new_node._nj_xsub += dist
+                node._nj_xsub += dist
+                for node_to_join in nodes_to_join:
+                    node._nj_xsub -= node_to_join._nj_distances[node]
+
+            # calculate the branch lengths
+            if n > 2:
+                v1 = 0.5 * nodes_to_join[0]._nj_distances[nodes_to_join[1]]
+                v4  = 1.0/(2*(n-2)) * (nodes_to_join[0]._nj_xsub - nodes_to_join[1]._nj_xsub)
+                delta_f = v1 + v4
+                delta_g = nodes_to_join[0]._nj_distances[nodes_to_join[1]] - delta_f
+                nodes_to_join[0].edge.length = delta_f
+                nodes_to_join[1].edge.length = delta_g
+            else:
+                d = nodes_to_join[0]._nj_distances[nodes_to_join[1]]
+                nodes_to_join[0].edge.length = d / 2
+                nodes_to_join[1].edge.length = d / 2
+
+            # clean up
+            for node_to_join in nodes_to_join:
+                del node_to_join._nj_distances
+                del node_to_join._nj_xsub
+
+            # add the new node to the pool of nodes
+            node_pool.append(new_node)
+
+            # adjust count
+            n -= 1
+
+        tree.seed_node = node_pool[0]
+        del tree.seed_node._nj_distances
+        del tree.seed_node._nj_xsub
+        return tree
+
+    def upgma_tree(self,
+            is_weighted_edge_distances=True,
+            tree_factory=None,
+            ):
+        """
+        Returns an Unweighted Pair Group Method with Arithmetic Mean (UPGMA) tree
+        based on the distances in the matrix.
+
+        Parameters
+        ----------
+        is_weighted_edge_distances: bool
+            If ``True`` then edge lengths will be considered for distances.
+            Otherwise, just the number of edges.
+
+        Returns
+        -------
+        t : |Tree|
+            A |Tree| instance corresponding to the UPGMA tree
+            for this data.
+
+        Examples
+        --------
+
+        ::
+
+            import dendropy
+
+            # Read data from a CSV file into a PhylogeneticDistanceMatrix
+            # object
+            with open("distance_matrix.csv") as src:
+                pdm = dendropy.PhylogeneticDistanceMatrix.from_csv(
+                        src,
+                        is_first_row_column_names=True,
+                        is_first_column_row_names=True,
+                        is_allow_new_taxa=True,
+                        delimiter=",",
+                        )
+
+            # Calculate the tree
+            upgma_tree = pdm.upgma_tree()
+
+            # Print it
+            print(upgma_tree.as_string("nexus"))
+
+        """
+
+        if is_weighted_edge_distances:
+            original_dmatrix = self._taxon_phylogenetic_distances
+        else:
+            original_dmatrix = self._taxon_phylogenetic_path_steps
+        if tree_factory is None:
+            tree_factory = dendropy.Tree
+        tree = tree_factory(taxon_namespace=self.taxon_namespace)
+        node_pool = []
+        for t1 in self._mapped_taxa:
+            nd = tree.node_factory()
+            nd.taxon = t1
+            nd._upgma_cluster = set([nd])
+            nd._upgma_distance_from_tip = 0.0
+            nd._upgma_distances = {}
+            node_pool.append(nd)
+        for idx1, nd1 in enumerate(node_pool[:-1]):
+            for idx2, nd2 in enumerate(node_pool[idx1+1:]):
+                d = original_dmatrix[nd1.taxon][nd2.taxon]
+                nd1._upgma_distances[nd2] = d
+                nd2._upgma_distances[nd1] = d
+        while len(node_pool) > 1:
+            min_distance = None
+            nodes_to_join = None
+            for idx1, nd1 in enumerate(node_pool[:-1]):
+                for idx2, nd2 in enumerate(node_pool[idx1+1:]):
+                    d = nd1._upgma_distances[nd2]
+                    if min_distance is None or d < min_distance:
+                        nodes_to_join = (nd1, nd2)
+                        min_distance = d
+            new_node = tree.node_factory()
+            new_node._upgma_cluster = set()
+            new_node._upgma_distances = {}
+            elen = min_distance / 2.0
+            for node_to_join in nodes_to_join:
+                new_node.add_child(node_to_join)
+                new_node._upgma_cluster.update(node_to_join._upgma_cluster)
+                node_to_join.edge.length = elen - node_to_join._upgma_distance_from_tip
+                node_pool.remove(node_to_join)
+            new_node._upgma_distance_from_tip = nodes_to_join[0].edge.length + nodes_to_join[0]._upgma_distance_from_tip
+            for idx1, nd1 in enumerate(node_pool):
+                d1 = 0.0
+                count = 0.0
+                for node_to_join in nodes_to_join:
+                    d2 = node_to_join._upgma_distances[nd1]
+                    xc = len(node_to_join._upgma_cluster)
+                    d1 += (d2 * xc)
+                    count += xc
+                d = d1 / count
+                nd1._upgma_distances[new_node] = d
+                new_node._upgma_distances[nd1] = d
+            for node_to_join in nodes_to_join:
+                del node_to_join._upgma_cluster
+                del node_to_join._upgma_distance_from_tip
+                del node_to_join._upgma_distances
+            node_pool.append(new_node)
+        tree.seed_node = node_pool[0]
+        del tree.seed_node._upgma_cluster
+        del tree.seed_node._upgma_distance_from_tip
+        del tree.seed_node._upgma_distances
+        return tree
+
+    def as_data_table(self, is_weighted_edge_distances=True):
+        """
+        Returns this as a table.
+        """
+        if is_weighted_edge_distances:
+            df = self.patristic_distance
+        else:
+            df = self.path_edge_count
+        dt = container.DataTable()
+        for t1 in self._mapped_taxa:
+            dt.add_row(row_name=t1.label)
+            dt.add_column(column_name=t1.label)
+        for t1 in self._mapped_taxa:
+            for t2 in self._mapped_taxa:
+                dt[t1.label, t2.label] = df(t1, t2)
+        return dt
+
+    def write_csv(self,
+            out,
+            is_first_row_column_names=True,
+            is_first_column_row_names=True,
+            is_weighted_edge_distances=True,
+            is_normalize_by_tree_size=True,
+            label_transform_fn=None,
+            **csv_writer_kwargs
+            ):
+        if isinstance(out, str):
+            dest = open(out, "w")
+        else:
+            dest = out
+        if label_transform_fn is None:
+            label_transform_fn = lambda x: x
+        dmatrix, normalization_factor = self._get_distance_matrix_and_normalization_factor(
+                is_weighted_edge_distances=is_weighted_edge_distances,
+                is_normalize_by_tree_size=is_normalize_by_tree_size,
+                )
+        if "delimiter" not in csv_writer_kwargs:
+            csv_writer_kwargs["delimiter"] = ","
+        writer = csv.writer(dest, csv_writer_kwargs)
+        if is_first_row_column_names:
+            row = []
+            if is_first_column_row_names:
+                row.append("")
+            for taxon in self._mapped_taxa:
+                row.append(label_transform_fn(taxon.label))
+            writer.writerow(row)
+            # dest.write(delimiter.join(row))
+            # dest.write("\n")
+        for taxon1 in self._mapped_taxa:
+            row = []
+            if is_first_column_row_names:
+                row.append(label_transform_fn(taxon1.label))
+            for taxon2 in self._mapped_taxa:
+                d = dmatrix[taxon1][taxon2] / normalization_factor
+                row.append("{}".format(d))
+            writer.writerow(row)
+            # dest.write(delimiter.join(row))
+            # dest.write("\n")
+
+    def assemblage_membership_definitions_from_csv(
+            self,
+            src,
+            default_data_type=float,
+            **csv_reader_kwargs):
+        """
+        Convenience method to return list of community sets from a delimited
+        file that lists taxon (labels) in columns and community
+        presence/absences or abundances in rows.
+        """
+        if isinstance(src, str):
+            with open(src) as srcf:
+                data_table = container.DataTable.from_csv(
+                        src,
+                        default_data_type=default_data_type,
+                        **csv_reader_kwargs
+                        )
+        else:
+            data_table = container.DataTable.from_csv(
+                    src,
+                    default_data_type=default_data_type,
+                    **csv_reader_kwargs
+                    )
+        mapped_taxon_labels = set([taxon.label for taxon in self.taxon_iter()])
+        for column_name in data_table.column_name_iter():
+            assert column_name in mapped_taxon_labels
+        assemblage_memberships = collections.OrderedDict()
+        for row_name in data_table.row_name_iter():
+            assemblage_membership = set()
+            for taxon in self.taxon_iter():
+                if data_table[row_name, taxon.label] > 0:
+                    assemblage_membership.add(taxon)
+            assemblage_memberships[row_name] = assemblage_membership
+        return assemblage_memberships
+
+    def _get_taxon_to_all_other_taxa_comparisons(self, filter_fn=None):
+        permutations = collections.defaultdict(list)
+        for taxon1 in self._mapped_taxa:
+            # permutations[taxon1] = []
+            if filter_fn and not filter_fn(taxon1):
+                continue
+            for taxon2 in self._mapped_taxa:
+                if taxon1 is taxon2:
+                    continue
+                if filter_fn and not filter_fn(taxon2):
+                    continue
+                permutations[taxon1].append(taxon2)
+        return permutations
+
+    def _get_distance_matrix_and_normalization_factor(self,
+            is_weighted_edge_distances,
+            is_normalize_by_tree_size):
+        if is_weighted_edge_distances:
+            dmatrix = self._taxon_phylogenetic_distances
+            if is_normalize_by_tree_size:
+                normalization_factor = self._tree_length
+            else:
+                normalization_factor = 1.0
+        else:
+            dmatrix = self._taxon_phylogenetic_path_steps
+            if is_normalize_by_tree_size:
+                normalization_factor = float(self._num_edges)
+            else:
+                normalization_factor = 1.0
+        return dmatrix, normalization_factor
+
+    def _calculate_mean_pairwise_distance(self,
+            comparison_regime,
+            is_weighted_edge_distances,
+            is_normalize_by_tree_size):
+        dmatrix, normalization_factor = self._get_distance_matrix_and_normalization_factor(
+                is_weighted_edge_distances=is_weighted_edge_distances,
+                is_normalize_by_tree_size=is_normalize_by_tree_size,)
+        distances = []
+        for taxon1, taxon2 in comparison_regime:
+            distances.append(dmatrix[taxon1][taxon2])
+        if distances:
+            return (sum(distances) / normalization_factor) / (len(distances) * 1.0)
+        else:
+            raise error.NullAssemblageException("No taxa in assemblage")
+
+    def _calculate_mean_nearest_taxon_distance(self,
+            comparison_regime,
+            is_weighted_edge_distances,
+            is_normalize_by_tree_size):
+        dmatrix, normalization_factor = self._get_distance_matrix_and_normalization_factor(
+                is_weighted_edge_distances=is_weighted_edge_distances,
+                is_normalize_by_tree_size=is_normalize_by_tree_size,)
+        distances = []
+        for taxon1 in comparison_regime:
+            # subdistances = [dmatrix[taxon1][taxon2] for taxon2 in comparison_regime[taxon1]]
+            # distances.append(min(subdistances))
+            min_distance = dmatrix[taxon1][comparison_regime[taxon1][0]]
+            for taxon2 in comparison_regime[taxon1][1:]:
+                d = dmatrix[taxon1][taxon2]
+                if d < min_distance:
+                    min_distance = d
+            distances.append(min_distance)
+        if distances:
+            return (sum(distances) / normalization_factor) / (len(distances) * 1.0)
+        else:
+            raise error.NullAssemblageException("No taxa in assemblage")
+
+    def _calculate_standardized_effect_size(self,
+            statisticf_name,
+            comparison_regimes,
+            is_weighted_edge_distances,
+            is_normalize_by_tree_size,
+            null_model_type="taxa.label",
+            num_randomization_replicates=1000,
+            rng=None):
+        result_type = collections.namedtuple("PhylogeneticCommunityStandardizedEffectSizeStatisticCalculationResult",
+                ["obs", "null_model_mean", "null_model_sd", "z", "rank", "p",])
+        statisticf_kwargs={
+            "is_weighted_edge_distances": is_weighted_edge_distances,
+            "is_normalize_by_tree_size": is_normalize_by_tree_size
+        }
+        observed_stat_values = {}
+        null_model_stat_values = {}
+        null_model_matrix = self.clone()
+        assert null_model_matrix == self
+        if is_weighted_edge_distances:
+            is_shuffle_phylogenetic_distances = True
+            is_shuffle_phylogenetic_path_steps = False
+        else:
+            is_shuffle_phylogenetic_distances = False
+            is_shuffle_phylogenetic_path_steps = True
+        for rep_idx in range(num_randomization_replicates):
+            null_model_matrix.shuffle_taxa(
+                    is_shuffle_phylogenetic_distances=is_shuffle_phylogenetic_distances,
+                    is_shuffle_phylogenetic_path_steps=is_shuffle_phylogenetic_distances,
+                    is_shuffle_mrca=False,
+                    rng=rng)
+            for comparison_regime_idx, comparison_regime in enumerate(comparison_regimes):
+                statisticf_kwargs["comparison_regime"] = comparison_regime
+                if rep_idx == 0:
+                    observed_stat_values[comparison_regime_idx] = getattr(self, statisticf_name)(**statisticf_kwargs)
+                    null_model_stat_values[comparison_regime_idx] = []
+                stat_value = getattr(null_model_matrix, statisticf_name)(**statisticf_kwargs)
+                null_model_stat_values[comparison_regime_idx].append(stat_value)
+        results = []
+        for comparison_regime_idx, comparison_regime in enumerate(comparison_regimes):
+            obs_value = observed_stat_values[comparison_regime_idx]
+            stat_values = null_model_stat_values[comparison_regime_idx]
+            null_model_mean, null_model_var = statistics.mean_and_sample_variance(stat_values)
+            rank = statistics.rank(
+                    value_to_be_ranked=obs_value,
+                    value_providing_rank=stat_values)
+            if null_model_var > 0:
+                null_model_sd = math.sqrt(null_model_var)
+                z = (obs_value - null_model_mean) / null_model_sd
+            else:
+                null_model_sd = 0.0
+                z = None
+            p = float(rank) / len(stat_values)
+            result = result_type(
+                    obs=obs_value,
+                    null_model_mean=null_model_mean,
+                    null_model_sd=null_model_sd,
+                    z=z,
+                    rank=rank,
+                    p=p)
+            results.append(result)
+        return results
+
+class NodeDistanceMatrix(object):
+
+    @classmethod
+    def from_tree(cls, tree):
+        ndm = cls()
+        ndm.compile_from_tree(tree=tree)
+        return ndm
+
+    def __init__(self):
+        self.clear()
+
+    def clear(self):
+        self._tree_length = None
+        self._num_edges = None
+        self._node_phylogenetic_distances = {}
+        self._node_phylogenetic_path_steps = {}
+        self._mrca = {}
+
+    def compile_from_tree(self, tree):
+        self.clear()
+        self._tree_length = 0.0
+        self._num_edges = 0
+        for node1 in tree.postorder_node_iter():
+            try:
+                self._tree_length += node1.edge.length
+            except TypeError: # None for edge length
+                pass
+            self._num_edges += 1
+            if node1 not in self._node_phylogenetic_distances:
+                self._node_phylogenetic_distances[node1] = {node1: 0.0}
+                self._node_phylogenetic_path_steps[node1] = {node1: 0}
+                self._mrca[node1] = {node1: node1}
+            children = node1.child_nodes()
+            for ch_idx, ch1 in enumerate(children):
+                ch1_elen = ch1.edge.length if ch1.edge.length is not None else 0.0
+                for ch1_subtree_node in self._node_phylogenetic_distances[ch1].keys():
+                    if ch1_subtree_node not in self._node_phylogenetic_distances[node1]:
+                        d = self._node_phylogenetic_distances[ch1][ch1_subtree_node] + ch1_elen
+                        d2 = self._node_phylogenetic_path_steps[ch1][ch1_subtree_node] + 1
+                        self._node_phylogenetic_distances[node1][ch1_subtree_node] = d
+                        self._node_phylogenetic_distances[ch1_subtree_node][node1] = d
+                        self._node_phylogenetic_path_steps[node1][ch1_subtree_node] = d2
+                        self._node_phylogenetic_path_steps[ch1_subtree_node][node1] = d2
+                self._node_phylogenetic_distances[node1][ch1] = ch1_elen
+                self._node_phylogenetic_distances[ch1][node1] = ch1_elen
+                self._node_phylogenetic_path_steps[node1][ch1] = 1
+                self._node_phylogenetic_path_steps[ch1][node1] = 1
+                for ch2 in children[ch_idx+1:]:
+                    self._mrca[ch1][ch2] = node1
+                    self._mrca[ch2][ch1] = node1
+                    ch2_elen = ch2.edge.length if ch2.edge.length is not None else 0.0
+                    d = ch1_elen + ch2_elen
+                    self._node_phylogenetic_distances[ch1][ch2] = d
+                    self._node_phylogenetic_distances[ch2][ch1] = d
+                    self._node_phylogenetic_path_steps[ch1][ch2] = 2
+                    self._node_phylogenetic_path_steps[ch2][ch1] = 2
+            # Below is ugly, ugly, ugly. Basic idea is to link nodes of each
+            # the subtrees of each of the child nodes of node1. Assumes
+            # that any pairwise comparison of nodes descending from node1
+            # (as given by nodes in a pairwise comparison with node1) not
+            # already made have their MRCA at node1.
+            for snd1 in self._node_phylogenetic_distances[node1]:
+                for snd2 in self._node_phylogenetic_distances[node1]:
+                    if snd1 is snd2:
+                        continue
+                    if snd1 not in self._node_phylogenetic_distances:
+                        self._node_phylogenetic_distances[snd1] = {}
+                        self._node_phylogenetic_path_steps[snd1] = {}
+                    if snd2 not in self._node_phylogenetic_distances:
+                        self._node_phylogenetic_distances[snd2] = {}
+                        self._node_phylogenetic_path_steps[snd2] = {}
+                    if snd2 not in self._node_phylogenetic_distances[snd1]:
+                        self._node_phylogenetic_distances[snd1][snd2] = self._node_phylogenetic_distances[node1][snd1] + self._node_phylogenetic_distances[node1][snd2]
+                        self._node_phylogenetic_path_steps[snd1][snd2] = self._node_phylogenetic_path_steps[node1][snd1] + self._node_phylogenetic_path_steps[node1][snd2]
+                    if snd1 not in self._node_phylogenetic_distances[snd2]:
+                        self._node_phylogenetic_distances[snd2][snd1] = self._node_phylogenetic_distances[node1][snd1] + self._node_phylogenetic_distances[node1][snd2]
+                        self._node_phylogenetic_path_steps[snd2][snd1] = self._node_phylogenetic_path_steps[node1][snd1] + self._node_phylogenetic_path_steps[node1][snd2]
+                    if snd1 not in self._mrca:
+                        self._mrca[snd1] = {}
+                    if snd2 not in self._mrca:
+                        self._mrca[snd2] = {}
+                    if snd2 not in self._mrca[snd1]:
+                        self._mrca[snd1][snd2] = node1
+                        self._mrca[snd2][snd1] = node1
+
+    def __eq__(self, o):
+        if self.node_namespace is not o.node_namespace:
+            return False
+        return (True
+                and (self._node_phylogenetic_distances == o._node_phylogenetic_distances)
+                and (self._node_phylogenetic_path_steps == o._node_phylogenetic_path_steps)
+                and (self._mrca == o._mrca)
+                and (self._tree_length == o._tree_length)
+                and (self._num_edges == o._num_edges)
+                )
+
+    def __iter__(self):
+        for node in self._node_phylogenetic_distances:
+            yield node
+
+    def __hash__(self):
+        return id(self)
+
+    def __call__(self, node1, node2):
+        return self.patristic_distance(node1, node2)
+
+    def __copy__(self):
+        return self.clone()
+
+    def clone(self):
+        o = self.__class__()
+        o._tree_length = self._tree_length
+        o._num_edges = self._num_edges
+        for src, dest in (
+                (self._node_phylogenetic_distances, o._node_phylogenetic_distances,),
+                (self._node_phylogenetic_path_steps, o._node_phylogenetic_path_steps,),
+                (self._mrca, o._mrca,),
+                ):
+            for t1 in src:
+                dest[t1] = {}
+                for t2 in src[t1]:
+                    dest[t1][t2] = src[t1][t2]
+        return o
+
+    def mrca(self, node1, node2):
+        """
+        Returns MRCA of two node objects.
+        """
+        return self._mrca[node1][node2]
+
+    def distance(self,
+            node1,
+            node2,
+            is_weighted_edge_distances=True,
+            is_normalize_by_tree_size=False):
+        """
+        Returns distance between node1 and node2.
+        """
+        if is_weighted_edge_distances:
+            return self.patristic_distance(node1, node2, is_normalize_by_tree_size=is_normalize_by_tree_size)
+        else:
+            return self.path_edge_count(node1, node2, is_normalize_by_tree_size=is_normalize_by_tree_size)
+
+
+    def patristic_distance(self, node1, node2, is_normalize_by_tree_size=False):
+        """
+        Returns patristic distance between two node objects.
+        """
+        if node1 is node2:
+            return 0.0
+        d = self._node_phylogenetic_distances[node1][node2]
+        if is_normalize_by_tree_size:
+            return d / self._tree_length
+        else:
+            return d
+
+    def path_edge_count(self, node1, node2, is_normalize_by_tree_size=False):
+        """
+        Returns the number of edges between two node objects.
+        """
+        if node1 is node2:
+            return 0
+        d = self._node_phylogenetic_path_steps[node1][node2]
+        if is_normalize_by_tree_size:
+            return float(d) / self._num_edges
+        else:
+            return d
+
+
diff --git a/dendropy/calculate/popgenstat.py b/dendropy/calculate/popgenstat.py
index fc2c9fe..795da98 100644
--- a/dendropy/calculate/popgenstat.py
+++ b/dendropy/calculate/popgenstat.py
@@ -23,6 +23,7 @@ Population genetic statistics.
 import math
 import dendropy
 from dendropy.calculate import probability
+from dendropy.calculate import combinatorics
 
 ###############################################################################
 ## internal functions: generally taking lower-level data, such as sequences etc.
@@ -63,7 +64,14 @@ def _count_differences(char_sequences, state_alphabet, ignore_uncertain=True):
                 if f1 != f2:
                     diff += 1
             sum_diff += float(diff)
-            mean_diff += float(diff) / counted
+            # If counted < 0, this means that there is sites between these sequences
+            # in which both are not ignored: i.e., one or the other has a gap
+            # or an uncertain character. We consider this to mean (maybe
+            # somewhat paradoxically) that there are no sites that are
+            # different between the sequences. Put less paradoxically: there
+            # are no non-ignored sites that are different between the
+            # sequences.
+            mean_diff += (float(diff) / counted) if counted > 0 else float(diff)
             sq_diff += (diff ** 2)
     return sum_diff, mean_diff / comps, sq_diff
 
@@ -85,7 +93,7 @@ def _average_number_of_pairwise_differences(char_sequences, state_alphabet, igno
     sampled.
     """
     sum_diff, mean_diff, sq_diff = _count_differences(char_sequences, state_alphabet, ignore_uncertain)
-    return sum_diff / probability.binomial_coefficient(len(char_sequences), 2)
+    return sum_diff / combinatorics.choose(len(char_sequences), 2)
 
 def _num_segregating_sites(char_sequences, state_alphabet, ignore_uncertain=True):
     """
@@ -228,11 +236,11 @@ class PopulationPairSummaryStatistics(object):
         """
         diffs_x, mean_diffs_x, sq_diff_x = _count_differences(self.pop1_seqs, self.state_alphabet, self.ignore_uncertain)
         diffs_y, mean_diffs_y, sq_diff_y = _count_differences(self.pop2_seqs, self.state_alphabet, self.ignore_uncertain)
-        d_x = diffs_x / probability.binomial_coefficient(len(self.pop1_seqs), 2)
-        d_y = diffs_y / probability.binomial_coefficient(len(self.pop2_seqs), 2)
+        d_x = diffs_x / combinatorics.choose(len(self.pop1_seqs), 2)
+        d_y = diffs_y / combinatorics.choose(len(self.pop2_seqs), 2)
         d_xy = self._average_number_of_pairwise_differences_between_populations()
-        s2_x = (float(sq_diff_x) / probability.binomial_coefficient(len(self.pop1_seqs), 2) ) - (d_x ** 2)
-        s2_y = (float(sq_diff_y) / probability.binomial_coefficient(len(self.pop2_seqs), 2) ) - (d_y ** 2)
+        s2_x = (float(sq_diff_x) / combinatorics.choose(len(self.pop1_seqs), 2) ) - (d_x ** 2)
+        s2_y = (float(sq_diff_y) / combinatorics.choose(len(self.pop2_seqs), 2) ) - (d_y ** 2)
         s2_xy = self._variance_of_pairwise_differences_between_populations(d_xy)
         n = len(self.combined_seqs)
         n_x = float(len(self.pop1_seqs))
diff --git a/dendropy/calculate/probability.py b/dendropy/calculate/probability.py
index e9fe89d..a7c3fae 100644
--- a/dendropy/calculate/probability.py
+++ b/dendropy/calculate/probability.py
@@ -21,32 +21,9 @@ Functions to calculate or draw values from various probability distributions.
 """
 
 import math
+from dendropy.calculate import combinatorics
 from dendropy.utility import GLOBAL_RNG
 
-def factorial(num):
-    """factorial(n): return the factorial of the integer num.
-    factorial(0) = 1
-    factorial(n) with n<0 is -factorial(abs(n))
-    """
-    result = 1
-    for i in range(1, abs(num)+1):
-        result *= i
-    return result
-
-def binomial_coefficient(population, sample):
-    "Returns  ``population`` choose ``sample``."
-    s = max(sample, population - sample)
-    assert s <= population
-    assert population > -1
-    if s == population:
-        return 1
-    numerator = 1
-    denominator = 1
-    for i in range(s+1, population + 1):
-        numerator *= i
-        denominator *= (i - s)
-    return numerator/denominator
-
 def binomial_rv(n, p, rng=None):
     """
     Returns the number of successes in a sample of ``n`` trials, with the
@@ -121,7 +98,7 @@ def poisson_pmf(k, rate):
     with rate parameter, ``rate`` (= 1/mean).
     """
     mean = 1.0/rate
-    return float((mean ** k) * math.exp(-mean))/factorial(k)
+    return float((mean ** k) * math.exp(-mean))/combinatorics.factorial(k)
 
 def sample_multinomial(probs, rng=None):
     """Returns the index of the probability bin in ``probs``.
@@ -305,7 +282,7 @@ def hypergeometric_pmf(x, m, n, k):
 
             p(x) = (choose(m, x) * choose(n, k-x)) / choose(m+n, k)
     """
-    return float(binomial_coefficient(m, x) * binomial_coefficient(n, k-x))/binomial_coefficient(m+n, k)
+    return float(combinatorics.choose(m, x) * combinatorics.choose(n, k-x))/combinatorics.choose(m+n, k)
 
 def hypergeometric_pmf(x, m, n, k):
     """
@@ -317,8 +294,8 @@ def hypergeometric_pmf(x, m, n, k):
     """
     # following fails with 'OverflowError: long int too large to convert to
     # float' with large numbers
-    # return float(binomial_coefficient(m, x) * binomial_coefficient(n, k-x))/binomial_coefficient(m+n, k)
-    a = math.log(binomial_coefficient(m, x))
-    b = math.log(binomial_coefficient(n, k-x))
-    c = math.log(binomial_coefficient(m+n, k))
+    # return float(combinatorics.choose(m, x) * combinatorics.choose(n, k-x))/combinatorics.choose(m+n, k)
+    a = math.log(combinatorics.choose(m, x))
+    b = math.log(combinatorics.choose(n, k-x))
+    c = math.log(combinatorics.choose(m+n, k))
     return math.exp(a+b-c)
diff --git a/dendropy/calculate/statistics.py b/dendropy/calculate/statistics.py
index 0897de5..56432a4 100644
--- a/dendropy/calculate/statistics.py
+++ b/dendropy/calculate/statistics.py
@@ -246,6 +246,16 @@ def variance_covariance(data, population_variance=False):
     # print ""
     return covar
 
+def rank(value_to_be_ranked, value_providing_rank):
+    """
+    Returns the rank of ``value_to_be_ranked`` in set of values, ``values``.
+    Works even if ``values`` is a non-orderable collection (e.g., a set).
+    A binary search would be an optimized way of doing this if we can constrain
+    ``values`` to be an ordered collection.
+    """
+    num_lesser = [v for v in value_providing_rank if v < value_to_be_ranked]
+    return len(num_lesser)
+
 class FishersExactTest(object):
     """
     Given a 2x2 table:
diff --git a/dendropy/calculate/treecompare.py b/dendropy/calculate/treecompare.py
index 28c577a..a2308a1 100644
--- a/dendropy/calculate/treecompare.py
+++ b/dendropy/calculate/treecompare.py
@@ -20,7 +20,8 @@
 Statistics, metrics, measurements, and values calculated *between* *two* trees.
 """
 
-from math import sqrt
+import math
+import collections
 from dendropy.utility import error
 
 ###############################################################################
@@ -33,7 +34,7 @@ def symmetric_difference(tree1, tree2, is_bipartitions_updated=False):
     Trees need to share the same |TaxonNamespace| reference. The
     bipartition bitmasks of the trees must be correct for the current tree
     structures (by calling :meth:`Tree.encode_bipartitions()` method) or the
-    ``is_bipartitions_updated`` argument must be `False` to force recalculation
+    ``is_bipartitions_updated`` argument must be |False| to force recalculation
     of bipartitions.
 
     Parameters
@@ -47,8 +48,8 @@ def symmetric_difference(tree1, tree2, is_bipartitions_updated=False):
         same |TaxonNamespace| reference as ``tree1`` and must have
         bipartitions encoded.
     is_bipartitions_updated : bool
-        If `False`, then the bipartitions on *both* trees will be updated
-        before comparison. If `True` then the bipartitions will only be
+        If |False|, then the bipartitions on *both* trees will be updated
+        before comparison. If |True| then the bipartitions will only be
         calculated for a |Tree| object if they have not been calculated
         before, either explicitly or implicitly.
 
@@ -87,7 +88,7 @@ def symmetric_difference(tree1, tree2, is_bipartitions_updated=False):
 
 def unweighted_robinson_foulds_distance(tree1, tree2, is_bipartitions_updated=False):
     """
-    Alias for `symmetric_difference()`.
+    Alias for ``symmetric_difference()``.
     """
     return symmetric_difference(tree1, tree2, is_bipartitions_updated)
 
@@ -103,7 +104,7 @@ def weighted_robinson_foulds_distance(
     Trees need to share the same |TaxonNamespace| reference. The
     bipartition bitmasks of the trees must be correct for the current tree
     structures (by calling :meth:`Tree.encode_bipartitions()` method) or the
-    ``is_bipartitions_updated`` argument must be `False` to force recalculation of
+    ``is_bipartitions_updated`` argument must be |False| to force recalculation of
     bipartitions.
 
     Parameters
@@ -119,8 +120,8 @@ def weighted_robinson_foulds_distance(
     edge_weight_attr : string
         Name of attribute on edges of trees to be used as the weight.
     is_bipartitions_updated : bool
-        If `True`, then the bipartitions on *both* trees will be updated before
-        comparison. If `False` (default) then the bipartitions will only be
+        If |True|, then the bipartitions on *both* trees will be updated before
+        comparison. If |False| (default) then the bipartitions will only be
         calculated for a |Tree| object if they have not been calculated
         before, either explicitly or implicitly.
 
@@ -171,7 +172,7 @@ def false_positives_and_negatives(
     Trees need to share the same |TaxonNamespace| reference. The
     bipartition bitmasks of the trees must be correct for the current tree
     structures (by calling :meth:`Tree.encode_bipartitions()` method) or the
-    ``is_bipartitions_updated`` argument must be `False` to force recalculation of
+    ``is_bipartitions_updated`` argument must be |False| to force recalculation of
     bipartitions.
 
     Parameters
@@ -185,8 +186,8 @@ def false_positives_and_negatives(
         same |TaxonNamespace| reference as ``tree1`` and must have
         bipartitions encoded.
     is_bipartitions_updated : bool
-        If `True`, then the bipartitions on *both* trees will be updated
-        before comparison. If `False` (default) then the bipartitions
+        If |True|, then the bipartitions on *both* trees will be updated
+        before comparison. If |False| (default) then the bipartitions
         will only be calculated for a |Tree| object if they have not been
         calculated before, either explicitly or implicitly.
 
@@ -246,7 +247,7 @@ def euclidean_distance(
     Trees need to share the same |TaxonNamespace| reference. The
     bipartition bitmasks of the trees must be correct for the current tree
     structures (by calling :meth:`Tree.encode_bipartitions()` method) or the
-    ``is_bipartitions_updated`` argument must be `False` to force recalculation of
+    ``is_bipartitions_updated`` argument must be |False| to force recalculation of
     bipartitions.
 
     Parameters
@@ -262,8 +263,8 @@ def euclidean_distance(
     edge_weight_attr : string
         Name of attribute on edges of trees to be used as the weight.
     is_bipartitions_updated : bool
-        If `True`, then the bipartitions on *both* trees will be updated
-        before comparison. If `False` (default) then the bipartitions
+        If |True|, then the bipartitions on *both* trees will be updated
+        before comparison. If |False| (default) then the bipartitions
         will only be calculated for a |Tree| object if they have not been
         calculated before, either explicitly or implicitly.
 
@@ -293,7 +294,7 @@ def euclidean_distance(
         print(treecompare.euclidean_distance(tree1, tree2))
 
     """
-    df = lambda length_diffs: sqrt(sum([pow(i[0] - i[1], 2) for i in length_diffs]))
+    df = lambda length_diffs: math.sqrt(sum([pow(i[0] - i[1], 2) for i in length_diffs]))
     return _bipartition_difference(tree1,
                            tree2,
                            dist_fn=df,
@@ -309,7 +310,7 @@ def find_missing_bipartitions(reference_tree, comparison_tree, is_bipartitions_u
     Trees need to share the same |TaxonNamespace| reference. The
     bipartition bitmasks of the trees must be correct for the current tree
     structures (by calling :meth:`Tree.encode_bipartitions()` method) or the
-    ``is_bipartitions_updated`` argument must be `False` to force recalculation of
+    ``is_bipartitions_updated`` argument must be |False| to force recalculation of
     bipartitions.
 
     Parameters
@@ -323,8 +324,8 @@ def find_missing_bipartitions(reference_tree, comparison_tree, is_bipartitions_u
         same |TaxonNamespace| reference as ``tree1`` and must have
         bipartitions encoded.
     is_bipartitions_updated : bool
-        If `True`, then the bipartitions on *both* trees will be updated
-        before comparison. If `False` (default) then the bipartitions
+        If |True|, then the bipartitions on *both* trees will be updated
+        before comparison. If |False| (default) then the bipartitions
         will only be calculated for a |Tree| object if they have not been
         calculated before, either explicitly or implicitly.
 
@@ -339,7 +340,7 @@ def find_missing_bipartitions(reference_tree, comparison_tree, is_bipartitions_u
         raise error.TaxonNamespaceIdentityError(reference_tree, comparison_tree)
     if not is_bipartitions_updated:
         reference_tree.encode_bipartitions()
-        comparision_tree.encode_bipartitions()
+        comparison_tree.encode_bipartitions()
     else:
         if reference_tree.bipartition_encoding is None:
             reference_tree.encode_bipartitions()
@@ -352,6 +353,289 @@ def find_missing_bipartitions(reference_tree, comparison_tree, is_bipartitions_u
             missing.append(bipartition)
     return missing
 
+##############################################################################
+### TreeshapeKernel
+
+class TreeShapeKernel(object):
+
+    _TreeShapeKernelNodeCache = collections.namedtuple("_TreeShapeKernelNodeCache",
+            ["production", "index", "edge_lengths", "sum_of_square_edge_lengths"])
+
+    def __init__(self,
+                sigma=1,
+                gauss_factor=1,
+                decay_factor=0.1):
+        """
+        Calculator for tree shape kernel tricking.
+
+        References
+        ----------
+
+        [1] Poon, A. F., Pond, S. L. K., Bennett, P., Richman, D. D., Brown, A.
+        J. L., & Frost, S. D. (2007). Adaptation to human populations is
+        revealed by within-host polymorphisms in HIV-1 and hepatitis C virus.
+        PLoS Pathog, 3(3), e45.
+
+        [2] Poon, A. F., Walker, L. W., Murray, H., McCloskey, R. M., Harrigan,
+        P. R., & Liang, R. H. (2013). Mapping the shapes of phylogenetic trees
+        from human and zoonotic RNA viruses. PLoS one, 8(11), e78122.
+
+        [3] Poon, A. F., Walker, L. W., Murray, H., McCloskey, R. M., Harrigan,
+        P. R., & Liang, R. H. (2013). Mapping the shapes of phylogenetic trees
+        from human and zoonotic RNA viruses. PLoS one, 8(11), e78122.
+
+        [4] Poon, A. F. (2015). Phylodynamic inference with kernel ABC and its
+        application to HIV epidemiology. Molecular biology and evolution,
+        msv123.
+
+        """
+
+        # kernel function
+        self.sigma = sigma
+        self.gauss_factor = gauss_factor
+        self.decay_factor = decay_factor
+
+        # cache management
+        self._tree_cache = {}
+
+    def update_cache(self, tree):
+        """
+        Pre-computes values needed for the kernel trick with this tree and
+        caches them.
+        """
+        current_tree_cache = {}
+        for nd in tree.leaf_node_iter():
+            current_tree_cache[nd] = TreeShapeKernel._TreeShapeKernelNodeCache(
+                    production=0,
+                    index=0,
+                    edge_lengths=None,
+                    sum_of_square_edge_lengths=0)
+            nd.production = 0
+        for nd_idx, nd in enumerate(tree.postorder_internal_node_iter()):
+            nterms = 0
+            edge_lengths = []
+            for ch in nd.child_node_iter():
+                if current_tree_cache[ch].production == 0:
+                    nterms += 1
+                edge_lengths.append(ch.edge.length)
+            production = nterms + 1
+            index = nd_idx
+            sum_of_square_edge_lengths = sum([elen**2 for elen in edge_lengths])
+            current_tree_cache[nd] = TreeShapeKernel._TreeShapeKernelNodeCache(
+                    production=production,
+                    index=index,
+                    edge_lengths=edge_lengths,
+                    sum_of_square_edge_lengths=sum_of_square_edge_lengths)
+        self._tree_cache[tree] = current_tree_cache
+        return current_tree_cache
+
+    def __call__(self,
+            tree1,
+            tree2,
+            is_tree1_cache_updated=False,
+            is_tree2_cache_updated=False,
+            ):
+        """
+        Recursive function for computing tree convolution
+        kernel.
+
+        Parameters
+        ----------
+        tree1 : |Tree| instance
+            First tree to be compared. If it has already been seen by self, its
+            values will have been cached. If the tree has changed since it has been
+            seen by self, it will need to be recached, either explicitly before
+            the calculation by calling 'update_cache' or by specifying
+            'is_tree1_cache_updated=False'
+        tree2 : |Tree| instance
+            Second tree to be compared. If it has already been seen by self, its
+            values will have been cached. If the tree has changed since it has been
+            seen by self, it will need to be recached, either explicitly before
+            the calculation by calling 'update_cache' or by specifying
+            'is_tree2_cache_updated=True'
+        is_tree1_cache_updated : bool
+            If ``tree1`` has not been seen before, then this is ignored as the
+            cache will be updated regardless. If ``tree1`` has been seen, then
+            the cached values representing it will be used unless
+            ``is_tree1_cache_updated`` is ``False``.
+        is_tree2_cache_updated : bool
+            If ``tree1`` has not been seen before, then this is ignored as the
+            cache will be updated regardless. If ``tree1`` has been seen, then
+            the cached values representing it will be used unless
+            ``is_tree1_cache_updated`` is ``False``.
+
+        Acknowledgements
+        ----------------
+
+        Based in part on:
+
+            KAMPHIR
+            https://github.com/ArtPoon/kamphir.git
+            KAMPHIR is written and maintained by: Art F.Y. Poon.
+            With major contributions from: Rosemary McCloskey
+
+        Copyright (c) 2015, Art Poon. All rights reserved.
+        See https://github.com/ArtPoon/kamphir/blob/master/LICENSE.md for
+        more license information.
+
+        Original work adapted from Moschitti (2006) Making tree kernels
+        practical for natural language learning. Proceedings of the
+        11th Conference of the European Chapter of the Association
+        for Computational Linguistics.
+        """
+        internal_nodes2 = list(tree2.postorder_internal_node_iter())
+        k = 0
+        if not is_tree1_cache_updated:
+            tree1_cache = self.update_cache(tree1)
+        else:
+            try:
+                tree1_cache = self._tree_cache[tree1]
+            except KeyError:
+                tree1_cache = self.update_cache(tree1)
+        if not is_tree2_cache_updated:
+            tree2_cache = self.update_cache(tree2)
+        else:
+            try:
+                tree2_cache = self._tree_cache[tree2]
+            except KeyError:
+                tree2_cache = self.update_cache(tree2)
+        dp_matrix = {}
+        for ni, tree1_node in enumerate(tree1.postorder_internal_node_iter()):
+            tree1_cache_node = tree1_cache[tree1_node]
+            for tree2_node in internal_nodes2:
+                tree2_cache_node = tree2_cache[tree2_node]
+                if tree1_cache_node.production != tree2_cache_node.production:
+                    continue
+                res = self.decay_factor * math.exp( -1. / self.gauss_factor
+                    * (tree1_cache_node.sum_of_square_edge_lengths + tree2_cache_node.sum_of_square_edge_lengths - 2*sum([(tree1_cache_node.edge_lengths[i]*tree2_cache_node.edge_lengths[i]) for i in range(len(tree1_cache_node.edge_lengths))])))
+                ## TODO:
+                ##  - (check and) handles cases where unequal number of children
+                ##  - how to handle rotation mismatch problems? or do we assume
+                ##    trees have equal rotations
+                # for node_idx in range(2):
+                #     c1 = tree1_node.clades[node_idx]
+                #     c2 = tree2_node.clades[node_idx]
+                for c1, c2 in zip(tree1_node.child_node_iter(), tree2_node.child_node_iter()):
+                    if tree1_cache[c1].production != tree2_cache[c2].production:
+                        continue
+                    if tree1_cache[c1].production == 0:
+                        # branches are terminal
+                        res *= self.sigma + self.decay_factor
+                    else:
+                        try:
+                            res *= self.sigma + dp_matrix[(tree1_cache[c1].index, tree2_cache[c2].index)]
+                        except KeyError:
+                            res *= self.sigma
+                dp_matrix[(tree1_cache[tree1_node].index, tree2_cache[tree2_node].index)] = res
+                k += res
+        return k
+
+##############################################################################
+### AssemblageInducedTree
+
+class AssemblageInducedTreeManager(object):
+
+    def __init__(self, *args, **kwargs):
+        self.is_exchangeable_assemblage_classifications = kwargs.pop("is_exchangeable_assemblage_classifications", True)
+        self._num_assemblage_classifications = kwargs.pop("num_assemblages", None)
+        self._tree_assemblage_induced_trees_map = {}
+
+    def generate_induced_trees(self, tree, assemblage_leaf_sets):
+        if assemblage_leaf_sets is None:
+            if self._num_assemblage_classifications is not None:
+                raise ValueError("Expecting {} assemblage leaf set classifications, but none provided".format(self._num_assemblage_classifications))
+        else:
+            if self._num_assemblage_classifications is None:
+                self._num_assemblage_classifications = len(assemblage_leaf_sets)
+            elif len(assemblage_leaf_sets) != self._num_assemblage_classifications:
+                    raise ValueError("Expecting {} assemblage leaf set classifications, but only {} specified".format(
+                        self._num_assemblage_classifications,
+                        len(assemblage_leaf_sets)))
+        induced_trees = []
+        for assemblage_leaf_set in assemblage_leaf_sets:
+            node_filter_fn = lambda nd: nd in assemblage_leaf_set
+            induced_tree = tree.extract_tree(
+                               node_filter_fn=node_filter_fn,
+                               is_apply_filter_to_leaf_nodes=True,
+                               is_apply_filter_to_internal_nodes=False)
+            induced_trees.append(induced_tree)
+        self._tree_assemblage_induced_trees_map[tree] = induced_trees
+        return induced_trees
+
+##############################################################################
+### AssemblageInducedTreeShapeKernel
+
+class AssemblageInducedTreeShapeKernel(TreeShapeKernel, AssemblageInducedTreeManager):
+
+    def __init__(self, *args, **kwargs):
+        TreeShapeKernel.__init__(self, *args, **kwargs)
+        AssemblageInducedTreeManager.__init__(self, *args, **kwargs)
+        self._cache_induced_tree_scores = {}
+
+    def update_assemblage_induced_tree_cache(self,
+            tree,
+            assemblage_leaf_sets):
+        self.update_cache(tree=tree)
+        induced_trees = self.generate_induced_trees(tree=tree,
+                assemblage_leaf_sets=assemblage_leaf_sets)
+        # self._cache_induced_tree_scores[tree] = []
+        # for induced_tree1 in induced_trees:
+        #     self.update_cache(tree=induced_tree1)
+        #     s0 = TreeShapeKernel.__call__(self,
+        #             tree1=induced_tree1,
+        #             tree2=tree,
+        #             is_tree1_cache_updated=True,
+        #             is_tree2_cache_updated=True,
+        #             )
+        #     for induced_tree2 in induced_trees:
+        #         s1 = TreeShapeKernel.__call__(self,
+        #                 tree1=induced_tree1,
+        #                 tree2=induced_tree2,
+        #                 is_tree1_cache_updated=True,
+        #                 is_tree2_cache_updated=True,
+        #                 )
+        #         self._cache_induced_tree_scores[tree].append(s1-s0)
+
+    def __call__(self,
+            tree1,
+            tree2,
+            tree1_assemblage_leaf_sets,
+            tree2_assemblage_leaf_sets,
+            is_tree1_cache_updated=False,
+            is_tree2_cache_updated=False,
+            ):
+        score_vector = []
+        main_trees_score = TreeShapeKernel.__call__(self,
+                tree1=tree1,
+                tree2=tree2,
+                is_tree1_cache_updated=is_tree1_cache_updated,
+                is_tree2_cache_updated=is_tree2_cache_updated,
+                )
+        if not is_tree1_cache_updated or tree1 not in self._tree_assemblage_induced_trees_map:
+            self.update_assemblage_induced_tree_cache(
+                    tree=tree1,
+                    assemblage_leaf_sets=tree1_assemblage_leaf_sets)
+        if not is_tree2_cache_updated or tree2 not in self._tree_assemblage_induced_trees_map:
+            self.update_assemblage_induced_tree_cache(
+                    tree=tree2,
+                    assemblage_leaf_sets=tree2_assemblage_leaf_sets)
+        ## ++ main tree score
+        score_vector.append(main_trees_score)
+        induced_trees1 = self._tree_assemblage_induced_trees_map[tree1]
+        induced_trees2 = self._tree_assemblage_induced_trees_map[tree1]
+        assert len(induced_trees1) == len(induced_trees2) == self._num_assemblage_classifications
+        if not self.is_exchangeable_assemblage_classifications:
+            for induced_tree1, induced_tree2 in zip(induced_trees1, induced_trees2):
+                s = TreeShapeKernel.__call__(self,
+                                tree1=induced_tree1,
+                                tree2=induced_tree2,
+                                is_tree1_cache_updated=True,
+                                is_tree2_cache_updated=True,
+                                )
+                ## ++ raw scores direct comparisons of each of the induced trees
+                score_vector.append(s)
+        return score_vector
+
 ###############################################################################
 ## Legacy
 
@@ -433,6 +717,8 @@ def _get_length_diffs(
         except KeyError: # excep
             elen2 = 0.0
         value2 = value_type(elen2) #  ctor + bind # best case
+        # if abs(value2-value1) > 1e-5:
+        #     print("{}: {}, {}".format(bipartition.leafset_as_newick_string(tree1.taxon_namespace), value2, value1))
         length_diffs.append((value1,value2)) # ctor + listappend
         bipartition_length_diffs[bipartition] = length_diffs[-1]
 
diff --git a/dendropy/calculate/treemeasure.py b/dendropy/calculate/treemeasure.py
index add17dc..5416a0f 100644
--- a/dendropy/calculate/treemeasure.py
+++ b/dendropy/calculate/treemeasure.py
@@ -21,134 +21,22 @@ Statistics, metrics, measurements, and values calculated on (single) trees.
 """
 
 import math
+from dendropy.calculate import phylogeneticdistance
 
 EULERS_CONSTANT = 0.5772156649015328606065120900824024310421
 
-class PatristicDistanceMatrix(object):
-    """
-    Calculates and maintains patristic distance information of taxa on a tree.
-    ``max_dist_taxa`` and ``max_dist_nodes`` will return a tuple of taxon objects
-    and corresponding nodes, respectively, that span the greatest path distance
-    in the tree. The mid-point between the two is *guaranteed* to be on the
-    closer to the first item of each pair.
-    """
-
-    def __init__(self, tree=None):
-        self.tree = None
-        self.taxon_namespace = None
-        self._pat_dists = {}
-        self._path_steps = {}
-        self.max_dist = None
-        self.max_dist_taxa = None
-        self.max_dist_nodes = None
-        self._mrca = {}
-        if tree is not None:
-            self.tree = tree
-            self.calc()
-
-    def __call__(self, taxon1, taxon2):
-        """
-        Returns patristic distance between two taxon objects.
-        """
-        if taxon1 is taxon2:
-            return 0.0
-        try:
-            return self._pat_dists[taxon1][taxon2]
-        except KeyError:
-            return self._pat_dists[taxon2][taxon1]
-
-    def mrca(self, taxon1, taxon2):
-        """
-        Returns MRCA of two taxon objects.
-        """
-        if taxon1 is taxon2:
-            return taxon1
-        try:
-            return self._mrca[taxon1][taxon2]
-        except KeyError:
-            return self._mrca[taxon2][taxon1]
-
-    def path_edge_count(self, taxon1, taxon2):
-        """
-        Returns the number of edges between two taxon objects.
-        """
-        if taxon1 is taxon2:
-            return 0
-        try:
-            return self._path_steps[taxon1][taxon2]
-        except KeyError:
-            return self._path_steps[taxon2][taxon1]
-
-    def calc(self, tree=None, create_midpoints=None, is_bipartitions_updated=False):
-        """
-        Calculates the distances. Note that the path length (in number of
-        steps) between taxa that span the root will be off by one if
-        the tree is unrooted.
-        """
-        if tree is not None:
-            self.tree = tree
-        assert self.tree is not None
-        if not is_bipartitions_updated:
-            self.tree.encode_bipartitions()
-        self.taxon_namespace = self.tree.taxon_namespace
-        self._pat_dists = {}
-        self._path_steps = {}
-        for i1, t1 in enumerate(self.taxon_namespace):
-            self._pat_dists[t1] = {}
-            self._path_steps[t1] = {}
-            self._mrca[t1] = {}
-            self.max_dist = None
-            self.max_dist_taxa = None
-            self.max_dist_nodes = None
-
-        for node in self.tree.postorder_node_iter():
-            children = node.child_nodes()
-            if len(children) == 0:
-                node.desc_paths = {node : (0,0)}
-            else:
-                node.desc_paths = {}
-                for cidx1, c1 in enumerate(children):
-                    for desc1, (desc1_plen, desc1_psteps) in c1.desc_paths.items():
-                        node.desc_paths[desc1] = (desc1_plen + c1.edge.length, desc1_psteps + 1)
-                        for c2 in children[cidx1+1:]:
-                            for desc2, (desc2_plen, desc2_psteps) in c2.desc_paths.items():
-                                self._mrca[desc1.taxon][desc2.taxon] = c1.parent_node
-                                pat_dist = node.desc_paths[desc1][0] + desc2_plen + c2.edge.length
-                                self._pat_dists[desc1.taxon][desc2.taxon] = pat_dist
-                                path_steps = node.desc_paths[desc1][1] + desc2_psteps + 1
-                                self._path_steps[desc1.taxon][desc2.taxon] = path_steps
-                                if self.max_dist is None or pat_dist > self.max_dist:
-                                    self.max_dist = pat_dist
-                                    midpoint = float(pat_dist) / 2
-                                    if midpoint - node.desc_paths[desc1][0] <= 0:
-                                        self.max_dist_nodes = (desc1, desc2)
-                                        self.max_dist_taxa = (desc1.taxon, desc2.taxon)
-                                    else:
-                                        self.max_dist_nodes = (desc2, desc1)
-                                        self.max_dist_taxa = (desc2.taxon, desc1.taxon)
-                    del(c1.desc_paths)
-
-    def distances(self):
-        """
-        Returns list of patristic distances.
-        """
-        dists = []
-        for dt in self._pat_dists.values():
-            for d in dt.values():
-                dists.append(d)
-        return dists
+## legacy: will soon be deprecated
+class PatrisiticDistanceMatrix(phylogeneticdistance.PhylogeneticDistanceMatrix):
 
-    def sum_of_distances(self):
-        """
-        Returns sum of patristic distances on tree.
-        """
-        return sum(self.distances())
+    def __init__(self, tree):
+        phylogeneticdistance.PhylogeneticDistanceMatrix.__init__(self)
+        self.compile_from_tree(tree=tree)
 
 def patristic_distance(tree, taxon1, taxon2, is_bipartitions_updated=False):
     """
     Given a tree with bipartitions encoded, and two taxa on that tree, returns the
     patristic distance between the two. Much more inefficient than constructing
-    a PatristicDistanceMatrix object.
+    a PhylogeneticDistanceMatrix object.
     """
     mrca = tree.mrca(taxa=[taxon1, taxon2], is_bipartitions_updated=is_bipartitions_updated)
     dist = 0
diff --git a/dendropy/calculate/treesum.py b/dendropy/calculate/treesum.py
index eb3b57e..4015ba9 100644
--- a/dendropy/calculate/treesum.py
+++ b/dendropy/calculate/treesum.py
@@ -233,9 +233,9 @@ class TreeSummarizer(object):
         result of ``summarization_fn`` applied to the vector of ages of the
         same node on the input trees (in ``split_distribution``, a
         `SplitDistribution` object) being summarized.
-        ``summarization_fn`` should take an iterable of floats, and return a float. If `None`, it
+        ``summarization_fn`` should take an iterable of floats, and return a float. If |None|, it
         defaults to calculating the mean (``lambda x: float(sum(x))/len(x)``).
-        If ``set_edge_lengths`` is `True`, then edge lengths will be set to so that the actual node ages
+        If ``set_edge_lengths`` is |True|, then edge lengths will be set to so that the actual node ages
         correspond to the ``age`` attribute value.
         If ``collapse_negative_edges`` is True, then edge lengths with negative values will be set to 0.
         If ``allow_negative_edges`` is True, then no error will be raised if edges have negative lengths.
@@ -280,7 +280,7 @@ class TreeSummarizer(object):
         lengths of the corresponding edges on the input trees (in
         ``split_distribution``, a `SplitDistribution` object) being
         summarized.
-        ``summarization_fn`` should take an iterable of floats, and return a float. If `None`, it
+        ``summarization_fn`` should take an iterable of floats, and return a float. If |None|, it
         defaults to calculating the mean (``lambda x: float(sum(x))/len(x)``).
         """
         if summarization_fn is None:
diff --git a/dendropy/dataio/fastawriter.py b/dendropy/dataio/fastawriter.py
index 14ff740..10d4efa 100644
--- a/dendropy/dataio/fastawriter.py
+++ b/dendropy/dataio/fastawriter.py
@@ -33,9 +33,9 @@ class FastaWriter(ioservice.DataWriter):
         Keyword Arguments
         -----------------
 
-        wrap: boolean, default: `True`
-            If `False`, then sequences are written out as single, unbroken lines.
-            Defaults to `True`: wraps sequences at 70 colums.
+        wrap: boolean, default: |True|
+            If |False|, then sequences are written out as single, unbroken lines.
+            Defaults to |True|: wraps sequences at 70 colums.
         """
         ioservice.DataWriter.__init__(self)
         self.wrap = kwargs.get("wrap", True)
diff --git a/dendropy/dataio/ioservice.py b/dendropy/dataio/ioservice.py
index 121ffad..055febd 100644
--- a/dendropy/dataio/ioservice.py
+++ b/dendropy/dataio/ioservice.py
@@ -21,6 +21,7 @@ import collections
 import warnings
 from dendropy.datamodel import taxonmodel
 from dendropy.utility import deprecate
+from dendropy.utility import textprocessing
 if not (sys.version_info.major >= 3 and sys.version_info.minor >= 4):
     from dendropy.utility.filesys import pre_py34_open as open
 
@@ -126,7 +127,7 @@ class DataReader(IOService):
             where ``taxon_namespace`` is an existing |TaxonNamespace| object that
             should be used.
 
-            If ``taxon_namespace_factor`` is `None`, then no tree data will be
+            If ``taxon_namespace_factor`` is |None|, then no tree data will be
             parsed.
 
         tree_list_factory : function object
@@ -182,7 +183,7 @@ class DataReader(IOService):
 
                 char_matrix = dataset.new_char_matrix
 
-            If ``char_matrix_factory`` is `None`, then no character data will be
+            If ``char_matrix_factory`` is |None|, then no character data will be
             parsed.
 
         state_alphabet_factory : function object
@@ -192,7 +193,7 @@ class DataReader(IOService):
         global_annotations_target : |Annotable| object
             Any object that will be the target (or subject, in the grammatical
             sense) of general metadata or annotations in the data source. If
-            `None`, then such metadata or annotations will not be stored.
+            |None|, then such metadata or annotations will not be stored.
 
         Returns
         -------
@@ -221,9 +222,9 @@ class DataReader(IOService):
         dataset : |DataSet| object
             The target |DataSet| to populate/build.
         exclude_trees : boolean, default: False
-            If set to `True`, tree data will not be read from the source.
+            If set to |True|, tree data will not be read from the source.
         exclude_chars : boolean, default: False
-            If set to `True`, character data will not be read from the source.
+            If set to |True|, character data will not be read from the source.
 
         """
         if taxon_namespace is not None:
@@ -308,7 +309,7 @@ class DataReader(IOService):
             where ``taxon_namespace`` is an existing |TaxonNamespace| object that
             should be used.
 
-            If ``taxon_namespace_factor`` is `None`, then no tree data will be
+            If ``taxon_namespace_factor`` is |None|, then no tree data will be
             parsed.
 
         tree_list_factory : function object
@@ -345,7 +346,7 @@ class DataReader(IOService):
         global_annotations_target : |Annotable| object
             Any object that will be the target (or subject, in the grammatical
             sense) of general metadata or annotations in the data source. If
-            `None`, then such metadata or annotations will not be stored.
+            |None|, then such metadata or annotations will not be stored.
 
         Returns
         -------
@@ -424,7 +425,7 @@ class DataWriter(IOService):
         global_annotations_target : |Annotable| object
             Any object that will be the source (or subject, in the grammatical
             sense) of general metadata or annotations for the data. If
-            `None`, then such metadata or annotations will not be stored.
+            |None|, then such metadata or annotations will not be stored.
 
         """
         raise NotImplementedError
@@ -443,13 +444,13 @@ class DataWriter(IOService):
         dataset : |DataSet| object
             The |DataSet| to write.
         exclude_trees : boolean, default: False
-            If set to `True`, tree data will not be written to the destination.
+            If set to |True|, tree data will not be written to the destination.
         exclude_chars : boolean, default: False
-            If set to `True`, character data will not be written to the destination.
+            If set to |True|, character data will not be written to the destination.
         global_annotations_target : |Annotable| object
             Any object that will be the source (or subject, in the grammatical
             sense) of general metadata or annotations for the data. If
-            `None`, then such metadata or annotations will not be stored.
+            |None|, then such metadata or annotations will not be stored.
         """
         tree_lists = dataset.tree_lists if not exclude_trees else None
         char_matrices = dataset.char_matrices if not exclude_chars else None
@@ -529,7 +530,7 @@ class DataYielder(IOService):
                 yield item
 
     def iterate_over_file(self, current_file):
-        if isinstance(current_file, str):
+        if textprocessing.is_str_type(current_file):
             self._current_file = open(current_file, "r")
             self._current_file_name = current_file
         else:
diff --git a/dendropy/dataio/newickreader.py b/dendropy/dataio/newickreader.py
index a385b5f..090dbd2 100644
--- a/dendropy/dataio/newickreader.py
+++ b/dendropy/dataio/newickreader.py
@@ -22,12 +22,9 @@ Parsing of NEWICK-format tree from a stream.
 
 import re
 import warnings
-try:
-    from StringIO import StringIO # Python 2 legacy support: StringIO in this module is the one needed (not io)
-except ImportError:
-    from io import StringIO # Python 3
 from dendropy.utility import error
 from dendropy.utility import deprecate
+from dendropy.utility.textprocessing import StringIO
 from dendropy.dataio import tokenizer
 from dendropy.dataio import nexusprocessing
 from dendropy.dataio import ioservice
@@ -143,50 +140,50 @@ class NewickReader(ioservice.DataReader):
             Specifies the type of the edge lengths (``int`` or ``float``). Tokens
             interpreted as branch lengths will be cast to this type.
             Defaults to ``float``.
-        suppress_edge_lengths : boolean, default: `False`
-            If `True`, edge length values will not be processed. If `False`,
+        suppress_edge_lengths : boolean, default: |False|
+            If |True|, edge length values will not be processed. If |False|,
             edge length values will be processed.
-        extract_comment_metadata : boolean, default: `True`
-            If `True` (default), any comments that begin with '&' or '&&' will
+        extract_comment_metadata : boolean, default: |True|
+            If |True| (default), any comments that begin with '&' or '&&' will
             be parsed and stored as part of the annotation set of the
             corresponding object (accessible through the ``annotations``
             attribute of the object). This requires that the comment
             contents conform to a particular format (NHX or BEAST: 'field =
-            value'). If `False`, then the comments will not be parsed,
+            value'). If |False|, then the comments will not be parsed,
             but will be instead stored directly as elements of the ``comments``
             list attribute of the associated object.
-        store_tree_weights : boolean, default: `False`
-            If `True`, process the tree weight (e.g. "[&W 1/2]") comment
-            associated with each tree, if any. Defaults to `False`.
-        encode_splits : boolean, default: `False`
-            If `True`, split hash bitmasks will be calculated and attached to
+        store_tree_weights : boolean, default: |False|
+            If |True|, process the tree weight (e.g. "[&W 1/2]") comment
+            associated with each tree, if any. Defaults to |False|.
+        encode_splits : boolean, default: |False|
+            If |True|, split hash bitmasks will be calculated and attached to
             the edges.
-        finish_node_fn : function object, default: `None`
+        finish_node_fn : function object, default: |None|
             If specified, this function will be applied to each node after
             it has been constructed.
-        case_sensitive_taxon_labels : boolean, default: `False`
-            If `True`, then taxon labels are case sensitive (e.g., "P.regius"
+        case_sensitive_taxon_labels : boolean, default: |False|
+            If |True|, then taxon labels are case sensitive (e.g., "P.regius"
             and "P.REGIUS" wil be treated as different operation taxonomic
             unit concepts). Otherwise, taxon label intepretation will be made
             without regard for case.
-        preserve_underscores : boolean, default: `False`
-            If `True`, unquoted underscores in labels will *not* converted to
-            spaces. Defaults to `False`: all underscores not protected by
+        preserve_underscores : boolean, default: |False|
+            If |True|, unquoted underscores in labels will *not* converted to
+            spaces. Defaults to |False|: all underscores not protected by
             quotes will be converted to spaces.
-        suppress_internal_node_taxa : boolean, default: `True`
-            If `False`, internal node labels will be instantantiated into
-            |Taxon| objects. If `True`, internal node labels
+        suppress_internal_node_taxa : boolean, default: |True|
+            If |False|, internal node labels will be instantantiated into
+            |Taxon| objects. If |True|, internal node labels
             will *not* be instantantiated as strings.
-        suppress_leaf_node_taxa : boolean, default: `False`
-            If `False`, leaf (external) node labels will be instantantiated
-            into |Taxon| objects. If `True`, leaff (external) node
+        suppress_leaf_node_taxa : boolean, default: |False|
+            If |False|, leaf (external) node labels will be instantantiated
+            into |Taxon| objects. If |True|, leaff (external) node
             labels will *not* be instantantiated as strings.
-        terminating_semicolon_required : boolean, default: `True`
-            If `True` [default], then a tree statement that does not end in a
-            semi-colon is an error. If `False`, then no error will be raised.
-        ignore_unrecognized_keyword_arguments : boolean, default: `False`
-            If `True`, then unsupported or unrecognized keyword arguments will
-            not result in an error. Default is `False`: unsupported keyword
+        terminating_semicolon_required : boolean, default: |True|
+            If |True| [default], then a tree statement that does not end in a
+            semi-colon is an error. If |False|, then no error will be raised.
+        ignore_unrecognized_keyword_arguments : boolean, default: |False|
+            If |True|, then unsupported or unrecognized keyword arguments will
+            not result in an error. Default is |False|: unsupported keyword
             arguments will result in an error.
         """
 
@@ -558,7 +555,7 @@ class NewickReader(ioservice.DataReader):
         self._tree_statement_complete = False
         if is_internal_node is None:
             # Initial call using ``seed_node`` does not set ``is_internal_node`` to
-            # `True` or `False`, explicitly, but rather `None`. If this is the
+            # |True| or |False|, explicitly, but rather |None|. If this is the
             # case, the rest of the tree has be constructed, and we simply look
             # at whether there are children or not to determine if it is an
             # internal node. This approach allows for a single-tip tree.
@@ -585,12 +582,16 @@ class NewickReader(ioservice.DataReader):
                 try:
                     nexus_tokenizer.require_next_token()
                 except tokenizer.Tokenizer.UnexpectedEndOfStreamError as e:
-                    message = e.message + ". (Perhaps the terminating semicolon for the tree statement is missing? If so, add a semicolon to the tree statement or specify 'terminating_semicolon_required=False' to allow for missing semicolons)"
-                    raise tokenizer.Tokenizer.UnexpectedEndOfStreamError(
-                            message=message,
-                            line_num=e.line_num,
-                            col_num=e.col_num,
-                            stream=e.stream)
+                    if self.terminating_semicolon_required:
+                        message = e.message + ". (Perhaps the terminating semicolon for the tree statement is missing? If so, add a semicolon to the tree statement or specify 'terminating_semicolon_required=False' to allow for missing semicolons)"
+                        raise tokenizer.Tokenizer.UnexpectedEndOfStreamError(
+                                message=message,
+                                line_num=e.line_num,
+                                col_num=e.col_num,
+                                stream=e.stream)
+                    else:
+                        self._tree_statement_complete = True
+                        break
 
             elif nexus_tokenizer.current_token == ")": #253
                 # closing of parent token
diff --git a/dendropy/dataio/newickwriter.py b/dendropy/dataio/newickwriter.py
index 147d4b9..24ba8cb 100644
--- a/dendropy/dataio/newickwriter.py
+++ b/dendropy/dataio/newickwriter.py
@@ -22,11 +22,8 @@ Writing of Newick-format tree to a stream.
 
 import re
 import warnings
-try:
-    from StringIO import StringIO # Python 2 legacy support: StringIO in this module is the one needed (not io)
-except ImportError:
-    from io import StringIO # Python 3
 from dendropy.utility import error
+from dendropy.utility import textprocessing
 from dendropy.dataio import tokenizer
 from dendropy.dataio import nexusprocessing
 from dendropy.dataio import ioservice
@@ -44,75 +41,75 @@ class NewickWriter(ioservice.DataWriter):
 
         Keyword Arguments
         -----------------
-        suppress_leaf_taxon_labels : boolean, default: `False`
-            If `True`, then taxon labels will not be rendered for leaves.
-            Default is `False`: render leaf taxon labels. See notes below for
+        suppress_leaf_taxon_labels : boolean, default: |False|
+            If |True|, then taxon labels will not be rendered for leaves.
+            Default is |False|: render leaf taxon labels. See notes below for
             details.
-        suppress_leaf_node_labels : boolean, default: `True`
-            If `False`, then node labels (if available) will be printed for
-            leaves. Defaults to `True`: do not render leaf node labels. See
+        suppress_leaf_node_labels : boolean, default: |True|
+            If |False|, then node labels (if available) will be printed for
+            leaves. Defaults to |True|: do not render leaf node labels. See
             notes below for details.
-        suppress_internal_taxon_labels : boolean, default: `False`
-            If `True`, then taxon labels will not be printed for internal
-            nodes. Default is `False`: print taxon labels for internal nodes.
+        suppress_internal_taxon_labels : boolean, default: |False|
+            If |True|, then taxon labels will not be printed for internal
+            nodes. Default is |False|: print taxon labels for internal nodes.
             See notes below for details.
-        suppress_internal_node_labels : boolean, default: `False`
-            If `True`, then node labels will not be printed for internal nodes.
-            Default is `False`: print node labels for internal nodes. See notes
+        suppress_internal_node_labels : boolean, default: |False|
+            If |True|, then node labels will not be printed for internal nodes.
+            Default is |False|: print node labels for internal nodes. See notes
             below for details.
-        suppress_rooting : boolean, default: `False`
-            If `True`, will not write rooting token ('[&R]' or '[&U]').
-            Default is `False`: rooting token will be written.
-        suppress_edge_lengths : boolean, default: `False`
-            If `True`, will not write edge lengths. Default is `False`: edge
+        suppress_rooting : boolean, default: |False|
+            If |True|, will not write rooting token ('[&R]' or '[&U]').
+            Default is |False|: rooting token will be written.
+        suppress_edge_lengths : boolean, default: |False|
+            If |True|, will not write edge lengths. Default is |False|: edge
             lengths will be written.
-        unquoted_underscores : boolean, default: `False`
-            If `True`, labels with underscores will not be quoted, which will
+        unquoted_underscores : boolean, default: |False|
+            If |True|, labels with underscores will not be quoted, which will
             mean that they will be interpreted as spaces if read again ("soft"
-            underscores).  If `False`, then labels with underscores
+            underscores).  If |False|, then labels with underscores
             will be quoted, resulting in "hard" underscores.  Default is
-            `False`.
-        preserve_spaces : boolean, default: `False`
-            If `True`, spaces will not be replaced with underscores in labels
+            |False|.
+        preserve_spaces : boolean, default: |False|
+            If |True|, spaces will not be replaced with underscores in labels
             (which means any labels containing spaces will have to be quoted).
-            Default is `False`: spaces will be converted to underscores.
+            Default is |False|: spaces will be converted to underscores.
             False.
-        store_tree_weights : boolean, default: `False`
-            If `True`, tree weights are written. Default is `False`: tree
+        store_tree_weights : boolean, default: |False|
+            If |True|, tree weights are written. Default is |False|: tree
             weights will not be written.
-        taxon_token_map : boolean or dict or `None`, default: `None`.
-            If not `False` or `None`, a "TRANSLATE" statement will be written
+        taxon_token_map : boolean or dict or |None|, default: |None|.
+            If not |False| or |None|, a "TRANSLATE" statement will be written
             and referenced in tree statements (instead of using the taxon
-            labels). If `True`, then a default translate statement will
+            labels). If |True|, then a default translate statement will
             be used, with tokens given by the taxon indexes. If a dictionary is
             given, then the keys should be |Taxon| objects and the
             values should be the token (strings).
-        suppress_annotations : boolean, default: `True`
-            If `False`, metadata annotations will be written out as special
-            comments. Defaults to `True`: metadata annotations will be ignored.
-        annotations_as_nhx : boolean, default: `False`
-            If `True`, and if ``suppress_annotations`` is `False`, will write
-            annotation as NHX statements. Default is `False`: annotations
+        suppress_annotations : boolean, default: |True|
+            If |False|, metadata annotations will be written out as special
+            comments. Defaults to |True|: metadata annotations will be ignored.
+        annotations_as_nhx : boolean, default: |False|
+            If |True|, and if ``suppress_annotations`` is |False|, will write
+            annotation as NHX statements. Default is |False|: annotations
             will not be written as NHX statements.
-        suppress_item_comments : boolean, default: `True`
-            If `False`, any additional comments associated with trees, nodes,
-            edges, etc. will be written. Default is `True`: comments will be
+        suppress_item_comments : boolean, default: |True|
+            If |False|, any additional comments associated with trees, nodes,
+            edges, etc. will be written. Default is |True|: comments will be
             ignored.
         node_label_element_separator : string, default: ' '
             If both ``suppress_leaf_taxon_labels`` and
-            ``suppress_leaf_node_labels`` are `False`, then this will be the
+            ``suppress_leaf_node_labels`` are |False|, then this will be the
             string used to join them. Defaults to ' ' (space).
-        node_label_compose_fn : function object or `None`, default: `None`
-            If not `None`, should be a function that takes a |Node|
+        node_label_compose_fn : function object or |None|, default: |None|
+            If not |None|, should be a function that takes a |Node|
             object as an argument and returns the string to be used to
             represent the node in the tree statement. The return value from
             this function is used unconditionally to print a node
             representation in a tree statement, by-passing the default
             labelling function, ignoring ``suppress_leaf_taxon_labels``,
             ``suppress_leaf_node_labels=True``, ``suppress_internal_taxon_labels``,
-            ``suppress_internal_node_labels``, etc. Defaults to `None`.
-        edge_label_compose_fn : function object or `None`, default: `None`
-            If not `None`, should be a function that takes an Edge object as
+            ``suppress_internal_node_labels``, etc. Defaults to |None|.
+        edge_label_compose_fn : function object or |None|, default: |None|
+            If not |None|, should be a function that takes an Edge object as
             an argument, and returns the string to be used to represent the
             edge length in the tree statement.
         real_value_format_specifier : string, default: ''
@@ -121,9 +118,9 @@ class NewickWriter(ioservice.DataWriter):
             annotations. The format specifier should be given in Python's
             string format specification mini-language. E.g. ".8f", ".4E",
             "8.4f".
-        ignore_unrecognized_keyword_arguments : boolean, default: `False`
-            If `True`, then unsupported or unrecognized keyword arguments will
-            not result in an error. Default is `False`: unsupported keyword
+        ignore_unrecognized_keyword_arguments : boolean, default: |False|
+            If |True|, then unsupported or unrecognized keyword arguments will
+            not result in an error. Default is |False|: unsupported keyword
             arguments will result in an error.
 
         Notes
@@ -136,7 +133,7 @@ class NewickWriter(ioservice.DataWriter):
         any one node can only be rendered with a single token or symbol. Thus,
         if there is more than one source of label available for a particular
         node (e.g., if both ``suppress_leaf_taxon_labels`` and
-        ``suppress_leaf_node_labels`` are `False`, and a particular leaf
+        ``suppress_leaf_node_labels`` are |False|, and a particular leaf
         node has both a taxon *and* a label associated with it), then
         the node symbol will be rendered as concatenation of the unsuppressed
         candidate labels, with each candidate label separated by the value
@@ -331,7 +328,7 @@ class NewickWriter(ioservice.DataWriter):
     def _compose_comment_string(self, item):
         if not self.suppress_item_comments and item.comments:
             item_comments = []
-            if isinstance(item.comments, str):
+            if textprocessing.is_str_type(item.comments):
                 item.comments = [item.comments]
             for comment in item.comments:
                 item_comments.append("[{}]".format(comment))
diff --git a/dendropy/dataio/newickyielder.py b/dendropy/dataio/newickyielder.py
index ffdefb7..5288cda 100644
--- a/dendropy/dataio/newickyielder.py
+++ b/dendropy/dataio/newickyielder.py
@@ -39,9 +39,8 @@ class NewickTreeDataYielder(ioservice.TreeDataYielder):
         files : iterable of sources
             Iterable of sources, which can either be strings specifying file
             paths or file-like objects open for reading. If a source element is
-            a string (``isinstance(i,str) == True``), then it is assumed to be
-            a path to a file. Otherwise, the source is assumed to be a file-like
-            object.
+            a stringm then it is assumed to be a path to a file. Otherwise, the
+            source is assumed to be a file-like object.
         taxon_namespace : |TaxonNamespace| instance
             The operational taxonomic unit concept namespace to use to manage
             taxon definitions.
diff --git a/dendropy/dataio/nexmlreader.py b/dendropy/dataio/nexmlreader.py
index 2a6fa87..bb876e2 100644
--- a/dendropy/dataio/nexmlreader.py
+++ b/dendropy/dataio/nexmlreader.py
@@ -232,12 +232,12 @@ class NexmlReader(ioservice.DataReader, _AnnotationParser):
 
         default_namespace : str
             Default namespace to use for elements.
-        case_sensitive_taxon_labels: boolean, default: `False`
-            If `True`, then case is respected when matching taxon names.
-            Default is `False`: case is ignored.
-        ignore_unrecognized_keyword_arguments : boolean, default: `False`
-            If `True`, then unsupported or unrecognized keyword arguments will
-            not result in an error. Default is `False`: unsupported keyword
+        case_sensitive_taxon_labels: boolean, default: |False|
+            If |True|, then case is respected when matching taxon names.
+            Default is |False|: case is ignored.
+        ignore_unrecognized_keyword_arguments : boolean, default: |False|
+            If |True|, then unsupported or unrecognized keyword arguments will
+            not result in an error. Default is |False|: unsupported keyword
             arguments will result in an error.
 
         """
diff --git a/dendropy/dataio/nexmlwriter.py b/dendropy/dataio/nexmlwriter.py
index 652ff70..f9a6c33 100644
--- a/dendropy/dataio/nexmlwriter.py
+++ b/dendropy/dataio/nexmlwriter.py
@@ -24,11 +24,7 @@ import json
 import textwrap
 import collections
 from dendropy.dataio import ioservice
-
-try:
-    from StringIO import StringIO # Python 2 legacy support: StringIO in this module is the one needed (not io)
-except ImportError:
-    from io import StringIO # Python 3
+from dendropy.utility.textprocessing import StringIO
 
 ############################################################################
 ## Local Module Methods
@@ -98,17 +94,17 @@ class NexmlWriter(ioservice.DataWriter):
         -----------------
 
         markup_as_sequences : boolean
-            If `True`, then character data will be marked up as sequences
-            instead of individual cells. Defaults to `False`.
-        suppress_unreferenced_taxon_namespaces: boolean, default: `False`
-            If `True`, then when writing |DataSet| objects, any
+            If |True|, then character data will be marked up as sequences
+            instead of individual cells. Defaults to |False|.
+        suppress_unreferenced_taxon_namespaces: boolean, default: |False|
+            If |True|, then when writing |DataSet| objects, any
             |TaxonNamespace| object in the DataSet's ``taxon_namespaces``
             collection will *not* be written as a "TAXA" block if it is not
             referenced by any character matrix (``char_matrices``) or tree list
             (``tree_lists``).
-        ignore_unrecognized_keyword_arguments : boolean, default: `False`
-            If `True`, then unsupported or unrecognized keyword arguments will
-            not result in an error. Default is `False`: unsupported keyword
+        ignore_unrecognized_keyword_arguments : boolean, default: |False|
+            If |True|, then unsupported or unrecognized keyword arguments will
+            not result in an error. Default is |False|: unsupported keyword
             arguments will result in an error.
 
         """
@@ -337,7 +333,7 @@ class NexmlWriter(ioservice.DataWriter):
                         print_count += 1
                 dest.write("\n{}</seq>\n".format(self.indent * (indent_level+3)))
             else:
-                for col_idx, (char_value, cell_char_type, cell_annotations) in enumerate(char_vector.iter_cells()):
+                for col_idx, (char_value, cell_char_type, cell_annotations) in enumerate(char_vector.cell_iter()):
                     parts = []
                     parts.append('%s<cell' % (self.indent*(indent_level+3)))
                     parts.append('char="%s"' % cell_char_type_id_map[ (taxon, col_idx) ])
@@ -592,7 +588,7 @@ class NexmlWriter(ioservice.DataWriter):
         char_type_ids_written = set()
         for taxon in char_matrix:
             char_vector = char_matrix[taxon]
-            for col_idx, (char_value, cell_char_type, cell_annotations) in enumerate(char_vector.iter_cells()):
+            for col_idx, (char_value, cell_char_type, cell_annotations) in enumerate(char_vector.cell_iter()):
                 if cell_char_type is None:
                     if char_matrix.data_type == "continuous":
                         char_type_id, char_type_xml = self._compose_char_type_xml_for_continuous_type(indent_level=indent_level+1)
diff --git a/dendropy/dataio/nexmlyielder.py b/dendropy/dataio/nexmlyielder.py
index f801059..f717b0f 100644
--- a/dendropy/dataio/nexmlyielder.py
+++ b/dendropy/dataio/nexmlyielder.py
@@ -43,9 +43,8 @@ class NexmlTreeDataYielder(
         files : iterable of sources
             Iterable of sources, which can either be strings specifying file
             paths or file-like objects open for reading. If a source element is
-            a string (``isinstance(i,str) == True``), then it is assumed to be
-            a path to a file. Otherwise, the source is assumed to be a file-like
-            object.
+            a string, then it is assumed to be a path to a file. Otherwise, the
+            source is assumed to be a file-like object.
         taxon_namespace : |TaxonNamespace| instance
             The operational taxonomic unit concept namespace to use to manage
             taxon definitions.
diff --git a/dendropy/dataio/nexusprocessing.py b/dendropy/dataio/nexusprocessing.py
index 90e92dc..fca774d 100644
--- a/dendropy/dataio/nexusprocessing.py
+++ b/dendropy/dataio/nexusprocessing.py
@@ -26,6 +26,7 @@ import itertools
 import numbers
 import decimal
 from dendropy.dataio.tokenizer import Tokenizer
+from dendropy.utility import textprocessing
 from dendropy.utility import container
 from dendropy.datamodel import basemodel
 
@@ -221,7 +222,7 @@ class NexusTaxonSymbolMapper(object):
             self.number_taxon_label_map[s] = taxon.label
 
     def add_translate_token(self, token, taxon):
-        if not isinstance(token, str):
+        if not textprocessing.is_str_type(token):
             token = str(token)
         self.token_taxon_map[token] = taxon
 
@@ -232,7 +233,7 @@ class NexusTaxonSymbolMapper(object):
         #     return self.label_taxon_map[symbol]
         # if symbol in self.number_taxon_map:
         #     return self.number_taxon_map[symbol]
-        if not isinstance(symbol, str):
+        if not textprocessing.is_str_type(symbol):
             symbol = str(symbol)
         try:
             return self.token_taxon_map[symbol]
@@ -421,12 +422,12 @@ def format_item_annotations_as_comments(
                    "8.4f". If the annotation has its ``format_specifier``
                    attribute set, then this argument is ignored for rendering
                    that particular annotation unless
-                   ``override_annotation_format_specifier`` is `True`. Defaults to "".
+                   ``override_annotation_format_specifier`` is |True|. Defaults to "".
     ``override_annotation_format_specifier``
                     If the annotation has its ``format_specifier`` attribute set,
                     then this it will be used in preference to the
                     ``real_value_format_specifier`` above unless this argument is
-                    `True`. Defaults to `False`.
+                    |True|. Defaults to |False|.
     """
     if not annotated.annotations:
         return ""
@@ -515,7 +516,7 @@ def group_ranges(L):
     >>> [list(x) for x in group_ranges([1, 2, 3, 5, 6, 8])]
     [[1, 3], [5, 6], [8]]
     """
-    for w, z in itertools.groupby(L, lambda x, y=itertools.count(): next(y)-x):
+    for w, z in itertools.groupby(sorted(L), lambda x, y=itertools.count(): next(y)-x):
         grouped = list(z)
         yield (x for x in [grouped[0], grouped[-1]][:len(grouped)])
 
diff --git a/dendropy/dataio/nexusreader.py b/dendropy/dataio/nexusreader.py
index 7652a13..69e2be8 100644
--- a/dendropy/dataio/nexusreader.py
+++ b/dendropy/dataio/nexusreader.py
@@ -215,76 +215,76 @@ class NexusReader(ioservice.DataReader):
             Specifies the type of the edge lengths (``int`` or ``float``). Tokens
             interpreted as branch lengths will be cast to this type.
             Defaults to ``float``.
-        suppress_edge_lengths : boolean, default: `False`
-            If `True`, edge length values will not be processed. If `False`,
+        suppress_edge_lengths : boolean, default: |False|
+            If |True|, edge length values will not be processed. If |False|,
             edge length values will be processed.
-        extract_comment_metadata : boolean, default: `True`
-            If `True` (default), any comments that begin with '&' or '&&' will
+        extract_comment_metadata : boolean, default: |True|
+            If |True| (default), any comments that begin with '&' or '&&' will
             be parsed and stored as part of the annotation set of the
             corresponding object (accessible through the ``annotations``
             attribute of the object). This requires that the comment
             contents conform to a particular format (NHX or BEAST: 'field =
-            value'). If `False`, then the comments will not be parsed,
+            value'). If |False|, then the comments will not be parsed,
             but will be instead stored directly as elements of the ``comments``
             list attribute of the associated object.
-        store_tree_weights : boolean, default: `False`
-            If `True`, process the tree weight (e.g. "[&W 1/2]") comment
-            associated with each tree, if any. Defaults to `False`.
-        encode_splits : boolean, default: `False`
-            If `True`, split hash bitmasks will be calculated and attached to
+        store_tree_weights : boolean, default: |False|
+            If |True|, process the tree weight (e.g. "[&W 1/2]") comment
+            associated with each tree, if any. Defaults to |False|.
+        encode_splits : boolean, default: |False|
+            If |True|, split hash bitmasks will be calculated and attached to
             the edges.
-        finish_node_fn : function object, default: `None`
+        finish_node_fn : function object, default: |None|
             If specified, this function will be applied to each node after
             it has been constructed.
-        case_sensitive_taxon_labels : boolean, default: `False`
-            If `True`, then taxon labels are case sensitive (e.g., "P.regius"
+        case_sensitive_taxon_labels : boolean, default: |False|
+            If |True|, then taxon labels are case sensitive (e.g., "P.regius"
             and "P.REGIUS" wil be treated as different operation taxonomic
             unit concepts). Otherwise, taxon label intepretation will be made
             without regard for case.
-        preserve_underscores : boolean, default: `False`
-            If `True`, unquoted underscores in labels will *not* converted to
-            spaces. Defaults to `False`: all underscores not protected by
+        preserve_underscores : boolean, default: |False|
+            If |True|, unquoted underscores in labels will *not* converted to
+            spaces. Defaults to |False|: all underscores not protected by
             quotes will be converted to spaces.
-        suppress_internal_node_taxa : boolean, default: `True`
-            If `False`, internal node labels will be instantantiated into
-            |Taxon| objects. If `True`, internal node labels
+        suppress_internal_node_taxa : boolean, default: |True|
+            If |False|, internal node labels will be instantantiated into
+            |Taxon| objects. If |True|, internal node labels
             will *not* be instantantiated as strings.
-        suppress_leaf_node_taxa : boolean, default: `False`
-            If `False`, leaf (external) node labels will be instantantiated
-            into |Taxon| objects. If `True`, leaff (external) node
+        suppress_leaf_node_taxa : boolean, default: |False|
+            If |False|, leaf (external) node labels will be instantantiated
+            into |Taxon| objects. If |True|, leaff (external) node
             labels will *not* be instantantiated as strings.
-        terminating_semicolon_required : boolean, default: `True`
-            If `True` [default], then a tree statement that does not end in a
-            semi-colon is an error. If `False`, then no error will be raised.
+        terminating_semicolon_required : boolean, default: |True|
+            If |True| [default], then a tree statement that does not end in a
+            semi-colon is an error. If |False|, then no error will be raised.
         unconstrained_taxa_accumulation_mode : bool
-            If `True`, then no error is raised even if the number of taxon
+            If |True|, then no error is raised even if the number of taxon
             names defined exceeds the number of declared taxa (as specified by
-            'NTAX'). Defaults to `False`.
+            'NTAX'). Defaults to |False|.
         automatically_substitute_missing_taxa_blocks : bool
-            If `True` then, if a taxon namespace is linked to by title but is
+            If |True| then, if a taxon namespace is linked to by title but is
             not given in the data file, then, if one and exactly one other
             taxon namespace has been given in the data file, this taxon
             namespace will be used; if there are multiple taxon namespaces,
-            then if ``automatically_create_missing_taxa_blocks`` is `True` a
+            then if ``automatically_create_missing_taxa_blocks`` is |True| a
             new taxon namespace will be created, otherwise an error is raised.
-            Default is `False`: if a taxon namespace is linked to by title but
+            Default is |False|: if a taxon namespace is linked to by title but
             is not given in the data file, then an error is raised.
         automatically_create_missing_taxa_blocks : bool
-            If `True` then taxon namespaces linked to by title but not given in
-            the data file will be automatically created. If `False` taxon
+            If |True| then taxon namespaces linked to by title but not given in
+            the data file will be automatically created. If |False| taxon
             namespaces linked to by title but not given in the data file will
             result in error.
         exclude_chars : bool
-            If `False`, then character data will not be read. Defaults to
-            `True`: character data will be read.
+            If |False|, then character data will not be read. Defaults to
+            |True|: character data will be read.
         exclude_trees : bool
-            If `False`, then tree data will not be read. Defaults to
-            `True`: tree data will be read.
+            If |False|, then tree data will not be read. Defaults to
+            |True|: tree data will be read.
         attached_taxon_namespace : |TaxonNamespace|
             Unify all operational taxonomic unit definitions in this namespace.
-        ignore_unrecognized_keyword_arguments : boolean, default: `False`
-            If `True`, then unsupported or unrecognized keyword arguments will
-            not result in an error. Default is `False`: unsupported keyword
+        ignore_unrecognized_keyword_arguments : boolean, default: |False|
+            If |True|, then unsupported or unrecognized keyword arguments will
+            not result in an error. Default is |False|: unsupported keyword
             arguments will result in an error.
         """
 
@@ -352,7 +352,11 @@ class NexusReader(ioservice.DataReader):
         """
         self._taxon_namespace_factory = taxon_namespace_factory
         self._tree_list_factory = tree_list_factory
+        if self._tree_list_factory is None:
+            self.exclude_trees = True
         self._char_matrix_factory = char_matrix_factory
+        if self._char_matrix_factory is None:
+            self.exclude_chars = True
         self._state_alphabet_factory = state_alphabet_factory
         self._global_annotations_target = global_annotations_target
         self._parse_nexus_stream(stream)
@@ -1238,7 +1242,7 @@ class NexusReader(ioservice.DataReader):
         Reads character sequence data substatement until the number of
         character states read is equal to ``self._file_specified_nchar`` (with
         multi-state characters, such as '(AG)' counting as a single
-        state) or, if ``self._interleave`` is `True`, until an EOL is
+        state) or, if ``self._interleave`` is |True|, until an EOL is
         reached.
 
         Given a sequence of characters, with ambiguities denoted by
@@ -1332,7 +1336,7 @@ class NexusReader(ioservice.DataReader):
         Reads character sequence data substatement until the number of
         character states read is equal to ``self._file_specified_nchar`` (with
         multi-state characters, such as '(AG)' counting as a single
-        state) or, if ``self._interleave`` is `True`, until an EOL is
+        state) or, if ``self._interleave`` is |True|, until an EOL is
         reached.
         """
         if self._interleave:
diff --git a/dendropy/dataio/nexuswriter.py b/dendropy/dataio/nexuswriter.py
index 4f07013..6272f64 100644
--- a/dendropy/dataio/nexuswriter.py
+++ b/dendropy/dataio/nexuswriter.py
@@ -21,12 +21,9 @@ Writing data in NEXUS format to an output stream.
 """
 
 import re
-try:
-    from StringIO import StringIO # Python 2 legacy support: StringIO in this module is the one needed (not io)
-except ImportError:
-    from io import StringIO # Python 3
 import warnings
 import collections
+from dendropy.utility import textprocessing
 from dendropy.dataio import ioservice
 from dendropy.dataio import newick
 from dendropy.dataio import nexusprocessing
@@ -45,24 +42,24 @@ class NexusWriter(ioservice.DataWriter):
 
         Keyword Arguments
         -----------------
-        simple : boolean, default: `False`
-            If `True`, write in simple NEXUS format, i.e. in a single "DATA"
+        simple : boolean, default: |False|
+            If |True|, write in simple NEXUS format, i.e. in a single "DATA"
             block, instead of separate "TAXA" and "CHARACTER" blocks.
-        suppress_taxa_blocks: boolean, default: `False`
-            If `True`, do not write a "TAXA" block. Note that this may make the
+        suppress_taxa_blocks: boolean, default: |False|
+            If |True|, do not write a "TAXA" block. Note that this may make the
             file impossible to parse if there are multiple taxon namespaces in
             the data.
-        suppress_unreferenced_taxon_namespaces: boolean, default: `False`
-            If `True`, then when writing |DataSet| objects, any
+        suppress_unreferenced_taxon_namespaces: boolean, default: |False|
+            If |True|, then when writing |DataSet| objects, any
             |TaxonNamespace| object in the DataSet's ``taxon_namespaces``
             collection will *not* be written as a "TAXA" block if it is not
             referenced by any character matrix (``char_matrices``) or tree list
             (``tree_lists``).
-        suppress_block_titles : bool or `None`
-            If `True` then 'TITLE' element to blocks will not be written. Note
+        suppress_block_titles : bool or |None|
+            If |True| then 'TITLE' element to blocks will not be written. Note
             that this may make the file impossible to parse if there are
-            multiple taxon namespaces in the data. If `False`, then the
-            'TITLE' element will always be written. Default is `None`: the
+            multiple taxon namespaces in the data. If |False|, then the
+            'TITLE' element will always be written. Default is |None|: the
             'TITLE' element will only be written if needed because there is
             more than on taxon namespace in the data.
         file_comments: iterable [``str``]
@@ -74,8 +71,8 @@ class NexusWriter(ioservice.DataWriter):
             List of strings to be written after data (e.g., PAUP blocks,
             MrBayes blocks etc.).
         allow_multiline_comments : bool
-            If `False` then comments will be merged into a single string before
-            being written. Default is `True`: each comment element will be
+            If |False| then comments will be merged into a single string before
+            being written. Default is |True|: each comment element will be
             written on its own line.
         continuous_character_state_value_format_fn : function object
             When writing |ContinuousCharacterMatrix| data: a function that
@@ -86,77 +83,77 @@ class NexusWriter(ioservice.DataWriter):
             |StandardCharacterMatrix|): a function that takes a
             standard character state value (i.e., a |StateIdentity| instance)
             and returns the string representation of it.
-        suppress_leaf_taxon_labels : boolean, default: `False`
-            If `True`, then taxon labels will not be rendered for leaves.
-            Default is `False`: render leaf taxon labels. See notes below for
+        suppress_leaf_taxon_labels : boolean, default: |False|
+            If |True|, then taxon labels will not be rendered for leaves.
+            Default is |False|: render leaf taxon labels. See notes below for
             details.
-        suppress_leaf_node_labels : boolean, default: `True`
-            If `False`, then node labels (if available) will be printed for
-            leaves. Defaults to `True`: do not render leaf node labels. See
+        suppress_leaf_node_labels : boolean, default: |True|
+            If |False|, then node labels (if available) will be printed for
+            leaves. Defaults to |True|: do not render leaf node labels. See
             notes below for details.
-        suppress_internal_taxon_labels : boolean, default: `False`
-            If `True`, then taxon labels will not be printed for internal
-            nodes. Default is `False`: print taxon labels for internal nodes.
+        suppress_internal_taxon_labels : boolean, default: |False|
+            If |True|, then taxon labels will not be printed for internal
+            nodes. Default is |False|: print taxon labels for internal nodes.
             See notes below for details.
-        suppress_internal_node_labels : boolean, default: `False`
-            If `True`, then node labels will not be printed for internal nodes.
-            Default is `False`: print node labels for internal nodes. See notes
+        suppress_internal_node_labels : boolean, default: |False|
+            If |True|, then node labels will not be printed for internal nodes.
+            Default is |False|: print node labels for internal nodes. See notes
             below for details.
-        suppress_rooting : boolean, default: `False`
-            If `True`, will not write rooting token ('[&R]' or '[&U]').
-            Default is `False`: rooting token will be written.
-        suppress_edge_lengths : boolean, default: `False`
-            If `True`, will not write edge lengths. Default is `False`: edge
+        suppress_rooting : boolean, default: |False|
+            If |True|, will not write rooting token ('[&R]' or '[&U]').
+            Default is |False|: rooting token will be written.
+        suppress_edge_lengths : boolean, default: |False|
+            If |True|, will not write edge lengths. Default is |False|: edge
             lengths will be written.
-        unquoted_underscores : boolean, default: `False`
-            If `True`, labels with underscores will not be quoted, which will
+        unquoted_underscores : boolean, default: |False|
+            If |True|, labels with underscores will not be quoted, which will
             mean that they will be interpreted as spaces if read again ("soft"
-            underscores).  If `False`, then labels with underscores
+            underscores).  If |False|, then labels with underscores
             will be quoted, resulting in "hard" underscores.  Default is
-            `False`.
-        preserve_spaces : boolean, default: `False`
-            If `True`, spaces will not be replaced with underscores in labels
+            |False|.
+        preserve_spaces : boolean, default: |False|
+            If |True|, spaces will not be replaced with underscores in labels
             (which means any labels containing spaces will have to be quoted).
-            Default is `False`: spaces will be converted to underscores.
+            Default is |False|: spaces will be converted to underscores.
             False.
-        store_tree_weights : boolean, default: `False`
-            If `True`, tree weights are written. Default is `False`: tree
+        store_tree_weights : boolean, default: |False|
+            If |True|, tree weights are written. Default is |False|: tree
             weights will not be written.
-        translate_tree_taxa : boolean or dict or `None`, default: `None`.
-            If `False` or `None`, then a "TRANSLATE" statement will not be
+        translate_tree_taxa : boolean or dict or |None|, default: |None|.
+            If |False| or |None|, then a "TRANSLATE" statement will not be
             used, and tree statements will contain the full taxon labels. If
-            not `False` or `None`, a "TRANSLATE" statement will be written and
+            not |False| or |None|, a "TRANSLATE" statement will be written and
             referenced in tree statements (instead of using the taxon labels).
-            If `True`, then a default translate statement will be used, with
+            If |True|, then a default translate statement will be used, with
             tokens given by the taxon indexes. If a dictionary is given, then
             the keys should be |Taxon| objects and the values should be the
             token (strings).
-        suppress_annotations : boolean, default: `False`
-            If `True`, metadata annotations will be ignored.
-            Defaults to `False`: metadata annotations will be written.
-        annotations_as_nhx : boolean, default: `False`
-            If `True`, and if ``suppress_annotations`` is `False`, will write
-            annotations as NHX statements. Default is `False`: annotations
+        suppress_annotations : boolean, default: |False|
+            If |True|, metadata annotations will be ignored.
+            Defaults to |False|: metadata annotations will be written.
+        annotations_as_nhx : boolean, default: |False|
+            If |True|, and if ``suppress_annotations`` is |False|, will write
+            annotations as NHX statements. Default is |False|: annotations
             will not be written as NHX statements.
-        suppress_item_comments : boolean, default: `False`
-            If `True`: comments will be ignored. Default is `False`: any
+        suppress_item_comments : boolean, default: |False|
+            If |True|: comments will be ignored. Default is |False|: any
             additional comments associated with trees, nodes, edges, etc. will
             be written.
         node_label_element_separator : string, default: ' '
             If both ``suppress_leaf_taxon_labels`` and
-            ``suppress_leaf_node_labels`` are `False`, then this will be the
+            ``suppress_leaf_node_labels`` are |False|, then this will be the
             string used to join them. Defaults to ' ' (space).
-        node_label_compose_fn : function object or `None`, default: `None`
-            If not `None`, should be a function that takes a |Node|
+        node_label_compose_fn : function object or |None|, default: |None|
+            If not |None|, should be a function that takes a |Node|
             object as an argument and returns the string to be used to
             represent the node in the tree statement. The return value from
             this function is used unconditionally to print a node
             representation in a tree statement, by-passing the default
             labelling function, ignoring ``suppress_leaf_taxon_labels``,
             ``suppress_leaf_node_labels=True``, ``suppress_internal_taxon_labels``,
-            ``suppress_internal_node_labels``, etc. Defaults to `None`.
-        edge_label_compose_fn : function object or `None`, default: `None`
-            If not `None`, should be a function that takes an Edge object as
+            ``suppress_internal_node_labels``, etc. Defaults to |None|.
+        edge_label_compose_fn : function object or |None|, default: |None|
+            If not |None|, should be a function that takes an Edge object as
             an argument, and returns the string to be used to represent the
             edge length in the tree statement.
         real_value_format_specifier : string, default: ''
@@ -165,9 +162,9 @@ class NexusWriter(ioservice.DataWriter):
             annotations. The format specifier should be given in Python's
             string format specification mini-language. E.g. ".8f", ".4E",
             "8.4f".
-        ignore_unrecognized_keyword_arguments : boolean, default: `False`
-            If `True`, then unsupported or unrecognized keyword arguments will
-            not result in an error. Default is `False`: unsupported keyword
+        ignore_unrecognized_keyword_arguments : boolean, default: |False|
+            If |True|, then unsupported or unrecognized keyword arguments will
+            not result in an error. Default is |False|: unsupported keyword
             arguments will result in an error.
 
         """
@@ -433,13 +430,13 @@ class NexusWriter(ioservice.DataWriter):
 
     def _write_comments(self, stream, comments):
         if self.allow_multiline_comments:
-            if isinstance(comments, str):
+            if textprocessing.is_str_type(comments):
                 stream.write("[{}]\n".format(comments))
             else:
                 comments = "\n".join([str(c) for c in comments])
                 stream.write("[\n{}\n]\n".format(comments))
         else:
-            if isinstance(comments, str):
+            if textprocessing.is_str_type(comments):
                 comments = comments.replace("\r\n", "\n").replace("\n\r","\n").replace("\r","\n")
                 # comments = re.split(r'[\r\n]+', comments)
                 comments = [c for c in re.split(r'[\r\n]+', comments) if c]
diff --git a/dendropy/dataio/nexusyielder.py b/dendropy/dataio/nexusyielder.py
index aa3ed3b..faa06e8 100644
--- a/dendropy/dataio/nexusyielder.py
+++ b/dendropy/dataio/nexusyielder.py
@@ -23,6 +23,7 @@ Implementation of NEXUS-schema tree iterator.
 import sys
 if not (sys.version_info.major >= 3 and sys.version_info.minor >= 4):
     from dendropy.utility.filesys import pre_py34_open as open
+from dendropy.utility import textprocessing
 from dendropy.dataio import ioservice
 from dendropy.dataio import nexusreader
 from dendropy.dataio import nexusprocessing
diff --git a/dendropy/dataio/phylipreader.py b/dendropy/dataio/phylipreader.py
index 5741d98..873a49a 100644
--- a/dendropy/dataio/phylipreader.py
+++ b/dendropy/dataio/phylipreader.py
@@ -65,29 +65,29 @@ class PhylipReader(ioservice.DataReader):
             A |StateAlphabet| object to be used to manage the alphabet of the
             characters (|StandardCharacterMatrix| **only**).
         strict : bool
-            If `True`, then data is given in 'strict' format, where first 10
+            If |True|, then data is given in 'strict' format, where first 10
             characters are the taxon label and remaining characters are the sequence.
-            Default is `False`: relaxed format, where taxon labels are of
+            Default is |False|: relaxed format, where taxon labels are of
             arbitrary length and separation of sequences are is by one or more (if
-            ``multispace_delimiter`` is `False`) or two or more (if
-            ``multispace_delimiter`` is `True`) spaces.
+            ``multispace_delimiter`` is |False|) or two or more (if
+            ``multispace_delimiter`` is |True|) spaces.
         interleaved : bool
-            If `True`, then data is in interleaved format.
-            Default is `False`: data is non-interleaved.
+            If |True|, then data is in interleaved format.
+            Default is |False|: data is non-interleaved.
         multispace_delimiter: bool
-            If `True` (and ``strict`` is `False`), then at least two spaces are
+            If |True| (and ``strict`` is |False|), then at least two spaces are
             required to delimit taxon label and associated sequence. Default is
-            `False`: one or more spaces delimit taxon label and associated
+            |False|: one or more spaces delimit taxon label and associated
             sequence.
         underscore_to_spaces: bool
-            If `True`, then underscores in taxon labels are converted to
-            spaces. Default is `False`: underscores are not converted.
+            If |True|, then underscores in taxon labels are converted to
+            spaces. Default is |False|: underscores are not converted.
         ignore_invalid_chars : bool
-            If `True` then any invalid characters in sequences will be ignored.
-            Default is `False`: invalid characters result in errors.
-        ignore_unrecognized_keyword_arguments : boolean, default: `False`
-            If `True`, then unsupported or unrecognized keyword arguments will
-            not result in an error. Default is `False`: unsupported keyword
+            If |True| then any invalid characters in sequences will be ignored.
+            Default is |False|: invalid characters result in errors.
+        ignore_unrecognized_keyword_arguments : boolean, default: |False|
+            If |True|, then unsupported or unrecognized keyword arguments will
+            not result in an error. Default is |False|: unsupported keyword
             arguments will result in an error.
         """
         ioservice.DataReader.__init__(self)
diff --git a/dendropy/dataio/phylipwriter.py b/dendropy/dataio/phylipwriter.py
index 864f22f..b0e43aa 100644
--- a/dendropy/dataio/phylipwriter.py
+++ b/dendropy/dataio/phylipwriter.py
@@ -20,10 +20,6 @@
 Implementation of PHYLIP-format data writer.
 """
 
-try:
-    from StringIO import StringIO # Python 2 legacy support: StringIO in this module is the one needed (not io)
-except ImportError:
-    from io import StringIO # Python 3
 from dendropy.dataio import ioservice
 from dendropy.utility import textprocessing
 
@@ -39,25 +35,29 @@ class PhylipWriter(ioservice.DataWriter):
         -----------------
 
         strict : bool
-            If `True`, use 'strict' format, i.e., taxon labels given in
+            If |True|, use 'strict' format, i.e., taxon labels given in
             first 10 characters, followed by sequence starting at character 11.
-            Default is `False`: use 'relaxed' format, with arbitrary-length
+            Default is |False|: use 'relaxed' format, with arbitrary-length
             taxon labels separated from sequences by two or more spaces.
         spaces_to_underscores : bool
-            If `True`, all spaces will be converted to underscores. Default is
-            `False`: spaces will be preserved.
+            If |True|, all spaces will be converted to underscores. Default is
+            |False|: spaces will be preserved.
         force_unique_taxon_labels : bool
-            If `True`, then taxon labels will be modified to avoid duplicate
-            labels. Default is `False`: taxon labels will not be modified.
-        ignore_unrecognized_keyword_arguments : boolean, default: `False`
-            If `True`, then unsupported or unrecognized keyword arguments will
-            not result in an error. Default is `False`: unsupported keyword
+            If |True|, then taxon labels will be modified to avoid duplicate
+            labels. Default is |False|: taxon labels will not be modified.
+        suppress_missing_taxa : bool
+            If |True|, then taxa with zero characters will not be printed
+            Default is |False|: all taxa will be printed
+        ignore_unrecognized_keyword_arguments : boolean, default: |False|
+            If |True|, then unsupported or unrecognized keyword arguments will
+            not result in an error. Default is |False|: unsupported keyword
             arguments will result in an error.
         """
         ioservice.DataWriter.__init__(self, **kwargs)
         self.strict = kwargs.pop("strict", False)
         self.spaces_to_underscores = kwargs.pop("spaces_to_underscores", False)
         self.force_unique_taxon_labels = kwargs.pop("force_unique_taxon_labels", False)
+        self.suppress_missing_taxa = kwargs.pop("suppress_missing_taxa", False)
         self.check_for_unused_keyword_arguments(kwargs)
 
     def _write(self,
@@ -95,11 +95,12 @@ class PhylipWriter(ioservice.DataWriter):
         stream.write("%d %d\n" % (n_seqs, n_sites))
         for taxon in char_matrix.taxon_namespace:
             label = taxon_label_map[taxon]
-            try:
-                seq_vec = char_matrix[taxon]
-            except KeyError:
-                continue
-            stream.write("%s%s%s\n" % ( label.ljust(maxlen), spacer, str(seq_vec.symbols_as_string())))
+            if taxon in char_matrix:
+                seq_vec = char_matrix[taxon].symbols_as_string()
+            else:
+                seq_vec = ""
+            if len(seq_vec) or (not self.suppress_missing_taxa):
+                stream.write("%s%s%s\n" % ( label.ljust(maxlen), spacer, str(seq_vec)))
 
     def get_taxon_label_map(self, taxon_namespace):
         taxon_label_map = {}
diff --git a/dendropy/dataio/xmlprocessing.py b/dendropy/dataio/xmlprocessing.py
index 7f956af..2cff71b 100644
--- a/dendropy/dataio/xmlprocessing.py
+++ b/dendropy/dataio/xmlprocessing.py
@@ -21,10 +21,7 @@ XML-parsing abstraction layer.
 """
 
 from xml.etree import ElementTree
-try:
-    from StringIO import StringIO # Python 2 legacy support: StringIO in this module is the one needed (not io)
-except ImportError:
-    from io import StringIO # Python 3
+from dendropy.utility.textprocessing import StringIO
 
 class XmlNamespaces(object):
 
diff --git a/dendropy/datamodel/basemodel.py b/dendropy/datamodel/basemodel.py
index b6daa67..95db357 100644
--- a/dendropy/datamodel/basemodel.py
+++ b/dendropy/datamodel/basemodel.py
@@ -23,10 +23,8 @@ Infrastructure for phylogenetic data objects.
 import os
 import copy
 import sys
-try:
-    from StringIO import StringIO # Python 2 legacy support: StringIO in this module is the one needed (not io)
-except ImportError:
-    from io import StringIO # Python 3
+import collections
+from dendropy.utility.textprocessing import StringIO
 if not (sys.version_info.major >= 3 and sys.version_info.minor >= 4):
     from dendropy.utility.filesys import pre_py34_open as open
 from dendropy.utility import container
@@ -696,7 +694,7 @@ class Annotable(object):
             ``other``) and ``id(x)`` is found in ``attribute_object_mapper``,
             then in the copy the owner of the attribute is changed to
             ``attribute_object_mapper[id(x)]``.
-            If ``attribute_object_mapper`` is `None` (default), then the
+            If ``attribute_object_mapper`` is |None| (default), then the
             following mapping is automatically inserted: ``id(other): self``.
             That is, any references to ``other`` in any |Annotation|
             object will be remapped to ``self``.  If really no reattribution
@@ -993,8 +991,9 @@ class AnnotationSet(container.OrderedSet):
             return container.OrderedSet.__getitem__(self, name)
         for a in self:
             if a.name == name:
-                return a.value
-        return self.add_new(name, "")
+                return a
+        a = self.add_new(name, "")
+        return a
 
     def __setitem__(self, name, value):
         """
@@ -1368,9 +1367,9 @@ class AnnotationSet(container.OrderedSet):
 
         Returns
         -------
-        results : |AnnotationSet| or `None`
+        results : |AnnotationSet| or |None|
             |AnnotationSet| containing |Annotation| objects that
-            match criteria, or `None` if no matching annotations found.
+            match criteria, or |None| if no matching annotations found.
         """
         results = []
         for a in self:
@@ -1394,9 +1393,9 @@ class AnnotationSet(container.OrderedSet):
 
         Returns
         -------
-        results : |Annotation| or `None`
+        results : |Annotation| or |None|
             First |Annotation| object found that matches criteria, or
-            `None` if no matching annotations found.
+            |None| if no matching annotations found.
         """
         if "default" in kwargs:
             default = kwargs["default"]
@@ -1427,9 +1426,9 @@ class AnnotationSet(container.OrderedSet):
 
         Returns
         -------
-        results : |Annotation| or `None`
+        results : |Annotation| or |None|
             ``value`` of first |Annotation| object found that matches
-            criteria, or `None` if no matching annotations found.
+            criteria, or |None| if no matching annotations found.
         """
         for a in self:
             if a.is_match(name=name):
@@ -1450,7 +1449,7 @@ class AnnotationSet(container.OrderedSet):
 
         Returns
         -------
-        results : |Annotation| or `None`
+        results : |Annotation| or |None|
             ``value`` of first |Annotation| object found that matches
             criteria.
         """
diff --git a/dendropy/datamodel/charmatrixmodel.py b/dendropy/datamodel/charmatrixmodel.py
index 525271a..3c587f4 100644
--- a/dendropy/datamodel/charmatrixmodel.py
+++ b/dendropy/datamodel/charmatrixmodel.py
@@ -23,10 +23,8 @@ Character and character-sequence data structures.
 import warnings
 import copy
 import collections
-try:
-    from StringIO import StringIO # Python 2 legacy support: StringIO in this module is the one needed (not io)
-except ImportError:
-    from io import StringIO # Python 3
+from dendropy.utility.textprocessing import StringIO
+from dendropy.utility import textprocessing
 from dendropy.utility import error
 from dendropy.utility import deprecate
 from dendropy.utility import container
@@ -126,7 +124,7 @@ class CharacterDataSequence(
     ``character_value`` argument, thus allowing for setting of the value,
     character type, and annotation set simultaneously. While iteration over
     character values are available through the standard list iteration
-    interface, the method ``CharacterDataSequence.iter_cells()`` provides for
+    interface, the method ``CharacterDataSequence.cell_iter()`` provides for
     iterating over ``<character-value, character-type,
     character-annotation-set>`` triplets.
 
@@ -257,7 +255,7 @@ class CharacterDataSequence(
 
     next = __next__ # Python 2 legacy support
 
-    def iter_cells(self):
+    def cell_iter(self):
         """
         Iterate over triplets of character values and associated
         |CharacterType| and |AnnotationSet| instances.
@@ -366,7 +364,7 @@ class CharacterDataSequence(
 
     def has_annotations_at(self, idx):
         """
-        Return `True` if character at ``idx`` has metadata annotations.
+        Return |True| if character at ``idx`` has metadata annotations.
 
         Parameters
         ----------
@@ -376,7 +374,7 @@ class CharacterDataSequence(
         Returns
         -------
         b : bool
-            `True` if character at ``idx`` has metadata annotations, `False`
+            |True| if character at ``idx`` has metadata annotations, |False|
             otherwise.
         """
         return not self._character_annotations[idx] is None
@@ -563,16 +561,16 @@ class CharacterMatrix(
 
             - **label** (*str*) -- Name or identifier to be assigned to the new
               object; if not given, will be assigned the one specified in the
-              data source, or `None` otherwise.
+              data source, or |None| otherwise.
             - **taxon_namespace** (|TaxonNamespace|) -- The |TaxonNamespace|
               instance to use to :doc:`manage the taxon names </primer/taxa>`.
               If not specified, a new one will be created.
             - **matrix_offset** (*int*) -- 0-based index of character block or
               matrix in source to be parsed. If not specified then the
               first matrix (offset = 0) is assumed.
-            - **ignore_unrecognized_keyword_arguments** (*bool*) -- If `True`,
+            - **ignore_unrecognized_keyword_arguments** (*bool*) -- If |True|,
               then unsupported or unrecognized keyword arguments will not
-              result in an error. Default is `False`: unsupported keyword
+              result in an error. Default is |False|: unsupported keyword
               arguments will result in an error.
 
         **Optional Schema-Specific Keyword Arguments:**
@@ -700,7 +698,7 @@ class CharacterMatrix(
         values are of type `CharacterDataSequence`, then they are added
         as-is.  Otherwise `CharacterDataSequence` instances are
         created for them. Values may be coerced into types compatible with
-        particular matrices. The classmethod `coerce_values()` will be
+        particular matrices. The classmethod ``coerce_values()`` will be
         called for this.
 
         Examples
@@ -732,9 +730,9 @@ class CharacterMatrix(
             specified, a new one will be created using keyword arguments
             specified by ``kwargs``.
         case_sensitive_taxon_labels : boolean
-            If `True`, matching of string labels specified as keys in ``d`` will
+            If |True|, matching of string labels specified as keys in ``d`` will
             be matched to |Taxon| objects in current taxon namespace
-            with case being respected. If `False`, then case will be ignored.
+            with case being respected. If |False|, then case will be ignored.
         \*\*kwargs : keyword arguments, optional
             Keyword arguments to be passed to constructor of
             |CharacterMatrix| when creating new instance to populate, if
@@ -748,46 +746,18 @@ class CharacterMatrix(
         if char_matrix is None:
             char_matrix = cls(**kwargs)
         for key in source_dict:
-            if isinstance(key, str):
+            if textprocessing.is_str_type(key):
                 taxon = char_matrix.taxon_namespace.require_taxon(key,
                         is_case_sensitive=case_sensitive_taxon_labels)
             else:
                 taxon = key
                 if taxon not in char_matrix.taxon_namespace:
                     char_matrix.taxon_namespace.add_taxon(taxon)
-            s = cls.coerce_values(source_dict[key])
+            s = char_matrix.coerce_values(source_dict[key])
             char_matrix[taxon] = s
         return char_matrix
     from_dict = classmethod(from_dict)
 
-    def coerce_values(cls, values):
-        """
-        Converts elements of ``values`` to type of matrix.
-
-        This method is called by :meth:`CharacterMatrix.from_dict` to create
-        sequences from iterables of values.  This method should be overridden
-        by derived classes to ensure that ``values`` consists of types compatible
-        with the particular type of matrix. For example, a CharacterMatrix type
-        with a fixed state alphabet (such as |DnaCharacterMatrix|) would
-        dereference the string elements of ``values`` to return a list of
-        |StateIdentity| objects corresponding to the symbols represented
-        by the strings.  If there is no value-type conversion done, then
-        ``values`` should be returned as-is. If no value-type conversion is
-        possible (e.g., when the type of a value is dependent on positionaly
-        information), then a TypeError should be raised.
-
-        Parameters
-        ----------
-        values : iterable
-            Iterable of values to be converted.
-
-        Returns
-        -------
-        v : list of values.
-        """
-        return values
-    coerce_values = classmethod(coerce_values)
-
     ###########################################################################
     ### Lifecycle and Identity
 
@@ -990,7 +960,7 @@ class CharacterMatrix(
                 taxon = self.taxon_namespace[key]
             else:
                 raise IndexError(key)
-        elif isinstance(key, str):
+        elif textprocessing.is_str_type(key):
             taxon = self.taxon_namespace.get_taxon(label=key)
             if taxon is None:
                 raise KeyError(key)
@@ -1007,7 +977,7 @@ class CharacterMatrix(
         ----------
         taxon : |Taxon|
             |Taxon| instance with which this sequence is associated.
-        values : iterable or `None`
+        values : iterable or |None|
             An initial set of values with which to populate the new character
             sequence.
 
@@ -1089,8 +1059,8 @@ class CharacterMatrix(
 
     def __contains__(self, key):
         """
-        Returns `True` if a sequence associated with ``key`` is in ``self``, or
-        `False` otherwise.
+        Returns |True| if a sequence associated with ``key`` is in ``self``, or
+        |False| otherwise.
 
         Parameters
         ----------
@@ -1106,7 +1076,7 @@ class CharacterMatrix(
         Returns
         -------
         b : boolean
-            `True` if ``key`` is in ``self``; `False` otherwise.
+            |True| if ``key`` is in ``self``; |False| otherwise.
         """
         return self._taxon_sequence_map.__contains__(key)
 
@@ -1154,6 +1124,36 @@ class CharacterMatrix(
         return self.sequences()
 
     ###########################################################################
+    ### Symbol/alphabet management
+
+    def coerce_values(self, values):
+        """
+        Converts elements of ``values`` to type of matrix.
+
+        This method is called by :meth:`CharacterMatrix.from_dict` to create
+        sequences from iterables of values.  This method should be overridden
+        by derived classes to ensure that ``values`` consists of types compatible
+        with the particular type of matrix. For example, a CharacterMatrix type
+        with a fixed state alphabet (such as |DnaCharacterMatrix|) would
+        dereference the string elements of ``values`` to return a list of
+        |StateIdentity| objects corresponding to the symbols represented
+        by the strings.  If there is no value-type conversion done, then
+        ``values`` should be returned as-is. If no value-type conversion is
+        possible (e.g., when the type of a value is dependent on positionaly
+        information), then a TypeError should be raised.
+
+        Parameters
+        ----------
+        values : iterable
+            Iterable of values to be converted.
+
+        Returns
+        -------
+        v : list of values.
+        """
+        return values
+
+    ###########################################################################
     ### Sequence Access Iteration
 
     def __iter__(self):
@@ -1265,11 +1265,11 @@ class CharacterMatrix(
             A valid value (e.g., a numeric value for continuous characters, or
             a |StateIdentity| for discrete character).
         size : integer or None
-            The size (length) up to which the sequences will be padded. If `None`, then
+            The size (length) up to which the sequences will be padded. If |None|, then
             the maximum (longest) sequence size will be used.
         append : boolean
-            If `True` (default), then new values will be added to the end of
-            each sequence. If `False`, then new values will be inserted to the
+            If |True| (default), then new values will be added to the end of
+            each sequence. If |False|, then new values will be inserted to the
             front of each sequence.
         """
         if size is None:
@@ -1307,11 +1307,11 @@ class CharacterMatrix(
             A valid value (e.g., a numeric value for continuous characters, or
             a |StateIdentity| for discrete character).
         size : integer or None
-            The size (length) up to which the sequences will be padded. If `None`, then
+            The size (length) up to which the sequences will be padded. If |None|, then
             the maximum (longest) sequence size will be used.
         append : boolean
-            If `True` (default), then new values will be added to the end of
-            each sequence. If `False`, then new values will be inserted to the
+            If |True| (default), then new values will be added to the end of
+            each sequence. If |False|, then new values will be inserted to the
             front of each sequence.
         """
         self.fill_taxa()
@@ -1588,7 +1588,7 @@ class CharacterMatrix(
         of columns given by the CharacterSubset, ``character_subset``.
         Note that this new matrix will still reference the same taxon set.
         """
-        if isinstance(character_subset, str):
+        if textprocessing.is_str_type(character_subset):
             if character_subset not in self.character_subsets:
                 raise KeyError(character_subset)
             else:
@@ -1605,7 +1605,7 @@ class CharacterMatrix(
         # clear out character subsets; otherwise all indices will have to be
         # recalculated, which will require some careful and perhaps arbitrary
         # handling of corner cases
-        clone.character_subsets = []
+        clone.character_subsets = container.OrderedCaselessDict()
         # clone.clone_from(self)
         for vec in clone.values():
             for cell_idx in range(len(vec)-1, -1, -1):
@@ -1665,36 +1665,38 @@ class CharacterMatrix(
 ###############################################################################
 ## Specialized Matrices
 
-class ContinuousCharacterMatrix(CharacterMatrix):
-    """
-    Specializes |CharacterMatrix| for continuous data.
+### Continuous Characters ##################################################
 
-    Sequences stored using |ContinuousCharacterDataSequence|, with values of
-    elements assumed to be ``float`` .
+class ContinuousCharacterDataSequence(CharacterDataSequence):
+    """
+    A sequence of continuous character values for a particular taxon or entry
+    in a data matrix. Specializes `CharacterDataSequence` by assuming all
+    values are primitive numerics (i.e., either floats or integers) when
+    copying or representing self.
     """
 
-    class ContinuousCharacterDataSequence(CharacterDataSequence):
+    def symbols_as_list(self):
         """
-        A sequence of continuous character values for a particular taxon or entry
-        in a data matrix. Specializes `CharacterDataSequence` by assuming all
-        values are primitive numerics (i.e., either floats or integers) when
-        copying or representing self.
+        Returns list of string representation of values of this vector.
+
+        Returns
+        -------
+        v : list
+            List of string representation of values making up this vector.
         """
+        return [str(v) for v in self]
 
-        def symbols_as_list(self):
-            """
-            Returns list of string representation of values of this vector.
+    def symbols_as_string(self, sep=" "):
+        # different default
+        return CharacterDataSequence.symbols_as_string(self, sep=sep)
 
-            Returns
-            -------
-            v : list
-                List of string representation of values making up this vector.
-            """
-            return [str(v) for v in self]
+class ContinuousCharacterMatrix(CharacterMatrix):
+    """
+    Specializes |CharacterMatrix| for continuous data.
 
-        def symbols_as_string(self, sep=" "):
-            # different default
-            return CharacterDataSequence.symbols_as_string(self, sep=sep)
+    Sequences stored using |ContinuousCharacterDataSequence|, with values of
+    elements assumed to be ``float`` .
+    """
 
     character_sequence_type = ContinuousCharacterDataSequence
     data_type = "continuous"
@@ -1702,10 +1704,13 @@ class ContinuousCharacterMatrix(CharacterMatrix):
     def __init__(self, *args, **kwargs):
         CharacterMatrix.__init__(self, *args, **kwargs)
 
+### Discrete Characters ##################################################
+
+class DiscreteCharacterDataSequence(CharacterDataSequence):
+    pass
+
 class DiscreteCharacterMatrix(CharacterMatrix):
 
-    class DiscreteCharacterDataSequence(CharacterDataSequence):
-        pass
     character_sequence_type = DiscreteCharacterDataSequence
 
     data_type = "discrete"
@@ -1735,11 +1740,11 @@ class DiscreteCharacterMatrix(CharacterMatrix):
         if taxon not in self:
             self[taxon] = CharacterDataSequence()
         for value in state_symbols:
-            if isinstance(value, str):
+            if textprocessing.is_str_type(value):
                 symbol = value
             else:
                 symbol = str(value)
-            self[taxon].append(CharacterDataCell(value=self.default_symbol_state_map[symbol]))
+            self[taxon].append(self.default_symbol_state_map[symbol])
 
     def remap_to_state_alphabet_by_symbol(self,
             state_alphabet,
@@ -1751,14 +1756,13 @@ class DiscreteCharacterMatrix(CharacterMatrix):
         reassigned to any state alphabet element in ``sa`` that has the same
         symbol. Raises KeyError if no matching symbol can be found.
         """
-        symbol_state_map = state_alphabet.symbol_state_map()
         for vi, vec in enumerate(self._taxon_sequence_map.values()):
             for ci, cell in enumerate(vec):
-                cell.value = symbol_state_map[cell.value.symbol]
+                vec[ci] = state_alphabet[cell.symbol]
         for ct in self.character_types:
-            ct.state_alphabet = state_alphabet
+            if ct is not None:
+                ct.state_alphabet = state_alphabet
         if purge_other_state_alphabets:
-            self.state_alphabets = [state_alphabet]
             self.default_state_alphabet = state_alphabet
 
     def remap_to_default_state_alphabet_by_symbol(self,
@@ -1789,11 +1793,11 @@ class DiscreteCharacterMatrix(CharacterMatrix):
 
         char_indices : iterable of ints
             An iterable of indexes of characters to include (by column). If not
-            given or `None` [default], then all characters are included.
+            given or |None| [default], then all characters are included.
 
         gaps_as_missing : boolean
-            If `True` [default] then gap characters will be treated as missing
-            data values. If `False`, then they will be treated as an additional
+            If |True| [default] then gap characters will be treated as missing
+            data values. If |False|, then they will be treated as an additional
             (fundamental) state.`
 
         Returns
@@ -1851,10 +1855,13 @@ class DiscreteCharacterMatrix(CharacterMatrix):
             taxon_to_state_indices[t] = v
         return taxon_to_state_indices
 
+### Fixed Alphabet Characters ##################################################
+
+class FixedAlphabetCharacterDataSequence(CharacterDataSequence):
+    pass
+
 class FixedAlphabetCharacterMatrix(DiscreteCharacterMatrix):
 
-    class FixedAlphabetCharacterDataSequence(CharacterDataSequence):
-        pass
     character_sequence_type = FixedAlphabetCharacterDataSequence
     data_type = "fixed"
     datatype_alphabet = None
@@ -1864,74 +1871,102 @@ class FixedAlphabetCharacterMatrix(DiscreteCharacterMatrix):
         self.state_alphabets.append(self.__class__.datatype_alphabet)
         self._default_state_alphabet = self.__class__.datatype_alphabet
 
+    def coerce_values(self, values):
+        if self.datatype_alphabet is None:
+            raise ValueError("'datatype_alphabet' not set")
+        return charstatemodel.coerce_to_state_identities(
+                state_alphabet=self.datatype_alphabet,
+                values=values)
+
+### DNA Characters ##################################################
+
+class DnaCharacterDataSequence(FixedAlphabetCharacterDataSequence):
+    pass
+
 class DnaCharacterMatrix(FixedAlphabetCharacterMatrix):
     """
     Specializes |CharacterMatrix| for DNA data.
     """
-    class DnaCharacterDataSequence(FixedAlphabetCharacterMatrix.FixedAlphabetCharacterDataSequence):
-        pass
     character_sequence_type = DnaCharacterDataSequence
     data_type = "dna"
     datatype_alphabet = DNA_STATE_ALPHABET
 
+### RNA Characters ##################################################
+
+class RnaCharacterDataSequence(FixedAlphabetCharacterDataSequence):
+    pass
+
 class RnaCharacterMatrix(FixedAlphabetCharacterMatrix):
     """
     Specializes |CharacterMatrix| for DNA data.
     """
-    class RnaCharacterDataSequence(FixedAlphabetCharacterMatrix.FixedAlphabetCharacterDataSequence):
-        pass
     character_sequence_type = RnaCharacterDataSequence
     data_type = "rna"
     datatype_alphabet = RNA_STATE_ALPHABET
 
+### Nucleotide Characters ##################################################
+
+class NucleotideCharacterDataSequence(FixedAlphabetCharacterDataSequence):
+    pass
+
 class NucleotideCharacterMatrix(FixedAlphabetCharacterMatrix):
     """
     Specializes |CharacterMatrix| for RNA data.
     """
-    class NucleotideCharacterDataSequence(FixedAlphabetCharacterMatrix.FixedAlphabetCharacterDataSequence):
-        pass
     character_sequence_type = NucleotideCharacterDataSequence
     data_type = "nucleotide"
     datatype_alphabet = NUCLEOTIDE_STATE_ALPHABET
 
+### Protein Characters ##################################################
+
+class ProteinCharacterDataSequence(FixedAlphabetCharacterDataSequence):
+    pass
+
 class ProteinCharacterMatrix(FixedAlphabetCharacterMatrix):
     """
     Specializes |CharacterMatrix| for protein or amino acid data.
     """
-    class ProteinCharacterDataSequence(FixedAlphabetCharacterMatrix.FixedAlphabetCharacterDataSequence):
-        pass
     character_sequence_type = ProteinCharacterDataSequence
     data_type = "protein"
     datatype_alphabet = PROTEIN_STATE_ALPHABET
 
+### Restricted Site Characters ##################################################
+
+class RestrictionSitesCharacterDataSequence(FixedAlphabetCharacterDataSequence):
+    pass
+
 class RestrictionSitesCharacterMatrix(FixedAlphabetCharacterMatrix):
     """
     Specializes |CharacterMatrix| for restriction site data.
     """
-    class RestrictionSitesCharacterDataSequence(FixedAlphabetCharacterMatrix.FixedAlphabetCharacterDataSequence):
-        pass
     character_sequence_type = RestrictionSitesCharacterDataSequence
     data_type = "restriction"
     datatype_alphabet = RESTRICTION_SITES_STATE_ALPHABET
 
+### Infinite Sites Characters ##################################################
+
+class InfiniteSitesCharacterDataSequence(FixedAlphabetCharacterDataSequence):
+    pass
+
 class InfiniteSitesCharacterMatrix(FixedAlphabetCharacterMatrix):
     """
     Specializes |CharacterMatrix| for infinite sites data.
     """
-    class InfiniteSitesCharacterDataSequence(FixedAlphabetCharacterMatrix.FixedAlphabetCharacterDataSequence):
-        pass
     character_sequence_type = InfiniteSitesCharacterDataSequence
     data_type = "infinite"
     datatype_alphabet = INFINITE_SITES_STATE_ALPHABET
 
+### Standard Characters ##################################################
+
+class StandardCharacterDataSequence(DiscreteCharacterDataSequence):
+    pass
+
 class StandardCharacterMatrix(DiscreteCharacterMatrix):
     """
     Specializes |CharacterMatrix| for "standard" data (i.e., generic discrete
     character data).
 
     """
-    class StandardCharacterDataSequence(DiscreteCharacterMatrix.DiscreteCharacterDataSequence):
-        pass
     character_sequence_type = StandardCharacterDataSequence
 
     data_type = "standard"
@@ -1954,6 +1989,14 @@ class StandardCharacterMatrix(DiscreteCharacterMatrix):
         if default_state_alphabet is not None:
             self.default_state_alphabet = default_state_alphabet
 
+    def coerce_values(self, values):
+        if self.default_state_alphabet is None:
+            raise ValueError("'default_state_alphabet' not set")
+        return charstatemodel.coerce_to_state_identities(
+                state_alphabet=self.default_state_alphabet,
+                values=values)
+
+
 ###############################################################################
 ## Main Character Matrix Factory Function
 
@@ -1961,6 +2004,7 @@ data_type_matrix_map = {
     'continuous' : ContinuousCharacterMatrix,
     'dna' : DnaCharacterMatrix,
     'rna' : RnaCharacterMatrix,
+    'nucleotide' : NucleotideCharacterMatrix,
     'protein' : ProteinCharacterMatrix,
     'standard' : StandardCharacterMatrix,
     'restriction' : RestrictionSitesCharacterMatrix,
diff --git a/dendropy/datamodel/charstatemodel.py b/dendropy/datamodel/charstatemodel.py
index a29ad57..6af544c 100644
--- a/dendropy/datamodel/charstatemodel.py
+++ b/dendropy/datamodel/charstatemodel.py
@@ -28,6 +28,7 @@ of the state alphabet and state alphabet elements).
 import collections
 import itertools
 from dendropy.datamodel import basemodel
+from dendropy.utility import textprocessing
 from dendropy.utility import container
 
 ###############################################################################
@@ -91,7 +92,7 @@ class StateAlphabet(
         If specified, automatically creates a "no data" ambiguous state,
         represented by the (canonical, or primary) symbol
         "no_data_symbol", which maps to all fundamental states.
-        This will also insert `None` into all symbol look-up maps, which, when
+        This will also insert |None| into all symbol look-up maps, which, when
         dereferenced will return this state. Furthermore, the attribute
         ``self.no_data_symbol`` will return this symbol and ``self.no_data_state``
         will return this state. The 'no data' state will be an ambiguous
@@ -274,7 +275,7 @@ class StateAlphabet(
             been used to refer to any other state, fundamental or otherwise, as
             a primary or synonymous symbol (including implicit synonyms given
             by case-variants if the state alphabet is not case-sensitive).
-            Cannot be blank ("") or `None`.
+            Cannot be blank ("") or |None|.
 
         Returns
         -------
@@ -311,7 +312,7 @@ class StateAlphabet(
             been used to refer to any other state, fundamental or otherwise, as
             a primary or synonymous symbol (including implicit synonyms given
             by case-variants if the state alphabet is not case-sensitive). Can
-            be blank ("") or `None` if there.
+            be blank ("") or |None| if there.
 
         \*\*kwargs : keyword arguments, mandatory
             Exactly one of the following must be specified:
@@ -348,7 +349,7 @@ class StateAlphabet(
             been used to refer to any other state, fundamental or otherwise, as
             a primary or synonymous symbol (including implicit synonyms given
             by case-variants if the state alphabet is not case-sensitive). Can
-            be blank ("") or `None` if there.
+            be blank ("") or |None| if there.
 
         \*\*kwargs : keyword arguments, mandatory
             Exactly one of the following must be specified:
@@ -386,7 +387,7 @@ class StateAlphabet(
             been used to refer to any other state, fundamental or otherwise, as
             a primary or synonymous symbol (including implicit synonyms given
             by case-variants if the state alphabet is not case-sensitive). Can
-            be blank ("") or `None` if there.
+            be blank ("") or |None| if there.
 
         state_denomination : enum
             StateAlphabet.POLYMORPHIC_STATE or StateAlphabet.AMBIGUOUS_STATE
@@ -682,7 +683,7 @@ class StateAlphabet(
     def fundamental_symbol_iter(self, include_synonyms=True):
         """
         Returns an iterator over all symbols (including synonyms, unless
-        ``include_synonyms`` is `False`) that map to fundamental states.
+        ``include_synonyms`` is |False|) that map to fundamental states.
         """
         for state in self.fundamental_state_iter():
             yield state.symbol
@@ -693,7 +694,7 @@ class StateAlphabet(
     def ambiguous_symbol_iter(self, include_synonyms=True):
         """
         Returns an iterator over all symbols (including synonyms, unless
-        ``include_synonyms`` is `False`) that map to ambiguous states.
+        ``include_synonyms`` is |False|) that map to ambiguous states.
         """
         for state in self.ambiguous_state_iter():
             yield state.symbol
@@ -704,7 +705,7 @@ class StateAlphabet(
     def polymorphic_symbol_iter(self, include_synonyms=True):
         """
         Returns an iterator over all symbols (including synonyms, unless
-        ``include_synonyms`` is `False`) that map to polymorphic states.
+        ``include_synonyms`` is |False|) that map to polymorphic states.
         """
         for state in self.polymorphic_state_iter():
             yield state.symbol
@@ -715,7 +716,7 @@ class StateAlphabet(
     def multistate_symbol_iter(self, include_synonyms=True):
         """
         Returns an iterator over all symbols (including synonyms, unless
-        ``include_synonyms`` is `False`) that map to multistate states.
+        ``include_synonyms`` is |False|) that map to multistate states.
         """
         for state in self.multistate_state_iter():
             yield state.symbol
@@ -1033,14 +1034,14 @@ class StateIdentity(
 
     def _is_single_state(self):
         """
-        `True` if a FUNDAMENTAL state.
+        |True| if a FUNDAMENTAL state.
         """
         return self._state_denomination == StateAlphabet.FUNDAMENTAL_STATE
     is_single_state = property(_is_single_state)
 
     def _is_fundamental_state(self):
         """
-        `True` if a FUNDAMENTAL state.
+        |True| if a FUNDAMENTAL state.
         """
         return self._state_denomination == StateAlphabet.FUNDAMENTAL_STATE
     is_fundamental_state = property(_is_fundamental_state)
@@ -1422,4 +1423,19 @@ def new_standard_state_alphabet(
         s.set_state_as_attribute(state, attr_name)
     return s
 
+###############################################################################
+## Convenience Functions
+
+def coerce_to_state_identities(state_alphabet, values):
+    coerced_values = []
+    for v in values:
+        if isinstance(v, StateIdentity):
+            coerced_values.append(v)
+        elif textprocessing.is_str_type(v) or isinstance(v, int):
+            s = state_alphabet[v]
+            coerced_values.append(s)
+        else:
+            raise ValueError(v)
+    return coerced_values
+
 
diff --git a/dendropy/datamodel/datasetmodel.py b/dendropy/datamodel/datasetmodel.py
index a4849ed..19d7b10 100644
--- a/dendropy/datamodel/datasetmodel.py
+++ b/dendropy/datamodel/datasetmodel.py
@@ -23,15 +23,12 @@ that manages collections of |TaxonNamespace|, |TreeList|, and
 """
 
 import warnings
-try:
-    from StringIO import StringIO # Python 2 legacy support: StringIO in this module is the one needed (not io)
-except ImportError:
-    from io import StringIO # Python 3
 import copy
 import sys
 from dendropy.utility import container
 from dendropy.utility import error
 from dendropy.utility import deprecate
+from dendropy.utility import textprocessing
 from dendropy.datamodel import basemodel
 from dendropy.datamodel import taxonmodel
 from dendropy.datamodel import treecollectionmodel
@@ -156,16 +153,16 @@ class DataSet(
 
         **Optional General Keyword Arguments:**
 
-            - **exclude_trees** (*bool*) -- If ``True``, then all tree data in the data
+            - **exclude_trees** (*bool*) -- If |True|, then all tree data in the data
               source will be skipped.
-            - **exclude_chars** (*bool*) -- If ``True``, then all character
+            - **exclude_chars** (*bool*) -- If |True|, then all character
               data in the data source will be skipped.
             - **taxon_namespace** (|TaxonNamespace|) -- The |TaxonNamespace|
               instance to use to :doc:`manage the taxon names </primer/taxa>`.
               If not specified, a new one will be created.
-            - **ignore_unrecognized_keyword_arguments** (*bool*) -- If `True`,
+            - **ignore_unrecognized_keyword_arguments** (*bool*) -- If |True|,
               then unsupported or unrecognized keyword arguments will not
-              result in an error. Default is `False`: unsupported keyword
+              result in an error. Default is |False|: unsupported keyword
               arguments will result in an error.
 
         **Optional Schema-Specific Keyword Arguments:**
@@ -305,19 +302,19 @@ class DataSet(
 
         **Optional General Keyword Arguments:**
 
-            - **exclude_trees** (*bool*) -- If ``True``, then all tree data in the data
+            - **exclude_trees** (*bool*) -- If |True|, then all tree data in the data
               source will be skipped.
-            - **exclude_chars** (*bool*) -- If ``True``, then all character
+            - **exclude_chars** (*bool*) -- If |True|, then all character
               data in the data source will be skipped.
             - **taxon_namespace** (|TaxonNamespace|) -- The |TaxonNamespace|
               instance to use to :doc:`manage the taxon names </primer/taxa>`.
               If not specified, a new one will be created unless the DataSet
               object is in attached taxon namespace mode
-              (``self.attached_taxon_namespace`` is not ``None`` but assigned
+              (``self.attached_taxon_namespace`` is not |None| but assigned
               to a specific |TaxonNamespace| instance).
-            - **ignore_unrecognized_keyword_arguments** (*bool*) -- If `True`,
+            - **ignore_unrecognized_keyword_arguments** (*bool*) -- If |True|,
               then unsupported or unrecognized keyword arguments will not
-              result in an error. Default is `False`: unsupported keyword
+              result in an error. Default is |False|: unsupported keyword
               arguments will result in an error.
 
         **Optional Schema-Specific Keyword Arguments:**
@@ -642,7 +639,7 @@ class DataSet(
                     repr(self.attached_taxon_namespace), repr(kwargs["taxon_namespace"])))
             else:
                 kwargs["taxon_namespace"] = self.attached_taxon_namespace
-        if isinstance(char_matrix_type, str):
+        if textprocessing.is_str_type(char_matrix_type):
             char_matrix = charmatrixmodel.new_char_matrix(
                     data_type=char_matrix_type,
                     *args,
diff --git a/dendropy/datamodel/taxonmodel.py b/dendropy/datamodel/taxonmodel.py
index 70ade01..687eba2 100644
--- a/dendropy/datamodel/taxonmodel.py
+++ b/dendropy/datamodel/taxonmodel.py
@@ -78,10 +78,7 @@ be related through correct interpretation of their taxon labels.
 import warnings
 import collections
 import copy
-try:
-    from StringIO import StringIO # Python 2 legacy support: StringIO in this module is the one needed (not io)
-except ImportError:
-    from io import StringIO # Python 3
+from dendropy.utility.textprocessing import StringIO
 from dendropy.datamodel import basemodel
 from dendropy.utility import bitprocessing
 from dendropy.utility import textprocessing
@@ -227,7 +224,7 @@ class TaxonNamespaceAssociated(object):
         concept namespace scope.
 
         Current :attr:`self.taxon_namespace` value will be replaced with value
-        given in ``taxon_namespace`` if this is not `None`, or a new
+        given in ``taxon_namespace`` if this is not |None|, or a new
         |TaxonNamespace| object. Following this,
         ``reconstruct_taxon_namespace()`` will be called: each distinct
         |Taxon| object associated with ``self`` or members of ``self`` that
@@ -239,14 +236,14 @@ class TaxonNamespaceAssociated(object):
 
         Label mapping case sensitivity follows the
         ``self.taxon_namespace.is_case_sensitive`` setting. If
-        `False` and ``unify_taxa_by_label`` is also `True`, then the
+        |False| and ``unify_taxa_by_label`` is also |True|, then the
         establishment of correspondence between |Taxon| objects in the
         old and new namespaces with be based on case-insensitive matching of
         labels. E.g., if there are four |Taxon| objects with labels
         'Foo', 'Foo', 'FOO', and 'FoO' in the old namespace, then all objects
         that reference these will reference a single new |Taxon| object
         in the new namespace (with a label some existing casing variant of
-        'foo'). If `True`: if ``unify_taxa_by_label`` is `True`,
+        'foo'). If |True|: if ``unify_taxa_by_label`` is |True|,
         |Taxon| objects with labels identical except in case will be
         considered distinct.
 
@@ -257,10 +254,10 @@ class TaxonNamespaceAssociated(object):
             will be moved.
 
         unify_taxa_by_label : boolean, optional
-            If `True`, then references to distinct |Taxon| objects with
+            If |True|, then references to distinct |Taxon| objects with
             identical labels in the current namespace will be replaced with a
             reference to a single |Taxon| object in the new namespace.
-            If `False`: references to distinct |Taxon| objects will
+            If |False|: references to distinct |Taxon| objects will
             remain distinct, even if the labels are the same.
 
         taxon_mapping_memo : dictionary
@@ -325,14 +322,14 @@ class TaxonNamespaceAssociated(object):
 
         Label mapping case sensitivity follows the
         ``self.taxon_namespace.is_case_sensitive`` setting. If
-        `False` and ``unify_taxa_by_label`` is also `True`, then the
+        |False| and ``unify_taxa_by_label`` is also |True|, then the
         establishment of correspondence between |Taxon| objects in the
         old and new namespaces with be based on case-insensitive matching of
         labels. E.g., if there are four |Taxon| objects with labels
         'Foo', 'Foo', 'FOO', and 'FoO' in the old namespace, then all objects
         that reference these will reference a single new |Taxon| object
         in the new namespace (with a label some existing casing variant of
-        'foo'). If `True`: if ``unify_taxa_by_label`` is `True`,
+        'foo'). If |True|: if ``unify_taxa_by_label`` is |True|,
         |Taxon| objects with labels identical except in case will be
         considered distinct.
 
@@ -346,10 +343,10 @@ class TaxonNamespaceAssociated(object):
         Parameters
         ----------
         unify_taxa_by_label : boolean, optional
-            If `True`, then references to distinct |Taxon| objects with
+            If |True|, then references to distinct |Taxon| objects with
             identical labels in the current namespace will be replaced with a
             reference to a single |Taxon| object in the new namespace.
-            If `False`: references to distinct |Taxon| objects will
+            If |False|: references to distinct |Taxon| objects will
             remain distinct, even if the labels are the same.
 
         taxon_mapping_memo : dictionary
@@ -461,11 +458,11 @@ class TaxonNamespace(
         \*\*kwargs : keyword arguments
             label : string
                 The label or name for this namespace.
-            is_mutable : boolean, optional (default = `True`)
-                If `True` (default), then |Taxon| objects can be added to this
-                namespace. If `False`, then adding |Taxon| objects will result
+            is_mutable : boolean, optional (default = |True|)
+                If |True| (default), then |Taxon| objects can be added to this
+                namespace. If |False|, then adding |Taxon| objects will result
                 in an error.
-            is_case_sensitive : boolean, optional (default = `False`)
+            is_case_sensitive : boolean, optional (default = |False|)
                 Whether or not taxon names are considered case sensitive or
                 insensitive.
 
@@ -663,7 +660,7 @@ class TaxonNamespace(
 
     def __contains__(self, taxon):
         """
-        Returns `True` if Taxon object ``taxon`` is in self.
+        Returns |True| if Taxon object ``taxon`` is in self.
         """
         # look-up in dictionary for O(1) instead of O(n) in list
         return taxon in self._taxon_accession_index_map
@@ -681,30 +678,30 @@ class TaxonNamespace(
         ----------
         label : str
             The label for which to search.
-        is_case_sensitive : `None` or bool
+        is_case_sensitive : |None| or bool
             By default, label lookup will use the
             ``is_case_sensitive`` attribute of ``self`` to decide
             whether or not to respect case when trying to match labels to
             operational taxonomic unit names represented by |Taxon|
             instances. This can be over-ridden by specifying
-            ``is_case_sensitive`` to `True` (forcing case-sensitivity) or `False`
+            ``is_case_sensitive`` to |True| (forcing case-sensitivity) or |False|
             (forcing case-insensitivity).
         first_match_only : bool
-            If `False`, then the entire namespace will be searched and *all*
+            If |False|, then the entire namespace will be searched and *all*
             |Taxon| objects with the matching labels will be returned
-            as a list. If `True` then the function will return after
+            as a list. If |True| then the function will return after
             processing the first |Taxon| object with a matching label
             (i.e., the entire namespace is not searched). Setting this
-            argument to `True` will be more efficient and should be preferred
+            argument to |True| will be more efficient and should be preferred
             if there are no redundant or duplicate labels.
         error_if_not_found : bool
-            If `True`, then a LookupError is raised if there are no matches.
+            If |True|, then a LookupError is raised if there are no matches.
 
         Returns
         -------
-        t : `None` or |Taxon| instance or list[|Taxon|]
+        t : |None| or |Taxon| instance or list[|Taxon|]
             If no |Taxon| instances have ``label`` attributes that match
-            the ``label`` argument, then `None`. Otherise, if
+            the ``label`` argument, then |None|. Otherise, if
             `first_match_only==True`, then a |Taxon| instance with
             ``label`` attribute matching the value of the ``label`` argument; if
             `first_match_only==False`, a list of one or more |Taxon|
@@ -755,7 +752,7 @@ class TaxonNamespace(
         ------
         TypeError
             If this namespace is immutable (i.e.
-            :attr:`TaxonNamespace.is_mutable` is `False`).
+            :attr:`TaxonNamespace.is_mutable` is |False|).
 
         """
         # NOTE
@@ -800,7 +797,7 @@ class TaxonNamespace(
         ------
         TypeError
             If this namespace is immutable (i.e. :attr:`TaxonNamespace.is_mutable` is
-            `False`).
+            |False|).
         """
         for t in taxa:
             self.add_taxon(t)
@@ -834,20 +831,20 @@ class TaxonNamespace(
 
         Parameters
         ----------
-        labels : `collections.Iterable` [string]
+        labels : ``collections.Iterable`` [string]
             The values of the ``label`` attributes of the new |Taxon| objects to
             be created, added to this namespace collection, and returned.
 
         Returns
         -------
-        taxa : `collections.Iterable` [|Taxon|]
+        taxa : ``collections.Iterable`` [|Taxon|]
             A list of |Taxon| objects created and added.
 
         Raises
         ------
         TypeError
             If this namespace is immutable (i.e.
-            :attr:`TaxonNamespace.is_mutable` is `False`).
+            :attr:`TaxonNamespace.is_mutable` is |False|).
 
         """
         if not self.is_mutable:
@@ -907,20 +904,20 @@ class TaxonNamespace(
         ----------
         label : string or string-like
             The value of the |Taxon| object label to remove.
-        is_case_sensitive : `None` or bool
+        is_case_sensitive : |None| or bool
             By default, label lookup will use the
             ``is_case_sensitive`` attribute of ``self`` to decide
             whether or not to respect case when trying to match labels to
             operational taxonomic unit names represented by |Taxon|
             instances. This can be over-ridden by specifying
-            ``is_case_sensitive`` to `True` (forcing case-sensitivity) or `False`
+            ``is_case_sensitive`` to |True| (forcing case-sensitivity) or |False|
             (forcing case-insensitivity).
         first_match_only : bool
-            If `False`, then the entire namespace will be searched and *all*
+            If |False|, then the entire namespace will be searched and *all*
             |Taxon| objects with the matching labels will be remove. If
-            `True` then only the first |Taxon| object with a matching
+            |True| then only the first |Taxon| object with a matching
             label will be removed (i.e., the entire namespace is not searched).
-            Setting this argument to `True` will be more efficient and should
+            Setting this argument to |True| will be more efficient and should
             be preferred if there are no redundant or duplicate labels.
 
         Raises
@@ -955,20 +952,20 @@ class TaxonNamespace(
         ----------
         label : string or string-like
             The value of the |Taxon| object label to remove.
-        is_case_sensitive : `None` or bool
+        is_case_sensitive : |None| or bool
             By default, label lookup will use the
             ``is_case_sensitive`` attribute of ``self`` to decide
             whether or not to respect case when trying to match labels to
             operational taxonomic unit names represented by |Taxon|
             instances. This can be over-ridden by specifying
-            ``is_case_sensitive`` to `True` (forcing case-sensitivity) or `False`
+            ``is_case_sensitive`` to |True| (forcing case-sensitivity) or |False|
             (forcing case-insensitivity).
         first_match_only : bool
-            If `False`, then the entire namespace will be searched and *all*
+            If |False|, then the entire namespace will be searched and *all*
             |Taxon| objects with the matching labels will be remove. If
-            `True` then only the first |Taxon| object with a matching
+            |True| then only the first |Taxon| object with a matching
             label will be removed (i.e., the entire namespace is not searched).
-            Setting this argument to `True` will be more efficient and should
+            Setting this argument to |True| will be more efficient and should
             be preferred if there are no redundant or duplicate labels.
 
         See Also
@@ -1008,13 +1005,13 @@ class TaxonNamespace(
         label : string or string-like
             The value which the ``label`` attribute of the |Taxon| object(s)
             to be returned must match.
-        is_case_sensitive : `None` or bool
+        is_case_sensitive : |None| or bool
             By default, label lookup will use the
             ``is_case_sensitive`` attribute of ``self`` to decide
             whether or not to respect case when trying to match labels to
             operational taxonomic unit names represented by |Taxon|
             instances. This can be over-ridden by specifying
-            ``is_case_sensitive`` to `True` (forcing case-sensitivity) or `False`
+            ``is_case_sensitive`` to |True| (forcing case-sensitivity) or |False|
             (forcing case-insensitivity).
 
         Returns
@@ -1042,20 +1039,20 @@ class TaxonNamespace(
         ----------
         label : string or string-like
             The value of the |Taxon| object label to match.
-        is_case_sensitive : `None` or bool
+        is_case_sensitive : |None| or bool
             By default, label lookup will use the
             ``is_case_sensitive`` attribute of ``self`` to decide
             whether or not to respect case when trying to match labels to
             operational taxonomic unit names represented by |Taxon|
             instances. This can be over-ridden by specifying
-            ``is_case_sensitive`` to `True` (forcing case-sensitivity) or `False`
+            ``is_case_sensitive`` to |True| (forcing case-sensitivity) or |False|
             (forcing case-insensitivity).
 
         Returns
         -------
         b : boolean
-            `True` if there is at least one |Taxon| object in this namespace
-            with a label matching the value of ``label``. Otherwise, `False`.
+            |True| if there is at least one |Taxon| object in this namespace
+            with a label matching the value of ``label``. Otherwise, |False|.
         """
         t = self._lookup_label(
                 label=label,
@@ -1071,23 +1068,23 @@ class TaxonNamespace(
 
         Parameters
         ----------
-        labels : `collections.Iterable` [string]
+        labels : ``collections.Iterable`` [string]
             The values of the |Taxon| object labels to match.
-        is_case_sensitive : `None` or bool
+        is_case_sensitive : |None| or bool
             By default, label lookup will use the
             ``is_case_sensitive`` attribute of ``self`` to decide
             whether or not to respect case when trying to match labels to
             operational taxonomic unit names represented by |Taxon|
             instances. This can be over-ridden by specifying
-            ``is_case_sensitive`` to `True` (forcing case-sensitivity) or `False`
+            ``is_case_sensitive`` to |True| (forcing case-sensitivity) or |False|
             (forcing case-insensitivity).
 
         Returns
         -------
         b : boolean
-            Returns `True` if, for every element in the iterable ``labels``,
+            Returns |True| if, for every element in the iterable ``labels``,
             there is at least one |Taxon| object that has a label attribute
-            that matches this. `False` otherwise.
+            that matches this. |False| otherwise.
         """
         for label in labels:
             f = self._lookup_label(label=label,
@@ -1106,27 +1103,27 @@ class TaxonNamespace(
         If multiple |Taxon| objects exist with labels that match
         ``label``, then only the first one is returned.  If no |Taxon|
         object is found in this namespace with the specified critieria,
-        `None` is returned.
+        |None| is returned.
 
         Parameters
         ----------
         label : string or string-like
             The value which the ``label`` attribute of the |Taxon| object
             to be returned must match.
-        is_case_sensitive : `None` or bool
+        is_case_sensitive : |None| or bool
             By default, label lookup will use the
             ``is_case_sensitive`` attribute of ``self`` to decide
             whether or not to respect case when trying to match labels to
             operational taxonomic unit names represented by |Taxon|
             instances. This can be over-ridden by specifying
-            ``is_case_sensitive`` to `True` (forcing case-sensitivity) or `False`
+            ``is_case_sensitive`` to |True| (forcing case-sensitivity) or |False|
             (forcing case-insensitivity).
 
         Returns
         -------
-        taxon : |Taxon| object or `None`
+        taxon : |Taxon| object or |None|
             The first |Taxon| object in this namespace collection with a label
-            matching ``label``, or `None` if no such |Taxon| object exists.
+            matching ``label``, or |None| if no such |Taxon| object exists.
         """
         return self._lookup_label(label=label,
                 is_case_sensitive=is_case_sensitive,
@@ -1140,25 +1137,25 @@ class TaxonNamespace(
 
         Parameters
         ----------
-        labels : `collections.Iterable` [string]
+        labels : ``collections.Iterable`` [string]
             Any |Taxon| object in this namespace collection that has a label
             attribute that matches any value in ``labels`` will be included in
             the list returned.
-        is_case_sensitive : `None` or bool
+        is_case_sensitive : |None| or bool
             By default, label lookup will use the
             ``is_case_sensitive`` attribute of ``self`` to decide
             whether or not to respect case when trying to match labels to
             operational taxonomic unit names represented by |Taxon|
             instances. This can be over-ridden by specifying
-            ``is_case_sensitive`` to `True` (forcing case-sensitivity) or `False`
+            ``is_case_sensitive`` to |True| (forcing case-sensitivity) or |False|
             (forcing case-insensitivity).
         first_match_only : bool
-            If `False`, then for *each* label in ``labels``, the entire namespace
+            If |False|, then for *each* label in ``labels``, the entire namespace
             will be searched and *all* |Taxon| objects with the matches
-            will be added to the lest. If `True` then, for each label in
+            will be added to the lest. If |True| then, for each label in
             ``labels``, only the first |Taxon| object with a matching
             label will be added to the list (i.e., the entire namespace is not
-            searched). Setting this argument to `True` will be more
+            searched). Setting this argument to |True| will be more
             efficient and should be preferred if there are no redundant or
             duplicate labels.
 
@@ -1204,18 +1201,18 @@ class TaxonNamespace(
         label : string or string-like
             The value which the ``label`` attribute of the |Taxon| object
             to be returned must match.
-        is_case_sensitive : `None` or bool
+        is_case_sensitive : |None| or bool
             By default, label lookup will use the
             ``is_case_sensitive`` attribute of ``self`` to decide
             whether or not to respect case when trying to match labels to
             operational taxonomic unit names represented by |Taxon|
             instances. This can be over-ridden by specifying
-            ``is_case_sensitive`` to `True` (forcing case-sensitivity) or `False`
+            ``is_case_sensitive`` to |True| (forcing case-sensitivity) or |False|
             (forcing case-insensitivity).
 
         Returns
         -------
-        taxon : |Taxon| object or `None`
+        taxon : |Taxon| object or |None|
             A |Taxon| object in this namespace collection with a label
             matching ``label``.
 
@@ -1224,7 +1221,7 @@ class TaxonNamespace(
         TypeError
             If no |Taxon| object is currently in the collection with a label
             matching the input ``label`` and the ``is_mutable`` attribute of self
-            is `False`.
+            is |False|.
         """
         taxon = self._lookup_label(label=label,
                 is_case_sensitive=is_case_sensitive,
@@ -1252,7 +1249,7 @@ class TaxonNamespace(
             returns the value that determines its sort order. Defaults to
             sorting by label.
         reverse : boolean, optional
-            If `True`, sort will be in reverse order.
+            If |True|, sort will be in reverse order.
         """
         if key is None:
             key = lambda x: x.label
@@ -1286,7 +1283,7 @@ class TaxonNamespace(
         If the |TaxonNamespace| is currently case-insensitive, then the
         dictionary returned will have case-insensitive keys, other the
         dictionary will be case-sensitive. You can override this by explicitly
-        specifying ``is_case_sensitive`` to `False` or `True`.
+        specifying ``is_case_sensitive`` to |False| or |True|.
 
         No attempt is made to handle collisions.
 
@@ -1410,9 +1407,9 @@ class TaxonNamespace(
         \*\*kwargs : keyword arguments
             Requires one of:
 
-                taxa : `collections.Iterable` [|Taxon|]
+                taxa : ``collections.Iterable`` [|Taxon|]
                     Iterable of |Taxon| objects.
-                labels : `collections.Iterable` [string]
+                labels : ``collections.Iterable`` [string]
                     Iterable of |Taxon| label values.
 
         Returns
@@ -1441,9 +1438,9 @@ class TaxonNamespace(
         \*\*kwargs : keyword arguments
             Requires one of:
 
-                taxa : `collections.Iterable` [|Taxon|]
+                taxa : ``collections.Iterable`` [|Taxon|]
                     Iterable of |Taxon| objects.
-                labels : `collections.Iterable` [string]
+                labels : ``collections.Iterable`` [string]
                     Iterable of |Taxon| label values.
 
         Returns
@@ -1500,12 +1497,12 @@ class TaxonNamespace(
         bitmask : integer
             Split hash bitmask value.
         preserve_spaces : boolean, optional
-            If `False` (default), then spaces in taxon labels will be replaced
-            by underscores. If `True`, then taxon labels with spaces will be
+            If |False| (default), then spaces in taxon labels will be replaced
+            by underscores. If |True|, then taxon labels with spaces will be
             wrapped in quotes.
         quote_underscores : boolean, optional
-            If `True` (default), then taxon labels with underscores will be
-            wrapped in quotes. If `False`, then the labels will not be wrapped
+            If |True| (default), then taxon labels with underscores will be
+            wrapped in quotes. If |False|, then the labels will not be wrapped
             in quotes.
 
         Returns
@@ -1532,12 +1529,12 @@ class TaxonNamespace(
         bitmask : integer
             Split hash bitmask value.
         preserve_spaces : boolean, optional
-            If `False` (default), then spaces in taxon labels will be replaced
-            by underscores. If `True`, then taxon labels with spaces will be
+            If |False| (default), then spaces in taxon labels will be replaced
+            by underscores. If |True|, then taxon labels with spaces will be
             wrapped in quotes.
         quote_underscores : boolean, optional
-            If `True` (default), then taxon labels with underscores will be
-            wrapped in quotes. If `False`, then the labels will not be wrapped
+            If |True| (default), then taxon labels with underscores will be
+            wrapped in quotes. If |False|, then the labels will not be wrapped
             in quotes.
 
         Returns
diff --git a/dendropy/datamodel/treecollectionmodel.py b/dendropy/datamodel/treecollectionmodel.py
index d6f4bc9..bca1660 100644
--- a/dendropy/datamodel/treecollectionmodel.py
+++ b/dendropy/datamodel/treecollectionmodel.py
@@ -23,10 +23,6 @@ trees.
 
 import collections
 import math
-try:
-    from StringIO import StringIO # Python 2 legacy support: StringIO in this module is the one needed (not io)
-except ImportError:
-    from io import StringIO # Python 3
 import copy
 import sys
 from dendropy.utility import container
@@ -83,7 +79,7 @@ class TreeList(
             Identifier of format of data in ``stream``
 
         collection_offset : integer or None
-            0-based index indicating collection of trees to parse. If `None`,
+            0-based index indicating collection of trees to parse. If |None|,
             then all tree collections are retrieved, with each distinct
             collection parsed into a separate |TreeList| object. If the
             tree colleciton offset index is equal or greater than the number of
@@ -98,7 +94,7 @@ class TreeList(
         tree_offset : integer or None
             0-based index indicating particular tree within a particular
             collection of trees at which to begin reading.  If not specified or
-            `None` (default), then all trees are parsed.  Otherwise, must be an
+            |None| (default), then all trees are parsed.  Otherwise, must be an
             integer value up the length of the collection minus 1.  A positive
             offset indicates the number of trees in the collection to skip;
             e.g. a ``tree_offset`` of 20 means to skip the first 20 trees in the
@@ -235,7 +231,7 @@ class TreeList(
 
             - **label** (*str*) -- Name or identifier to be assigned to the new
               object; if not given, will be assigned the one specified in the
-              data source, or `None` otherwise.
+              data source, or |None| otherwise.
             - **taxon_namespace** (|TaxonNamespace|) -- The |TaxonNamespace|
               instance to use to :doc:`manage the taxon names </primer/taxa>`.
               If not specified, a new one will be created.
@@ -248,9 +244,9 @@ class TreeList(
               specified, then the first tree (offset = 0) is assumed (i.e., no
               trees within the specified collection will be skipped). Use this
               to specify, e.g. a burn-in.
-            - **ignore_unrecognized_keyword_arguments** (*bool*) -- If `True`,
+            - **ignore_unrecognized_keyword_arguments** (*bool*) -- If |True|,
               then unsupported or unrecognized keyword arguments will not
-              result in an error. Default is `False`: unsupported keyword
+              result in an error. Default is |False|: unsupported keyword
               arguments will result in an error.
 
         **Optional Schema-Specific Keyword Arguments:**
@@ -338,7 +334,6 @@ class TreeList(
 
             # /usr/bin/env python
 
-            import StringIO
             from dendropy import TaxonNamespace, Tree, TreeList
 
             # instantiate an empty tree
@@ -540,7 +535,7 @@ class TreeList(
             Identifier of format of data in ``stream``.
 
         collection_offset : integer or None
-            0-based index indicating collection of trees to parse. If `None`,
+            0-based index indicating collection of trees to parse. If |None|,
             then all tree collections are retrieved, with each distinct
             collection parsed into a separate |TreeList| object. If the
             tree colleciton offset index is equal or greater than the number of
@@ -555,7 +550,7 @@ class TreeList(
         tree_offset : integer or None
             0-based index indicating particular tree within a particular
             collection of trees at which to begin reading.  If not specified or
-            `None` (default), then all trees are parsed.  Otherwise, must be an
+            |None| (default), then all trees are parsed.  Otherwise, must be an
             integer value up the length of the collection minus 1.  A positive
             offset indicates the number of trees in the collection to skip;
             e.g. a ``tree_offset`` of 20 means to skip the first 20 trees in the
@@ -646,9 +641,9 @@ class TreeList(
               specified, then the first tree (offset = 0) is assumed (i.e., no
               trees within the specified collection will be skipped). Use this
               to specify, e.g. a burn-in.
-            - **ignore_unrecognized_keyword_arguments** (*bool*) -- If `True`,
+            - **ignore_unrecognized_keyword_arguments** (*bool*) -- If |True|,
               then unsupported or unrecognized keyword arguments will not
-              result in an error. Default is `False`: unsupported keyword
+              result in an error. Default is |False|: unsupported keyword
               arguments will result in an error.
 
         **Optional Schema-Specific Keyword Arguments:**
@@ -1040,7 +1035,7 @@ class TreeList(
         and passing on keyword arguments pertaining to TreeArray
         construction, and leaving everything else.
         """
-        # TODO: maybe ignore_node_ages defaults to `False` but ``ultrametricity_precision`` defaults to 0?
+        # TODO: maybe ignore_node_ages defaults to |False| but ``ultrametricity_precision`` defaults to 0?
         ta = TreeArray.from_tree_list(
                 trees=self,
                 # taxon_namespace=self.taxon_namespace,
@@ -1049,6 +1044,8 @@ class TreeList(
                 ignore_node_ages=kwargs_dict.pop("ignore_node_ages", True),
                 use_tree_weights=kwargs_dict.pop("use_tree_weights", True),
                 ultrametricity_precision=kwargs_dict.pop("ultrametricity_precision", constants.DEFAULT_ULTRAMETRICITY_PRECISION),
+                is_force_max_age=kwargs_dict.pop("is_force_max_age", None),
+                taxon_label_age_map=kwargs_dict.pop("taxon_label_age_map", None),
                 is_bipartitions_updated=kwargs_dict.pop("is_bipartitions_updated", False)
                 )
         return ta
@@ -1108,8 +1105,8 @@ class TreeList(
         Parameters
         ----------
         include_external_splits : bool
-            If `True`, then non-internal split posteriors will be included in
-            the score. Defaults to `False`: these are skipped. This should only
+            If |True|, then non-internal split posteriors will be included in
+            the score. Defaults to |False|: these are skipped. This should only
             make a difference when dealing with splits collected from trees of
             different leaf sets.
 
@@ -1137,8 +1134,8 @@ class TreeList(
         Parameters
         ----------
         include_external_splits : bool
-            If `True`, then non-internal split posteriors will be included in
-            the score. Defaults to `False`: these are skipped. This should only
+            If |True|, then non-internal split posteriors will be included in
+            the score. Defaults to |False|: these are skipped. This should only
             make a difference when dealing with splits collected from trees of
             different leaf sets.
 
@@ -1172,6 +1169,7 @@ class TreeList(
         will be normalized for the comparison.
         """
         split = None
+        is_bipartitions_updated = kwargs.pop("is_bipartitions_updated", False)
         if "split_bitmask" in kwargs:
             split = kwargs["split_bitmask"]
         elif "bipartition" in kwargs:
@@ -1185,6 +1183,8 @@ class TreeList(
             if bitprocessing.num_set_bits(split) != k:
                 raise IndexError('Not all taxa could be mapped to bipartition (%s): %s' \
                     % (self.taxon_namespace.bitmask_as_bitstring(split), k))
+        else:
+            raise TypeError("Need to specify one of the following keyword arguments: 'split_bitmask', 'bipartition', 'taxa', or 'labels'")
         unnormalized_split = split
         normalized_split = treemodel.Bipartition.normalize_bitmask(
             bitmask=split,
@@ -1192,9 +1192,8 @@ class TreeList(
             lowest_relevant_bit=1)
         found = 0
         total = 0
-        is_bipartitions_updated = kwargs.get("is_bipartitions_updated", False)
         for tree in self:
-            if not is_bipartitions_updated or not tree.bipartitions:
+            if not is_bipartitions_updated or not tree.bipartition_encoding:
                 tree.encode_bipartitions()
             bipartition_encoding = set(b.split_bitmask for b in tree.bipartition_encoding)
             total += 1
@@ -1228,13 +1227,14 @@ class SplitDistribution(taxonmodel.TaxonNamespaceAssociated):
 
     SUMMARY_STATS_FIELDNAMES = ('mean', 'median', 'sd', 'hpd95', 'quant_5_95', 'range')
 
-
     def __init__(self,
             taxon_namespace=None,
             ignore_edge_lengths=False,
             ignore_node_ages=True,
             use_tree_weights=True,
-            ultrametricity_precision=constants.DEFAULT_ULTRAMETRICITY_PRECISION):
+            ultrametricity_precision=constants.DEFAULT_ULTRAMETRICITY_PRECISION,
+            is_force_max_age=False,
+            taxon_label_age_map=None):
 
         # Taxon Namespace
         taxonmodel.TaxonNamespaceAssociated.__init__(self,
@@ -1246,13 +1246,16 @@ class SplitDistribution(taxonmodel.TaxonNamespaceAssociated):
         self.use_tree_weights = use_tree_weights
         self.ultrametricity_precision = ultrametricity_precision
 
-        # storage
+        # storage/function
         self.total_trees_counted = 0
         self.sum_of_tree_weights = 0.0
         self.tree_rooting_types_counted = set()
         self.split_counts = collections.defaultdict(float)
         self.split_edge_lengths = collections.defaultdict(list)
         self.split_node_ages = collections.defaultdict(list)
+        self.is_force_max_age = is_force_max_age
+        self.is_force_min_age = False
+        self.taxon_label_age_map = taxon_label_age_map
 
         # secondary/derived/generated/collected data
         self._is_rooted = False
@@ -1331,8 +1334,8 @@ class SplitDistribution(taxonmodel.TaxonNamespaceAssociated):
         tree : a |Tree| object.
             The tree on which to count the splits.
         is_bipartitions_updated : bool
-            If `False` [default], then the tree will have its splits encoded or
-            updated. Otherwise, if `True`, then the tree is assumed to have its
+            If |False| [default], then the tree will have its splits encoded or
+            updated. Otherwise, if |True|, then the tree is assumed to have its
             splits already encoded and updated.
 
         Returns
@@ -1347,7 +1350,16 @@ class SplitDistribution(taxonmodel.TaxonNamespaceAssociated):
         assert tree.taxon_namespace is self.taxon_namespace
         self.total_trees_counted += 1
         if not self.ignore_node_ages:
-            tree.calc_node_ages(ultrametricity_precision=self.ultrametricity_precision)
+            if self.taxon_label_age_map:
+                set_node_age_fn = self._set_node_age
+            else:
+                set_node_age_fn = None
+            tree.calc_node_ages(
+                    ultrametricity_precision=self.ultrametricity_precision,
+                    is_force_max_age=self.is_force_max_age,
+                    is_force_min_age=self.is_force_min_age,
+                    set_node_age_fn=set_node_age_fn,
+                    )
         if tree.weight is not None and self.use_tree_weights:
             weight_to_use = float(tree.weight)
         else:
@@ -1506,12 +1518,12 @@ class SplitDistribution(taxonmodel.TaxonNamespaceAssociated):
         tree : |Tree|
             The |Tree| which will be scored.
         is_bipartitions_updated : bool
-            If `False` [default], then the tree will have its splits encoded or
-            updated. Otherwise, if `True`, then the tree is assumed to have its
+            If |False| [default], then the tree will have its splits encoded or
+            updated. Otherwise, if |True|, then the tree is assumed to have its
             splits already encoded and updated.
         include_external_splits : bool
-            If `True`, then non-internal split posteriors will be included.
-            If `False`, then these are skipped. This should only make a
+            If |True|, then non-internal split posteriors will be included.
+            If |False|, then these are skipped. This should only make a
             difference when dealing with splits collected from trees of
             different leaf sets.
         traversal_strategy : str
@@ -1567,6 +1579,12 @@ class SplitDistribution(taxonmodel.TaxonNamespaceAssociated):
                 pass
         return self._split_node_age_summaries
 
+    def _set_node_age(self, nd):
+        if nd.taxon is None or nd._child_nodes:
+            return None
+        else:
+            return self.taxon_label_age_map.get(nd.taxon.label, 0.0)
+
     def _get_split_edge_length_summaries(self):
         if self._split_edge_length_summaries is None \
                 or self._trees_counted_for_summaries != self.total_trees_counted:
@@ -1603,11 +1621,11 @@ class SplitDistribution(taxonmodel.TaxonNamespaceAssociated):
         tree : |Tree|
             The tree for which the score should be calculated.
         is_bipartitions_updated : bool
-            If `True`, then the splits are assumed to have already been encoded
+            If |True|, then the splits are assumed to have already been encoded
             and will not be updated on the trees.
         include_external_splits : bool
-            If `True`, then non-internal split posteriors will be included in
-            the score. Defaults to `False`: these are skipped. This should only
+            If |True|, then non-internal split posteriors will be included in
+            the score. Defaults to |False|: these are skipped. This should only
             make a difference when dealing with splits collected from trees of
             different leaf sets.
 
@@ -1642,11 +1660,11 @@ class SplitDistribution(taxonmodel.TaxonNamespaceAssociated):
         tree : |Tree|
             The tree for which the score should be calculated.
         is_bipartitions_updated : bool
-            If `True`, then the splits are assumed to have already been encoded
+            If |True|, then the splits are assumed to have already been encoded
             and will not be updated on the trees.
         include_external_splits : bool
-            If `True`, then non-internal split posteriors will be included in
-            the score. Defaults to `False`: these are skipped. This should only
+            If |True|, then non-internal split posteriors will be included in
+            the score. Defaults to |False|: these are skipped. This should only
             make a difference when dealing with splits collected from trees of
             different leaf sets.
 
@@ -1665,6 +1683,30 @@ class SplitDistribution(taxonmodel.TaxonNamespaceAssociated):
             sum_of_split_support += split_support
         return sum_of_split_support
 
+    def collapse_edges_with_less_than_minimum_support(self,
+            tree,
+            min_freq=constants.GREATER_THAN_HALF,
+            ):
+        """
+        Collapse edges on tree that have support less than indicated by
+        ``min_freq``.
+        """
+        if not tree.is_rooted and self.is_all_counted_trees_rooted():
+            raise ValueError("Tree is interpreted as unrooted, but split support is based on rooted trees")
+        elif tree.is_rooted and self.is_all_counted_trees_treated_as_unrooted():
+            raise ValueError("Tree is interpreted as rooted, but split support is based on unrooted trees")
+        tree.encode_bipartitions()
+        split_frequencies = self._get_split_frequencies()
+        to_collapse = []
+        for nd in tree.postorder_node_iter():
+            s = nd.edge.bipartition.split_bitmask
+            if s not in split_frequencies:
+                to_collapse.append(nd)
+            elif split_frequencies[s] < min_freq:
+                to_collapse.append(nd)
+        for nd in to_collapse:
+            nd.edge.collapse(adjust_collapsed_head_children_edge_lengths=True)
+
     def consensus_tree(self,
             min_freq=constants.GREATER_THAN_HALF,
             is_rooted=None,
@@ -1683,8 +1725,8 @@ class SplitDistribution(taxonmodel.TaxonNamespaceAssociated):
 
         is_rooted : bool
             Should tree be rooted or not? If *all* trees counted for splits are
-            explicitly rooted or unrooted, then this will default to `True` or
-            `False`, respectively. Otherwise it defaults to `None`.
+            explicitly rooted or unrooted, then this will default to |True| or
+            |False|, respectively. Otherwise it defaults to |None|.
 
         \*\*split_summarization_kwargs : keyword arguments
             These will be passed directly to the underlying
@@ -1699,7 +1741,7 @@ class SplitDistribution(taxonmodel.TaxonNamespaceAssociated):
         if is_rooted is None:
             if self.is_all_counted_trees_rooted():
                 is_rooted = True
-            elif self.is_all_counted_trees_strictly_unrooted:
+            elif self.is_all_counted_trees_strictly_unrooted():
                 is_rooted = False
         split_frequencies = self._get_split_frequencies()
         to_try_to_add = []
@@ -1737,7 +1779,7 @@ class SplitDistribution(taxonmodel.TaxonNamespaceAssociated):
             Tree to be decorated with support values.
 
         is_bipartitions_updated: bool
-            If `True`, then bipartitions will not be recalculated.
+            If |True|, then bipartitions will not be recalculated.
 
         \*\*split_summarization_kwargs : keyword arguments
             These will be passed directly to the underlying
@@ -1802,7 +1844,7 @@ class SplitDistributionSummarizer(object):
                 - "median-length": median of edge lengths for split
                 - "mean-age": such that split age is equal to mean of ages
                 - "median-age": such that split age is equal to mean of ages
-                - `None`: do not set edge lengths
+                - |None|: do not set edge lengths
 
         add_support_as_node_attribute: bool
             Adds each node's support value as an attribute of the node,
@@ -1810,7 +1852,7 @@ class SplitDistributionSummarizer(object):
 
         add_support_as_node_annotation: bool
             Adds support as a metadata annotation, "``support``". If
-            ``add_support_as_node_attribute`` is `True`, then the value will be
+            ``add_support_as_node_attribute`` is |True|, then the value will be
             dynamically-bound to the value of the node's "``support``" attribute.
 
         set_support_as_node_label : bool
@@ -1836,7 +1878,7 @@ class SplitDistributionSummarizer(object):
                 - ``age_hpd95``
                 - ``age_range``
 
-            If ``add_node_age_summaries_as_node_attributes`` is `True`, then the
+            If ``add_node_age_summaries_as_node_attributes`` is |True|, then the
             values will be dynamically-bound to the corresponding node
             attributes.
 
@@ -1860,7 +1902,7 @@ class SplitDistributionSummarizer(object):
                 - ``length_hpd95``
                 - ``length_range``
 
-            If ``add_edge_length_summaries_as_edge_attributes`` is `True`, then the
+            If ``add_edge_length_summaries_as_edge_attributes`` is |True|, then the
             values will be dynamically-bound to the corresponding edge
             attributes.
 
@@ -1877,13 +1919,9 @@ class SplitDistributionSummarizer(object):
             set to this.
 
         error_on_negative_edge_lengths : bool
-            If `True`, an inferred edge length that is less than 0 will result
+            If |True|, an inferred edge length that is less than 0 will result
             in a ValueError.
 
-        no_data_value : str or float
-            Value to substitute in for node ages, edge lengths and associated
-            summary statistics if a split is not found. Defaults to 0.0.
-
         """
         self.set_edge_lengths = kwargs.pop("set_edge_lengths", None)
         self.add_support_as_node_attribute = kwargs.pop("add_support_as_node_attribute", True)
@@ -1898,6 +1936,11 @@ class SplitDistributionSummarizer(object):
         self.support_label_compose_fn = kwargs.pop("support_label_compose_fn", None)
         self.primary_fieldnames = ["support",]
         self.summary_stats_fieldnames = SplitDistribution.SUMMARY_STATS_FIELDNAMES
+        self.no_data_values = {
+                'hpd95': [],
+                'quant_5_95': [],
+                'range': [],
+            }
         self.node_age_summaries_fieldnames = list("age_{}".format(f) for f in self.summary_stats_fieldnames)
         self.edge_length_summaries_fieldnames = list("length_{}".format(f) for f in self.summary_stats_fieldnames)
         self.fieldnames = self.primary_fieldnames + self.node_age_summaries_fieldnames + self.edge_length_summaries_fieldnames
@@ -1907,7 +1950,6 @@ class SplitDistributionSummarizer(object):
             setattr(self, "is_{}_annotation_dynamic".format(fieldname), kwargs.pop("is_{}_annotation_dynamic".format(fieldname), True))
         self.minimum_edge_length = kwargs.pop("minimum_edge_length", None)
         self.error_on_negative_edge_lengths = kwargs.pop("error_on_negative_edge_lengths", False)
-        self.no_data_value = kwargs.pop("no_data_value", 0.0)
         if kwargs:
             TypeError("Unrecognized or unsupported arguments: {}".format(kwargs))
 
@@ -1973,10 +2015,11 @@ class SplitDistributionSummarizer(object):
                 node.label = support_label_fn(split_support)
             if (self.add_node_age_summaries_as_node_attributes or self.add_node_age_summaries_as_node_annotations) and node_age_summaries:
                 for fieldname, stats_fieldname in zip(self.node_age_summaries_fieldnames, self.summary_stats_fieldnames):
+                    no_data_value = self.no_data_values.get(stats_fieldname, 0.0)
                     if not node_age_summaries or split_bitmask not in node_age_summaries:
-                        value = self.no_data_value
+                        value = no_data_value
                     else:
-                        value = node_age_summaries[split_bitmask].get(stats_fieldname, 0.0)
+                        value = node_age_summaries[split_bitmask].get(stats_fieldname, no_data_value)
                     self._decorate(
                         target=node,
                         fieldname=fieldname,
@@ -1986,10 +2029,11 @@ class SplitDistributionSummarizer(object):
                         )
             if (self.add_edge_length_summaries_as_edge_attributes or self.add_edge_length_summaries_as_edge_annotations) and edge_length_summaries:
                 for fieldname, stats_fieldname in zip(self.edge_length_summaries_fieldnames, self.summary_stats_fieldnames):
+                    no_data_value = self.no_data_values.get(stats_fieldname, 0.0)
                     if not edge_length_summaries or split_bitmask not in edge_length_summaries:
-                        value = self.no_data_value
+                        value = no_data_value
                     else:
-                        value = edge_length_summaries[split_bitmask].get(stats_fieldname, 0.0)
+                        value = edge_length_summaries[split_bitmask].get(stats_fieldname, no_data_value)
                     self._decorate(
                         target=node.edge,
                         fieldname=fieldname,
@@ -2012,12 +2056,12 @@ class SplitDistributionSummarizer(object):
                     try:
                         node.age = node_age_summaries[split_bitmask]["mean"]
                     except KeyError:
-                        node.age = self.no_data_value
+                        node.age = self.no_data_values.get("mean", 0.0)
                 elif self.set_edge_lengths == "median-age":
                     try:
                         node.age = node_age_summaries[split_bitmask]["median"]
                     except KeyError:
-                        node.age = self.no_data_value
+                        node.age = self.no_data_values.get("median", 0.0)
                 else:
                     raise ValueError(self.set_edge_lengths)
             elif self.set_edge_lengths in ("mean-length", "median-length"):
@@ -2027,12 +2071,12 @@ class SplitDistributionSummarizer(object):
                     try:
                         node.edge.length = edge_length_summaries[split_bitmask]["mean"]
                     except KeyError:
-                        node.edge.length = self.no_data_value
+                        node.edge.length = self.no_data_values.get("mean", 0.0)
                 elif self.set_edge_lengths == "median-length":
                     try:
                         node.edge.length = edge_length_summaries[split_bitmask]["median"]
                     except KeyError:
-                        node.edge.length = self.no_data_value
+                        node.edge.length = self.no_data_values.get("median", 0.0)
                 else:
                     raise ValueError(self.set_edge_lengths)
                 if self.minimum_edge_length is not None and edge.length < self.minimum_edge_length:
@@ -2092,6 +2136,8 @@ class TreeArray(
             ignore_node_ages=True,
             use_tree_weights=True,
             ultrametricity_precision=constants.DEFAULT_ULTRAMETRICITY_PRECISION,
+            is_force_max_age=None,
+            taxon_label_age_map=None,
             is_bipartitions_updated=False,
             ):
         taxon_namespace = trees.taxon_namespace
@@ -2101,7 +2147,9 @@ class TreeArray(
             ignore_edge_lengths=ignore_edge_lengths,
             ignore_node_ages=ignore_node_ages,
             use_tree_weights=use_tree_weights,
-            ultrametricity_precision=constants.DEFAULT_ULTRAMETRICITY_PRECISION,
+            ultrametricity_precision=ultrametricity_precision,
+            is_force_max_age=is_force_max_age,
+            taxon_label_age_map=taxon_label_age_map,
             )
         ta.add_trees(
                 trees=trees,
@@ -2118,6 +2166,8 @@ class TreeArray(
             ignore_node_ages=True,
             use_tree_weights=True,
             ultrametricity_precision=constants.DEFAULT_ULTRAMETRICITY_PRECISION,
+            is_force_max_age=None,
+            taxon_label_age_map=None,
             ):
         """
         Parameters
@@ -2127,17 +2177,17 @@ class TreeArray(
             references.
         is_rooted_trees : bool
             If not set, then it will be set based on the rooting state of the
-            first tree added. If `True`, then trying to add an unrooted tree
-            will result in an error. If `False`, then trying to add a rooted
+            first tree added. If |True|, then trying to add an unrooted tree
+            will result in an error. If |False|, then trying to add a rooted
             tree will result in an error.
         ignore_edge_lengths : bool
-            If `True`, then edge lengths of splits will not be stored. If
-            `False`, then edge lengths will be stored.
+            If |True|, then edge lengths of splits will not be stored. If
+            |False|, then edge lengths will be stored.
         ignore_node_ages : bool
-            If `True`, then node ages of splits will not be stored. If
-            `False`, then node ages will be stored.
+            If |True|, then node ages of splits will not be stored. If
+            |False|, then node ages will be stored.
         use_tree_weights : bool
-            If `False`, then tree weights will not be used to weight splits.
+            If |False|, then tree weights will not be used to weight splits.
         """
         taxonmodel.TaxonNamespaceAssociated.__init__(self,
                 taxon_namespace=taxon_namespace)
@@ -2147,8 +2197,9 @@ class TreeArray(
         self.ignore_edge_lengths = ignore_edge_lengths
         self.ignore_node_ages = ignore_node_ages
         self.use_tree_weights = use_tree_weights
-        self.default_edge_length_value = 0 # edge.length of `None` gets this value
+        self.default_edge_length_value = 0 # edge.length of |None| gets this value
         self.tree_type = treemodel.Tree
+        self.taxon_label_age_map = taxon_label_age_map
 
         # Storage
         self._tree_split_bitmasks = []
@@ -2160,6 +2211,8 @@ class TreeArray(
                 ignore_edge_lengths=self.ignore_edge_lengths,
                 ignore_node_ages=self.ignore_node_ages,
                 ultrametricity_precision=ultrametricity_precision,
+                is_force_max_age=is_force_max_age,
+                taxon_label_age_map=self.taxon_label_age_map,
                 )
 
     ##############################################################################
@@ -2230,8 +2283,8 @@ class TreeArray(
             all the other trees accessioned into this collection as well as
             that of ``self.is_rooted_trees``.
         is_bipartitions_updated : bool
-            If `False` [default], then the tree will have its splits encoded or
-            updated. Otherwise, if `True`, then the tree is assumed to have its
+            If |False| [default], then the tree will have its splits encoded or
+            updated. Otherwise, if |True|, then the tree is assumed to have its
             splits already encoded and updated.
         index : integer
             Insert before index.
@@ -2298,8 +2351,8 @@ class TreeArray(
             have the same rooting state as all the other trees accessioned into
             this collection as well as that of ``self.is_rooted_trees``.
         is_bipartitions_updated : bool
-            If `False` [default], then the tree will have its splits encoded or
-            updated. Otherwise, if `True`, then the tree is assumed to have its
+            If |False| [default], then the tree will have its splits encoded or
+            updated. Otherwise, if |True|, then the tree is assumed to have its
             splits already encoded and updated.
 
         """
@@ -2392,9 +2445,9 @@ class TreeArray(
               specified, then the first tree (offset = 0) is assumed (i.e., no
               trees within the specified collection will be skipped). Use this
               to specify, e.g. a burn-in.
-            - **ignore_unrecognized_keyword_arguments** (*bool*) -- If `True`,
+            - **ignore_unrecognized_keyword_arguments** (*bool*) -- If |True|,
               then unsupported or unrecognized keyword arguments will not
-              result in an error. Default is `False`: unsupported keyword
+              result in an error. Default is |False|: unsupported keyword
               arguments will result in an error.
 
         **Optional Schema-Specific Keyword Arguments:**
@@ -2428,34 +2481,6 @@ class TreeArray(
         """
         return basemodel.MultiReadable._read_from(self, **kwargs)
 
-
-    # def read_from_stream(self, fileobj, schema, **kwargs):
-    #     """
-    #     Reads trees from a file. See :meth:|TreeList|.read_from_stream()`.
-    #     """
-    #     return self.read_from_files(
-    #             files=[fileobj],
-    #             schema=schema,
-    #             **kwargs)
-
-    # def read_from_path(self, filepath, schema, **kwargs):
-    #     """
-    #     Reads trees from a path. See :meth:|TreeList|.read_from_path()`.
-    #     """
-    #     return self.read_from_files(
-    #             files=[filepath],
-    #             schema=schema,
-    #             **kwargs)
-
-    # def read_from_string(self, src_str, schema, **kwargs):
-    #     """
-    #     Reads trees from a string. See :meth:|TreeList|.read_from_string()`.
-    #     """
-    #     return self.read_from_files(
-    #             files=[StringIO(src_str)],
-    #             schema=schema,
-    #             **kwargs)
-
     ##############################################################################
     ## Container (List) Interface
 
@@ -2471,8 +2496,8 @@ class TreeArray(
             all the other trees accessioned into this collection as well as
             that of ``self.is_rooted_trees``.
         is_bipartitions_updated : bool
-            If `False` [default], then the tree will have its splits encoded or
-            updated. Otherwise, if `True`, then the tree is assumed to have its
+            If |False| [default], then the tree will have its splits encoded or
+            updated. Otherwise, if |True|, then the tree is assumed to have its
             splits already encoded and updated.
 
         """
@@ -2493,8 +2518,8 @@ class TreeArray(
             all the other trees accessioned into this collection as well as
             that of ``self.is_rooted_trees``.
         is_bipartitions_updated : bool
-            If `False` [default], then the tree will have its splits encoded or
-            updated. Otherwise, if `True`, then the tree is assumed to have its
+            If |False| [default], then the tree will have its splits encoded or
+            updated. Otherwise, if |True|, then the tree is assumed to have its
             splits already encoded and updated.
 
         Returns
@@ -2658,8 +2683,8 @@ class TreeArray(
         Parameters
         ----------
         include_external_splits : bool
-            If `True`, then non-internal split posteriors will be included in
-            the score. Defaults to `False`: these are skipped. This should only
+            If |True|, then non-internal split posteriors will be included in
+            the score. Defaults to |False|: these are skipped. This should only
             make a difference when dealing with splits collected from trees of
             different leaf sets.
 
@@ -2703,8 +2728,8 @@ class TreeArray(
         Parameters
         ----------
         include_external_splits : bool
-            If `True`, then non-internal split posteriors will be included in
-            the score. Defaults to `False`: these are skipped. This should only
+            If |True|, then non-internal split posteriors will be included in
+            the score. Defaults to |False|: these are skipped. This should only
             make a difference when dealing with splits collected from trees of
             different leaf sets.
 
@@ -2738,8 +2763,8 @@ class TreeArray(
         Parameters
         ----------
         include_external_splits : bool
-            If `True`, then non-internal split posteriors will be included in
-            the score. Defaults to `False`: these are skipped. This should only
+            If |True|, then non-internal split posteriors will be included in
+            the score. Defaults to |False|: these are skipped. This should only
             make a difference when dealing with splits collected from trees of
             different leaf sets.
 
@@ -2781,8 +2806,8 @@ class TreeArray(
         Parameters
         ----------
         include_external_splits : bool
-            If `True`, then non-internal split posteriors will be included in
-            the score. Defaults to `False`: these are skipped. This should only
+            If |True|, then non-internal split posteriors will be included in
+            the score. Defaults to |False|: these are skipped. This should only
             make a difference when dealing with splits collected from trees of
             different leaf sets.
 
@@ -2807,6 +2832,14 @@ class TreeArray(
                 )
         return tree
 
+    def collapse_edges_with_less_than_minimum_support(self,
+            tree,
+            min_freq=constants.GREATER_THAN_HALF,
+            ):
+        return self.split_distribution.collapse_edges_with_less_than_minimum_support(
+                tree=tree,
+                min_freq=min_freq)
+
     def consensus_tree(self,
             min_freq=constants.GREATER_THAN_HALF,
             summarize_splits=True,
@@ -2824,8 +2857,8 @@ class TreeArray(
 
         is_rooted : bool
             Should tree be rooted or not? If *all* trees counted for splits are
-            explicitly rooted or unrooted, then this will default to `True` or
-            `False`, respectively. Otherwise it defaults to `None`.
+            explicitly rooted or unrooted, then this will default to |True| or
+            |False|, respectively. Otherwise it defaults to |None|.
 
         \*\*split_summarization_kwargs : keyword arguments
             These will be passed directly to the underlying
@@ -2953,20 +2986,20 @@ class TreeArray(
         Parameters
         ----------
         sort_descending : bool
-            If `True`, then topologies will be sorted in *descending* frequency
+            If |True|, then topologies will be sorted in *descending* frequency
             order (i.e., topologies with the highest frequencies will be listed
-            first). If `False`, then they will be sorted in *ascending*
-            frequency. If `None` (default), then they will not be sorted.
+            first). If |False|, then they will be sorted in *ascending*
+            frequency. If |None| (default), then they will not be sorted.
         frequency_attr_name : str
             Name of attribute to add to each |Tree| representing
-            the frequency of that topology in the collection. If `None`
+            the frequency of that topology in the collection. If |None|
             then the attribute will not be added.
         frequency_annotation_name : str
             Name of annotation to add to the annotations of each |Tree|,
             representing the frequency of that topology in the collection. The
             value of this annotation will be dynamically-bound to the attribute
-            specified by ``frequency_attr_name`` unless that is `None`. If
-            ``frequency_annotation_name`` is `None` then the annotation will not
+            specified by ``frequency_attr_name`` unless that is |None|. If
+            ``frequency_annotation_name`` is |None| then the annotation will not
             be added.
         """
         if sort_descending is not None and frequency_attr_name is None:
diff --git a/dendropy/datamodel/treemodel.py b/dendropy/datamodel/treemodel.py
index 996418b..43bc1cb 100644
--- a/dendropy/datamodel/treemodel.py
+++ b/dendropy/datamodel/treemodel.py
@@ -23,10 +23,7 @@ as well as all the structural classes that make up a tree.
 
 import collections
 import math
-try:
-    from StringIO import StringIO # Python 2 legacy support: StringIO in this module is the one needed (not io)
-except ImportError:
-    from io import StringIO # Python 3
+from dendropy.utility.textprocessing import StringIO
 import copy
 import sys
 from dendropy.utility import GLOBAL_RNG
@@ -36,6 +33,7 @@ from dendropy.utility import error
 from dendropy.utility import bitprocessing
 from dendropy.utility import deprecate
 from dendropy.utility import constants
+from dendropy.utility import textprocessing
 from dendropy.datamodel import basemodel
 from dendropy.datamodel import taxonmodel
 from dendropy import dataio
@@ -101,7 +99,7 @@ class Bipartition(object):
     such, it is crucial that this value does not change once a particular
     |Bipartition| object is stored in a dictionary or set. To this end,
     we impose the constraint that |Bipartition| objects are immutable
-    unless the ``is_mutable`` attribute is explicitly set to `True` as a sort
+    unless the ``is_mutable`` attribute is explicitly set to |True| as a sort
     of waiver signed by the client code. Client code does this at its risk,
     with the warning that anything up to and including the implosion of the
     universe may occur if the |Bipartition| object is a member of an set
@@ -173,7 +171,7 @@ class Bipartition(object):
 
     def is_compatible_bitmasks(m1, m2, fill_bitmask):
         """
-        Returns `True` if ``m1`` is compatible with ``m2``
+        Returns |True| if ``m1`` is compatible with ``m2``
 
         Parameters
         ----------
@@ -185,7 +183,7 @@ class Bipartition(object):
         Returns
         -------
         bool
-            `True` if ``m1`` is compatible with ``m2``. `False` otherwise.
+            |True| if ``m1`` is compatible with ``m2``. |False| otherwise.
         """
         if fill_bitmask != 0:
             m1 = fill_bitmask & m1
@@ -303,6 +301,15 @@ class Bipartition(object):
     def __str__(self):
         return bin(self._split_bitmask)[2:].rjust(bitprocessing.bit_length(self._tree_leafset_bitmask), '0')
 
+    def __int__(self):
+        return self._split_bitmask
+
+    def split_as_int(self):
+        return self._split_bitmask
+
+    def leafset_as_int(self):
+        return self._leafset_bitmask
+
     def split_as_bitstring(self, symbol0="0", symbol1="1", reverse=False):
         """
         Composes and returns and representation of the bipartition as a
@@ -315,7 +322,7 @@ class Bipartition(object):
         symbol1 : str
             The symbol to represent group '1' in the bitmask.
         reverse : bool
-            If `True`, then the first taxon will correspond to the
+            If |True|, then the first taxon will correspond to the
             most-significant bit, instead of the least-significant bit, as is
             the default.
 
@@ -349,7 +356,7 @@ class Bipartition(object):
         symbol1 : str
             The symbol to represent group '1' in the bitmask.
         reverse : bool
-            If `True`, then the first taxon will correspond to the
+            If |True|, then the first taxon will correspond to the
             most-significant bit, instead of the least-significant bit, as is
             the default.
 
@@ -426,7 +433,7 @@ class Bipartition(object):
         the lowest-significant bit (i.e., the group to which the first taxon
         belongs) is set to '0'.
 
-        Also makes this bipartition immutable (unless ``is_mutable`` is `False`),
+        Also makes this bipartition immutable (unless ``is_mutable`` is |False|),
         which facilitates it being used in dictionaries and sets.
 
         Parameters
@@ -437,18 +444,18 @@ class Bipartition(object):
             bipartition is associated. The least-significant bit corresponds to
             the first taxon, the next least-signficant bit corresponds to the
             second taxon, and so on, with the last taxon corresponding to the
-            most-significant bit. If not specified or `None`, the current value
+            most-significant bit. If not specified or |None|, the current value
             of ``self.leafset_bitmask`` is used.
         tree_leafset_bitmask : integer
             The ``leafset_bitmask`` of the root edge of the tree with which this
             bipartition is associated. In, general, this will be $0b1111...n$,
             where $n$ is the number of taxa, *except* in cases of trees with
             incomplete leaf-sets, where the positions corresponding to the
-            missing taxa will have the bits unset. If not specified or `None`,
+            missing taxa will have the bits unset. If not specified or |None|,
             the current value of ``self.tree_leafset_bitmask`` is used.
         is_rooted : bool
             Specifies whether or not the tree with which this bipartition is
-            associated is rooted. If not specified or `None`, the current value
+            associated is rooted. If not specified or |None|, the current value
             of ``self.is_rooted`` is used.
 
         Returns
@@ -489,7 +496,7 @@ class Bipartition(object):
         the lowest-significant bit (i.e., the group to which the first taxon
         belongs) is set to '0'.
 
-        Also makes this bipartition immutable (unless ``is_mutable`` is `False`),
+        Also makes this bipartition immutable (unless ``is_mutable`` is |False|),
         which facilitates it being used in dictionaries and sets.
 
         Note that this requires full population of the following fields:
@@ -525,7 +532,7 @@ class Bipartition(object):
 
     def is_compatible_with(self, other):
         """
-        Returns `True` if ``other`` is compatible with self.
+        Returns |True| if ``other`` is compatible with self.
 
         Parameters
         ----------
@@ -535,7 +542,7 @@ class Bipartition(object):
         Returns
         -------
         bool
-            `True` if ``other`` is compatible with ``self``; `False` otherwise.
+            |True| if ``other`` is compatible with ``self``; |False| otherwise.
         """
         m1 = self._split_bitmask
         if isinstance(other, int):
@@ -546,7 +553,7 @@ class Bipartition(object):
 
     def is_incompatible_with(self, other):
         """
-        Returns `True` if ``other`` conflicts with self.
+        Returns |True| if ``other`` conflicts with self.
 
         Parameters
         ----------
@@ -556,13 +563,13 @@ class Bipartition(object):
         Returns
         -------
         bool
-            `True` if ``other`` conflicts with ``self``; `False` otherwise.
+            |True| if ``other`` conflicts with ``self``; |False| otherwise.
         """
         return not self.is_compatible_with(other)
 
     def is_nested_within(self, other, is_other_masked_for_tree_leafset=False):
         """
-        Returns `True` if the current bipartition is contained
+        Returns |True| if the current bipartition is contained
         within other.
 
         Parameters
@@ -573,7 +580,7 @@ class Bipartition(object):
         Returns
         -------
         bool
-            `True` if the the bipartition is "contained" within ``other``
+            |True| if the the bipartition is "contained" within ``other``
         """
         if self._is_rooted:
             m1 = self._leafset_bitmask
@@ -587,7 +594,7 @@ class Bipartition(object):
 
     def is_leafset_nested_within(self, other):
         """
-        Returns `True` if the leafset of ``self`` is a subset of the leafset of
+        Returns |True| if the leafset of ``self`` is a subset of the leafset of
         ``other``.
 
         Parameters
@@ -598,7 +605,7 @@ class Bipartition(object):
         Returns
         -------
         bool
-            `True` if the leafset of ``self`` is contained in ``other``.
+            |True| if the leafset of ``self`` is contained in ``other``.
         """
         if isinstance(other, int):
             m2 = other
@@ -612,7 +619,7 @@ class Bipartition(object):
         Returns
         -------
         bool
-            `True` if this bipartition divides a leaf and the rest of the
+            |True| if this bipartition divides a leaf and the rest of the
             tree.
         """
         return Bipartition.is_trivial_bitmask(self._split_bitmask,
@@ -630,12 +637,12 @@ class Bipartition(object):
         taxon_namespace : |TaxonNamespace| instance
             The operational taxonomic unit concept namespace to reference.
         preserve_spaces : boolean, optional
-            If `False` (default), then spaces in taxon labels will be replaced
-            by underscores. If `True`, then taxon labels with spaces will be
+            If |False| (default), then spaces in taxon labels will be replaced
+            by underscores. If |True|, then taxon labels with spaces will be
             wrapped in quotes.
         quote_underscores : boolean, optional
-            If `True` (default), then taxon labels with underscores will be
-            wrapped in quotes. If `False`, then the labels will not be wrapped
+            If |True| (default), then taxon labels with underscores will be
+            wrapped in quotes. If |False|, then the labels will not be wrapped
             in quotes.
 
         Returns
@@ -660,12 +667,12 @@ class Bipartition(object):
         taxon_namespace : |TaxonNamespace| instance
             The operational taxonomic unit concept namespace to reference.
         preserve_spaces : boolean, optional
-            If `False` (default), then spaces in taxon labels will be replaced
-            by underscores. If `True`, then taxon labels with spaces will be
+            If |False| (default), then spaces in taxon labels will be replaced
+            by underscores. If |True|, then taxon labels with spaces will be
             wrapped in quotes.
         quote_underscores : boolean, optional
-            If `True` (default), then taxon labels with underscores will be
-            wrapped in quotes. If `False`, then the labels will not be wrapped
+            If |True| (default), then taxon labels with underscores will be
+            wrapped in quotes. If |False|, then the labels will not be wrapped
             in quotes.
 
         Returns
@@ -678,7 +685,7 @@ class Bipartition(object):
                 preserve_spaces=preserve_spaces,
                 quote_underscores=quote_underscores)
 
-    def leafset_taxa(self, taxon_namespace):
+    def leafset_taxa(self, taxon_namespace, index=0):
         """
         Returns list of |Taxon| objects in the leafset of this
         bipartition.
@@ -817,7 +824,8 @@ class Edge(
         Inserts all children of the head_node of self as children of the
         tail_node of self in the same place in the child_node list that
         head_node had occupied. The edge length and head_node will no longer be
-        part of the tree.
+        part of the tree unless ``adjust_collapsed_head_children_edge_lengths``.
+        is True.
         """
         to_del = self.head_node
         parent = self.tail_node
@@ -1032,7 +1040,7 @@ class Node(
         return self is other
 
     def __repr__(self):
-        return "<Node object at {}: '{}' ({})>".format(hex(id(self)), self._label, repr(self.taxon))
+        return "<{} object at {}: '{}' ({})>".format(self.__class__.__name__, hex(id(self)), self._label, repr(self.taxon))
 
     ###########################################################################
     ### Iterators
@@ -1043,15 +1051,15 @@ class Node(
 
         Visits self and all descendant nodes, with each node visited before its
         children. Nodes can optionally be filtered by ``filter_fn``: only nodes
-        for which ``filter_fn`` returns `True` when called with the node as an
+        for which ``filter_fn`` returns |True| when called with the node as an
         argument are yielded.
 
         Parameters
         ----------
         filter_fn : function object, optional
             A function object that takes a |Node| object as an argument
-            and returns `True` if the |Node| object is to be yielded by
-            the iterator, or `False` if not. If ``filter_fn`` is `None`
+            and returns |True| if the |Node| object is to be yielded by
+            the iterator, or |False| if not. If ``filter_fn`` is |None|
             (default), then all nodes visited will be yielded.
 
         Returns
@@ -1074,20 +1082,20 @@ class Node(
         Visits self and all internal descendant nodes, with each node visited
         before its children. In DendroPy, "internal nodes" are nodes that have
         at least one child node, and thus the root or seed node is typically included
-        unless ``exclude_seed_node`` is `True`. Nodes can optionally be filtered
-        by ``filter_fn``: only nodes for which ``filter_fn`` returns `True` when
+        unless ``exclude_seed_node`` is |True|. Nodes can optionally be filtered
+        by ``filter_fn``: only nodes for which ``filter_fn`` returns |True| when
         passed the node as an argument are yielded.
 
         Parameters
         ----------
         filter_fn : function object, optional
             A function object that takes a |Node| object as an argument
-            and returns `True` if the |Node| object is to be yielded by
-            the iterator, or `False` if not. If ``filter_fn`` is `None`
+            and returns |True| if the |Node| object is to be yielded by
+            the iterator, or |False| if not. If ``filter_fn`` is |None|
             (default), then all nodes visited will be yielded.
         exclude_seed_node : boolean, optional
-            If `False` (default), then the seed node or root is visited. If
-            `True`, then the seed node is skipped.
+            If |False| (default), then the seed node or root is visited. If
+            |True|, then the seed node is skipped.
 
         Returns
         -------
@@ -1109,17 +1117,17 @@ class Node(
         """
         Post-order iterator over nodes of subtree rooted at this node.
 
-        Visits self and all descendant nodes, with each node visited first
-        followed by its children. Nodes can optionally be filtered by
-        ``filter_fn``: only nodes for which ``filter_fn`` returns `True` when
-        called with the node as an argument are yielded.
+        Visits self and all descendant nodes, with each node visited after its
+        children. Nodes can optionally be filtered by ``filter_fn``: only nodes
+        for which ``filter_fn`` returns |True| when called with the node as an
+        argument are yielded.
 
         Parameters
         ----------
         filter_fn : function object, optional
             A function object that takes a |Node| object as an argument
-            and returns `True` if the |Node| object is to be yielded by
-            the iterator, or `False` if not. If ``filter_fn`` is `None`
+            and returns |True| if the |Node| object is to be yielded by
+            the iterator, or |False| if not. If ``filter_fn`` is |None|
             (default), then all nodes visited will be yielded.
 
         Returns
@@ -1168,20 +1176,20 @@ class Node(
         Visits self and all internal descendant nodes, with each node visited
         after its children. In DendroPy, "internal nodes" are nodes that have
         at least one child node, and thus the root or seed node is typically
-        included unless ``exclude_seed_node`` is `True`. Nodes can optionally be
+        included unless ``exclude_seed_node`` is |True|. Nodes can optionally be
         filtered by ``filter_fn``: only nodes for which ``filter_fn`` returns
-        `True` when passed the node as an argument are yielded.
+        |True| when passed the node as an argument are yielded.
 
         Parameters
         ----------
         filter_fn : function object, optional
             A function object that takes a |Node| object as an argument
-            and returns `True` if the |Node| object is to be yielded by
-            the iterator, or `False` if not. If ``filter_fn`` is `None`
+            and returns |True| if the |Node| object is to be yielded by
+            the iterator, or |False| if not. If ``filter_fn`` is |None|
             (default), then all nodes visited will be yielded.
         exclude_seed_node : boolean, optional
-            If `False` (default), then the seed node or root is visited. If
-            `True`, then the seed node is skipped.
+            If |False| (default), then the seed node or root is visited. If
+            |True|, then the seed node is skipped.
 
         Returns
         -------
@@ -1206,15 +1214,15 @@ class Node(
         Visits self and all descendant nodes, with each node and other nodes at
         the same level (distance from root) visited before their children.
         Nodes can optionally be filtered by ``filter_fn``: only nodes for which
-        ``filter_fn`` returns `True` when called with the node as an argument are
+        ``filter_fn`` returns |True| when called with the node as an argument are
         visited.
 
         Parameters
         ----------
         filter_fn : function object, optional
             A function object that takes a |Node| object as an argument
-            and returns `True` if the |Node| object is to be yielded by
-            the iterator, or `False` if not. If ``filter_fn`` is `None`
+            and returns |True| if the |Node| object is to be yielded by
+            the iterator, or |False| if not. If ``filter_fn`` is |None|
             (default), then all nodes visited will be yielded.
 
         Returns
@@ -1249,14 +1257,14 @@ class Node(
         Visits self and all descendant nodes, with each node visited in-between
         its children. Only valid for strictly-bifurcating trees. Nodes can
         optionally be filtered by ``filter_fn``: only nodes for which ``filter_fn``
-        returns `True` when called with the node as an argument are yielded.
+        returns |True| when called with the node as an argument are yielded.
 
         Parameters
         ----------
         filter_fn : function object, optional
             A function object that takes a |Node| object as an argument
-            and returns `True` if the |Node| object is to be yielded by
-            the iterator, or `False` if not. If ``filter_fn`` is `None`
+            and returns |True| if the |Node| object is to be yielded by
+            the iterator, or |False| if not. If ``filter_fn`` is |None|
             (default), then all nodes visited will be yielded.
 
         Returns
@@ -1284,14 +1292,14 @@ class Node(
 
         Visits all leaf or tip nodes descended from this node. Nodes can
         optionally be filtered by ``filter_fn``: only nodes for which ``filter_fn``
-        returns `True` when called with the node as an argument are yielded.
+        returns |True| when called with the node as an argument are yielded.
 
         Parameters
         ----------
         filter_fn : function object, optional
             A function object that takes a |Node| object as an argument
-            and returns `True` if the |Node| object is to be yielded by
-            the iterator, or `False` if not. If ``filter_fn`` is `None`
+            and returns |True| if the |Node| object is to be yielded by
+            the iterator, or |False| if not. If ``filter_fn`` is |None|
             (default), then all nodes visited will be yielded.
 
         Returns
@@ -1314,8 +1322,8 @@ class Node(
         ----------
         filter_fn : function object, optional
             A function object that takes a |Node| object as an argument
-            and returns `True` if the |Node| object is to be yielded by
-            the iterator, or `False` if not. If ``filter_fn`` is `None`
+            and returns |True| if the |Node| object is to be yielded by
+            the iterator, or |False| if not. If ``filter_fn`` is |None|
             (default), then all nodes visited will be yielded.
 
         Returns
@@ -1335,8 +1343,8 @@ class Node(
         ----------
         filter_fn : function object, optional
             A function object that takes a |Edge| object as an argument
-            and returns `True` if the |Edge| object is to be yielded by
-            the iterator, or `False` if not. If ``filter_fn`` is `None`
+            and returns |True| if the |Edge| object is to be yielded by
+            the iterator, or |False| if not. If ``filter_fn`` is |None|
             (default), then all edges visited will be yielded.
 
         Returns
@@ -1353,20 +1361,20 @@ class Node(
         Iterator over all ancestors of this node.
 
         Visits all nodes that are the ancestors of this node.  If ``inclusive``
-        is `True`, ``self`` is returned as the first item of the sequence;
+        is |True|, ``self`` is returned as the first item of the sequence;
         otherwise ``self`` is skipped. Nodes can optionally be filtered by
-        ``filter_fn``: only nodes for which ``filter_fn`` returns `True` when
+        ``filter_fn``: only nodes for which ``filter_fn`` returns |True| when
         passed the node as an argument are yielded.
 
         Parameters
         ----------
         filter_fn : function object, optional
             A function object that takes a |Node| object as an argument
-            and returns `True` if the |Node| object is to be yielded by
-            the iterator, or `False` if not. If ``filter_fn`` is `None`
+            and returns |True| if the |Node| object is to be yielded by
+            the iterator, or |False| if not. If ``filter_fn`` is |None|
             (default), then all nodes visited will be yielded.
         inclusive : boolean, optional
-            If `True`, includes this node in the sequence. If `False`, this is
+            If |True|, includes this node in the sequence. If |False|, this is
             skipped.
 
         Returns
@@ -1391,25 +1399,25 @@ class Node(
         Iterates over nodes in order of age ('age' is as given by the ``age``
         attribute, which is usually the sum of edge lengths from tips
         to node, i.e., time since present).
-        If ``include_leaves`` is `True` (default), leaves are included in the
-        iteration; if ``include_leaves`` is `False`, leaves will be skipped.
-        If ``descending`` is `False` (default), younger nodes will be returned
-        before older ones; if `True`, older nodes will be returned before
+        If ``include_leaves`` is |True| (default), leaves are included in the
+        iteration; if ``include_leaves`` is |False|, leaves will be skipped.
+        If ``descending`` is |False| (default), younger nodes will be returned
+        before older ones; if |True|, older nodes will be returned before
         younger ones.
 
         Parameters
         ----------
         filter_fn : function object, optional
             A function object that takes a |Node| object as an argument
-            and returns `True` if the |Node| object is to be yielded by
-            the iterator, or `False` if not. If ``filter_fn`` is `None`
+            and returns |True| if the |Node| object is to be yielded by
+            the iterator, or |False| if not. If ``filter_fn`` is |None|
             (defau
         include_leaves : boolean, optional
-            If `True` (default), then leaf nodes are included in the iteration.
-            If `False`, then leaf nodes are skipped.lt), then all nodes visited will be yielded.
+            If |True| (default), then leaf nodes are included in the iteration.
+            If |False|, then leaf nodes are skipped.lt), then all nodes visited will be yielded.
         descending : boolean, optional
-            If `False` (default), then younger nodes are visited before older
-            ones. If `True`, then older nodes are visited before younger ones.
+            If |False| (default), then younger nodes are visited before older
+            ones. If |True|, then older nodes are visited before younger ones.
 
         Returns
         -------
@@ -1519,11 +1527,11 @@ class Node(
 
         Parameters
         ----------
-        before_fn : function object or `None`
+        before_fn : function object or |None|
             A function object that takes a |Node| as its argument.
-        after_fn : function object or `None`
+        after_fn : function object or |None|
             A function object that takes a |Node| as its argument.
-        leaf_fn : function object or `None`
+        leaf_fn : function object or |None|
             A function object that takes a |Node| as its argument.
 
         Notes
@@ -1687,19 +1695,19 @@ class Node(
         """
         Removes a node from the child set of this node.
 
-        Results in the parent of the node being removed set to `None`.  If
-        ``suppress_unifurcations`` is `True`, if this node ends up having only one
+        Results in the parent of the node being removed set to |None|.  If
+        ``suppress_unifurcations`` is |True|, if this node ends up having only one
         child after removal of the specified node, then this node will be
         removed from the tree, with its single child added to the child node
         set of its parent and the edge length adjusted accordingly.
-        ``suppress_unifurcations`` should only be `True` for unrooted trees.
+        ``suppress_unifurcations`` should only be |True| for unrooted trees.
 
         Parameters
         ----------
         node : |Node|
             The node to be removed.
         suppress_unifurcations : boolean, optional
-            If `False` (default), no action is taken. If `True`, then if the
+            If |False| (default), no action is taken. If |True|, then if the
             node removal results in a node with degree of two (i.e., a single
             parent and a single child), then it will be removed from
             the tree and its (sole) child will be added as a child of its
@@ -1995,25 +2003,25 @@ class Node(
 
     def is_leaf(self):
         """
-        Returns `True` if the node is a tip or a leaf node, i.e. has no child
+        Returns |True| if the node is a tip or a leaf node, i.e. has no child
         nodes.
 
         Returns
         -------
         boolean
-            `True` if the node is a leaf, i.e., has no child nodes. `False`
+            |True| if the node is a leaf, i.e., has no child nodes. |False|
             otherwise.
         """
         return bool(not self._child_nodes)
 
     def is_internal(self):
         """
-        Returns `True` if the node is *not* a tip or a leaf node.
+        Returns |True| if the node is *not* a tip or a leaf node.
 
         Returns
         -------
         boolean
-            `True` if the node is not a leaf. `False` otherwise.
+            |True| if the node is not a leaf. |False| otherwise.
         """
         return bool(self._child_nodes)
 
@@ -2138,6 +2146,116 @@ class Node(
         """Legacy synonym for :meth:`Node.sister_nodes()`"""
         return self.sibling_nodes()
 
+    def extract_subtree(self,
+            extraction_source_reference_attr_name="extraction_source",
+            node_filter_fn=None,
+            suppress_unifurcations=True,
+            is_apply_filter_to_leaf_nodes=True,
+            is_apply_filter_to_internal_nodes=False,
+            node_factory=None,
+            ):
+        """
+        Returns a clone of the structure descending from this node.
+
+        Parameters
+        ----------
+        extraction_source_reference_attr_name : str
+            Name of attribute to set on cloned nodes that references
+            corresponding original node. If ``None``, then attribute (and
+            reference) will not be created.
+        node_filter_fn : None or function object
+            If ``None``, then entire tree structure is cloned.
+            If not ``None``, must be a function object that returns ``True``
+            if a particular |Node| instance on the original tree should
+            be included in the cloned tree, or ``False`` otherwise.
+        is_apply_filter_to_leaf_nodes : bool
+            If ``True`` then the above filter will be applied to leaf nodes. If
+            ``False`` then it will not (and all leaf nodes will be
+            automatically included, unless excluded by an ancestral node being
+            filtered out).
+        is_apply_filter_to_internal_nodes : bool
+            If ``True`` then the above filter will be applied to internal nodes. If
+            ``False`` then it will not (internal nodes without children will
+            still be filtered out).
+        node_factory : function
+            If not ``None``, must be a function that takes no arguments and
+            returns a new |Node| (or equivalent) instance.
+
+        Returns
+        -------
+        nd : |Node|
+            A node with descending subtree mirroring this one.
+
+        """
+        memo = {}
+        is_excluded_nodes = False
+        start_node = None
+        start_node_to_match = self
+        if node_factory is None:
+            node_factory = self.__class__
+        for nd0 in self.postorder_iter():
+            if node_filter_fn is not None:
+                if nd0._child_nodes:
+                    if is_apply_filter_to_internal_nodes:
+                        is_apply_filter = True
+                    else:
+                        is_apply_filter = False
+                else:
+                    if is_apply_filter_to_leaf_nodes:
+                        is_apply_filter = True
+                    else:
+                        is_apply_filter = False
+                if is_apply_filter and not node_filter_fn(nd0):
+                    is_excluded_nodes = True
+                    continue
+            original_node_has_children = False
+            children_to_add = []
+            for ch_nd0 in nd0.child_node_iter():
+                original_node_has_children = True
+                ch_nd1 = memo.get(ch_nd0, None)
+                if ch_nd1 is not None:
+                    children_to_add.append(ch_nd1)
+            if not children_to_add and original_node_has_children:
+                # filter removes all descendents of internal node,
+                # so this internal node is not added
+                if nd0.parent_node is None:
+                    raise error.SeedNodeDeletionException("Attempting to remove seed node or node without parent")
+                if nd0 is self:
+                    start_node_to_match = nd0.parent_node
+                continue
+            elif len(children_to_add) == 1 and suppress_unifurcations:
+                if nd0.edge.length is not None:
+                    if children_to_add[0].edge.length is None:
+                        children_to_add[0].edge.length = nd0.edge.length
+                    else:
+                        children_to_add[0].edge.length += nd0.edge.length
+                else:
+                    nd1.edge.length = children_to_add[0].edge.length
+                if nd0.parent_node is None:
+                    start_node = children_to_add[0]
+                    break
+                if nd0 is self:
+                    start_node_to_match = nd0.parent_node
+                memo[nd0] = children_to_add[0]
+            else:
+                nd1 = node_factory()
+                nd1.label = nd0.label
+                nd1.taxon = nd0.taxon
+                nd1.edge.length = nd0.edge.length
+                nd1.edge.label = nd0.edge.label
+                for ch_nd1 in children_to_add:
+                    nd1.add_child(ch_nd1)
+                if nd0 is start_node_to_match:
+                    start_node = nd1
+                memo[nd0] = nd1
+                if extraction_source_reference_attr_name:
+                    setattr(nd1, extraction_source_reference_attr_name, nd0)
+        if start_node is not None:
+            return start_node
+        else:
+            ## TODO: find a replacement node
+            raise ValueError
+
     ###########################################################################
     ### Metrics
 
@@ -2427,7 +2545,7 @@ class Tree(
         used to specify the 0-based index of the tree collection, and
         ``tree_offset`` argument can be used to specify the 0-based index of
         the tree within the collection, as the source. If ``collection_offset``
-        is not specified or `None`, then the first collection (offset=0) is
+        is not specified or |None|, then the first collection (offset=0) is
         assumed. If ``tree_offset`` is not specified, then the first tree
         (offset=0) is returned.
 
@@ -2435,7 +2553,7 @@ class Tree(
         :meth:|TreeList|.read()`, which wraps the actual parsing.
 
         If no tree is found in the source according to the specified criteria,
-        then `None` is returned.
+        then |None| is returned.
 
         Notes
         -----
@@ -2485,9 +2603,9 @@ class Tree(
 
         Returns
         -------
-        |Tree| or `None`
+        |Tree| or |None|
             The |Tree| object corresponding to the tree in the data
-            source, or `None` if no valid tree description was found.
+            source, or |None| if no valid tree description was found.
 
         """
         from dendropy.datamodel.treecollectionmodel import TreeList
@@ -2549,7 +2667,7 @@ class Tree(
 
             - **label** (*str*) -- Name or identifier to be assigned to the new
               object; if not given, will be assigned the one specified in the
-              data source, or `None` otherwise.
+              data source, or |None| otherwise.
             - **taxon_namespace** (|TaxonNamespace|) -- The |TaxonNamespace|
               instance to use to :doc:`manage the taxon names </primer/taxa>`.
               If not specified, a new one will be created.
@@ -2559,9 +2677,9 @@ class Tree(
             - **tree_offset** (*int*) -- 0-based index of tree within the
               collection specified by ``collection_offset`` to be parsed. If
               not specified, then the first tree (offset = 0) is assumed.
-            - **ignore_unrecognized_keyword_arguments** (*bool*) -- If `True`,
+            - **ignore_unrecognized_keyword_arguments** (*bool*) -- If |True|,
               then unsupported or unrecognized keyword arguments will not
-              result in an error. Default is `False`: unsupported keyword
+              result in an error. Default is |False|: unsupported keyword
               arguments will result in an error.
 
         **Optional Schema-Specific Keyword Arguments:**
@@ -2720,7 +2838,7 @@ class Tree(
             taxon definitions.
         is_rooted : bool
             Specifies whether or not the tree is rooted.
-        edge_lengths : iterable or `None`
+        edge_lengths : iterable or |None|
             An iterable of edge lengths. This should be in the same order
             as the bipartitions in the bipartition encoding.
 
@@ -2769,8 +2887,8 @@ class Tree(
             taxon definitions.
         is_rooted : bool
             Specifies whether or not the tree is rooted.
-        edge_lengths : dict or `False` or `None`
-            If `False` or `None`, then no edge lengths will be added.
+        edge_lengths : dict or |False| or |None|
+            If |False| or |None|, then no edge lengths will be added.
             Otherwise, this should be a dictionary mapping splits to edge
             lengths.
         Returns
@@ -3074,6 +3192,9 @@ class Tree(
     def __eq__(self, other):
         return self is other
 
+    ##############################################################################
+    ## Copying/cloning
+
     def _clone_from(self, tree, kwargs_dict):
         # super(Tree, self).__init__()
         memo = {}
@@ -3141,86 +3262,379 @@ class Tree(
         # return other
 
     ###########################################################################
-    ### I/O
+    ### Extracting Trees and Subtrees
+
+    def extract_tree(self,
+            extraction_source_reference_attr_name="extraction_source",
+            node_filter_fn=None,
+            suppress_unifurcations=True,
+            is_apply_filter_to_leaf_nodes=True,
+            is_apply_filter_to_internal_nodes=False,
+            tree_factory=None,
+            node_factory=None,
+            ):
+        """
+        Returns a copy of this tree that only includes the basic structure
+        (nodes, edges), and minimal attributes (edge lengths, node labels, and
+        taxon associations). Annotations, comments, and other attributes are
+        not copied.
+
+        Parameters
+        ----------
+        extraction_source_reference_attr_name : str
+            Name of attribute to set on cloned nodes that references
+            corresponding original node. If ``None``, then attribute (and
+            reference) will not be created.
+        node_filter_fn : None or function object
+            If ``None``, then entire tree structure is cloned.
+            If not ``None``, must be a function object that returns ``True``
+            if a particular |Node| instance on the original tree should
+            be included in the cloned tree, or ``False`` otherwise.
+        suppress_unifurcations : bool
+            If |True|, nodes of outdegree 1 will be deleted. Only will
+            be done if some nodes are excluded from the cloned tree.
+        is_apply_filter_to_leaf_nodes : bool
+            If ``True`` then the above filter will be applied to leaf nodes. If
+            ``False`` then it will not (and all leaf nodes will be
+            automatically included, unless excluded by an ancestral node being
+            filtered out).
+        is_apply_filter_to_internal_nodes : bool
+            If ``True`` then the above filter will be applied to internal nodes. If
+            ``False`` then it will not (internal nodes without children will
+            still be filtered out).
+        tree_factory : function
+            If not ``None``, must be a function that optionally takes a
+            |TaxonNamespace| as an argument and returns a new |Tree| (or
+            equivalent) instance.
+        node_factory : function
+            If not ``None``, must be a function that takes no arguments and
+            returns a new |Node| (or equivalent) instance.
+
+        Examples
+        --------
+
+        A simple clone::
+
+            tree0 = dendropy.Tree.get(
+                        path="mammals.tre",
+                        schema="newick")
+            tree1 = tree0.extract_tree()
+
+        A clone that only extracts a subtree with taxa in the genus
+        "Rhacophorus"::
+
+            tree0 = dendropy.Tree.get(
+                        path="old_world_frogs.tre",
+                        schema="newick")
+            # Include taxa only if label starts with "Rhacophorus"
+            node_filter_fn = lambda nd: nd.is_internal() or \
+                        nd.taxon.label.startswith("Rhacophorus")
+            tree1 = tree0.extract_tree(node_filter_fn=node_filter_fn)
+
+            # Above is equivalent to, but more efficient than:
+            #   inclusion_set = [nd.taxon for nd in tree0.leaf_node_iter()
+            #           if nd.taxon.label.startswith("Rhacophorus)]
+            #   tree1 = dendropy.Tree(tree0)
+            #   tree1.retain_taxa(inclusion_set)
+
+        A clone that only extracts a subtree with nodes with taxa associated
+        with the habitat "mountain" or "forest"::
+
+            tree0 = dendropy.Tree.get(
+                        path="birds.tre",
+                        schema="newick")
+            include_habitats = set(["mountain", "forest"])
+            node_filter_fn = lambda nd: nd.taxon is None or \
+                        nd.taxon.annotations["habitat"] in include_habitats
+            tree1 = tree0.extract_tree(node_filter_fn=node_filter_fn)
+
+        Returns
+        -------
+        t : |Tree|
+            A new tree based on this one, with nodes filtered out if specified.
+
+        """
+        if tree_factory is None:
+            other = self.__class__(taxon_namespace=self.taxon_namespace)
+        else:
+            other = tree_factory(taxon_namespace=self.taxon_namespace)
+            if node_factory is None:
+                try:
+                    node_factory = other.node_factory
+                except AttributeError:
+                    pass
+        other._is_rooted = self._is_rooted
+        other.weight = self.weight
+        other.length_type = self.length_type
+        other.label = self.label
+        other.seed_node = self.seed_node.extract_subtree(
+                extraction_source_reference_attr_name=extraction_source_reference_attr_name,
+                node_filter_fn=node_filter_fn,
+                suppress_unifurcations=suppress_unifurcations,
+                is_apply_filter_to_leaf_nodes=is_apply_filter_to_leaf_nodes,
+                is_apply_filter_to_internal_nodes=is_apply_filter_to_internal_nodes,
+                node_factory=node_factory,
+                )
+        return other
+
+    def extract_tree_with_taxa(self,
+            taxa,
+            extraction_source_reference_attr_name="extraction_source",
+            suppress_unifurcations=True,
+            ):
+        """
+        Returns a copy of this tree that only includes leaf nodes if they
+        are associated with the taxon objects listed in ``taxa``. Note that
+        this copy will be a "thin" copy, including just the basic structure
+        (nodes, edges) and minimal attributes (edge lengths, node labels, and
+        taxon associations). Annotations, comments, and other attributes are
+        not copied.
 
-    # def _parse_and_add_from_stream(self, stream, schema, **kwargs):
-    #     """
-    #     Redefines this |Tree| object based on data from ``source``.
-
-    #     The current |TaxonNamespace| reference will be retained (and
-    #     modified if new operational taxonomic unit concept definitions
-    #     are encountered in the data source). *All* other information,
-    #     including metadata/annotations, will be lost or replaced with
-    #     information from the new data source.
-
-    #     If the source defines multiple tree collections (e.g. multiple NEXUS
-    #     "Trees" blocks), then the ``collection_offset`` argument
-    #     can be used to specify the 0-based index of the tree collection, and
-    #     ``tree_offset`` argument can be used to specify the 0-based
-    #     index of the tree within the collection, as the source. If
-    #     ``collection_offset`` is not specified or `None`, then all collections in
-    #     the source are merged before considering ``tree_offset``.  If
-    #     ``tree_offset`` is not specified, then the first tree (offset=0) is
-    #     returned.
-
-    #     Notes
-    #     -----
-    #     *All* operational taxonomic unit concepts in the data source will be included
-    #     in the |TaxonNamespace| object associated with the new
-    #     |TreeList| object and its contained |Tree| objects, even those
-    #     not associated with tree being retrieved.
-
-    #     Parameters
-    #     ----------
-
-    #     stream : file or file-like object
-    #         Source of data.
-
-    #     schema : string
-    #         Identifier of format of data in ``stream``
-
-    #     collection_offset : integer or None
-    #         0-based index of tree block or collection in source to be parsed.
-
-    #     tree_offset : integer or None
-    #         0-based index of tree in source to be parsed. If
-    #         ``collection_offset`` is `None`, then this is the 0-based index of
-    #         the tree across all collections considered together. Otherwise,
-    #         this is the 0-based index within a particular collection. If
-    #         ``tree_offset`` is `None` or not specified, then the first tree is
-    #         returned.
-
-    #     \*\*kwargs : keyword arguments
-    #         Arguments to customize parsing and instantiation this |Tree|
-    #         from the data source, including schema- or format-specific
-    #         handling. The following optional keyword arguments are recognized
-    #         and handled by this constructor:
-
-    #             - ``label``: The label the tree |Tree| object.
-
-    #         Other keyword arguments may be available, depending on the
-    #         implementation of the reader specialized to handle ``schema``
-    #         formats. See documentation for details on keyword arguments
-    #         supported by readers of various schemas.
-
-    #     Returns
-    #     -------
-    #     tree : |Tree|
-    #          Returns ``self``.
-
-    #     Raises
-    #     ------
-    #     ValueError
-    #         If no valid trees matching criteria found in source.
-
-    #     """
-    #     if "taxon_namespace" in kwargs and kwargs['taxon_namespace'] is not self.taxon_namespace:
-    #         raise TypeError("Cannot change ``taxon_namespace`` when reading an existing Tree")
-    #     kwargs["taxon_namespace"] = self.taxon_namespace
-    #     tree = Tree._parse_and_create_from_stream(stream, schema, **kwargs)
-    #     if tree is None:
-    #         raise ValueError("Invalid tree source specification")
-    #     self.__dict__ = tree.__dict__
+        Parameters
+        ----------
+        taxa : iterable of |Taxon| instances
+            List or some other iterable of |Taxon| objects to include.
+        suppress_unifurcations : bool
+            If |True|, nodes of outdegree 1 will be deleted. Only will
+            be done if some nodes are excluded from the cloned tree.
+        is_apply_filter_to_leaf_nodes : bool
+            If ``True`` then the above filter will be applied to leaf nodes. If
+            ``False`` then it will not (and all leaf nodes will be
+            automatically included, unless excluded by an ancestral node being
+            filtered out).
+        is_apply_filter_to_internal_nodes : bool
+            If ``True`` then the above filter will be applied to internal nodes. If
+            ``False`` then it will not (internal nodes without children will
+            still be filtered out).
+
+        Examples
+        --------
+
+        A clone that only extracts a subtree with taxa in the genus
+        "Rhacophorus"::
+
+            tree0 = dendropy.Tree.get(
+                        path="old_world_frogs.tre",
+                        schema="newick")
+            # Include taxa only if label starts with "Rhacophorus"
+            taxa_to_retain = set([taxon for taxon in tree0.taxon_namespace
+                    if taxon.label.startswith("Rhacophorus")])
+            tree1 = tree0.extract_tree_with_taxa(taxa=taxa_to_retain)
+
+            # Above is equivalent to, but more efficient than:
+            #   inclusion_set = [nd.taxon for nd in tree0.leaf_node_iter()
+            #           if nd.taxon.label.startswith("Rhacophorus)]
+            #   tree1 = dendropy.Tree(tree0)
+            #   tree1.retain_taxa(inclusion_set)
+
+        Returns
+        -------
+        t : |Tree|
+            A new tree based on this one, with nodes filtered out if specified.
+
+        """
+        node_filter_fn = lambda nd: nd.taxon is None or nd.taxon in set(taxa)
+        return self.extract_tree(
+                node_filter_fn=node_filter_fn,
+                extraction_source_reference_attr_name=extraction_source_reference_attr_name,
+                is_apply_filter_to_leaf_nodes=True,
+                is_apply_filter_to_internal_nodes=False,
+                )
+
+    def extract_tree_with_taxa_labels(self,
+            labels,
+            extraction_source_reference_attr_name="extraction_source",
+            suppress_unifurcations=True,
+            ):
+        """
+        Returns a copy of this tree that only includes leaf nodes if they are
+        associated with taxon objects with labels matching those listed in
+        ``labels``. Note that this copy will be a "thin" copy, including just
+        the basic structure (nodes, edges) and minimal attributes (edge
+        lengths, node labels, and taxon associations). Annotations,
+        comments, and other attributes are not copied.
+
+        Parameters
+        ----------
+        labels : iterable of str instances
+            List or some other iterable of strings to match.
+        suppress_unifurcations : bool
+            If |True|, nodes of outdegree 1 will be deleted. Only will
+            be done if some nodes are excluded from the cloned tree.
+        is_apply_filter_to_leaf_nodes : bool
+            If ``True`` then the above filter will be applied to leaf nodes. If
+            ``False`` then it will not (and all leaf nodes will be
+            automatically included, unless excluded by an ancestral node being
+            filtered out).
+        is_apply_filter_to_internal_nodes : bool
+            If ``True`` then the above filter will be applied to internal nodes. If
+            ``False`` then it will not (internal nodes without children will
+            still be filtered out).
+
+        Examples
+        --------
+
+        A clone that only extracts a subtree with taxa in the genus
+        "Rhacophorus"::
+
+            tree0 = dendropy.Tree.get(
+                        path="old_world_frogs.tre",
+                        schema="newick")
+            # Include taxa only if label starts with "Rhacophorus"
+            labels = set([taxon.label for taxon in tree0.taxon_namespace
+                    if taxon.label.startswith("Rhacophorus")])
+            tree1 = tree0.extract_tree_with_taxa_labels(labels=labels)
+
+            # Above is equivalent to, but more efficient than:
+            #   inclusion_set = [nd.taxon for nd in tree0.leaf_node_iter()
+            #           if nd.taxon.label.startswith("Rhacophorus)]
+            #   tree1 = dendropy.Tree(tree0)
+            #   tree1.retain_taxa(inclusion_set)
+
+        Returns
+        -------
+        t : |Tree|
+            A new tree based on this one, with nodes filtered out if specified.
+
+        """
+        node_filter_fn = lambda nd: nd.taxon is None or nd.taxon.label in set(labels)
+        return self.extract_tree(
+                node_filter_fn=node_filter_fn,
+                extraction_source_reference_attr_name=extraction_source_reference_attr_name,
+                is_apply_filter_to_leaf_nodes=True,
+                is_apply_filter_to_internal_nodes=False,
+                )
+
+    def extract_tree_without_taxa(self,
+            taxa,
+            extraction_source_reference_attr_name="extraction_source",
+            suppress_unifurcations=True,
+            ):
+        """
+        Returns a copy of this tree that only includes leaf nodes if they
+        are NOT associated with the taxon objects listed in ``taxa``. Note that
+        this copy will be a "thin" copy, including just the basic structure
+        (nodes, edges) and minimal attributes (edge lengths, node labels, and
+        taxon associations). Annotations, comments, and other attributes are
+        not copied.
+
+        Parameters
+        ----------
+        taxa : iterable of |Taxon| instances
+            List or some other iterable of |Taxon| objects to exclude.
+        suppress_unifurcations : bool
+            If |True|, nodes of outdegree 1 will be deleted. Only will
+            be done if some nodes are excluded from the cloned tree.
+        is_apply_filter_to_leaf_nodes : bool
+            If ``True`` then the above filter will be applied to leaf nodes. If
+            ``False`` then it will not (and all leaf nodes will be
+            automatically included, unless excluded by an ancestral node being
+            filtered out).
+        is_apply_filter_to_internal_nodes : bool
+            If ``True`` then the above filter will be applied to internal nodes. If
+            ``False`` then it will not (internal nodes without children will
+            still be filtered out).
+
+        Examples
+        --------
+
+        A clone that only extracts a subtree with taxa NOT in the genus
+        "Rhacophorus"::
+
+            tree0 = dendropy.Tree.get(
+                        path="old_world_frogs.tre",
+                        schema="newick")
+            # Exclude taxa if their name starts with "Rhacophorus"
+            taxa_to_exclude = set([taxon for taxon in tree0.taxon_namespace
+                    if taxon.label.startswith("Rhacophorus")])
+            tree1 = tree0.extract_tree_with_taxa(taxa=taxa_to_retain)
+
+            # Above is equivalent to, but more efficient than:
+            #   inclusion_set = [nd.taxon for nd in tree0.leaf_node_iter()
+            #           if nd.taxon.label.startswith("Rhacophorus)]
+            #   tree1 = dendropy.Tree(tree0)
+            #   tree1.retain_taxa(inclusion_set)
+
+        Returns
+        -------
+        t : |Tree|
+            A new tree based on this one, with nodes filtered out if specified.
+
+        """
+        node_filter_fn = lambda nd: nd.taxon is None or nd.taxon not in set(taxa)
+        return self.extract_tree(
+                node_filter_fn=node_filter_fn,
+                extraction_source_reference_attr_name=extraction_source_reference_attr_name,
+                is_apply_filter_to_leaf_nodes=True,
+                is_apply_filter_to_internal_nodes=False,
+                )
+
+    def extract_tree_without_taxa_labels(self,
+            labels,
+            extraction_source_reference_attr_name="extraction_source",
+            suppress_unifurcations=True,
+            ):
+        """
+        Returns a copy of this tree that only includes leaf nodes if they
+        are NOT associated with the taxon objects listed in ``taxa``. Note that
+        this copy will be a "thin" copy, including just the basic structure
+        (nodes, edges) and minimal attributes (edge lengths, node labels, and
+        taxon associations). Annotations, comments, and other attributes are
+        not copied.
+
+        Parameters
+        ----------
+        labels : iterable of str instances
+            List or some other iterable of strings to match.
+        suppress_unifurcations : bool
+            If |True|, nodes of outdegree 1 will be deleted. Only will
+            be done if some nodes are excluded from the cloned tree.
+        is_apply_filter_to_leaf_nodes : bool
+            If ``True`` then the above filter will be applied to leaf nodes. If
+            ``False`` then it will not (and all leaf nodes will be
+            automatically included, unless excluded by an ancestral node being
+            filtered out).
+        is_apply_filter_to_internal_nodes : bool
+            If ``True`` then the above filter will be applied to internal nodes. If
+            ``False`` then it will not (internal nodes without children will
+            still be filtered out).
+
+        Examples
+        --------
+
+        A clone that only extracts a subtree with taxa NOT in the genus
+        "Rhacophorus"::
+
+            tree0 = dendropy.Tree.get(
+                        path="old_world_frogs.tre",
+                        schema="newick")
+            # Exclude taxa if label starts with "Rhacophorus"
+            labels = set([taxon.label for taxon in tree0.taxon_namespace
+                    if taxon.label.startswith("Rhacophorus")])
+            tree1 = tree0.extract_tree_without_taxa_labels(labels=labels)
+
+            # Above is equivalent to, but more efficient than:
+            #   inclusion_set = [nd.taxon for nd in tree0.leaf_node_iter()
+            #           if nd.taxon.label.startswith("Rhacophorus)]
+            #   tree1 = dendropy.Tree(tree0)
+            #   tree1.prune_taxa(inclusion_set)
+
+        Returns
+        -------
+        t : |Tree|
+            A new tree based on this one, with nodes filtered out if specified.
+
+        """
+        node_filter_fn = lambda nd: nd.taxon is None or nd.taxon.label not in set(labels)
+        return self.extract_tree(
+                node_filter_fn=node_filter_fn,
+                extraction_source_reference_attr_name=extraction_source_reference_attr_name,
+                is_apply_filter_to_leaf_nodes=True,
+                is_apply_filter_to_internal_nodes=False,
+                )
+
+    ###########################################################################
+    ### I/O
 
     def _format_and_write_to_stream(self, stream, schema, **kwargs):
         """
@@ -3263,8 +3677,8 @@ class Tree(
 
         filter_fn : function object, optional
             A function object that takes a |Node| object as an argument
-            and returns `True` if the |Node| object is to be included in
-            the list, or `False` if not. If ``filter_fn`` is `None` (default),
+            and returns |True| if the |Node| object is to be included in
+            the list, or |False| if not. If ``filter_fn`` is |None| (default),
             then all nodes visited will be included.
 
         Returns
@@ -3290,13 +3704,13 @@ class Tree(
         """
         Returns list of internal nodes in the tree.
 
-        Root or seed node is included unless ``exclude_seed_node`` is `True`.
+        Root or seed node is included unless ``exclude_seed_node`` is |True|.
 
         Parameters
         ----------
         exclude_seed_node : boolean, optional
-            If `False` (default), then the seed node or root is included. If
-            `True`, then the seed node is omitted.
+            If |False| (default), then the seed node or root is included. If
+            |True|, then the seed node is omitted.
 
         Returns
         -------
@@ -3313,8 +3727,8 @@ class Tree(
         ----------
         filter_fn : function object, optional
             A function object that takes a |Edge| object as an argument
-            and returns `True` if the |Edge| object is to be included,
-            or `False` if not. If ``filter_fn`` is `None` (default), then all
+            and returns |True| if the |Edge| object is to be included,
+            or |False| if not. If ``filter_fn`` is |None| (default), then all
             edges will be included.
 
         Returns
@@ -3343,8 +3757,8 @@ class Tree(
         Parameters
         ----------
         exclude_seed_node : boolean, optional
-            If `False` (default), then the edge subtending the seed node or
-            root is included. If `True`, then the seed node is omitted.
+            If |False| (default), then the edge subtending the seed node or
+            root is included. If |True|, then the seed node is omitted.
 
         Returns
         -------
@@ -3366,28 +3780,57 @@ class Tree(
 
         then::
 
-            t.find_node(filter_fn=filter_fn)
+            node = t.find_node(filter_fn=filter_fn)
 
-        will return all nodes which have an attribute 'genes' and this value
-        is not None.
+        will return the first node which has the attribute 'genes' and this
+        value is not None.
 
         Parameters
         ----------
         filter_fn : function object
             Takes a single |Node| object as an argument and returns
-            `True` if the node should be returned.
+            |True| if the node should be returned.
 
         Returns
         -------
-        |Node| or `None`
+        |Node| or |None|
             Returns first |Node| object for which the filter function
-            ``filter_fn`` returns `True`, or `None` if no such node exists on
+            ``filter_fn`` returns |True|, or |None| if no such node exists on
             this tree.
         """
         for node in self.preorder_node_iter(filter_fn):
             return node
         return None
 
+    def find_nodes(self, filter_fn):
+        """
+        Find all nodes for which ``filter_fn(node) == True``.
+
+        For example, if::
+
+            filter_fn = lambda n: hasattr(n, 'genes') and n.genes is not None
+
+        then::
+
+            nodes = t.find_node(filter_fn=filter_fn)
+
+        will return all nodes which have the attribute 'genes' and this
+        value is not None.
+
+        Parameters
+        ----------
+        filter_fn : function object
+            Takes a single |Node| object as an argument and returns
+            |True| if the node should be returned.
+
+        Returns
+        -------
+        nodes : list of |Node| instances
+            Returns list of |Node| objects for which the filter function
+            ``filter_fn`` returns |True|.
+        """
+        return [node for node in self.preorder_node_iter(filter_fn)]
+
     def find_node_with_label(self, label):
         """
         Returns first node with ``label`` attribute matching ``label`` argument.
@@ -3399,9 +3842,9 @@ class Tree(
 
         Returns
         -------
-        |Node| or `None`
+        |Node| or |None|
             Returns first |Node| object with ``label`` attribute having value
-            given in ``label``, or `None` if no such node is found.
+            given in ``label``, or |None| if no such node is found.
 
         """
         for node in self.preorder_node_iter():
@@ -3421,9 +3864,9 @@ class Tree(
 
         Returns
         -------
-        |Node| or `None`
+        |Node| or |None|
             Returns first |Node| object with ``taxon`` attribute referencing same
-            object as ``taxon`` argument, or `None` if no such node exists.
+            object as ``taxon`` argument, or |None| if no such node exists.
         """
         for node in self.postorder_node_iter():
             try:
@@ -3436,20 +3879,20 @@ class Tree(
     def find_node_with_taxon(self, taxon_filter_fn=None):
         """
         Returns node associated with |Taxon| object for which ``taxon_filter_fn``
-        returns `True`.
+        returns |True|.
 
         Parameters
         ----------
         taxon_filter_fn : function object
             Takes a single |Taxon| object as an argument and returns
-            `True` if the node associated with that |Taxon| should be
+            |True| if the node associated with that |Taxon| should be
             returned.
 
         Returns
         -------
-        |Node| or `None`
+        |Node| or |None|
             Returns first |Node| object with ``taxon`` attribute passing filter
-            function ``taxon_filter_fn``, or `None` if no such node is found.
+            function ``taxon_filter_fn``, or |None| if no such node is found.
         """
         for node in self.preorder_node_iter():
             if hasattr(node, "taxon") and node.taxon is not None:
@@ -3468,9 +3911,9 @@ class Tree(
 
         Returns
         -------
-        |Node| or `None`
+        |Node| or |None|
             Returns first |Node| object with ``taxon`` attribute having label
-            ``label``, or`None` if no such node is found.
+            ``label``, or|None| if no such node is found.
 
         """
         return self.find_node_with_taxon(lambda x: x.label == label)
@@ -3493,7 +3936,7 @@ class Tree(
             * have the labels specified by the list of strings given by the
               keyword argument ``taxon_labels``
 
-        Returns `None` if no appropriate node is found. Assumes that
+        Returns |None| if no appropriate node is found. Assumes that
         bipartitions have been encoded on the tree. It is possible that the
         leafset bitmask is not compatible with the subtree that is returned!
         (compatibility tests are not fully performed).  This function is used
@@ -3525,8 +3968,8 @@ class Tree(
 
         Returns
         -------
-        |Node| or `None`
-            The most-recent common ancestor of the nodes specified, or `None`
+        |Node| or |None|
+            The most-recent common ancestor of the nodes specified, or |None|
             if no such node exists.
         """
         start_node = kwargs.get("start_node", self.seed_node)
@@ -3610,15 +4053,15 @@ class Tree(
 
         Visits nodes in ``self``, with each node visited before its children.
         Nodes can optionally be filtered by ``filter_fn``: only nodes for which
-        ``filter_fn`` returns `True` when called with the node as an argument are
+        ``filter_fn`` returns |True| when called with the node as an argument are
         yielded.
 
         Parameters
         ----------
         filter_fn : function object, optional
             A function object that takes a |Node| object as an argument
-            and returns `True` if the |Node| object is to be yielded by
-            the iterator, or `False` if not. If ``filter_fn`` is `None`
+            and returns |True| if the |Node| object is to be yielded by
+            the iterator, or |False| if not. If ``filter_fn`` is |None|
             (default), then all nodes visited will be yielded.
 
         Returns
@@ -3635,20 +4078,20 @@ class Tree(
         Visits internal nodes in ``self``, with each node visited before its
         children. In DendroPy, "internal nodes" are nodes that have at least
         one child node, and thus the root or seed node is typically included
-        unless ``exclude_seed_node`` is `True`. Nodes can optionally be filtered
-        by ``filter_fn``: only nodes for which ``filter_fn`` returns `True` when
+        unless ``exclude_seed_node`` is |True|. Nodes can optionally be filtered
+        by ``filter_fn``: only nodes for which ``filter_fn`` returns |True| when
         passed the node as an argument are yielded.
 
         Parameters
         ----------
         filter_fn : function object, optional
             A function object that takes a |Node| object as an argument
-            and returns `True` if the |Node| object is to be yielded by
-            the iterator, or `False` if not. If ``filter_fn`` is `None`
+            and returns |True| if the |Node| object is to be yielded by
+            the iterator, or |False| if not. If ``filter_fn`` is |None|
             (default), then all nodes visited will be yielded.
         exclude_seed_node : boolean, optional
-            If `False` (default), then the seed node or root is visited. If
-            `True`, then the seed node is skipped.
+            If |False| (default), then the seed node or root is visited. If
+            |True|, then the seed node is skipped.
 
         Returns
         -------
@@ -3662,17 +4105,17 @@ class Tree(
         """
         Post-order iterator over nodes of tree.
 
-        Visits nodes in ``self``, with each node visited first followed by its
+        Visits self and all descendant nodes, with each node visited after its
         children. Nodes can optionally be filtered by ``filter_fn``: only nodes
-        for which ``filter_fn`` returns `True` when called with the node as an
+        for which ``filter_fn`` returns |True| when called with the node as an
         argument are yielded.
 
         Parameters
         ----------
         filter_fn : function object, optional
             A function object that takes a |Node| object as an argument
-            and returns `True` if the |Node| object is to be yielded by
-            the iterator, or `False` if not. If ``filter_fn`` is `None`
+            and returns |True| if the |Node| object is to be yielded by
+            the iterator, or |False| if not. If ``filter_fn`` is |None|
             (default), then all nodes visited will be yielded.
 
         Returns
@@ -3689,20 +4132,20 @@ class Tree(
         Visits internal nodes in ``self``, with each node visited after its
         children. In DendroPy, "internal nodes" are nodes that have at least
         one child node, and thus the root or seed node is typically included
-        unless ``exclude_seed_node`` is `True`. Nodes can optionally be filtered
-        by ``filter_fn``: only nodes for which ``filter_fn`` returns `True` when
+        unless ``exclude_seed_node`` is |True|. Nodes can optionally be filtered
+        by ``filter_fn``: only nodes for which ``filter_fn`` returns |True| when
         passed the node as an argument are yielded.
 
         Parameters
         ----------
         filter_fn : function object, optional
             A function object that takes a |Node| object as an argument
-            and returns `True` if the |Node| object is to be yielded by
-            the iterator, or `False` if not. If ``filter_fn`` is `None`
+            and returns |True| if the |Node| object is to be yielded by
+            the iterator, or |False| if not. If ``filter_fn`` is |None|
             (default), then all nodes visited will be yielded.
         exclude_seed_node : boolean, optional
-            If `False` (default), then the seed node or root is visited. If
-            `True`, then the seed node is skipped.
+            If |False| (default), then the seed node or root is visited. If
+            |True|, then the seed node is skipped.
 
         Returns
         -------
@@ -3720,14 +4163,14 @@ class Tree(
         Visits nodes in ``self``, with each node and other nodes at the same
         level (distance from root) visited before their children.  Nodes can
         optionally be filtered by ``filter_fn``: only nodes for which ``filter_fn``
-        returns `True` when called with the node as an argument are visited.
+        returns |True| when called with the node as an argument are visited.
 
         Parameters
         ----------
         filter_fn : function object, optional
             A function object that takes a |Node| object as an argument
-            and returns `True` if the |Node| object is to be yielded by
-            the iterator, or `False` if not. If ``filter_fn`` is `None`
+            and returns |True| if the |Node| object is to be yielded by
+            the iterator, or |False| if not. If ``filter_fn`` is |None|
             (default), then all nodes visited will be yielded.
 
         Returns
@@ -3753,14 +4196,14 @@ class Tree(
         Visits nodes in ``self``, with each node visited in-between its children.
         Only valid for strictly-bifurcating trees. Nodes can optionally be
         filtered by ``filter_fn``: only nodes for which ``filter_fn`` returns
-        `True` when called with the node as an argument are yielded.
+        |True| when called with the node as an argument are yielded.
 
         Parameters
         ----------
         filter_fn : function object, optional
             A function object that takes a |Node| object as an argument
-            and returns `True` if the |Node| object is to be yielded by
-            the iterator, or `False` if not. If ``filter_fn`` is `None`
+            and returns |True| if the |Node| object is to be yielded by
+            the iterator, or |False| if not. If ``filter_fn`` is |None|
             (default), then all nodes visited will be yielded.
 
         Returns
@@ -3775,15 +4218,15 @@ class Tree(
         Iterate over all tips or leaves of tree.
 
         Visits all leaf or tip in ``self``. Nodes can optionally be filtered by
-        ``filter_fn``: only nodes for which ``filter_fn`` returns `True` when
+        ``filter_fn``: only nodes for which ``filter_fn`` returns |True| when
         called with the node as an argument are yielded.
 
         Parameters
         ----------
         filter_fn : function object, optional
             A function object that takes a |Node| object as an argument
-            and returns `True` if the |Node| object is to be yielded by
-            the iterator, or `False` if not. If ``filter_fn`` is `None`
+            and returns |True| if the |Node| object is to be yielded by
+            the iterator, or |False| if not. If ``filter_fn`` is |None|
             (default), then all nodes visited will be yielded.
 
         Returns
@@ -3810,25 +4253,25 @@ class Tree(
         Iterates over nodes in order of age ('age' is as given by the ``age``
         attribute, which is usually the sum of edge lengths from tips
         to node, i.e., time since present).
-        If ``include_leaves`` is `True` (default), leaves are included in the
-        iteration; if ``include_leaves`` is `False`, leaves will be skipped.
-        If ``descending`` is `False` (default), younger nodes will be returned
-        before older ones; if `True`, older nodes will be returned before
+        If ``include_leaves`` is |True| (default), leaves are included in the
+        iteration; if ``include_leaves`` is |False|, leaves will be skipped.
+        If ``descending`` is |False| (default), younger nodes will be returned
+        before older ones; if |True|, older nodes will be returned before
         younger ones.
 
         Parameters
         ----------
         include_leaves : boolean, optional
-            If `True` (default), then leaf nodes are included in the iteration.
-            If `False`, then leaf nodes are skipped.
+            If |True| (default), then leaf nodes are included in the iteration.
+            If |False|, then leaf nodes are skipped.
         filter_fn : function object, optional
             A function object that takes a |Node| object as an argument
-            and returns `True` if the |Node| object is to be yielded by
-            the iterator, or `False` if not. If ``filter_fn`` is `None`
+            and returns |True| if the |Node| object is to be yielded by
+            the iterator, or |False| if not. If ``filter_fn`` is |None|
             (default), then all nodes visited will be yielded.
         descending : boolean, optional
-            If `False` (default), then younger nodes are visited before older
-            ones. If `True`, then older nodes are visited before younger ones.
+            If |False| (default), then younger nodes are visited before older
+            ones. If |True|, then older nodes are visited before younger ones.
 
         Returns
         -------
@@ -3905,11 +4348,11 @@ class Tree(
 
         Parameters
         ----------
-        before_fn : function object or `None`
+        before_fn : function object or |None|
             A function object that takes a |Node| as its argument.
-        after_fn : function object or `None`
+        after_fn : function object or |None|
             A function object that takes a |Node| as its argument.
-        leaf_fn : function object or `None`
+        leaf_fn : function object or |None|
             A function object that takes a |Node| as its argument.
 
         Notes
@@ -3931,15 +4374,15 @@ class Tree(
 
         Visits nodes in ``self``, with each node visited before its children.
         Nodes can optionally be filtered by ``filter_fn``: only nodes for which
-        ``filter_fn`` returns `True` when called with the node as an argument are
+        ``filter_fn`` returns |True| when called with the node as an argument are
         yielded.
 
         Parameters
         ----------
         filter_fn : function object, optional
             A function object that takes a |Node| object as an argument
-            and returns `True` if the |Node| object is to be yielded by
-            the iterator, or `False` if not. If ``filter_fn`` is `None`
+            and returns |True| if the |Node| object is to be yielded by
+            the iterator, or |False| if not. If ``filter_fn`` is |None|
             (default), then all nodes visited will be yielded.
 
         Returns
@@ -3963,20 +4406,20 @@ class Tree(
         Visits internal edges in ``self``, with each edge visited before its
         children. In DendroPy, "internal edges" are edges that have at least
         one child edge, and thus the root or seed edge is typically included
-        unless ``exclude_seed_edge`` is `True`. Edges can optionally be filtered
-        by ``filter_fn``: only edges for which ``filter_fn`` returns `True` when
+        unless ``exclude_seed_edge`` is |True|. Edges can optionally be filtered
+        by ``filter_fn``: only edges for which ``filter_fn`` returns |True| when
         passed the edge as an argument are yielded.
 
         Parameters
         ----------
         filter_fn : function object, optional
             A function object that takes a |Edge| object as an argument
-            and returns `True` if the |Edge| object is to be yielded by
-            the iterator, or `False` if not. If ``filter_fn`` is `None`
+            and returns |True| if the |Edge| object is to be yielded by
+            the iterator, or |False| if not. If ``filter_fn`` is |None|
             (default), then all edges visited will be yielded.
         exclude_seed_edge : boolean, optional
-            If `False` (default), then the edge subtending the seed node or
-            root is visited. If `True`, then this edge is skipped.
+            If |False| (default), then the edge subtending the seed node or
+            root is visited. If |True|, then this edge is skipped.
 
         Returns
         -------
@@ -4000,17 +4443,17 @@ class Tree(
         """
         Post-order iterator over edges of tree.
 
-        Visits edges in ``self``, with each edge visited first followed by its
-        children. Edges can optionally be filtered by ``filter_fn``: only edges
-        for which ``filter_fn`` returns `True` when called with the edge as an
-        argument are yielded.
+        Visits edges in ``self``, with each edge visited after its children.
+        Edges can optionally be filtered by ``filter_fn``: only edges for which
+        ``filter_fn`` returns |True| when called with the edge as an argument
+        are yielded.
 
         Parameters
         ----------
         filter_fn : function object, optional
             A function object that takes a |Edge| object as an argument
-            and returns `True` if the |Edge| object is to be yielded by
-            the iterator, or `False` if not. If ``filter_fn`` is `None`
+            and returns |True| if the |Edge| object is to be yielded by
+            the iterator, or |False| if not. If ``filter_fn`` is |None|
             (default), then all edges visited will be yielded.
 
         Returns
@@ -4054,20 +4497,20 @@ class Tree(
         Visits internal edges in ``self``, with each edge visited after its
         children. In DendroPy, "internal edges" are edges that have at least
         one child edge, and thus the root or seed edge is typically included
-        unless ``exclude_seed_edge`` is `True`. Edges can optionally be filtered
-        by ``filter_fn``: only edges for which ``filter_fn`` returns `True` when
+        unless ``exclude_seed_edge`` is |True|. Edges can optionally be filtered
+        by ``filter_fn``: only edges for which ``filter_fn`` returns |True| when
         passed the edge as an argument are yielded.
 
         Parameters
         ----------
         filter_fn : function object, optional
             A function object that takes a |Edge| object as an argument
-            and returns `True` if the |Edge| object is to be yielded by
-            the iterator, or `False` if not. If ``filter_fn`` is `None`
+            and returns |True| if the |Edge| object is to be yielded by
+            the iterator, or |False| if not. If ``filter_fn`` is |None|
             (default), then all edges visited will be yielded.
         exclude_seed_edge : boolean, optional
-            If `False` (default), then the seed edge or root is visited. If
-            `True`, then the seed edge is skipped.
+            If |False| (default), then the seed edge or root is visited. If
+            |True|, then the seed edge is skipped.
 
         Returns
         -------
@@ -4094,14 +4537,14 @@ class Tree(
         Visits edges in ``self``, with each edge and other edges at the same
         level (distance from root) visited before their children.  Edges can
         optionally be filtered by ``filter_fn``: only edges for which ``filter_fn``
-        returns `True` when called with the edge as an argument are visited.
+        returns |True| when called with the edge as an argument are visited.
 
         Parameters
         ----------
         filter_fn : function object, optional
             A function object that takes a |Edge| object as an argument
-            and returns `True` if the |Edge| object is to be yielded by
-            the iterator, or `False` if not. If ``filter_fn`` is `None`
+            and returns |True| if the |Edge| object is to be yielded by
+            the iterator, or |False| if not. If ``filter_fn`` is |None|
             (default), then all edges visited will be yielded.
 
         Returns
@@ -4132,14 +4575,14 @@ class Tree(
         Visits edges in ``self``, with each edge visited in-between its children.
         Only valid for strictly-bifurcating trees. Edges can optionally be
         filtered by ``filter_fn``: only edges for which ``filter_fn`` returns
-        `True` when called with the edge as an argument are yielded.
+        |True| when called with the edge as an argument are yielded.
 
         Parameters
         ----------
         filter_fn : function object, optional
             A function object that takes a |Edge| object as an argument
-            and returns `True` if the |Edge| object is to be yielded by
-            the iterator, or `False` if not. If ``filter_fn`` is `None`
+            and returns |True| if the |Edge| object is to be yielded by
+            the iterator, or |False| if not. If ``filter_fn`` is |None|
             (default), then all edges visited will be yielded.
 
         Returns
@@ -4159,15 +4602,15 @@ class Tree(
         Iterate over all tips or leaves of tree.
 
         Visits all leaf or tip in ``self``. Edges can optionally be filtered by
-        ``filter_fn``: only edges for which ``filter_fn`` returns `True` when
+        ``filter_fn``: only edges for which ``filter_fn`` returns |True| when
         called with the edge as an argument are yielded.
 
         Parameters
         ----------
         filter_fn : function object, optional
             A function object that takes a |Edge| object as an argument
-            and returns `True` if the |Edge| object is to be yielded by
-            the iterator, or `False` if not. If ``filter_fn`` is `None`
+            and returns |True| if the |Edge| object is to be yielded by
+            the iterator, or |False| if not. If ``filter_fn`` is |None|
             (default), then all edges visited will be yielded.
 
         Returns
@@ -4556,10 +4999,29 @@ class Tree(
         ``suppress_unifurcations`` is False, then it will be
         removed from the tree.
         """
-        from dendropy.calculate import treemeasure
-        pdm = treemeasure.PatristicDistanceMatrix(self)
-        n1, n2 = pdm.max_dist_nodes
-        plen = float(pdm.max_dist) / 2
+        from dendropy.calculate.phylogeneticdistance import PhylogeneticDistanceMatrix
+        pdm = PhylogeneticDistanceMatrix.from_tree(self)
+
+        ## ugly, ugly, ugly code to find two nodes that span the midpoint
+        maxtax1, maxtax2 = pdm.max_pairwise_distance_taxa()
+        spanning_nodes = [None, None]
+        found = 0
+        for nd in self.leaf_node_iter():
+            for tax in (maxtax1, maxtax2):
+                if nd.taxon is tax:
+                    spanning_nodes[found] = nd
+                    found +=1
+                    break
+            if found == 2:
+                break
+        if spanning_nodes[0].distance_from_root() < spanning_nodes[1].distance_from_root():
+            n1 = spanning_nodes[1]
+            n2 = spanning_nodes[0]
+        else:
+            n1 = spanning_nodes[0]
+            n2 = spanning_nodes[1]
+
+        plen = float(pdm.patristic_distance(maxtax1, maxtax2)) / 2
         mrca_node = pdm.mrca(n1.taxon, n2.taxon)
         #assert mrca_node is self.mrca(taxa=[n1.taxon, n2.taxon])
         #mrca_node = self.mrca(taxa=[n1.taxon, n2.taxon])
@@ -4581,6 +5043,7 @@ class Tree(
                 cur_node = cur_node._parent_node
             else:
                 break_on_node = cur_node
+                break
 
         assert break_on_node is not None or target_edge is not None
 
@@ -4612,7 +5075,7 @@ class Tree(
         Parameters
         ----------
         update_bipartitions : bool
-            If `True` then the bipartitions encoding will be calculated.
+            If |True| then the bipartitions encoding will be calculated.
 
         """
         if update_bipartitions and self.bipartition_encoding:
@@ -4658,7 +5121,7 @@ class Tree(
             update_bipartitions=False):
         """
         Collapse all *internal* edges with edge lengths less than or equal to
-        ``threshold`` (or with `None` for edge length).
+        ``threshold`` (or with |None| for edge length).
         """
         for e in self.postorder_edge_iter():
             if e.length is None or (e.length <= threshold) and e.is_internal():
@@ -4679,13 +5142,13 @@ class Tree(
             The maximum number of children a node can have before being
             resolved.
         update_bipartitions : bool
-            If `True`, then bipartitions will be calculated.
-        rng : ``random.Random`` object or `None`
+            If |True|, then bipartitions will be calculated.
+        rng : ``random.Random`` object or |None|
             If ``rng`` is an object with a ``sample()`` method then the polytomy
             will be resolved by sequentially adding, generating all tree
             topologies equiprobably. ``rng.sample()`` should behave like
             ``random.sample()``
-            If ``rng`` is `None`, then polytomy is broken deterministically by
+            If ``rng`` is |None|, then polytomy is broken deterministically by
             repeatedly joining pairs of children.
         """
         polytomies = []
@@ -4747,70 +5210,77 @@ class Tree(
             update_bipartitions=False,
             suppress_unifurcations=True):
         """
-        Removes all leaves for which ``filter_fn`` returns `False`. If recursive
-        is `True`, then process is repeated until all leaf nodes in the tree will
-        evaluate to `True` when passed to ``filter_fn``.
+        Removes all leaves for which ``filter_fn`` returns |False|. If recursive
+        is |True|, then process is repeated until all leaf nodes in the tree will
+        evaluate to |True| when passed to ``filter_fn``.
 
         Parameters
         ----------
         ``filter_fn`` : function object
-            A function that takes a |Node| object and returns `True` if
-            the object is to be allowed as a leaf node, and `False` if otherwise.
+            A function that takes a |Node| object and returns |True| if
+            the object is to be allowed as a leaf node, and |False| if otherwise.
         recursive : bool
-            If `True`, then filter is repeatedly applied until all leaf nodes
-            evaluate to `True` under ``filter_fn``. If `False`, then only a
+            If |True|, then filter is repeatedly applied until all leaf nodes
+            evaluate to |True| under ``filter_fn``. If |False|, then only a
             single pass is made on the current leaf set. This may result in new
-            leaves for which the ``filter_fn`` is `False` (e.g., the parent node
-            of a cherry in which both children evaluated to `False`
-            under ``filter_fn`` now is a leaf node which may be `False`
+            leaves for which the ``filter_fn`` is |False| (e.g., the parent node
+            of a cherry in which both children evaluated to |False|
+            under ``filter_fn`` now is a leaf node which may be |False|
             under ``filter_fn``).
         suppress_unifurcations : bool
-            If `True`, nodes of outdegree 1 will be deleted as they are
+            If |True|, nodes of outdegree 1 will be deleted as they are
             encountered.
         update_bipartitions : bool
-            If `True`, then bipartitions will be calculated.
+            If |True|, then bipartitions will be calculated.
+
+        Returns
+        -------
+        nds : list[|Node|]
+            List of nodes removed.
         """
+        nodes_removed = []
         while True:
-            nodes_deleted = False
-            for nd in self.leaf_node_iter():
-                if not filter_fn(nd):
-                    if nd.edge.tail_node is None:
-                        raise error.SeedNodeDeletionException("Attempting to remove seed node or node without parent")
-                    nd.edge.tail_node.remove_child(nd)
-                    nodes_deleted = True
-            if not nodes_deleted or not recursive:
+            is_nodes_deleted = False
+            nodes_to_remove = [nd for nd in self.leaf_node_iter() if not filter_fn(nd)]
+            for nd in nodes_to_remove:
+                if nd.edge.tail_node is None:
+                    raise error.SeedNodeDeletionException("Attempting to remove seed node or node without parent")
+                nd.edge.tail_node.remove_child(nd)
+            if nodes_to_remove:
+                nodes_removed += nodes_to_remove
+                is_nodes_deleted = True
+            if not is_nodes_deleted or not recursive:
                 break
         if suppress_unifurcations:
             self.suppress_unifurcations()
         if update_bipartitions:
             self.update_bipartitions()
+        return nodes_removed
 
     def prune_leaves_without_taxa(self,
+            recursive=True,
             update_bipartitions=False,
             suppress_unifurcations=True):
         """
         Removes all terminal nodes that have their ``taxon`` attribute set to
-        `None`.
+        |None|.
         """
-        for nd in self.leaf_node_iter():
-            if nd.taxon is None:
+        nodes_removed = []
+        while True:
+            nodes_to_remove = []
+            for nd in self.leaf_node_iter():
+                if nd.taxon is None:
+                    nodes_to_remove.append(nd)
+            for nd in nodes_to_remove:
                 nd.edge.tail_node.remove_child(nd)
+            nodes_removed += nodes_to_remove
+            if not nodes_to_remove or not recursive:
+                break
         if suppress_unifurcations:
             self.suppress_unifurcations()
         if update_bipartitions:
             self.update_bipartitions()
-
-    def prune_taxa(self, taxa, update_bipartitions=False, suppress_unifurcations=True):
-        """
-        Removes terminal nodes associated with Taxon objects given by the container
-        ``taxa`` (which can be any iterable, including a TaxonNamespace object) from ``self``.
-        """
-        nodes_to_remove = []
-        for nd in self.postorder_node_iter():
-            if nd.taxon and nd.taxon in taxa:
-                nd.edge.tail_node.remove_child(nd)
-        self.prune_leaves_without_taxa(update_bipartitions=update_bipartitions,
-                suppress_unifurcations=suppress_unifurcations)
+        return nodes_removed
 
     def prune_nodes(self, nodes, prune_leaves_without_taxa=False, update_bipartitions=False, suppress_unifurcations=True):
         for nd in nodes:
@@ -4821,10 +5291,33 @@ class Tree(
             self.prune_leaves_without_taxa(update_bipartitions=update_bipartitions,
                     suppress_unifurcations=suppress_unifurcations)
 
+    def prune_taxa(self,
+            taxa,
+            update_bipartitions=False,
+            suppress_unifurcations=True,
+            is_apply_filter_to_leaf_nodes=True,
+            is_apply_filter_to_internal_nodes=False):
+        """
+        Removes terminal nodes associated with Taxon objects given by the container
+        ``taxa`` (which can be any iterable, including a TaxonNamespace object) from ``self``.
+        """
+        nodes_to_remove = []
+        for nd in self.postorder_node_iter():
+            if (
+                ((is_apply_filter_to_internal_nodes and nd._child_nodes)
+                or (is_apply_filter_to_leaf_nodes and not nd._child_nodes))
+                and (nd.taxon and nd.taxon in taxa)
+                ):
+                    nd.edge.tail_node.remove_child(nd)
+        self.prune_leaves_without_taxa(update_bipartitions=update_bipartitions,
+                suppress_unifurcations=suppress_unifurcations)
+
     def prune_taxa_with_labels(self,
             labels,
             update_bipartitions=False,
-            suppress_unifurcations=True):
+            suppress_unifurcations=True,
+            is_apply_filter_to_leaf_nodes=True,
+            is_apply_filter_to_internal_nodes=False):
         """
         Removes terminal nodes that are associated with Taxon objects with
         labels given by ``labels``.
@@ -4832,7 +5325,9 @@ class Tree(
         taxa = self.taxon_namespace.get_taxa(labels=labels)
         self.prune_taxa(taxa=taxa,
                 update_bipartitions=update_bipartitions,
-                suppress_unifurcations=suppress_unifurcations)
+                suppress_unifurcations=suppress_unifurcations,
+                is_apply_filter_to_leaf_nodes=is_apply_filter_to_leaf_nodes,
+                is_apply_filter_to_internal_nodes=is_apply_filter_to_internal_nodes)
 
     def retain_taxa(self,
             taxa,
@@ -4886,10 +5381,42 @@ class Tree(
             rng.shuffle(c)
             nd.set_child_nodes(c)
 
+    def shuffle_taxa(self, include_internal_nodes=False, rng=None):
+        """
+        Randomly re-assigns taxa associated with nodes. Note that in the case
+        of not all nodes being associated with taxa, this will NOT assign taxa
+        to nodes that currently do not have them, nor will nodes currently
+        associated with taxa end up not being associated with taxa.
+        Returns a dictionary mapping the old taxa to their new counterparts.
+        """
+        if rng is None:
+            rng = GLOBAL_RNG # use the global rng by default
+        if include_internal_nodes:
+            nd_iterator = self.preorder_node_iter
+        else:
+            nd_iterator = self.leaf_node_iter
+        current_node_taxon_map = {}
+        node_taxa = set()
+        for nd in nd_iterator():
+            if nd.taxon is not None:
+                current_node_taxon_map[nd] = nd.taxon
+                assert nd.taxon not in node_taxa
+                node_taxa.add(nd.taxon)
+        assert len(current_node_taxon_map) == len(node_taxa)
+        current_to_shuffled_taxon_map = {}
+        for nd in current_node_taxon_map:
+            new_taxon = rng.sample(node_taxa, 1)[0]
+            current_to_shuffled_taxon_map[nd.taxon] = new_taxon
+            nd.taxon = new_taxon
+            node_taxa.remove(new_taxon)
+        assert len(node_taxa) == 0, node_taxa
+        assert len(current_to_shuffled_taxon_map) == len(current_node_taxon_map)
+        return current_to_shuffled_taxon_map
+
     def ladderize(self, ascending=True):
         """
-        Sorts child nodes in ascending (if ``ascending`` is `False`) or
-        descending (if ``ascending`` is `False`) order in terms of the number of
+        Sorts child nodes in ascending (if ``ascending`` is |False|) or
+        descending (if ``ascending`` is |False|) order in terms of the number of
         children each child node has.
         """
         node_desc_counts = {}
@@ -4947,7 +5474,7 @@ class Tree(
             All edge lengths calculated to have a value less than this will be
             set to this.
         error_on_negative_edge_lengths : bool
-            If `True`, an inferred edge length that is less than 0 will result
+            If |True|, an inferred edge length that is less than 0 will result
             in a ValueError.
         """
         for nd in self.preorder_node_iter():
@@ -4966,27 +5493,109 @@ class Tree(
     ###########################################################################
     ### Ages, depths, branch lengths etc. (calculation)
 
-    def calc_node_ages(self, ultrametricity_precision=constants.DEFAULT_ULTRAMETRICITY_PRECISION, internal_only=False):
+    def phylogenetic_distance_matrix(self):
+        """
+        Returns a |PhylogeneticDistanceMatrix| instance based
+        on the tree (in its current state).
+
+        Returns
+        -------
+        pdc : a |PhylogeneticDistanceMatrix| instance
+            A |PhylogeneticDistanceMatrix| instance corresponding to the
+            tree in its current state.
+        """
+        from dendropy.calculate.phylogeneticdistance import PhylogeneticDistanceMatrix
+        return PhylogeneticDistanceMatrix.from_tree(tree=self)
+
+    def node_distance_matrix(self):
+        from dendropy.calculate.phylogeneticdistance import NodeDistanceMatrix
+        return NodeDistanceMatrix.from_tree(tree=self)
+
+    def calc_node_ages(self,
+            ultrametricity_precision=constants.DEFAULT_ULTRAMETRICITY_PRECISION,
+            is_force_max_age=False,
+            is_force_min_age=False,
+            set_node_age_fn=None,
+            is_return_internal_node_ages_only=False):
         """
         Adds an attribute called "age" to  each node, with the value equal to
-        the sum of edge lengths from the node to the tips. If the lengths of
-        different paths to the node differ by more than ``ultrametricity_precision``, then a
-        ValueError exception will be raised indicating deviation from
-        ultrametricity. If ``ultrametricity_precision`` is negative or False, then this check
-        will be skipped.
+        the sum of edge lengths from the node to the tips.
+
+        Parameters
+        ----------
+        ultrametricity_precision : numeric or bool or None
+            If the lengths of different paths to the node differ by more than
+            ``ultrametricity_precision``, then a ValueError exception will be
+            raised indicating deviation from ultrametricity. If
+            ``ultrametricity_precision`` is negative or False, then this check
+            will be skipped.
+        is_force_max_age: bool
+            If ``is_force_max_age`` is |True|, then each node will be set to the
+            maximum possible age, by being set to the oldest age given its
+            child set and the subtending edge lengths. This option only makes a
+            difference if the tree is not ultrametric, and so the
+            ultrametricity precision check is ignore if this option is set to
+            True.
+        is_force_min_age: bool
+            If ``is_force_min_age`` is |True| then each node will be set to the
+            minimum possible age, by being set to the youngest age given its
+            child set and the subtending edge lengths. This option only makes a
+            difference if the tree is not ultrametric, and so the
+            ultrametricity precision check is ignore if this option is set to
+            True.
+        set_node_age_fn: function object
+            If not |None|, then this should be a function that takes a node as
+            an argument and returns |None| or a non-|None| value. If
+            |None|, then this indicates that the node's age should be
+            calculated by this function. If not |None|, then this is the
+            value that this node's age should be set to. This can be used to
+            set non-contemporary tip ages by passing something like:
+
+                f = lambda nd: None if not nd.is_leaf else nd.annotations["height"]
+
+            which returns |None| if the node is an internal node, but
+            otherwise returns the value in the ``height`` annotation.
+
+        Returns
+        -------
+        a : iterable[numeric]
+            Returns collection of node ages.
+
         """
         ages = []
+        if is_force_max_age and is_force_min_age:
+            raise ValueError("Cannot specify both 'is_force_max_age' and 'is_force_min_age'")
         for node in self.postorder_node_iter():
-            ch = node.child_nodes()
-            if len(ch) == 0:
+            child_nodes = node.child_nodes()
+            if set_node_age_fn is not None:
+                node.age = set_node_age_fn(node)
+                # print("Setting node age: {} = {}".format(node.taxon, node.age))
+                if node.age is not None:
+                    continue
+            if len(child_nodes) == 0:
                node.age = 0.0
-               if not internal_only:
+               if not is_return_internal_node_ages_only:
                    ages.append(node.age)
             else:
-                first_child = ch[0]
-                node.age = first_child.age + first_child.edge.length
-                if not (ultrametricity_precision is None or ultrametricity_precision is False or ultrametricity_precision < 0):
-                    for nnd in ch[1:]:
+                if is_force_max_age:
+                    age_to_set = max([ (child.age + child.edge.length) for child in child_nodes ])
+                elif is_force_min_age:
+                    age_to_set = min([ (child.age + child.edge.length) for child in child_nodes ])
+                else:
+                    first_child = child_nodes[0]
+                    if first_child.edge.length is not None and first_child.age is not None:
+                        age_to_set = first_child.age + first_child.edge.length
+                    elif first_child.edge.length is None:
+                        first_child.edge.length = 0.0
+                        age_to_set = first_child.age
+                    elif first_child.age is None:
+                        first_child.age = 0.0
+                        age_to_set = first_child.edge.length
+                    else:
+                        age_to_set = 0.0
+                node.age = age_to_set
+                if not (is_force_max_age or is_force_min_age or ultrametricity_precision is None or ultrametricity_precision is False or ultrametricity_precision < 0):
+                    for nnd in child_nodes[1:]:
                         try:
                             ocnd = nnd.age + nnd.edge.length
                         except TypeError:
@@ -5019,22 +5628,42 @@ class Tree(
                 dists.append(node.root_distance)
         return dists
 
-    def internal_node_ages(self, ultrametricity_precision=constants.DEFAULT_ULTRAMETRICITY_PRECISION):
+    def internal_node_ages(self,
+            ultrametricity_precision=constants.DEFAULT_ULTRAMETRICITY_PRECISION,
+            is_force_max_age=False,
+            is_force_min_age=False,
+            set_node_age_fn=None,
+            ):
         """
         Returns list of ages of speciation events / coalescence times on tree.
         """
-        ages = self.calc_node_ages(ultrametricity_precision=ultrametricity_precision, internal_only=True)
+        ages = self.calc_node_ages(
+                ultrametricity_precision=ultrametricity_precision, is_return_internal_node_ages_only=True,
+                is_force_max_age=is_force_max_age,
+                is_force_min_age=is_force_min_age,
+                set_node_age_fn=set_node_age_fn,
+                )
         ages.sort()
         return ages
 
-    def node_ages(self, ultrametricity_precision=constants.DEFAULT_ULTRAMETRICITY_PRECISION, internal_only=False):
+    def node_ages(self,
+            ultrametricity_precision=constants.DEFAULT_ULTRAMETRICITY_PRECISION,
+            is_force_max_age=False,
+            is_force_min_age=False,
+            set_node_age_fn=None,
+            internal_only=False):
         """
         Returns list of ages of all nodes on tree.
         NOTE: Changed from DendroPy3: this function now returns the ages of
         *ALL* nodes. To get only internal node ages, use
         `Tree.internal_node_ages`.
         """
-        ages = self.calc_node_ages(ultrametricity_precision=ultrametricity_precision, internal_only=internal_only)
+        ages = self.calc_node_ages(
+                ultrametricity_precision=ultrametricity_precision,
+                is_force_max_age=is_force_max_age,
+                is_force_min_age=is_force_min_age,
+                set_node_age_fn=set_node_age_fn,
+                is_return_internal_node_ages_only=internal_only)
         ages.sort()
         return ages
 
@@ -5122,28 +5751,28 @@ class Tree(
         Parameters
         ----------
         suppress_unifurcations : bool
-            If `True`, nodes of outdegree 1 will be deleted as they are
+            If |True|, nodes of outdegree 1 will be deleted as they are
             encountered.
         collapse_unrooted_basal_bifurcation: bool
-            If `True`, then a basal bifurcation on an unrooted tree will be
+            If |True|, then a basal bifurcation on an unrooted tree will be
             collapsed to a trifurcation. This mean that an unrooted tree like
             '(A,(B,C))' will be changed to '(A,B,C)' after this.
         suppress_storage : bool
             By default, the bipartition encoding is stored as a list (assigned
             to ``self.bipartition_encoding``) and returned. If ``suppress_storage``
-            is `True`, then the list is not created.
+            is |True|, then the list is not created.
         is_bipartitions_mutable : bool
             By default, the |Bipartition| instances coded will be locked
             or frozen, allowing their use in hashing containers such as
             dictionary (keys) and sets. To allow modification of values, the
-            ``is_mutable`` attribute must be set to `True`.
+            ``is_mutable`` attribute must be set to |True|.
 
         Returns
         -------
-        list[|Bipartition|] or `None`
+        list[|Bipartition|] or |None|
             A list of |Bipartition| objects of this |Tree|
             representing the structure of this tree, or, if ``suppress_storage``
-            is `True`, then `None`.
+            is |True|, then |None|.
 
         """
         self._bipartition_edge_map = None
@@ -5317,7 +5946,7 @@ class Tree(
         Returns true if the |Bipartition| ``bipartition`` is compatible
         with all bipartitions of this tree.
         """
-        if not is_bipartitions_updated or not self.bipartitions_encoding:
+        if not is_bipartitions_updated or not self.bipartition_encoding:
             self.encode_bipartitions()
         if bipartition in self.bipartition_encoding:
             return True
@@ -5395,7 +6024,7 @@ class Tree(
         return "%s" % self._as_newick_string()
 
     def __repr__(self):
-        return "<Tree object at %s>" % (hex(id(self)))
+        return "<{} object at {}>".format(self.__class__.__name__, hex(id(self)))
 
     def description(self, depth=1, indent=0, itemize="", output=None):
         """
diff --git a/dendropy/interop/entrez.py b/dendropy/interop/entrez.py
index c46b0fb..38fd6b1 100644
--- a/dendropy/interop/entrez.py
+++ b/dendropy/interop/entrez.py
@@ -28,6 +28,7 @@ if sys.version_info.major < 3:
 else:
     from urllib.parse import urlencode
     from urllib.request import urlopen
+from dendropy.utility import textprocessing
 
 ENTREZ_EUTILS_BASE_URL = "http://eutils.ncbi.nlm.nih.gov/entrez/eutils"
 
@@ -36,7 +37,7 @@ def efetch(db, ids, rettype, retmode="xml", email=None):
     Raw fetch. Returns file-like object opened for reading on string
     returned by query.
     """
-    if isinstance(ids, str):
+    if textprocessing.is_str_type(ids):
         id_list = ids
     else:
         id_list = ",".join([str(i) for i in set(ids)])
@@ -82,7 +83,7 @@ def get_taxonomy(**kwargs):
 #         params["retmode"] = "xml"
 #     if "ids" in params:
 #         ids = params["ids"]
-#         if isinstance(ids, str):
+#         if textprocessing.is_str_type(ids):
 #             id_list = ids
 #         else:
 #             id_list = ",".join([str(i) for i in list(ids)])
diff --git a/dendropy/interop/paup.py b/dendropy/interop/paup.py
index 765ec74..1296c6d 100644
--- a/dendropy/interop/paup.py
+++ b/dendropy/interop/paup.py
@@ -26,12 +26,9 @@ import subprocess
 import tempfile
 import re
 import csv
-try:
-    from StringIO import StringIO # Python 2 legacy support: StringIO in this module is the one needed (not io)
-except ImportError:
-    from io import StringIO # Python 3
 
 import dendropy
+from dendropy.utility import textprocessing
 from dendropy.utility import error
 from dendropy.utility import metavar
 from dendropy.utility import container
@@ -74,19 +71,19 @@ class PaupService(object):
             A list or some other iterable of strings representing PAUP
             commands.
         suppress_standard_preamble : bool
-            If `True`, then the command sequence will not be prefaced by the
+            If |True|, then the command sequence will not be prefaced by the
             standard preamble.
         ignore_error_returncode : bool
-            If `True`, then a non-0 return code from the PAUP process will not
+            If |True|, then a non-0 return code from the PAUP process will not
             result in an exception being raised.
         ignore_nonempty_stderr : bool
-            If `True`, then the PAUP process writing to standard error will not
+            If |True|, then the PAUP process writing to standard error will not
             result in an exception being raised.
         strip_extraneous_prompts_from_stdout : bool
-            If `True`, then all occurrences of 'paup>' will be removed from the
+            If |True|, then all occurrences of 'paup>' will be removed from the
             standard output contents.
         strip_extraneous_prompts_from_stderr : bool
-            If `True`, then all occurrences of 'paup>' will be removed from the
+            If |True|, then all occurrences of 'paup>' will be removed from the
             standard error contents.
         cwd : string
             Set the working directory of the PAUP* process to this directory.
@@ -103,7 +100,7 @@ class PaupService(object):
         stderr : string
             Contents of the PAUP process standard error.
         """
-        if isinstance(paup_commands, str):
+        if textprocessing.is_str_type(paup_commands):
             commands = [paup_commands]
         else:
             commands = list(paup_commands)
@@ -197,11 +194,11 @@ class PaupService(object):
             A list or some other iterable of file paths containing trees in
             NEXUS format.
         is_rooted : bool
-            If `True` then trees will be treated as rooted. If `False`, then
+            If |True| then trees will be treated as rooted. If |False|, then
             rooting follows that specified in the tree statements, defaulting
             to unrooted if not specified.
         use_tree_weights : bool
-            If `False` then tree weighting statements are disregarded.
+            If |False| then tree weighting statements are disregarded.
             Otherwise, they will be regarded.
         burnin : integer
             Skip these many trees (from beginning of each source).
@@ -273,11 +270,11 @@ class PaupService(object):
             A list or some other iterable of file paths containing trees in
             NEXUS format.
         is_rooted : bool
-            If `True` then trees will be treated as rooted. If `False`, then
+            If |True| then trees will be treated as rooted. If |False|, then
             rooting follows that specified in the tree statements, defaulting
             to unrooted if not specified.
         use_tree_weights : bool
-            If `False` then tree weighting statements are disregarded.
+            If |False| then tree weighting statements are disregarded.
             Otherwise, they will be regarded.
         burnin : integer
             Skip these many trees (from beginning of each source).
@@ -334,7 +331,7 @@ class PaupService(object):
         Composes commands to load a set of trees into PAUP*, with the specified
         number of burnin dropped.
         """
-        if isinstance(tree_filepaths, str):
+        if textprocessing.is_str_type(tree_filepaths):
             raise Exception("expecting list of filepaths, not string")
         if is_rooted is None:
             rooting = ""
@@ -705,13 +702,13 @@ def estimate_tree(char_matrix,
     output_tree_filepath = output_tree_file_handle.name
     paup_args['est_tree_file'] = output_tree_filepath
     if extra_pre_est_commands:
-        if isinstance(extra_pre_est_commands, str):
+        if textprocessing.is_str_type(extra_pre_est_commands):
             extra_pre_est_commands = [extra_pre_est_commands]
         paup_args["pre_est_commands"] = ";\n".join(extra_pre_est_commands)
     else:
         paup_args["pre_est_commands"] = ""
     if extra_post_est_commands:
-        if isinstance(extra_post_est_commands, str):
+        if textprocessing.is_str_type(extra_post_est_commands):
             extra_post_est_commands = [extra_post_est_commands]
         paup_args["post_est_commands"] = ";\n".join(extra_post_est_commands)
     else:
diff --git a/dendropy/interop/rstats.py b/dendropy/interop/rstats.py
index b8bef06..9a6d31f 100644
--- a/dendropy/interop/rstats.py
+++ b/dendropy/interop/rstats.py
@@ -23,6 +23,7 @@ from dendropy.utility import error
 from dendropy.utility import metavar
 from dendropy.utility import libexec
 from dendropy.utility import processio
+from dendropy.utility import textprocessing
 
 RSCRIPT_EXECUTABLE = os.environ.get(metavar.DENDROPY_RSCRIPT_PATH_ENVAR, "Rscript")
 if RSCRIPT_EXECUTABLE == "NONE":
@@ -41,36 +42,16 @@ class RService(object):
             rscript_path=RSCRIPT_EXECUTABLE,
             ):
         """
-        Executes a sequence of commans in R and returns the results.
-
-        Note that newlines ('\n') and other special characters will be
-        converted before being passed to the R interpreter, so need to
-        be escaped or entered as raw string expressions.
-
-        That is, instead of, e.g.:
-
-            returncode, stdout, stderr = RService.call([
-                "cat('hello, world\n')",
-            ])
-
-        use this:
-
-            returncode, stdout, stderr = RService.call([
-                "cat('hello, world\\n')",
-            ])
-
-        or:
-
-            returncode, stdout, stderr = RService.call([
-                r"cat('hello, world\n')",
-            ])
+        Executes a sequence of commands in R and returns the results. All the
+        noise is sunk into the stderr return variable, and just the output
+        comes out cleanly in the stdout return variable.
 
         Parameters
         ----------
         r_commands : iterable of strings
             A list or some other iterable of strings of R commands.
         ignore_error_returncode : bool
-            If `True`, then a non-0 return code from the R process will not
+            If |True|, then a non-0 return code from the R process will not
             result in an exception being raised.
         cwd : string
             Set the working directory of the R process to this directory.
@@ -86,8 +67,76 @@ class RService(object):
             Contents of the R process standard output.
         stderr : string
             Contents of the R process standard error.
+
+        Examples
+        --------
+
+        Build up a script (``s``) to calculate a range of values, print them
+        to the standard output, and then post-process this to extract the
+        values::
+
+            import itertools
+            from dendropy.interop import rstats
+
+            bb = [0.01, 0.05, 0.10, 0.50, 1.0]
+            cc = [0.01, 0.05, 0.10, 0.50, 1.0]
+            ee = [0.0, 0.1, 0.2]
+
+            # store commands of script as a list
+            # to be passed to the ``call()``
+            s = []
+
+            # set options, load required libraries, etc.
+            s.append("options(digits=22)")
+            s.append("library(PBD)")
+
+            # build up list of commands in script
+            params = []
+            for b, c, e in itertools.product(bb, cc, ee):
+                s.append("print(pbd_durspec_mean(pars=c({},{},{})))".format(b, c, e))
+
+            # execute script
+            returncode, stdout, stderr  = rstats.call(s)
+
+            # peek at the results
+            print(stdout)
+
+            # [1] 69.31472
+            # [1] 9.853723
+            # [1] 4.981369
+            # [1] 0.9950331
+            # ...
+
+            # post-process the stdout to extract values
+            results = [float(x.split(" ")[1]) for x in stdout.split("\n") if x]
+
+        Notes
+        -----
+
+        Note that newlines ('\n') and other special characters will be
+        converted before being passed to the R interpreter, so need to
+        be escaped or entered as raw string expressions.
+
+        That is, instead of, e.g.::
+
+            returncode, stdout, stderr = RService.call([
+                "cat('hello, world\n')",
+            ])
+
+        use this::
+
+            returncode, stdout, stderr = RService.call([
+                "cat('hello, world\\n')",
+            ])
+
+        or::
+
+            returncode, stdout, stderr = RService.call([
+                r"cat('hello, world\n')",
+            ])
+
         """
-        if not isinstance(r_commands, str):
+        if not textprocessing.is_str_type(r_commands):
             r_commands = "\n".join(r_commands)
         r_commands += "\n"
         invocation_command = [RSCRIPT_EXECUTABLE, rsubprocess_pipe_path]
diff --git a/dendropy/interop/seqgen.py b/dendropy/interop/seqgen.py
index 87f7305..51caeea 100644
--- a/dendropy/interop/seqgen.py
+++ b/dendropy/interop/seqgen.py
@@ -21,10 +21,6 @@ Wrappers for interacting with SeqGen. Originally part of PySeqGen.
 """
 
 import subprocess
-try:
-    from StringIO import StringIO # Python 2 legacy support: StringIO in this module is the one needed (not io)
-except ImportError:
-    from io import StringIO # Python 3
 import uuid
 import tempfile
 import socket
diff --git a/dendropy/legacy/ncbi.py b/dendropy/legacy/ncbi.py
index 7c05853..21d980e 100644
--- a/dendropy/legacy/ncbi.py
+++ b/dendropy/legacy/ncbi.py
@@ -25,6 +25,7 @@ dendropy.interop.genbank.GenBankProtein instead ***
 
 import warnings
 from dendropy.utility import messaging
+from dendropy.utility import textprocessing
 from dendropy.utility import urlio
 _LOG = messaging.get_logger(__name__)
 
@@ -201,13 +202,13 @@ class Entrez(object):
         dendropy.interop.genbank.GenBankRna, or
         dendropy.interop.genbank.GenBankProtein instead ***
         Instantiates a broker that queries NCBI and returns data.  If
-        ``generate_labels`` is `True`, then appropriate labels for sequences
+        ``generate_labels`` is |True|, then appropriate labels for sequences
         will be automatically composed for each sequence based on the GenBank
         FASTA defline. ``label_num_desc_components`` specifies the number of
         components from the defline to use. ``label_separator`` specifies the
         string used to separate the different label components.
         ``label_id_in_front`` specifies whether the GenBank accession number
-        should form the beginning (`True`) or tail (`False`) end of the
+        should form the beginning (|True|) or tail (|False|) end of the
         label. ``sort_taxa_by_label`` specifies whether the sequences should be
         sorted by their final label values.
         """
@@ -224,7 +225,7 @@ class Entrez(object):
         Raw fetch. Returns file-like object opened for reading on string
         returned by query.
         """
-        if isinstance(ids, str):
+        if textprocessing.is_str_type(ids):
             id_list = ids
         else:
             id_list = ",".join([str(i) for i in set(ids)])
diff --git a/dendropy/legacy/treecalc.py b/dendropy/legacy/treecalc.py
index 2cf9d17..ab728d1 100644
--- a/dendropy/legacy/treecalc.py
+++ b/dendropy/legacy/treecalc.py
@@ -31,13 +31,13 @@ from dendropy.utility import deprecate
 ##############################################################################
 ## dendropy.calculate.treemeasure
 
-class PatristicDistanceMatrix(treemeasure.PatristicDistanceMatrix):
+class PhylogeneticDistanceMatrix(dendropy.PhylogeneticDistanceMatrix):
     def __init__(self, tree=None):
         deprecate.dendropy_deprecation_warning(
-                preamble="Deprecated since DendroPy 4: The 'dendropy.treecalc.PatristicDistanceMatrix' class has moved to 'dendropy.calculate.treemeasure.PatristicDistanceMatrix'.",
-                old_construct="from dendropy import treecalc\npdm = treecalc.PatristicDistanceMatrix(...)",
-                new_construct="from dendropy.calculate import treemeasure\npdm = treemeasure.PatristicDistanceMatrix(...)")
-        treemeasure.PatristicDistanceMatrix.__init__(self, tree=tree)
+                preamble="Deprecated since DendroPy 4: The 'dendropy.treecalc.PhylogeneticDistanceMatrix' class has moved to 'dendropy.PhylogeneticDistanceMatrix'.",
+                old_construct="from dendropy import treecalc\npdm = treecalc.PhylogeneticDistanceMatrix(...)",
+                new_construct="import dendropy\npdm = dendropy.PhylogeneticDistanceMatrix(...)")
+        dendropy.PhylogeneticDistanceMatrix.__init__(self, tree=tree)
 
 def patristic_distance(tree, taxon1, taxon2):
     deprecate.dendropy_deprecation_warning(
diff --git a/dendropy/model/birthdeath.py b/dendropy/model/birthdeath.py
index 2aedb00..b29cbb0 100644
--- a/dendropy/model/birthdeath.py
+++ b/dendropy/model/birthdeath.py
@@ -59,7 +59,7 @@ def birth_death_tree(birth_rate, death_rate, birth_rate_sd=0.0, death_rate_sd=0.
           tips (or 0 tips), then a tree will be randomly selected from the
           intervals which corresond to times at which the tree had exactly ``ntax``
           leaves (or len(taxon_namespace) tips). This allows for simulations according to
-          the "General Sampling Approach" of [citeHartmannWS2010]_
+          the "General Sampling Approach" of Hartmann et al. (2010).
 
 
     If more than one of the above is given, then tree growth will terminate when
@@ -82,14 +82,17 @@ def birth_death_tree(birth_rate, death_rate, birth_rate_sd=0.0, death_rate_sd=0.
     False.
 
     Under some conditions, it is possible for all lineages on a tree to go extinct.
-    In this case, if the keyword argument ``repeat_until_success`` is `True` (the
+    In this case, if the keyword argument ``repeat_until_success`` is |True| (the
     default), then a new branching process is initiated.
-    If `False` (default), then a TreeSimTotalExtinctionException is raised.
+    If |False| (default), then a TreeSimTotalExtinctionException is raised.
 
     A Random() object or equivalent can be passed using the ``rng`` keyword;
     otherwise GLOBAL_RNG is used.
 
-    .. [citeHartmannWS2010] Hartmann, Wong, and Stadler "Sampling Trees from Evolutionary Models" Systematic Biology. 2010. 59(4). 465-476
+    References
+    ----------
+
+    Hartmann, Wong, and Stadler "Sampling Trees from Evolutionary Models" Systematic Biology. 2010. 59(4). 465-476
 
     """
     target_num_taxa = kwargs.get('ntax')
@@ -344,9 +347,9 @@ def discrete_birth_death_tree(birth_rate, death_rate, birth_rate_sd=0.0, death_r
     False.
 
     Under some conditions, it is possible for all lineages on a tree to go extinct.
-    In this case, if the keyword argument ``repeat_until_success`` is `True`, then a new
+    In this case, if the keyword argument ``repeat_until_success`` is |True|, then a new
     branching process is initiated.
-    If `False` (default), then a TreeSimTotalExtinctionException is raised.
+    If |False| (default), then a TreeSimTotalExtinctionException is raised.
 
     A Random() object or equivalent can be passed using the ``rng`` keyword;
     otherwise GLOBAL_RNG is used.
@@ -509,7 +512,7 @@ def fit_pure_birth_model(**kwargs):
                 In some cases (typically, abnormal trees, e.g., 1-tip), the
                 likelihood estimation will fail. In this case a ValueError will
                 be raised. If ``ignore_likelihood_calculation_failure`` is
-                `True`, then the function call will still succeed, with the
+                |True|, then the function call will still succeed, with the
                 likelihood set to -``inf``.
 
     Returns
diff --git a/dendropy/model/coalescent.py b/dendropy/model/coalescent.py
index b288412..c819cb6 100644
--- a/dendropy/model/coalescent.py
+++ b/dendropy/model/coalescent.py
@@ -26,6 +26,7 @@ import dendropy
 from dendropy.utility import GLOBAL_RNG
 from dendropy.utility import constants
 from dendropy.calculate import probability
+from dendropy.calculate import combinatorics
 
 ###############################################################################
 ## Calculations and statistics
@@ -52,7 +53,7 @@ def discrete_time_to_coalescence(n_genes,
     n_to_coalesce : integer
         The waiting time that will be returned will be the waiting time for
         this number of genes in the sample to coalesce.
-    rng : `Random`
+    rng : ``Random`` object
         The random number generator instance.
 
     Returns
@@ -69,7 +70,7 @@ def discrete_time_to_coalescence(n_genes,
         time_units = pop_size
     if rng is None:
         rng = GLOBAL_RNG
-    p = pop_size / probability.binomial_coefficient(n_genes, n_to_coalesce)
+    p = pop_size / combinatorics.choose(n_genes, n_to_coalesce)
     tmrca = probability.geometric_rv(p)
     return tmrca * time_units
 
@@ -85,7 +86,7 @@ def time_to_coalescence(n_genes,
 
     Given the number of gene lineages in a sample, ``n_genes``, and a
     population size, ``pop_size``, this function returns a random number from
-    an exponential distribution with rate $\choose(``pop_size``, 2)$.
+    an exponential distribution with rate $\\choose(``pop_size``, 2)$.
     ``pop_size`` is the effective *haploid* population size; i.e., number of gene
     in the population: 2 * N in a diploid population of N individuals,
     or N in a haploid population of N individuals. If ``pop_size`` is 1 or 0 or
@@ -96,11 +97,11 @@ def time_to_coalescence(n_genes,
     The coalescence time, or the waiting time for the coalescence, of two
     gene lineages evolving in a population with haploid size $N$ is an
     exponentially-distributed random variable with rate of $N$ an
-    expectation of $\frac{1}{N}$).
+    expectation of $\\frac{1}{N}$).
     The waiting time for coalescence of *any* two gene lineages in a sample of
     $n$ gene lineages evolving in a population with haploid size $N$ is an
-    exponentially-distributed random variable with rate of $\choose{N, 2}$ and
-    an expectation of $\frac{1}{\choose{N, 2}}$.
+    exponentially-distributed random variable with rate of $\\choose{N, 2}$ and
+    an expectation of $\\frac{1}{\choose{N, 2}}$.
 
     Parameters
     ----------
@@ -113,7 +114,7 @@ def time_to_coalescence(n_genes,
     n_to_coalesce : integer
         The waiting time that will be returned will be the waiting time for
         this number of genes in the sample to coalesce.
-    rng : `Random`
+    rng : ``Random`` object
         The random number generator instance to use.
 
     Returns
@@ -129,7 +130,7 @@ def time_to_coalescence(n_genes,
         time_units = 1.0
     else:
         time_units = pop_size
-    rate = probability.binomial_coefficient(n_genes, n_to_coalesce)
+    rate = combinatorics.choose(n_genes, n_to_coalesce)
     tmrca = rng.expovariate(rate)
     return tmrca * time_units
 
@@ -150,7 +151,7 @@ def expected_tmrca(n_genes, pop_size=None, n_to_coalesce=2):
     n_to_coalesce : integer
         The waiting time that will be returned will be the waiting time for
         this number of genes in the sample to coalesce.
-    rng : `Random`
+    rng : ``Random`` object
         The random number generator instance.
 
     Returns
@@ -161,7 +162,7 @@ def expected_tmrca(n_genes, pop_size=None, n_to_coalesce=2):
         ``pop_size`` genes.
 
     """
-    nc2 = probability.binomial_coefficient(n_genes, n_to_coalesce)
+    nc2 = combinatorics.choose(n_genes, n_to_coalesce)
     tmrca = (float(1)/nc2)
     if pop_size is not None:
         return tmrca * pop_size
@@ -216,11 +217,11 @@ def coalesce_nodes(nodes,
         time equals 2N generations for a diploid population of size N, or N
         generations for a haploid population of size N. Otherwise time is in
         generations.
-    rng : `Random`
+    rng : ``Random`` object
         The random number generator instance to use. If not specified, the
         default RNG will be used.
     use_expected_tmrca : bool
-        If `True`, then instead of random times, the *expected* times will be
+        If |True|, then instead of random times, the *expected* times will be
         used.
 
     Returns
@@ -398,9 +399,11 @@ def log_probability_of_coalescent_frames(coalescent_frames, haploid_pop_size):
     Kingman1982b}, the waiting times between coalescent events in a
     sample of $k$ alleles segregating in a  population of (haploid) size
     $N_e$ is distributed exponentially with a rate parameter of
-    $\frac{{k \choose 2}}{N_e}$::
+    :math`\\frac{{k \choose 2}}{N_e}`::
 
-         \Pr(T) =  \frac{{k \choose 2}}{N_e} \e{-  \frac{{k \choose 2}}{N_e} T},
+        .. math::
+
+            \\Pr(T) =  \\frac{{k \\choose 2}}{N_e} \\e{-  \\frac{{k \\choose 2}}{N_e} T},
 
     where $T$ is the length of  (chronological) time in which there are
     $k$ alleles in the sample (i.e., for $k$ alleles to coalesce into
@@ -409,7 +412,7 @@ def log_probability_of_coalescent_frames(coalescent_frames, haploid_pop_size):
     lp = 0.0
     for k, t in coalescent_frames.items():
         k2N = (float(k * (k-1)) / 2) / haploid_pop_size
-#         k2N = float(probability.binomial_coefficient(k, 2)) / haploid_pop_size
+#         k2N = float(combinatorics.choose(k, 2)) / haploid_pop_size
         lp =  lp + math.log(k2N) - (k2N * t)
     return lp
 
diff --git a/dendropy/model/discrete.py b/dendropy/model/discrete.py
index fefd098..8f1cb3c 100644
--- a/dendropy/model/discrete.py
+++ b/dendropy/model/discrete.py
@@ -476,8 +476,8 @@ def simulate_discrete_chars(
         appended to existing sequences of corresponding taxa in char_matrix; if
         not, a new |DnaCharacterMatrix| object will be created.
     retain_sequences_on_tree : bool
-        If `False`, sequence annotations will be cleared from tree after
-        simulation. Set to `True` if you want to, e.g., evolve and accumulate
+        If |False|, sequence annotations will be cleared from tree after
+        simulation. Set to |True| if you want to, e.g., evolve and accumulate
         different sequences on tree, or retain information for other purposes.
     rng           : random number generator
         If not given, 'GLOBAL_RNG' will be used.
@@ -537,8 +537,8 @@ def hky85_chars(
         appended to existing sequences of corresponding taxa in char_matrix; if
         not, a new |DnaCharacterMatrix| object will be created.
     retain_sequences_on_tree : bool
-        If `False`, sequence annotations will be cleared from tree after
-        simulation. Set to `True` if you want to, e.g., evolve and accumulate
+        If |False|, sequence annotations will be cleared from tree after
+        simulation. Set to |True| if you want to, e.g., evolve and accumulate
         different sequences on tree, or retain information for other purposes.
     rng           : random number generator
         If not given, 'GLOBAL_RNG' will be used.
diff --git a/dendropy/model/parsimony.py b/dendropy/model/parsimony.py
index 8514a67..634a510 100644
--- a/dendropy/model/parsimony.py
+++ b/dendropy/model/parsimony.py
@@ -65,7 +65,7 @@ def fitch_down_pass(
         traversal of the tree.
     state_sets_attr_name : str
         Name of attribute on |Node| objects in which state set lists
-        will stored/accessed. If `None`, then state sets will not be stored on
+        will stored/accessed. If |None|, then state sets will not be stored on
         the tree.
     taxon_state_sets_map : dict[taxon] = state sets
         A dictionary that takes a taxon object as a key and returns a state set
@@ -75,7 +75,7 @@ def fitch_down_pass(
     weights : iterable
         A list of weights for each pattern.
     score_by_character_list : None or list
-        If not `None`, should be a reference to a list object.
+        If not |None|, should be a reference to a list object.
         This list will be populated by the scores on a character-by-character
         basis.
 
@@ -227,7 +227,7 @@ def fitch_up_pass(
         traversal of the tree.
     state_sets_attr_name : str
         Name of attribute on |Node| objects in which state set lists
-        will stored/accessed. If `None`, then state sets will not be stored on
+        will stored/accessed. If |None|, then state sets will not be stored on
         the tree.
     taxon_state_sets_map : dict[taxon] = state sets
         A dictionary that takes a taxon object as a key and returns a state set
@@ -325,12 +325,12 @@ def parsimony_score(
         A |CharacterMatrix|-derived object with data to be scored. Must have
         the same |TaxonNamespace| as ``tree``.
     gap_as_missing : bool
-        If `True` [default], then gaps will be treated as missing data.
-        If `False`, then gaps will be treated as a new/additional state.
+        If |True| [default], then gaps will be treated as missing data.
+        If |False|, then gaps will be treated as a new/additional state.
     weights : iterable
         A list of weights for each pattern/column in the matrix.
     score_by_character_list : None or list
-        If not `None`, should be a reference to a list object.
+        If not |None|, should be a reference to a list object.
         This list will be populated by the scores on a character-by-character
         basis.
 
@@ -368,7 +368,7 @@ def parsimony_score(
 
         # We store the site-specific scores here
         # This is optional; if we do not want to
-        # use the per-site scores, just pass in ``None``
+        # use the per-site scores, just pass in |None|
         # for the ``score_by_character_list`` argument
         # or do not specify this argument at all.
         score_by_character_list = []
diff --git a/dendropy/model/protractedspeciation.py b/dendropy/model/protractedspeciation.py
index b28d86a..de95ea9 100644
--- a/dendropy/model/protractedspeciation.py
+++ b/dendropy/model/protractedspeciation.py
@@ -17,40 +17,326 @@
 ##############################################################################
 
 """
-Models, modeling and model-fitting of the Protracted Speciation Process.
+Models, modeling and model-fitting of the protracted speciation, as described in::
+
+        Etienne, R.S., Morlon, H., and Lambert, A. 2014. Estimating the
+        duration of speciation from phylogenies. Evolution 2014: 2430-2440.
+        doi:10.1111/evo.12433
+
 """
 
+import math
 import itertools
 import dendropy
 from dendropy.utility import GLOBAL_RNG
+from dendropy.utility.error import ProcessFailedException
 from dendropy.utility.error import TreeSimTotalExtinctionException
 from dendropy.calculate import probability
 
-class ProtractedSpeciationModel(object):
-
-    class ProcessFailedException(TreeSimTotalExtinctionException):
-        pass
 
-    class ProtractedSpeciationModelLineage(object):
+def _D(speciation_initiation_rate,
+       speciation_completion_rate,
+       incipient_species_extinction_rate):
+    """
+    Returns value of D, as given in eq. 5 in Etienne et al.
+    (2014).
+
+    Parameters
+    ----------
+
+    speciation_initiation_rate : float
+        The birth rate, b (the incipient species birth
+        rate and the "good" species birth rate are assumed to be equal):
+        the rate at which new (incipient) species are produced from
+        either incipient or "good" species lineages.
+    speciation_completion_rate : float
+        The rate at which incipient species get converted to good
+        species, $\lambda_1$.
+    incipient_species_extinction_rate : float
+        The incipient species exctinction rate, $\mu_1$: the rate at which
+        incipient species go extinct.
+
+    Returns
+    -------
+    t : float
+        The duration of speciation.
+
+    """
+    D = math.sqrt(
+            pow(speciation_completion_rate + speciation_initiation_rate - incipient_species_extinction_rate, 2)
+            + (4.0 * speciation_completion_rate * incipient_species_extinction_rate)
+        )
+    return D
+
+def _phi(speciation_initiation_rate,
+       speciation_completion_rate,
+       incipient_species_extinction_rate):
+    """
+    Returns value of $\varphi$, as given in eq. 6 in Etienne et al.
+    (2014).
+
+    Parameters
+    ----------
+
+    speciation_initiation_rate : float
+        The birth rate, b (the incipient species birth
+        rate and the "good" species birth rate are assumed to be equal):
+        the rate at which new (incipient) species are produced from
+        either incipient or "good" species lineages.
+    speciation_completion_rate : float
+        The rate at which incipient species get converted to good
+        species, $\lambda_1$.
+    incipient_species_extinction_rate : float
+        The incipient species exctinction rate, $\mu_1$: the rate at which
+        incipient species go extinct.
+
+    Returns
+    -------
+    t : float
+        The duration of speciation.
+
+    """
+    phi = speciation_completion_rate - speciation_initiation_rate + incipient_species_extinction_rate
+    return phi
+
+def expected_duration_of_speciation(
+        speciation_initiation_rate,
+        speciation_completion_rate,
+        incipient_species_extinction_rate,
+        D=None,
+        ):
+    """
+    Returns mean duration of speciation, following Eqs. 4 in Etienne et al.
+    (2014):
+
+        The duration of speciation differs from the speciation-completion
+        time in that the latter is the waiting time until a single
+        incipient lineage completes the speciation process if extinction
+        was zero, whereas the former is the time needed for an incipient
+        species or one of its descendants to complete speciation, condi-
+        tional on the fact that speciation completes, that is, this is the
+        time taken by any species that succeeded in speciating completely.
+
+    Parameters
+    ----------
+
+    speciation_initiation_rate : float
+        The birth rate, b (the incipient species birth
+        rate and the "good" species birth rate are assumed to be equal):
+        the rate at which new (incipient) species are produced from
+        either incipient or "good" species lineages.
+    speciation_completion_rate : float
+        The rate at which incipient species get converted to good
+        species, $\lambda_1$.
+    incipient_species_extinction_rate : float
+        The incipient species exctinction rate, $\mu_1$: the rate at which
+        incipient species go extinct.
+    D : float
+        Value of ``D`` (as given in Eq. 5 in Etienne et al. 2014). Will be
+        calculated if not specified.
+
+    Returns
+    -------
+    t : float
+        The duration of speciation.
+
+    """
+    if D is None:
+        D = _D(
+            speciation_initiation_rate=speciation_initiation_rate,
+            speciation_completion_rate=speciation_completion_rate,
+            incipient_species_extinction_rate=incipient_species_extinction_rate)
+    t1 = 2.0/(D - speciation_completion_rate + speciation_initiation_rate - incipient_species_extinction_rate )
+    t2 = math.log(2.0/(1+((speciation_completion_rate - speciation_initiation_rate + incipient_species_extinction_rate)/D)))
+    t = t1 * t2
+    return t
+
+def probability_of_duration_of_speciation(
+        tau,
+        speciation_initiation_rate,
+        speciation_completion_rate,
+        incipient_species_extinction_rate,
+        D=None,
+        phi=None,
+        ):
+    """
+    Returns probability of duration of speciation, tau, following Eqs. 6
+    in Etienne et al.
+
+    Parameters
+    ----------
+
+    tau : float
+        The duration of speciation.
+    speciation_initiation_rate : float
+        The birth rate, b (the incipient species birth
+        rate and the "good" species birth rate are assumed to be equal):
+        the rate at which new (incipient) species are produced from
+        either incipient or "good" species lineages.
+    speciation_completion_rate : float
+        The rate at which incipient species get converted to good
+        species, $\lambda_1$.
+    incipient_species_extinction_rate : float
+        The incipient species exctinction rate, $\mu_1$: the rate at which
+        incipient species go extinct.
+    D : float
+        Value of ``D`` (as given in Eq. 5 in Etienne et al. 2014). Will be
+        calculated if not specified.
+    phi : float
+        Value of ``phi`` (as given in Eq. 7 in Etienne et al. 2014). Will be
+        calculated if not specified.
+
+    Returns
+    -------
+    p : float
+        The probability of the duration of speciation, tau.
+
+    """
+    if D is None:
+        D = _D(
+            speciation_initiation_rate=speciation_initiation_rate,
+            speciation_completion_rate=speciation_completion_rate,
+            incipient_species_extinction_rate=incipient_species_extinction_rate)
+    if phi is None:
+        phi = _phi(
+            speciation_initiation_rate=speciation_initiation_rate,
+            speciation_completion_rate=speciation_completion_rate,
+            incipient_species_extinction_rate=incipient_species_extinction_rate)
+    n1 = 2.0 * pow(D, 2) * math.exp(-D * tau) * (D + phi)
+    d1 = pow(D + phi + math.exp(-D * tau) * (D-phi), 2)
+    return n1/d1
+
+def log_probability_of_duration_of_speciation(
+        tau,
+        speciation_initiation_rate,
+        speciation_completion_rate,
+        incipient_species_extinction_rate,
+        D=None,
+        phi=None,
+        ):
+    """
+    Returns probability of duration of speciation, tau, following Eqs. 6
+    in Etienne et al.
+
+    Parameters
+    ----------
+
+    tau : float
+        The duration of speciation.
+    speciation_initiation_rate : float
+        The birth rate, b (the incipient species birth
+        rate and the "good" species birth rate are assumed to be equal):
+        the rate at which new (incipient) species are produced from
+        either incipient or "good" species lineages.
+    speciation_completion_rate : float
+        The rate at which incipient species get converted to good
+        species, $\lambda_1$.
+    incipient_species_extinction_rate : float
+        The incipient species exctinction rate, $\mu_1$: the rate at which
+        incipient species go extinct.
+    D : float
+        Value of ``D`` (as given in Eq. 5 in Etienne et al. 2014). Will be
+        calculated if not specified.
+    phi : float
+        Value of ``phi`` (as given in Eq. 7 in Etienne et al. 2014). Will be
+        calculated if not specified.
+
+    Returns
+    -------
+    p : float
+        The probability of the duration of speciation, tau.
+
+    """
+    if D is None:
+        D = _D(
+            speciation_initiation_rate=speciation_initiation_rate,
+            speciation_completion_rate=speciation_completion_rate,
+            incipient_species_extinction_rate=incipient_species_extinction_rate)
+    if phi is None:
+        phi = _phi(
+            speciation_initiation_rate=speciation_initiation_rate,
+            speciation_completion_rate=speciation_completion_rate,
+            incipient_species_extinction_rate=incipient_species_extinction_rate)
+    n1 = math.log(2.0) + (2 * math.log(D)) - (D * tau) + math.log(D + phi)
+    d1 = 2 * (math.log(D + phi + math.exp(-D * tau)*(D-phi)))
+    return n1 - d1
+
+def maximum_probability_duration_of_speciation(
+        speciation_initiation_rate,
+        speciation_completion_rate,
+        incipient_species_extinction_rate,
+        D=None,
+        phi=None,
+        ):
+    """
+    Returns duration of speciation that maximizes probability under given
+    process parameters, following eq. 8 of Etienne et al (2014).
+
+    Parameters
+    ----------
+
+    speciation_initiation_rate : float
+        The birth rate, b (the incipient species birth
+        rate and the "good" species birth rate are assumed to be equal):
+        the rate at which new (incipient) species are produced from
+        either incipient or "good" species lineages.
+    speciation_completion_rate : float
+        The rate at which incipient species get converted to good
+        species, $\lambda_1$.
+    incipient_species_extinction_rate : float
+        The incipient species exctinction rate, $\mu_1$: the rate at which
+        incipient species go extinct.
+    D : float
+        Value of ``D`` (as given in Eq. 5 in Etienne et al. 2014). Will be
+        calculated if not specified.
+    phi : float
+        Value of ``phi`` (as given in Eq. 7 in Etienne et al. 2014). Will be
+        calculated if not specified.
+
+    Returns
+    -------
+    t : float
+        The duration of speciation with the maximum probability under the
+        given process parameters.
+
+    """
+    if D is None:
+        D = _D(
+            speciation_initiation_rate=speciation_initiation_rate,
+            speciation_completion_rate=speciation_completion_rate,
+            incipient_species_extinction_rate=incipient_species_extinction_rate)
+    if phi is None:
+        phi = _phi(
+            speciation_initiation_rate=speciation_initiation_rate,
+            speciation_completion_rate=speciation_completion_rate,
+            incipient_species_extinction_rate=incipient_species_extinction_rate)
+    x = 1.0/D * math.log((D-phi)/(D+phi))
+    return max(0, x)
+
+class ProtractedSpeciationProcess(object):
+
+    class ProtractedSpeciationProcessLineage(object):
 
         def __init__(self,
                 index,
                 parent_lineage,
                 speciation_initiation_time,
-                is_full_species):
+                is_orthospecies,
+                orthospecies_index):
             self._index = index
-            self.is_full_species = is_full_species
+            self.is_orthospecies = is_orthospecies
             self.parent_lineage = parent_lineage
             self.speciation_initiation_time = speciation_initiation_time
             self.speciation_completion_time = None
             self.extinction_time = None
-            self.protracted_speciation_tree_node_history = []
+            self.lineage_tree_node_history = []
             self._label = "L{}".format(self._index)
+            self.orthospecies_index = orthospecies_index
 
         def _get_node(self):
-            return self.protracted_speciation_tree_node_history[-1]
+            return self.lineage_tree_node_history[-1]
         def _set_node(self, node):
-            self.protracted_speciation_tree_node_history.append(node)
+            self.lineage_tree_node_history.append(node)
         node = property(_get_node, _set_node)
 
         def _get_index(self):
@@ -65,17 +351,17 @@ class ProtractedSpeciationModel(object):
             return self._get_label()
 
     def __init__(self,
-            full_species_birth_rate,
-            full_species_extinction_rate,
-            incipient_species_birth_rate,
-            incipient_species_conversion_rate,
+            speciation_initiation_from_orthospecies_rate,
+            speciation_initiation_from_incipient_species_rate,
+            speciation_completion_rate,
+            orthospecies_extinction_rate,
             incipient_species_extinction_rate,
             rng=None,
             ):
-        self.full_species_birth_rate = full_species_birth_rate
-        self.full_species_extinction_rate = full_species_extinction_rate
-        self.incipient_species_birth_rate = incipient_species_birth_rate
-        self.incipient_species_conversion_rate = incipient_species_conversion_rate
+        self.speciation_initiation_from_orthospecies_rate = speciation_initiation_from_orthospecies_rate
+        self.orthospecies_extinction_rate = orthospecies_extinction_rate
+        self.speciation_initiation_from_incipient_species_rate = speciation_initiation_from_incipient_species_rate
+        self.speciation_completion_rate = speciation_completion_rate
         self.incipient_species_extinction_rate = incipient_species_extinction_rate
         if rng is None:
             self.rng = GLOBAL_RNG
@@ -88,57 +374,60 @@ class ProtractedSpeciationModel(object):
     def reset(self):
         self.current_time = 0.0
         self.current_lineage_index = 0
+        self.current_orthospecies_index = 0
         self.current_node_index = 0
-        self.current_full_species_lineages = []
+        self.current_orthospecies_lineages = []
         self.current_incipient_species_lineages = []
-        self._all_lineages = []
+        self.lineage_to_orthospecies_tree_node_map = {}
 
     def generate_sample(self, **kwargs):
         """
 
-        Samples from the Protracted Speciation Model process, returning a tuple of trees:
+        Samples from the Protracted Speciation Model process, returning a tuple:
 
-            -   The unpruned PSM tree: this tree has all nodes/lineages, i.e. both
-                full species as well as incipient species.
-            -   The pruned full species tree: the tree only has full species.
+            -   the lineage tree: this tree has all nodes/lineages, i.e. both
+                "good" species as well as incipient species.
+            -   the (ortho- or confirmed- or "good"-)species tree: the tree
+                only has "good" species, i.e. with all incipient species
+                pruned out.
 
-        Each node on the protracted speciation tree as will as the full species
+        Each node on the protracted speciation tree as will as the "good" species
         tree will have an attribute, ``protracted_speciation_model_lineage``,
         which is a reference to a
-        :class:`~dendropy.model.birthdeath.ProtractedSpeciationModel.ProtractedSpeciationModelLineage`
+        :class:`~dendropy.model.birthdeath.ProtractedSpeciationProcess.ProtractedSpeciationProcessLineage`
         instance which represents the lineage associated with this node. Note
         that each node can only be associated with a single lineage, but a
         lineage might span several nodes.
 
-        If ``is_correlate_protracted_speciation_and_full_speciation_trees`` is ``True``,
+        If ``is_correlate_lineage_and_species_trees`` is |True|,
         then additional attributes will be added. See
-        :meth:``dendropy.model.protractedspeciation.ProtractedSpeciationModel.correlate_protracted_speciation_and_full_speciation_trees`
+        :meth:``dendropy.model.protractedspeciation.ProtractedSpeciationProcess.correlate_lineage_and_species_trees`
         for details.
 
         Parameters
         ----------
 
-        max_time : float or `None`
-            Terminate and return results when this time is reached. If `None`,
+        max_time : float or |None|
+            Terminate and return results when this time is reached. If |None|,
             then do not terminated based on run time.
-        max_full_species : int or `None`
+        max_extant_orthospecies : int or |None|
             Terminate and return results when this number of tips are found in
-            the full-species tree (i.e., the pruned tree consisting of only
-            "full" or "good" species). If `None`, then do not terminate
-            based on the number of tipes on the full-species tree.
-        max_extant_protracted_speciation_lineages : int or `None`
+            the confirmed-species tree (i.e., the pruned tree consisting of only
+            "good" species). If |None|, then do not terminate
+            based on the number of tipes on the confirmed-species tree.
+        max_extant_lineages : int or |None|
             Terminate and return results when this number of tips are found in
-            the incipient tree (i.e. the tree with both incipient and full
-            species). If `None`, then do not terminate based on the
+            the lineage tree (i.e. the tree with both incipient and good
+            species). If |None|, then do not terminate based on the
             number of tipes on the incipient species tree.
-        is_initial_species_incipient : bool
-            Whether the first lineage that initialies the process is an
-            incipient or full species. Defaults to `False`: first species on
-            the tree is a full species.
+        is_initial_lineage_orthospecies : bool
+            Whether the first lineage that initialies the process is a
+            "good" species or not. Defaults to |True|: first species on
+            the tree is a "good" species.
         is_retry_on_total_extinction : bool
-            If ``False``, then a TreeSimTotalExtinctionException will be raised
+            If |False|, then a TreeSimTotalExtinctionException will be raised
             if all lineages go extinct before the termination conditions are
-            met. Defaults to ``True``: if all lineages go extinct before the
+            met. Defaults to |True|: if all lineages go extinct before the
             termination conditions are met, then the simulation is rerun, up to
             a maximum of ``max_retries``.
         max_retries : int
@@ -146,131 +435,273 @@ class ProtractedSpeciationModel(object):
             prematurely-terminated simulations due to all lineages going
             extinct. Once this number or re-runs is exceed, then
             TreeSimTotalExtinctionException is raised. Defaults to 1000. Set to
-            ``None`` to never quit trying.
-        is_correlate_protracted_speciation_and_full_speciation_trees: bool
-            If ``True`` then additional attributes will be added to the
+            |None| to never quit trying.
+        is_correlate_lineage_and_species_trees: bool
+            [NOT USED]
+            If |True| then additional attributes will be added to the
             resulting trees to relate them. See
-            :meth:``dendropy.model.protractedspeciation.ProtractedSpeciationModel.correlate_protracted_speciation_and_full_speciation_trees`
+            :meth:``dendropy.model.protractedspeciation.ProtractedSpeciationProcess.correlate_lineage_and_species_trees`
             for details.
 
         Returns
         -------
-        protracted_speciation_tree : |Tree| instance
+        lineage_tree : |Tree| instance
             A tree from the protracted speciation process, with all lineages
-            (full species as well as incipient species).
-        full_species_tree : |Tree| instance
-            A tree from the protracted speciation process with only full species.
+            (good species as well as incipient species).
+        orthospecies_tree : |Tree| instance
+            A tree from the protracted speciation process with only "good" species.
 
         """
         is_retry_on_total_extinction = kwargs.pop("is_retry_on_total_extinction", True)
         max_retries = kwargs.pop("max_retries", 1000)
         num_retries = 0
-        protracted_speciation_tree = None
-        full_species_tree = None
+        lineage_tree = None
+        orthospecies_tree = None
         while True:
             try:
-                protracted_speciation_tree, full_species_tree = self._run_protracted_speciation_process(**kwargs)
+                lineage_tree, orthospecies_tree = self._run_protracted_speciation_process(**kwargs)
                 break
-            except TreeSimTotalExtinctionException:
+            except ProcessFailedException:
                 if not is_retry_on_total_extinction:
                     raise
                 num_retries += 1
                 if max_retries is not None and num_retries > max_retries:
                     raise
-        assert protracted_speciation_tree is not None
-        return protracted_speciation_tree, full_species_tree
-
-    def correlate_protracted_speciation_and_full_speciation_trees(self,
-            protracted_speciation_tree,
-            full_species_tree):
-        """
-        Correlates the protracted speciation tree and the corresponding pruned
-        full species tree from a single sample of the protracted speciation
-        process (i.e., a call to ``generate_sample()``).
-
-        Each node on the protracted speciation tree will have the following
-        attributes added:
-
-            - ``is_full_speciation_event`` : ``True`` if the node represents a
-             full/good speciation event, ``False`` otherwise.
-
-        Each internal node on the full species tree will have the following
-        attributes added:
-
-            - ``protracted_speciation_tree_node``: a reference to the node on
-              the protratcted speciation tree to which it corresponds.
-
-        Each leaf node on the full species tree will have the following
-        attributes added:
-
-            - ``included_protracted_speciation_tree_leaf_nodes``: the set of
-              terminal/leaf nodes on the protracted speciation tree which are
-              descended/included in it.
-
-        """
-        protracted_speciation_tree.calc_node_ages()
-        for full_species_tree_nd in full_species_tree:
-            if full_species_tree_nd.is_leaf():
-                continue
-            protracted_speciation_tree_node = full_species_tree_nd.protracted_speciation_model_lineage.protracted_speciation_tree_node_history[0]
-            for nd in full_species_tree_nd.protracted_speciation_model_lineage.protracted_speciation_tree_node_history:
-                if nd.age is not None and nd.age > protracted_speciation_tree_node.age:
-                    protracted_speciation_tree_node = nd
-            protracted_speciation_tree_node.is_full_speciation_event = True
-            full_species_tree_nd.protracted_speciation_tree_node = protracted_speciation_tree_node
-        return protracted_speciation_tree, full_species_tree
+        assert lineage_tree is not None
+        return lineage_tree, orthospecies_tree
+
+    # def correlate_lineage_and_species_trees(self,
+    #         lineage_tree,
+    #         orthospecies_tree):
+    #     """
+    #     Correlates the protracted speciation tree and the corresponding pruned
+    #     "good" species tree from a single sample of the protracted speciation
+    #     process (i.e., a call to ``generate_sample()``).
+
+    #     Each node on the lineage tree will have the following
+    #     attributes added:
+
+    #         - ``is_orthospeciation_event`` : |True| if the node represents a
+    #          "good" speciation event, |False| otherwise.
+
+    #     Each internal node on the "good" species tree will have the following
+    #     attributes added:
+
+    #         - ``lineage_tree_node``: a reference to the node on
+    #           the protratcted speciation tree to which it corresponds.
+
+    #     Each leaf node on the orthospecies tree will have the following
+    #     attributes added:
+
+    #         - ``included_lineage_tree_leaf_nodes``: the set of
+    #           terminal/leaf nodes on the protracted speciation tree which are
+    #           descended/included in it.
+
+    #     """
+    #     return lineage_tree, orthospecies_tree
+    #     lineage_tree.calc_node_ages()
+
+    #     orthospecies_tree_leaf_node_parent_age_to_desc_node_and_lineages_map = {}
+    #     for os_nd in orthospecies_tree.leaf_node_iter():
+    #         if os_nd.parent_node is None:
+    #             raise ProcessFailedException()
+    #         age = str(os_nd.parent_node.age)
+    #         orthospecies_tree_leaf_node_parent_age_to_desc_node_and_lineages_map[age] = []
+    #         for ch1 in os_nd.parent_node.child_node_iter():
+    #             if not ch1._child_nodes:
+    #                 # desc_lineages = set([sch1.protracted_speciation_model_lineage for sch1 in ch1.preorder_node_iter])
+    #                 orthospecies_tree_leaf_node_parent_age_to_desc_node_and_lineages_map[age].append((ch1, ch1.protracted_speciation_model_lineage))
+
+
+    #             # desc_lineages = set([sch1.protracted_speciation_model_lineage for sch1 in ch1.preorder_node_iter])
+    #             # orthospecies_tree_leaf_node_parent_age_to_desc_node_and_lineages_map.append( (ch1, desc_lineages) )
+
+    #     for ln_nd in lineage_tree.leaf_node_iter():
+    #         cur_nd = ln_nd
+    #         if cur_nd.parent_node is None:
+    #             raise ProcessFailedException()
+    #         focal_nd_siblings = [snd for snd in ln_nd.parent_node.child_node_iter() if snd is not ln_nd]
+    #         focal_nd_parents = [pnd for pnd in ln_nd.ancestor_iter(inclusive=False)]
+    #         chain = []
+    #         age_found = False
+    #         found = None
+    #         while True:
+    #             if cur_nd is None:
+    #                 print("!!! {}: current is None".format(" > ".join(chain)) )
+    #                 break
+    #             chain.append(cur_nd.label)
+    #             if cur_nd.parent_node is None:
+    #                 print("!!! {}: parent is None".format(" > ".join(chain)) )
+    #                 break
+    #             age = str(cur_nd.parent_node.age)
+    #             if age in orthospecies_tree_leaf_node_parent_age_to_desc_node_and_lineages_map:
+    #                 age_found = True
+    #                 cur_nd_desc_lineages = set([sch.protracted_speciation_model_lineage for sch in cur_nd.preorder_iter()])
+    #                 for orthospecies_nd, orthospecies_lineage in orthospecies_tree_leaf_node_parent_age_to_desc_node_and_lineages_map[age]:
+    #                     if orthospecies_lineage in cur_nd_desc_lineages:
+    #                         print(":::: {} found in desc of {}: {}".format(orthospecies_nd.protracted_speciation_model_lineage.label, ln_nd.label, [x.label for x in cur_nd_desc_lineages]))
+    #                         orthospecies_nd.included_lineage_tree_leaf_nodes.add(ln_nd)
+    #                         found = orthospecies_nd
+    #                         break
+    #                 break
+    #             cur_nd = cur_nd.parent_node
+    #         if not age_found:
+    #             print("Age not found: {}".format(ln_nd.label))
+    #         elif not found:
+    #             print("Not found: {}".format(ln_nd.label))
+    #         else:
+    #             print("Found: {} => {}".format(ln_nd.label, found.label))
+    #     # lineage_tree_node_to_orthospecies_leaf_map = {}
+    #     # lineage_orthospecies_leaf_map = {}
+    #     # for orthospecies_tree_nd in orthospecies_tree:
+    #     #     if not orthospecies_tree_nd._child_nodes:
+    #     #         lineage_orthospecies_leaf_map[orthospecies_tree_nd.protracted_speciation_model_lineage] = orthospecies_tree_nd
+    #     #         continue
+    #     #     lineage_tree_node = sorted(orthospecies_tree_nd.protracted_speciation_model_lineage.lineage_tree_node_history, key=lambda x: x.age)[-1]
+    #     #     for history_nd in orthospecies_tree_nd.protracted_speciation_model_lineage.lineage_tree_node_history:
+    #     #         if not orthospecies_tree_nd._child_nodes:
+    #     #             lineage_tree_node_to_orthospecies_leaf_map[history_nd] = orthospecies_tree_nd
+    #     #         # if history_nd.age is not None and history_nd.age >= lineage_tree_node.age:
+    #     #         #     lineage_tree_node = history_nd
+    #     #     lineage_tree_node.is_orthospeciation_event = True
+    #     #     orthospecies_tree_nd.lineage_tree_node = lineage_tree_node
+
+    #     # for lineage_tree_leaf in lineage_tree.leaf_node_iter():
+    #     #     nd = lineage_tree_leaf
+    #     #     print("#### {}: {}".format(lineage_tree_leaf.label, nd.protracted_speciation_model_lineage.is_orthospecies))
+    #     #     while nd and nd.protracted_speciation_model_lineage.speciation_completion_time is not None:
+    #     #         print(">>>> {}: {}".format(lineage_tree_leaf.label, nd.label))
+    #     #         nd = nd.parent_node
+    #     #     if not nd:
+    #     #         print("!!! Failed: {}".format(lineage_tree_leaf.label))
+    #     #     elif not nd.protracted_speciation_model_lineage.is_orthospecies:
+    #     #         print("!!! Failed 2: {}".format(lineage_tree_leaf.label))
+    #     #     else:
+    #     #         current_lineages = [desc.protracted_speciation_model_lineage for desc in nd.preorder_iter()]
+    #     #         print("set for {}: {}".format(lineage_tree_leaf.label, [x.label for x in current_lineages]))
+    #     #         for lineage in current_lineages:
+    #     #             if lineage in lineage_orthospecies_leaf_map:
+    #     #                 lineage_orthospecies_leaf_map[lineage].included_lineage_tree_leaf_nodes.append(lineage_tree_leaf)
+    #     #                 break
+    #     #         else:
+    #     #             print("Not found: {}".format(lineage_tree_leaf.label))
+
+
+    #     # for lineage_tree_leaf in lineage_tree.leaf_node_iter():
+    #     #     lineage = lineage_tree_leaf.protracted_speciation_model_lineage
+    #     #     while lineage is not None and not lineage.is_orthospecies:
+    #     #         lineage = lineage.parent_lineage
+    #     #     if lineage is None:
+    #     #         ## TODO: special case
+    #     #         pass
+    #     #     for orthospecies_tree_nd in orthospecies_tree:
+    #     #         if orthospecies_tree_nd.protracted_speciation_model_lineage is lineage:
+    #     #             if orthospecies_tree_nd._child_nodes:
+    #     #                 print("Internal node {} for: {}".format(orthospecies_tree_nd.label, lineage_tree_leaf.label))
+    #     #             else:
+    #     #                 print("OK {} for: {}".format(orthospecies_tree_nd.label, lineage_tree_leaf.label))
+    #     #             break
+    #     #     else:
+    #     #         print("Not found: {}".format(lineage_tree_leaf.label))
+
+
+
+    #     # for lineage_tree_leaf in lineage_tree.leaf_node_iter():
+    #     #     print("....{}".format(lineage_tree_leaf.label))
+    #     #     if lineage_tree_leaf in lineage_tree_node_to_orthospecies_leaf_map:
+    #     #         print("516: {}: {} => {}".format(lineage_tree_node_to_orthospecies_leaf_map[lineage_tree_leaf].label, lineage_tree_leaf.label, list(x.label for x in lineage_tree_node_to_orthospecies_leaf_map[lineage_tree_leaf].included_lineage_tree_leaf_nodes)))
+    #     #         lineage_tree_node_to_orthospecies_leaf_map[lineage_tree_leaf].included_lineage_tree_leaf_nodes.append(lineage_tree_leaf)
+    #     #         print("518: {}: {} => {}".format(lineage_tree_node_to_orthospecies_leaf_map[lineage_tree_leaf].label, lineage_tree_leaf.label, list(x.label for x in lineage_tree_node_to_orthospecies_leaf_map[lineage_tree_leaf].included_lineage_tree_leaf_nodes)))
+    #     #     else:
+    #     #         print("519")
+    #     #         lineage = lineage_tree_leaf.protracted_speciation_model_lineage
+    #     #         while lineage is not None and lineage not in lineage_orthospecies_leaf_map:
+    #     #             lineage = lineage.parent_lineage
+    #     #         if lineage is None:
+    #     #             print("524")
+    #     #             orthospecies_tree.seed_node.included_lineage_tree_leaf_nodes.append(lineage_tree_leaf)
+    #     #             print("<<< {} >>>".format(lineage_tree_leaf.label))
+    #     #         else:
+    #     #             print("528")
+    #     #             lineage_orthospecies_leaf_map[lineage].included_lineage_tree_leaf_nodes.append(lineage_tree_leaf)
+
+    #         # # while lineage is not None and not lineage.is_orthospecies:
+    #         # #     lineage = lineage.parent_lineage
+    #         # if lineage is None:
+    #         #     orthospecies_tree_nd = orthospecies_tree.seed_node
+    #         # else:
+    #         #     orthospecies_tree_nd = self.lineage_to_orthospecies_tree_node_map[lineage]
+    #         #     # for xnd in orthospecies_tree.leaf_node_iter():
+    #         #     #     if xnd.protracted_speciation_model_lineage is lineage:
+    #         #     #         orthospecies_tree_nd = xnd
+    #         #     #         break
+    #         #     # else:
+    #         #     #     orthospecies_tree_nd = orthospecies_tree.seed_node
+    #         # try:
+    #         #     orthospecies_tree_nd.included_lineage_tree_leaf_nodes.append(lineage)
+    #         # except AttributeError:
+    #         #     orthospecies_tree_nd.included_lineage_tree_leaf_nodes = [lineage]
+
+    #         # while lineage is not None and lineage not in self.lineage_to_orthospecies_tree_node_map:
+    #         #     lineage = lineage.parent_lineage
+    #         # if lineage not in self.lineage_to_orthospecies_tree_node_map:
+    #         #     orthospecies_tree_nd = orthospecies_tree.seed_node
+    #         # else:
+    #         #     orthospecies_tree_nd = self.lineage_to_orthospecies_tree_node_map[lineage]
+    #         # orthospecies_tree_nd.included_lineage_tree_leaf_nodes.append(lineage)
+
+    #     return lineage_tree, orthospecies_tree
 
     def _run_protracted_speciation_process(self, **kwargs):
         self.reset()
         max_time = kwargs.get("max_time", None)
-        max_extant_protracted_speciation_lineages = kwargs.get("max_extant_protracted_speciation_lineages", None)
-        max_full_species = kwargs.get("max_full_species", None)
-        is_correlate_protracted_speciation_and_full_speciation_trees = kwargs.get("is_correlate_protracted_speciation_and_full_speciation_trees", False)
+        max_extant_lineages = kwargs.get("max_extant_lineages", None)
+        max_extant_orthospecies = kwargs.get("max_extant_orthospecies", None)
+        is_correlate_lineage_and_species_trees = kwargs.get("is_correlate_lineage_and_species_trees", False)
         taxon_namespace = kwargs.get("taxon_namespace", None)
-
-        is_full_species = not kwargs.get("is_initial_species_incipient", False)
-        if is_full_species:
-            initial_lineage = self._new_lineage(parent_lineage=None, is_full_species=True)
-        else:
-            initial_lineage = self._new_lineage(parent_lineage=None, is_full_species=False)
+        initial_lineage = self._new_lineage(
+                parent_lineage=None,
+                orthospecies_index=self.current_orthospecies_index,
+                is_orthospecies=kwargs.get("is_initial_lineage_orthospecies", True),
+                )
         seed_node = self._new_node(lineage=initial_lineage)
-        protracted_speciation_tree = self.tree_factory( taxon_namespace=taxon_namespace, seed_node=seed_node)
-        protracted_speciation_tree.is_rooted = True
+        lineage_tree = self.tree_factory( taxon_namespace=taxon_namespace, seed_node=seed_node)
+        lineage_tree.is_rooted = True
 
         while True:
 
             ## Draw time to next event
             event_rates = []
-            num_full_species = len(self.current_full_species_lineages)
-            if max_full_species is not None:
+            num_orthospecies = len(self.current_orthospecies_lineages)
+            if max_extant_orthospecies is not None:
                 ## note: expensive operation to count leaves!
                 try:
-                    full_species_tree = self._assemble_full_species_tree(taxon_namespace=taxon_namespace)
-                    num_leaves = len(full_species_tree.leaf_nodes())
-                    if num_leaves >= max_full_species:
-                        return self._postprocess_psm_and_full_species_trees(
-                                full_species_tree=full_species_tree,
-                                protracted_speciation_tree=protracted_speciation_tree,
-                                is_correlate_protracted_speciation_and_full_speciation_trees=is_correlate_protracted_speciation_and_full_speciation_trees,
+                    orthospecies_tree = self._assemble_orthospecies_tree(taxon_namespace=taxon_namespace)
+                    num_leaves = len(orthospecies_tree.leaf_nodes())
+                    if num_leaves >= max_extant_orthospecies:
+                        return self._postprocess_psm_and_orthospecies_trees(
+                                orthospecies_tree=orthospecies_tree,
+                                lineage_tree=lineage_tree,
+                                is_correlate_lineage_and_species_trees=is_correlate_lineage_and_species_trees,
                                 )
-                except ProtractedSpeciationModel.ProcessFailedException:
+                except ProcessFailedException:
                     pass
 
             num_incipient_species = len(self.current_incipient_species_lineages)
-            if max_extant_protracted_speciation_lineages is not None and (num_incipient_species + num_full_species) >= max_extant_protracted_speciation_lineages:
+            if max_extant_lineages is not None and (num_incipient_species + num_orthospecies) >= max_extant_lineages:
                 break
 
             # Event type 0
-            event_rates.append(self.full_species_birth_rate * num_full_species)
+            event_rates.append(self.speciation_initiation_from_orthospecies_rate * num_orthospecies)
 
             # Event type 1
-            event_rates.append(self.full_species_extinction_rate * num_full_species)
+            event_rates.append(self.orthospecies_extinction_rate * num_orthospecies)
 
             # Event type 2
-            event_rates.append(self.incipient_species_birth_rate * num_incipient_species)
+            event_rates.append(self.speciation_initiation_from_incipient_species_rate * num_incipient_species)
 
             # Event type 3
-            event_rates.append(self.incipient_species_conversion_rate * num_incipient_species)
+            event_rates.append(self.speciation_completion_rate * num_incipient_species)
 
             # Event type 4
             event_rates.append(self.incipient_species_extinction_rate * num_incipient_species)
@@ -282,12 +713,12 @@ class ProtractedSpeciationModel(object):
             waiting_time = self.rng.expovariate(rate_of_any_event)
             if max_time and (self.current_time + waiting_time) > max_time:
                 t = max_time - self.current_time
-                for lineage in itertools.chain(self.current_full_species_lineages, self.current_incipient_species_lineages):
+                for lineage in itertools.chain(self.current_orthospecies_lineages, self.current_incipient_species_lineages):
                     lineage.node.edge.length += t
                 self.current_time = max_time
                 break
             self.current_time += waiting_time
-            for lineage in itertools.chain(self.current_full_species_lineages, self.current_incipient_species_lineages):
+            for lineage in itertools.chain(self.current_orthospecies_lineages, self.current_incipient_species_lineages):
                 lineage.node.edge.length += waiting_time
 
             # Select event
@@ -296,59 +727,172 @@ class ProtractedSpeciationModel(object):
             # print("time {}: {}, selected = {}".format(self.current_time, event_rates, event_type_idx))
 
             if event_type_idx == 0:
-                self._process_full_species_birth(protracted_speciation_tree)
+                self._process_initiation_of_speciation_from_orthospecies(lineage_tree)
             elif event_type_idx == 1:
-                self._process_full_species_extinction(protracted_speciation_tree)
+                self._process_orthospecies_extinction(lineage_tree)
             elif event_type_idx == 2:
-                self._process_incipient_species_birth(protracted_speciation_tree)
+                self._process_initiation_of_speciation_from_incipient_species(lineage_tree)
             elif event_type_idx == 3:
-                self._process_incipient_species_conversion(protracted_speciation_tree)
+                self._process_completion_of_specation(lineage_tree)
             elif event_type_idx == 4:
-                self._process_incipient_species_extinction(protracted_speciation_tree)
+                self._process_incipient_species_extinction(lineage_tree)
             else:
                 raise Exception("Unexpected event type index: {}".format(event_type_idx))
 
-            if len(self.current_full_species_lineages) + len(self.current_incipient_species_lineages) == 0:
+            if len(self.current_orthospecies_lineages) + len(self.current_incipient_species_lineages) == 0:
                 raise TreeSimTotalExtinctionException()
 
-        full_species_tree = self._assemble_full_species_tree(taxon_namespace=taxon_namespace)
-        return self._postprocess_psm_and_full_species_trees(
-                protracted_speciation_tree=protracted_speciation_tree,
-                full_species_tree=full_species_tree,
-                is_correlate_protracted_speciation_and_full_speciation_trees=is_correlate_protracted_speciation_and_full_speciation_trees,
+        orthospecies_tree = self._assemble_orthospecies_tree(taxon_namespace=taxon_namespace)
+        return self._postprocess_psm_and_orthospecies_trees(
+                lineage_tree=lineage_tree,
+                orthospecies_tree=orthospecies_tree,
+                is_correlate_lineage_and_species_trees=is_correlate_lineage_and_species_trees,
                 )
 
-    def _process_full_species_birth(self, tree):
-        parent_lineage = self.rng.choice(self.current_full_species_lineages)
-        parent_node = parent_lineage.node
-        new_lineage = self._new_lineage(parent_lineage=parent_lineage, is_full_species=False)
-        c1 = self._new_node(lineage=parent_lineage)
-        c2 = self._new_node(lineage=new_lineage)
-        parent_node.add_child(c1)
-        parent_node.add_child(c2)
-
-    def _process_full_species_extinction(self, tree):
-        sp = self.rng.choice(self.current_full_species_lineages)
-        sp.extinction_time = self.current_time
-        self.current_full_species_lineages.remove(sp)
-        self._make_lineage_extinct_on_phylogeny(tree, sp.node)
-
-    def _process_incipient_species_birth(self, tree):
+    def _process_initiation_of_speciation_from_orthospecies(self, tree):
+        # parent_lineage = self.rng.choice(self.current_orthospecies_lineages)
+        # parent_node = parent_lineage.node
+        # new_lineage = self._new_lineage(
+        #         parent_lineage=parent_lineage,
+        #         orthospecies_index=parent_lineage.orthospecies_index,
+        #         is_orthospecies=False)
+        # c1 = self._new_node(lineage=parent_lineage)
+        # c2 = self._new_node(lineage=new_lineage)
+        # parent_node.add_child(c1)
+        # parent_node.add_child(c2)
+        parent_lineage = self.rng.choice(self.current_orthospecies_lineages)
+        self._process_initiation_of_speciation(parent_lineage=parent_lineage)
+
+    def _process_initiation_of_speciation_from_incipient_species(self, tree):
+        # parent_lineage = self.rng.choice(self.current_incipient_species_lineages)
+        # parent_node = parent_lineage.node
+        # new_lineage = self._new_lineage(
+        #         parent_lineage=parent_lineage,
+        #         orthospecies_index=parent_lineage.orthospecies_index,
+        #         is_orthospecies=False)
+        # c1 = self._new_node(lineage=parent_lineage)
+        # c2 = self._new_node(lineage=new_lineage)
+        # parent_node.add_child(c1)
+        # parent_node.add_child(c2)
         parent_lineage = self.rng.choice(self.current_incipient_species_lineages)
+        self._process_initiation_of_speciation(parent_lineage=parent_lineage)
+
+    def _process_initiation_of_speciation(self, parent_lineage):
         parent_node = parent_lineage.node
-        new_lineage = self._new_lineage(parent_lineage=parent_lineage, is_full_species=False)
+        new_lineage = self._new_lineage(
+                parent_lineage=parent_lineage,
+                orthospecies_index=parent_lineage.orthospecies_index,
+                is_orthospecies=False)
         c1 = self._new_node(lineage=parent_lineage)
         c2 = self._new_node(lineage=new_lineage)
         parent_node.add_child(c1)
         parent_node.add_child(c2)
 
-    def _process_incipient_species_conversion(self, tree):
+        # parent_node = parent_lineage.node
+        # new_lineage1 = self._new_lineage(
+        #         parent_lineage=parent_lineage,
+        #         orthospecies_index=parent_lineage.orthospecies_index,
+        #         is_orthospecies=False,
+        #         add_to_current_lineages=True)
+        # new_lineage2 = self._new_lineage(
+        #         parent_lineage=parent_lineage,
+        #         orthospecies_index=parent_lineage.orthospecies_index,
+        #         is_orthospecies=parent_lineage.is_orthospecies,
+        #         add_to_current_lineages=False)
+        # new_lineage2.lineage_tree_node_history = parent_lineage.lineage_tree_node_history
+        # c1 = self._new_node(lineage=new_lineage1)
+        # c2 = self._new_node(lineage=new_lineage2)
+        # parent_node.add_child(c1)
+        # parent_node.add_child(c2)
+
+    def _process_completion_of_specation(self, tree):
+
         lineage = self.rng.choice(self.current_incipient_species_lineages)
         self.current_incipient_species_lineages.remove(lineage)
-        self.current_full_species_lineages.append(lineage)
-        lineage.is_full_species = True
+        self.current_orthospecies_lineages.append(lineage)
+        self.current_orthospecies_index += 1
+        lineage.orthospecies_index = self.current_orthospecies_index
+        lineage.is_orthospecies = True
         lineage.speciation_completion_time = self.current_time
 
+        # original_lineage = self.rng.choice(self.current_incipient_species_lineages)
+        # self.current_incipient_species_lineages.remove(original_lineage)
+        # self.current_orthospecies_index += 1
+        # converted_lineage = self._new_lineage(
+        #         parent_lineage=original_lineage,
+        #         orthospecies_index=self.current_orthospecies_index,
+        #         is_orthospecies=True,
+        #         add_to_current_lineages=False)
+        # converted_lineage.orthospecies_index = self.current_orthospecies_index
+        # converted_lineage.is_orthospecies = True
+        # converted_lineage.speciation_completion_time = self.current_time
+        # self.current_orthospecies_lineages.append(converted_lineage)
+        # converted_lineage.node = original_lineage.node
+
+        # original_lineage = self.rng.choice(self.current_incipient_species_lineages)
+        # self.current_incipient_species_lineages.remove(original_lineage)
+        # self.current_orthospecies_index += 1
+        # converted_lineage = self._new_lineage(
+        #         parent_lineage=original_lineage,
+        #         orthospecies_index=self.current_orthospecies_index,
+        #         is_orthospecies=True,
+        #         add_to_current_lineages=False)
+        # converted_lineage.orthospecies_index = self.current_orthospecies_index
+        # converted_lineage.is_orthospecies = True
+        # converted_lineage.speciation_completion_time = self.current_time
+        # self.current_orthospecies_lineages.append(converted_lineage)
+        # c1 = self._new_node(lineage=converted_lineage)
+        # original_lineage.node.add_child(c1)
+
+        # original_lineage = self.rng.choice(self.current_incipient_species_lineages)
+        # self.current_incipient_species_lineages.remove(original_lineage)
+        # self.current_orthospecies_index += 1
+        # converted_lineage = self._new_lineage(
+        #         parent_lineage=original_lineage,
+        #         orthospecies_index=self.current_orthospecies_index,
+        #         is_orthospecies=True,
+        #         add_to_current_lineages=False)
+        # converted_lineage.orthospecies_index = self.current_orthospecies_index
+        # converted_lineage.is_orthospecies = True
+        # converted_lineage.speciation_completion_time = self.current_time
+        # self.current_orthospecies_lineages.append(converted_lineage)
+        # p2 = original_lineage.node
+        # c1 = self._new_node(lineage=converted_lineage)
+        # c2 = self._new_node(lineage=original_lineage)
+        # p2.add_child(c1)
+        # p2.add_child(c2)
+
+        # original_lineage = self.rng.choice(self.current_incipient_species_lineages)
+        # self.current_incipient_species_lineages.remove(original_lineage)
+        # self.current_orthospecies_index += 1
+        # converted_lineage = original_lineage
+        # converted_lineage.orthospecies_index = self.current_orthospecies_index
+        # converted_lineage.is_orthospecies = True
+        # converted_lineage.speciation_completion_time = self.current_time
+        # self.current_orthospecies_lineages.append(converted_lineage)
+
+        # lineage = self.rng.choice(self.current_incipient_species_lineages)
+        # self.current_incipient_species_lineages.remove(lineage)
+        # self.current_orthospecies_index += 1
+        # converted_lineage = self._new_lineage(
+        #         parent_lineage=lineage.parent_lineage,
+        #         orthospecies_index=self.current_orthospecies_index,
+        #         is_orthospecies =True)
+        # converted_lineage.speciation_completion_time = self.current_time
+        # self.current_orthospecies_lineages.append(converted_lineage)
+        # converted_lineage.lineage_tree_node_history = list(lineage.lineage_tree_node_history)
+        # old_node = lineage.node
+        # c1 = self._new_node(lineage=converted_lineage)
+        # c2 = self._new_node(lineage=lineage)
+        # old_node.add_child(c1)
+        # old_node.add_child(c2)
+
+    def _process_orthospecies_extinction(self, tree):
+        sp = self.rng.choice(self.current_orthospecies_lineages)
+        sp.extinction_time = self.current_time
+        self.current_orthospecies_lineages.remove(sp)
+        self._make_lineage_extinct_on_phylogeny(tree, sp.node)
+
     def _process_incipient_species_extinction(self, tree):
         sp = self.rng.choice(self.current_incipient_species_lineages)
         sp.extinction_time = self.current_time
@@ -356,24 +900,29 @@ class ProtractedSpeciationModel(object):
         self._make_lineage_extinct_on_phylogeny(tree, sp.node)
 
     def _make_lineage_extinct_on_phylogeny(self, tree, sp):
-        if len(self.current_full_species_lineages) == 0 and len(self.current_incipient_species_lineages) == 0:
+        if len(self.current_orthospecies_lineages) == 0 and len(self.current_incipient_species_lineages) == 0:
             raise TreeSimTotalExtinctionException()
         tree.prune_subtree(sp)
 
-    def _new_lineage(self, parent_lineage, is_full_species):
+    def _new_lineage(self,
+            parent_lineage,
+            orthospecies_index,
+            is_orthospecies,
+            add_to_current_lineages=True):
         self.current_lineage_index += 1
         lineage_index = self.current_lineage_index
         speciation_initiation_time = self.current_time
-        new_lineage = ProtractedSpeciationModel.ProtractedSpeciationModelLineage(
+        new_lineage = ProtractedSpeciationProcess.ProtractedSpeciationProcessLineage(
                 index=lineage_index,
                 parent_lineage=parent_lineage,
                 speciation_initiation_time=speciation_initiation_time,
-                is_full_species=is_full_species)
-        self._all_lineages.append(new_lineage)
-        if is_full_species:
-            self.current_full_species_lineages.append(new_lineage)
-        else:
-            self.current_incipient_species_lineages.append(new_lineage)
+                is_orthospecies=is_orthospecies,
+                orthospecies_index=orthospecies_index)
+        if add_to_current_lineages:
+            if is_orthospecies:
+                self.current_orthospecies_lineages.append(new_lineage)
+            else:
+                self.current_incipient_species_lineages.append(new_lineage)
         return new_lineage
 
     def _new_node(self,
@@ -382,54 +931,47 @@ class ProtractedSpeciationModel(object):
         node = self.node_factory()
         node.edge.length = 0.0
         node.protracted_speciation_model_lineage = lineage
-        node.is_full_speciation_event = False
-        node.annotations.add_bound_attribute("is_full_speciation_event")
+        node.is_orthospeciation_event = False
         self.current_node_index += 1
         node.label = "{}.n{}".format(lineage.label, self.current_node_index)
+        node.index = self.current_node_index
         node.annotations.add_new(name="lineage_index", value=lineage.index)
         node.annotations.add_new(name="lineage_label", value=lineage.label)
+        node.annotations.add_new(name="speciation_initiation_time", value=lineage.speciation_initiation_time)
         lineage.node = node
         return node
 
-    def _assemble_full_species_tree(self, taxon_namespace=None):
-        lineage_set = set(self.current_incipient_species_lineages + self.current_full_species_lineages)
+    def _assemble_orthospecies_tree(self, taxon_namespace=None):
+        lineage_set = set(self.current_incipient_species_lineages + self.current_orthospecies_lineages)
         sorted_lineages = sorted(lineage_set,
                 key = lambda x: -x.speciation_initiation_time)
-        # sys.stderr.write("\n--- full ---\n")
-        # self._debug_dump_lineages(self._all_lineages)
-        # sys.stderr.write("\n\n--- operational ---\n")
-        # self._debug_dump_lineages(sorted_lineages)
-        branching_points = {}
+        self.lineage_to_orthospecies_tree_node_map = {}
         while sorted_lineages:
             lineage = sorted_lineages.pop(0)
             lineage_set.remove(lineage)
             parent_lineage = lineage.parent_lineage
             if parent_lineage is None:
                 break
-            if lineage.is_full_species:
-                full_species_tree_node = self._require_full_species_tree_node(
-                        lineage_full_species_tree_node_map=branching_points,
-                        lineage=lineage)
+            if lineage.is_orthospecies:
+                orthospecies_tree_node = self._require_orthospecies_tree_node(lineage=lineage)
                 # try:
-                #     full_species_tree_node = branching_points[lineage]
+                #     orthospecies_tree_node = self.lineage_to_orthospecies_tree_node_map[lineage]
                 # except KeyError:
-                #     full_species_tree_node = dendropy.Node()
-                #     full_species_tree_node.label = "L{}".format(lineage.index)
-                #     full_species_tree_node.protracted_speciation_model_lineage = lineage
-                #     branching_points[lineage] = full_species_tree_node
-                if lineage.is_full_species:
-                    parent_lineage.is_full_species = True
+                #     orthospecies_tree_node = dendropy.Node()
+                #     orthospecies_tree_node.label = "L{}".format(lineage.index)
+                #     orthospecies_tree_node.protracted_speciation_model_lineage = lineage
+                #     self.lineage_to_orthospecies_tree_node_map[lineage] = orthospecies_tree_node
+                if lineage.is_orthospecies:
+                    parent_lineage.is_orthospecies = True
                 # try:
-                #     full_species_tree_parent_node = branching_points[parent_lineage]
+                #     orthospecies_tree_parent_node = self.lineage_to_orthospecies_tree_node_map[parent_lineage]
                 # except KeyError:
-                #     full_species_tree_parent_node = dendropy.Node()
-                #     full_species_tree_parent_node.label = "L{}".format(parent_lineage.index)
-                #     full_species_tree_parent_node.protracted_speciation_model_lineage = parent_lineage
-                #     branching_points[parent_lineage] = full_species_tree_parent_node
-                full_species_tree_parent_node = self._require_full_species_tree_node(
-                        lineage_full_species_tree_node_map=branching_points,
-                        lineage=parent_lineage)
-                full_species_tree_parent_node.add_child(full_species_tree_node)
+                #     orthospecies_tree_parent_node = dendropy.Node()
+                #     orthospecies_tree_parent_node.label = "L{}".format(parent_lineage.index)
+                #     orthospecies_tree_parent_node.protracted_speciation_model_lineage = parent_lineage
+                #     self.lineage_to_orthospecies_tree_node_map[parent_lineage] = orthospecies_tree_parent_node
+                orthospecies_tree_parent_node = self._require_orthospecies_tree_node(lineage=parent_lineage)
+                orthospecies_tree_parent_node.add_child(orthospecies_tree_node)
                 if parent_lineage not in lineage_set:
                     lineage_set.add(parent_lineage)
                     sorted_lineages = sorted(lineage_set,
@@ -437,71 +979,64 @@ class ProtractedSpeciationModel(object):
 
         # identify seed node
         seed_node = None
-        for nd in branching_points.values():
+        for nd in self.lineage_to_orthospecies_tree_node_map.values():
             if nd.parent_node is None:
                 seed_node = nd
                 break
         if seed_node is None:
-            raise ProtractedSpeciationModel.ProcessFailedException()
+            raise ProcessFailedException()
 
         # create pruned tree
-        full_species_tree = dendropy.Tree(taxon_namespace=taxon_namespace, seed_node=seed_node)
-        full_species_tree.is_rooted = True
+        orthospecies_tree = dendropy.Tree(taxon_namespace=taxon_namespace, seed_node=seed_node)
+        orthospecies_tree.is_rooted = True
 
-        # full_species_tree.suppress_unifurcations()
-        # full_species_tree.set_edge_lengths_from_node_ages()
+        # orthospecies_tree.suppress_unifurcations()
+        # orthospecies_tree.set_edge_lengths_from_node_ages()
 
-        ## assign ages to full species tree
-        for nd in full_species_tree.postorder_node_iter():
+        ## assign ages to orthospecies tree
+        for nd in orthospecies_tree.postorder_node_iter():
             if nd.is_leaf():
                 nd.age = 0
             else:
                 nd.age = self.current_time - min(ch.protracted_speciation_model_lineage.speciation_initiation_time for ch in nd.child_node_iter())
-        full_species_tree.set_edge_lengths_from_node_ages()
-        full_species_tree.suppress_unifurcations()
-
-        # point to tips on psm tree that are included in each full species
-        # for lineage in branching_points:
-        #     full_species_node = branching_points[lineage]
-        #     if full_species_node.is_leaf():
-        #         for protracted_speciation_tree_tip in lineage.protracted_speciation_tree_node_history:
-        #             if protracted_speciation_tree_tip.is_leaf():
-        #                 try:
-        #                     full_species_node.included_protracted_speciation_tree_leaf_nodes.append(protracted_speciation_tree_tip)
-        #                 except AttributeError:
-        #                     full_species_node.included_protracted_speciation_tree_leaf_nodes = [protracted_speciation_tree_tip]
-        #                 protracted_speciation_tree_tip.full_species_tree_node = protracted_speciation_tree_tip
-        #     else:
-        #         full_species_node.included_protracted_speciation_tree_leaf_nodes = []
-
-        return full_species_tree
-
-    def _postprocess_psm_and_full_species_trees(self,
-                        protracted_speciation_tree,
-                        full_species_tree,
-                        is_correlate_protracted_speciation_and_full_speciation_trees=False,
+        orthospecies_tree.set_edge_lengths_from_node_ages()
+        orthospecies_tree.suppress_unifurcations()
+        return orthospecies_tree
+
+    def _postprocess_psm_and_orthospecies_trees(self,
+                        lineage_tree,
+                        orthospecies_tree,
+                        is_correlate_lineage_and_species_trees=False,
                         ):
-        if is_correlate_protracted_speciation_and_full_speciation_trees:
-            return self.correlate_protracted_speciation_and_full_speciation_trees(
-                    protracted_speciation_tree=protracted_speciation_tree,
-                    full_species_tree=full_species_tree)
+        # lineage_tree.suppress_unifurcations()
+        for nd in lineage_tree:
+            nd.annotations.add_new(name="speciation_initiation_age", value=self.current_time - nd.annotations["speciation_initiation_time"].value)
+            nd.annotations.add_new(name="lineage_orthospecies_index", value=nd.protracted_speciation_model_lineage.orthospecies_index)
+            nd.label = "S{}.L{}.n{}".format(nd.protracted_speciation_model_lineage.orthospecies_index, nd.protracted_speciation_model_lineage.index, nd.index)
+        if is_correlate_lineage_and_species_trees:
+            raise NotImplementedError()
+            # return self.correlate_lineage_and_species_trees(
+            #         lineage_tree=lineage_tree,
+            #         orthospecies_tree=orthospecies_tree)
         else:
-            return protracted_speciation_tree, full_species_tree
+            return lineage_tree, orthospecies_tree
 
-    def _require_full_species_tree_node(self,
-            lineage_full_species_tree_node_map,
-            lineage):
+    def _require_orthospecies_tree_node(self, lineage):
         try:
-            return lineage_full_species_tree_node_map[lineage]
+            node = self.lineage_to_orthospecies_tree_node_map[lineage]
         except KeyError:
             node = self.node_factory()
-            node.label = lineage.label
+            node.label = "S{}".format(lineage.orthospecies_index)
+
+            ## this might be misleading, as, technically, multiple lineages
+            ## might be associated with this node; remove?
             node.protracted_speciation_model_lineage = lineage
             node.annotations.add_new(name="lineage_index", value=lineage.index)
             node.annotations.add_new(name="lineage_label", value=lineage.label)
-            lineage_full_species_tree_node_map[lineage] = node
-            return node
+            node.annotations.add_new(name="lineage_orthospecies_index", value=lineage.orthospecies_index)
 
+            self.lineage_to_orthospecies_tree_node_map[lineage] = node
+        return node
 
     def _debug_dump_lineages(self, lineages):
         sorted_lineages = sorted(lineages,
@@ -512,11 +1047,11 @@ class ProtractedSpeciationModel(object):
                 pt = "NA"
             else:
                 pi = k.parent_lineage.index
-                pt = k.parent_lineage.is_full_species
+                pt = k.parent_lineage.is_orthospecies
             sys.stderr.write("{:10.5f} : {:4} ({}) => {} ({})\n".format(
                     k.speciation_initiation_time,
                     k.index,
-                    k.is_full_species,
+                    k.is_orthospecies,
                     pi,
                     pt))
         sys.stderr.write("\n")
diff --git a/dendropy/model/reconcile.py b/dendropy/model/reconcile.py
index 0c1504d..c917e95 100644
--- a/dendropy/model/reconcile.py
+++ b/dendropy/model/reconcile.py
@@ -71,22 +71,22 @@ class ContainingTree(dendropy.Tree):
                 parasite trees.
 
             ``fit_containing_edge_lengths``
-                If `True` [default], then the branch lengths of
+                If |True| [default], then the branch lengths of
                 ``containing_tree`` will be adjusted to fit the contained tree
                 as they are added. Otherwise, the containing tree edge lengths
                 will not be changed.
 
             ``collapse_empty_edges``
-                If `True` [default], after edge lengths are adjusted,
+                If |True| [default], after edge lengths are adjusted,
                 zero-length branches will be collapsed.
 
             ``ultrametricity_precision``
-                If `False` [default], then trees will not be checked for
+                If |False| [default], then trees will not be checked for
                 ultrametricity. Otherwise this is the threshold within which
                 all node to tip distances for sister nodes must be equal.
 
             ``ignore_root_deep_coalescences``
-                If `True` [default], then deep coalescences in the root will
+                If |True| [default], then deep coalescences in the root will
                 not be counted.
 
         Other Keyword Arguments: Will be passed to Tree().
@@ -335,7 +335,7 @@ class ContainingTree(dendropy.Tree):
         conditional on self.
 
             ``rng``
-                Random number generator to use. If `None`, the default will
+                Random number generator to use. If |None|, the default will
                 be used.
 
             ``edge_pop_size_attr``
@@ -366,7 +366,7 @@ class ContainingTree(dendropy.Tree):
         conditional on self.
 
             ``rng``
-                Random number generator to use. If `None`, the default will
+                Random number generator to use. If |None|, the default will
                 be used.
 
             ``edge_pop_size_attr``
diff --git a/dendropy/model/treeshape.py b/dendropy/model/treeshape.py
index e063318..fd4f0df 100644
--- a/dendropy/model/treeshape.py
+++ b/dendropy/model/treeshape.py
@@ -17,11 +17,14 @@
 ##############################################################################
 
 """
-Models of canonical tree shapes.
+Models and operations with tree shapes.
 """
 
 import dendropy
 
+##############################################################################
+### Treeshape Generation
+
 def star_tree(taxon_namespace, **kwargs):
     "Builds and returns a star tree from the given taxa block."
     star_tree = dendropy.Tree(taxon_namespace=taxon_namespace, **kwargs)
diff --git a/dendropy/simulate/popgensim.py b/dendropy/simulate/popgensim.py
index 3d0c2a7..5dbc6fa 100644
--- a/dendropy/simulate/popgensim.py
+++ b/dendropy/simulate/popgensim.py
@@ -20,10 +20,6 @@
 Population genetic simlations.
 """
 
-try:
-    from StringIO import StringIO # Python 2 legacy support: StringIO in this module is the one needed (not io)
-except ImportError:
-    from io import StringIO # Python 3
 import random
 import copy
 
diff --git a/dendropy/test/benchmark/benchmark_newick_light_tree_parser.py b/dendropy/test/benchmark/benchmark_newick_light_tree_parser.py
index a787d7d..c8532fa 100644
--- a/dendropy/test/benchmark/benchmark_newick_light_tree_parser.py
+++ b/dendropy/test/benchmark/benchmark_newick_light_tree_parser.py
@@ -24,10 +24,7 @@ import sys
 import os
 import timeit
 import argparse
-try:
-    from StringIO import StringIO # Python 2 legacy support: StringIO in this module is the one needed (not io)
-except ImportError:
-    from io import StringIO # Python 3
+from dendropy.utility.textprocessing import StringIO
 from dendropy.utility import messaging
 from dendropy.test.support import pathmap
 
diff --git a/dendropy/test/benchmark/benchmark_newick_tree_parser.py b/dendropy/test/benchmark/benchmark_newick_tree_parser.py
index 7f9dc8f..cd02ae3 100644
--- a/dendropy/test/benchmark/benchmark_newick_tree_parser.py
+++ b/dendropy/test/benchmark/benchmark_newick_tree_parser.py
@@ -24,10 +24,6 @@ import sys
 import os
 import timeit
 import argparse
-try:
-    from StringIO import StringIO # Python 2 legacy support: StringIO in this module is the one needed (not io)
-except ImportError:
-    from io import StringIO # Python 3
 from dendropy.utility import messaging
 from dendropy.test.support import pathmap
 
diff --git a/dendropy/test/data/chars/community.data.tsv b/dendropy/test/data/chars/community.data.tsv
new file mode 100644
index 0000000..9138b6a
--- /dev/null
+++ b/dendropy/test/data/chars/community.data.tsv
@@ -0,0 +1,6 @@
+.	spA	spB	spC	spD	spE	spF	spG	spH	spI	spJ	spK	spL	spM	spN	spO
+C1	15	0	10	0	12	0	7	0	0	0	0	0	2	2	1
+C2	0	25	0	6	4	0	2	0	0	3	23	0	0	0	0
+C3	30	0	10	0	0	10	9	4	0	0	0	0	0	10	0
+C4	0	0	0	0	0	0	0	10	20	1	2	25	4	0	0
+C5	0	0	0	0	0	0	0	35	14	10	0	0	0	0	0
diff --git a/dendropy/test/data/other/community.data.tsv b/dendropy/test/data/other/community.data.tsv
new file mode 100644
index 0000000..9138b6a
--- /dev/null
+++ b/dendropy/test/data/other/community.data.tsv
@@ -0,0 +1,6 @@
+.	spA	spB	spC	spD	spE	spF	spG	spH	spI	spJ	spK	spL	spM	spN	spO
+C1	15	0	10	0	12	0	7	0	0	0	0	0	2	2	1
+C2	0	25	0	6	4	0	2	0	0	3	23	0	0	0	0
+C3	30	0	10	0	0	10	9	4	0	0	0	0	0	10	0
+C4	0	0	0	0	0	0	0	10	20	1	2	25	4	0	0
+C5	0	0	0	0	0	0	0	35	14	10	0	0	0	0	0
diff --git a/dendropy/test/data/other/community.data.weighted.unnormalized.ses.mntd.csv b/dendropy/test/data/other/community.data.weighted.unnormalized.ses.mntd.csv
new file mode 100644
index 0000000..0a6ba3e
--- /dev/null
+++ b/dendropy/test/data/other/community.data.weighted.unnormalized.ses.mntd.csv
@@ -0,0 +1,6 @@
+,ntaxa,mntd.obs,mntd.rand.mean,mntd.rand.sd,mntd.obs.rank,mntd.obs.z,mntd.obs.p,runs
+C1,7,1.6347319809428570991372,0.9807932306012356882263,0.4647308411074569933774,90629.0, 1.40713439371331716642999,0.906280937190628077537724,1e+05
+C2,6,1.0891173926393333815099,1.1014248921372569167687,0.5409714088730344094813,53923.5,-0.02275073931090523804421,0.539229607703922919625938,1e+05
+C3,6,1.0891173926543333827510,1.1067321596416703766153,0.5426009981949112548349,54979.0,-0.03246357276513796297213,0.549784502154978427235221,1e+05
+C4,6,0.1180230301583333335502,1.1042463120536243348369,0.5403321710730318860882,   31.5,-1.82521666244076352647596,0.000314996850031499674074,1e+05
+C5,3,0.1426761318733333339104,1.7795731495924900222860,0.9216293468345394535035,  332.0,-1.77609038095553350977696,0.003319966800331996571727,1e+05
diff --git a/dendropy/test/data/other/community.data.weighted.unnormalized.ses.mpd.csv b/dendropy/test/data/other/community.data.weighted.unnormalized.ses.mpd.csv
new file mode 100644
index 0000000..dbe956a
--- /dev/null
+++ b/dendropy/test/data/other/community.data.weighted.unnormalized.ses.mpd.csv
@@ -0,0 +1,6 @@
+,ntaxa,mpd.obs,mpd.rand.mean,mpd.rand.sd,mpd.obs.rank,mpd.obs.z,mpd.obs.p,runs
+C1,7,3.2225706087019050372078,2.472542460851128165444,0.5578018925940517735995,97130.5, 1.3446138455407150580356,0.971295287047129529689471,1e+05
+C2,6,1.9156605943056668195368,2.468689855458556348111,0.6461895847551316629520,21972.0,-0.8558312826451009991402,0.219717802821971786020327,1e+05
+C3,6,1.9156605943290001548007,2.472406340816184489029,0.6456980573413851898223,23113.5,-0.8622385341835230310181,0.231132688673113262378678,1e+05
+C4,6,1.9395923093204665565992,2.469928803225870606042,0.6456300343975983624389,25206.5,-0.8214247566723436033698,0.252062479375206260900910,1e+05
+C5,3,0.1934132401466666650869,2.472033069445358055560,1.1359378217800757404632,  382.5,-2.0059371081842942707851,0.003824961750382496143003,1e+05
diff --git a/dendropy/test/data/other/hiv1.distances.csv b/dendropy/test/data/other/hiv1.distances.csv
new file mode 100644
index 0000000..86fd869
--- /dev/null
+++ b/dendropy/test/data/other/hiv1.distances.csv
@@ -0,0 +1,194 @@
+,U97DCKFE45,H97DCEQTB1,A97DCKFE288,C97DCMBS20,A97DCMBFE78,A97DCMBFE247,G97DCKP74,J97DCKS16,K97DCEQTB43,A97DCKTB79,G97DCKCC1,F97DCF1KTB136,A97DCMBS28,H97DCKTB140,H97DCKS43,D97DCKTB27,K97DCKP13,A97DCKTB132,A97DCKTB13,D97DCMBS55,A97DCA1KFE58,D97DCMBS35,G97DCKS4,A97DCMBS4,A97DCKMST121,A97DCMBTB29,U97DCKTB17,U97DCKTB119,H97DCKTB176,D97DCKS15,G97DCKTB18,U97DCKMST120,A97DCEQS1,A97DCMBS9,D97DCMBS342,D97DCKP44,D97DCKTB181,A97DCEQTB14,A97DCKTB37,A97DCKFE198,A97DCEQS49,A97DCKP5,U97DCKTB22,A97DCKFE4 [...]
+U97DCKFE45,0.0,384.0,380.0,384.0,380.0,380.0,384.0,384.0,384.0,380.0,384.0,384.0,380.0,384.0,384.0,382.0,384.0,380.0,380.0,382.0,380.0,382.0,384.0,380.0,380.0,380.0,384.0,380.0,384.0,382.0,384.0,384.0,380.0,380.0,382.0,382.0,382.0,380.0,380.0,380.0,380.0,380.0,384.0,380.0,384.0,384.0,204.0,380.0,382.0,384.0,382.0,382.0,384.0,196.0,380.0,382.0,380.0,384.0,384.0,380.0,380.0,384.0,384.0,382.0,384.0,380.0,384.0,380.0,384.0,380.0,384.0,384.0,384.0,384.0,384.0,380.0,384.0,380.0,380.0,380.0,380 [...]
+H97DCEQTB1,384.0,0.0,384.0,150.0,384.0,384.0,82.0,82.0,150.0,384.0,82.0,150.0,384.0,30.0,30.0,384.0,150.0,384.0,384.0,384.0,384.0,384.0,82.0,384.0,384.0,384.0,150.0,384.0,26.0,384.0,82.0,82.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,82.0,384.0,150.0,82.0,384.0,384.0,384.0,150.0,384.0,384.0,150.0,384.0,384.0,384.0,384.0,150.0,82.0,384.0,384.0,82.0,150.0,384.0,150.0,384.0,150.0,384.0,150.0,384.0,26.0,150.0,82.0,30.0,30.0,384.0,150.0,384.0,384.0,384.0,384.0,30.0,150.0,384 [...]
+A97DCKFE288,380.0,384.0,0.0,384.0,336.0,336.0,384.0,384.0,384.0,336.0,384.0,384.0,336.0,384.0,384.0,382.0,384.0,336.0,242.0,382.0,376.0,382.0,384.0,336.0,242.0,336.0,384.0,378.0,384.0,382.0,384.0,384.0,346.0,336.0,382.0,382.0,382.0,254.0,336.0,336.0,254.0,336.0,384.0,242.0,384.0,384.0,380.0,376.0,382.0,384.0,382.0,382.0,384.0,380.0,378.0,382.0,336.0,384.0,384.0,336.0,336.0,384.0,384.0,382.0,384.0,336.0,384.0,218.0,384.0,242.0,384.0,384.0,384.0,384.0,384.0,336.0,384.0,336.0,242.0,376.0,37 [...]
+C97DCMBS20,384.0,150.0,384.0,0.0,384.0,384.0,150.0,150.0,148.0,384.0,150.0,148.0,384.0,150.0,150.0,384.0,148.0,384.0,384.0,384.0,384.0,384.0,150.0,384.0,384.0,384.0,148.0,384.0,150.0,384.0,150.0,150.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,150.0,384.0,142.0,150.0,384.0,384.0,384.0,148.0,384.0,384.0,144.0,384.0,384.0,384.0,384.0,116.0,150.0,384.0,384.0,150.0,148.0,384.0,146.0,384.0,142.0,384.0,148.0,384.0,150.0,148.0,150.0,150.0,150.0,384.0,148.0,384.0,384.0,384.0,384 [...]
+A97DCMBFE78,380.0,384.0,336.0,384.0,0.0,334.0,384.0,384.0,384.0,334.0,384.0,384.0,282.0,384.0,384.0,382.0,384.0,334.0,336.0,382.0,376.0,382.0,384.0,272.0,336.0,272.0,384.0,378.0,384.0,382.0,384.0,384.0,346.0,334.0,382.0,382.0,382.0,336.0,334.0,334.0,336.0,270.0,384.0,336.0,384.0,384.0,380.0,376.0,382.0,384.0,382.0,382.0,384.0,380.0,378.0,382.0,334.0,384.0,384.0,266.0,334.0,384.0,384.0,382.0,384.0,334.0,384.0,336.0,384.0,336.0,384.0,384.0,384.0,384.0,384.0,274.0,384.0,334.0,336.0,376.0,37 [...]
+A97DCMBFE247,380.0,384.0,336.0,384.0,334.0,0.0,384.0,384.0,384.0,320.0,384.0,384.0,334.0,384.0,384.0,382.0,384.0,320.0,336.0,382.0,376.0,382.0,384.0,334.0,336.0,334.0,384.0,378.0,384.0,382.0,384.0,384.0,346.0,320.0,382.0,382.0,382.0,336.0,320.0,294.0,336.0,334.0,384.0,336.0,384.0,384.0,380.0,376.0,382.0,384.0,382.0,382.0,384.0,380.0,378.0,382.0,294.0,384.0,384.0,334.0,332.0,384.0,384.0,382.0,384.0,294.0,384.0,336.0,384.0,336.0,384.0,384.0,384.0,384.0,384.0,334.0,384.0,332.0,336.0,376.0,3 [...]
+G97DCKP74,384.0,82.0,384.0,150.0,384.0,384.0,0.0,80.0,150.0,384.0,70.0,150.0,384.0,82.0,82.0,384.0,150.0,384.0,384.0,384.0,384.0,384.0,68.0,384.0,384.0,384.0,150.0,384.0,82.0,384.0,68.0,80.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,74.0,384.0,150.0,72.0,384.0,384.0,384.0,150.0,384.0,384.0,150.0,384.0,384.0,384.0,384.0,150.0,66.0,384.0,384.0,80.0,150.0,384.0,150.0,384.0,150.0,384.0,150.0,384.0,82.0,150.0,80.0,82.0,82.0,384.0,150.0,384.0,384.0,384.0,384.0,82.0,150.0,384. [...]
+J97DCKS16,384.0,82.0,384.0,150.0,384.0,384.0,80.0,0.0,150.0,384.0,80.0,150.0,384.0,82.0,82.0,384.0,150.0,384.0,384.0,384.0,384.0,384.0,80.0,384.0,384.0,384.0,150.0,384.0,82.0,384.0,80.0,44.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,80.0,384.0,150.0,80.0,384.0,384.0,384.0,150.0,384.0,384.0,150.0,384.0,384.0,384.0,384.0,150.0,80.0,384.0,384.0,42.0,150.0,384.0,150.0,384.0,150.0,384.0,150.0,384.0,82.0,150.0,42.0,82.0,82.0,384.0,150.0,384.0,384.0,384.0,384.0,82.0,150.0,384. [...]
+K97DCEQTB43,384.0,150.0,384.0,148.0,384.0,384.0,150.0,150.0,0.0,384.0,150.0,110.0,384.0,150.0,150.0,384.0,88.0,384.0,384.0,384.0,384.0,384.0,150.0,384.0,384.0,384.0,94.0,384.0,150.0,384.0,150.0,150.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,150.0,384.0,148.0,150.0,384.0,384.0,384.0,110.0,384.0,384.0,148.0,384.0,384.0,384.0,384.0,148.0,150.0,384.0,384.0,150.0,86.0,384.0,148.0,384.0,148.0,384.0,88.0,384.0,150.0,110.0,150.0,150.0,150.0,384.0,112.0,384.0,384.0,384.0,384.0, [...]
+A97DCKTB79,380.0,384.0,336.0,384.0,334.0,320.0,384.0,384.0,384.0,0.0,384.0,384.0,334.0,384.0,384.0,382.0,384.0,316.0,336.0,382.0,376.0,382.0,384.0,334.0,336.0,334.0,384.0,378.0,384.0,382.0,384.0,384.0,346.0,318.0,382.0,382.0,382.0,336.0,318.0,320.0,336.0,334.0,384.0,336.0,384.0,384.0,380.0,376.0,382.0,384.0,382.0,382.0,384.0,380.0,378.0,382.0,320.0,384.0,384.0,334.0,332.0,384.0,384.0,382.0,384.0,320.0,384.0,336.0,384.0,336.0,384.0,384.0,384.0,384.0,384.0,334.0,384.0,332.0,336.0,376.0,378 [...]
+G97DCKCC1,384.0,82.0,384.0,150.0,384.0,384.0,70.0,80.0,150.0,384.0,0.0,150.0,384.0,82.0,82.0,384.0,150.0,384.0,384.0,384.0,384.0,384.0,70.0,384.0,384.0,384.0,150.0,384.0,82.0,384.0,70.0,80.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,74.0,384.0,150.0,72.0,384.0,384.0,384.0,150.0,384.0,384.0,150.0,384.0,384.0,384.0,384.0,150.0,70.0,384.0,384.0,80.0,150.0,384.0,150.0,384.0,150.0,384.0,150.0,384.0,82.0,150.0,80.0,82.0,82.0,384.0,150.0,384.0,384.0,384.0,384.0,82.0,150.0,384. [...]
+F97DCF1KTB136,384.0,150.0,384.0,148.0,384.0,384.0,150.0,150.0,110.0,384.0,150.0,0.0,384.0,150.0,150.0,384.0,110.0,384.0,384.0,384.0,384.0,384.0,150.0,384.0,384.0,384.0,110.0,384.0,150.0,384.0,150.0,150.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,150.0,384.0,148.0,150.0,384.0,384.0,384.0,106.0,384.0,384.0,148.0,384.0,384.0,384.0,384.0,148.0,150.0,384.0,384.0,150.0,110.0,384.0,148.0,384.0,148.0,384.0,110.0,384.0,150.0,108.0,150.0,150.0,150.0,384.0,112.0,384.0,384.0,384.0, [...]
+A97DCMBS28,380.0,384.0,336.0,384.0,282.0,334.0,384.0,384.0,384.0,334.0,384.0,384.0,0.0,384.0,384.0,382.0,384.0,334.0,336.0,382.0,376.0,382.0,384.0,282.0,336.0,282.0,384.0,378.0,384.0,382.0,384.0,384.0,346.0,334.0,382.0,382.0,382.0,336.0,334.0,334.0,336.0,282.0,384.0,336.0,384.0,384.0,380.0,376.0,382.0,384.0,382.0,382.0,384.0,380.0,378.0,382.0,334.0,384.0,384.0,282.0,334.0,384.0,384.0,382.0,384.0,334.0,384.0,336.0,384.0,336.0,384.0,384.0,384.0,384.0,384.0,282.0,384.0,334.0,336.0,376.0,378 [...]
+H97DCKTB140,384.0,30.0,384.0,150.0,384.0,384.0,82.0,82.0,150.0,384.0,82.0,150.0,384.0,0.0,14.0,384.0,150.0,384.0,384.0,384.0,384.0,384.0,82.0,384.0,384.0,384.0,150.0,384.0,30.0,384.0,82.0,82.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,82.0,384.0,150.0,82.0,384.0,384.0,384.0,150.0,384.0,384.0,150.0,384.0,384.0,384.0,384.0,150.0,82.0,384.0,384.0,82.0,150.0,384.0,150.0,384.0,150.0,384.0,150.0,384.0,30.0,150.0,82.0,10.0,6.0,384.0,150.0,384.0,384.0,384.0,384.0,8.0,150.0,384. [...]
+H97DCKS43,384.0,30.0,384.0,150.0,384.0,384.0,82.0,82.0,150.0,384.0,82.0,150.0,384.0,14.0,0.0,384.0,150.0,384.0,384.0,384.0,384.0,384.0,82.0,384.0,384.0,384.0,150.0,384.0,30.0,384.0,82.0,82.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,82.0,384.0,150.0,82.0,384.0,384.0,384.0,150.0,384.0,384.0,150.0,384.0,384.0,384.0,384.0,150.0,82.0,384.0,384.0,82.0,150.0,384.0,150.0,384.0,150.0,384.0,150.0,384.0,30.0,150.0,82.0,14.0,14.0,384.0,150.0,384.0,384.0,384.0,384.0,14.0,150.0,384. [...]
+D97DCKTB27,382.0,384.0,382.0,384.0,382.0,382.0,384.0,384.0,384.0,382.0,384.0,384.0,382.0,384.0,384.0,0.0,384.0,382.0,382.0,182.0,382.0,162.0,384.0,382.0,382.0,382.0,384.0,382.0,384.0,184.0,384.0,384.0,382.0,382.0,186.0,182.0,182.0,382.0,382.0,382.0,382.0,382.0,384.0,382.0,384.0,384.0,382.0,382.0,182.0,384.0,182.0,162.0,384.0,382.0,382.0,182.0,382.0,384.0,384.0,382.0,382.0,384.0,384.0,192.0,384.0,382.0,384.0,382.0,384.0,382.0,384.0,384.0,384.0,384.0,384.0,382.0,384.0,382.0,382.0,382.0,382 [...]
+K97DCKP13,384.0,150.0,384.0,148.0,384.0,384.0,150.0,150.0,88.0,384.0,150.0,110.0,384.0,150.0,150.0,384.0,0.0,384.0,384.0,384.0,384.0,384.0,150.0,384.0,384.0,384.0,94.0,384.0,150.0,384.0,150.0,150.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,150.0,384.0,148.0,150.0,384.0,384.0,384.0,110.0,384.0,384.0,148.0,384.0,384.0,384.0,384.0,148.0,150.0,384.0,384.0,150.0,88.0,384.0,148.0,384.0,148.0,384.0,84.0,384.0,150.0,110.0,150.0,150.0,150.0,384.0,112.0,384.0,384.0,384.0,384.0,15 [...]
+A97DCKTB132,380.0,384.0,336.0,384.0,334.0,320.0,384.0,384.0,384.0,316.0,384.0,384.0,334.0,384.0,384.0,382.0,384.0,0.0,336.0,382.0,376.0,382.0,384.0,334.0,336.0,334.0,384.0,378.0,384.0,382.0,384.0,384.0,346.0,318.0,382.0,382.0,382.0,336.0,318.0,320.0,336.0,334.0,384.0,336.0,384.0,384.0,380.0,376.0,382.0,384.0,382.0,382.0,384.0,380.0,378.0,382.0,320.0,384.0,384.0,334.0,332.0,384.0,384.0,382.0,384.0,320.0,384.0,336.0,384.0,336.0,384.0,384.0,384.0,384.0,384.0,334.0,384.0,332.0,336.0,376.0,37 [...]
+A97DCKTB13,380.0,384.0,242.0,384.0,336.0,336.0,384.0,384.0,384.0,336.0,384.0,384.0,336.0,384.0,384.0,382.0,384.0,336.0,0.0,382.0,376.0,382.0,384.0,336.0,238.0,336.0,384.0,378.0,384.0,382.0,384.0,384.0,346.0,336.0,382.0,382.0,382.0,254.0,336.0,336.0,254.0,336.0,384.0,240.0,384.0,384.0,380.0,376.0,382.0,384.0,382.0,382.0,384.0,380.0,378.0,382.0,336.0,384.0,384.0,336.0,336.0,384.0,384.0,382.0,384.0,336.0,384.0,242.0,384.0,236.0,384.0,384.0,384.0,384.0,384.0,336.0,384.0,336.0,238.0,376.0,378 [...]
+D97DCMBS55,382.0,384.0,382.0,384.0,382.0,382.0,384.0,384.0,384.0,382.0,384.0,384.0,382.0,384.0,384.0,182.0,384.0,382.0,382.0,0.0,382.0,182.0,384.0,382.0,382.0,382.0,384.0,382.0,384.0,184.0,384.0,384.0,382.0,382.0,186.0,176.0,176.0,382.0,382.0,382.0,382.0,382.0,384.0,382.0,384.0,384.0,382.0,382.0,178.0,384.0,176.0,182.0,384.0,382.0,382.0,180.0,382.0,384.0,384.0,382.0,382.0,384.0,384.0,192.0,384.0,382.0,384.0,382.0,384.0,382.0,384.0,384.0,384.0,384.0,384.0,382.0,384.0,382.0,382.0,382.0,382 [...]
+A97DCA1KFE58,380.0,384.0,376.0,384.0,376.0,376.0,384.0,384.0,384.0,376.0,384.0,384.0,376.0,384.0,384.0,382.0,384.0,376.0,376.0,382.0,0.0,382.0,384.0,376.0,376.0,376.0,384.0,378.0,384.0,382.0,384.0,384.0,376.0,376.0,382.0,382.0,382.0,376.0,376.0,376.0,376.0,376.0,384.0,376.0,384.0,384.0,380.0,372.0,382.0,384.0,382.0,382.0,384.0,380.0,378.0,382.0,376.0,384.0,384.0,376.0,376.0,384.0,384.0,382.0,384.0,376.0,384.0,376.0,384.0,376.0,384.0,384.0,384.0,384.0,384.0,376.0,384.0,376.0,376.0,374.0,3 [...]
+D97DCMBS35,382.0,384.0,382.0,384.0,382.0,382.0,384.0,384.0,384.0,382.0,384.0,384.0,382.0,384.0,384.0,162.0,384.0,382.0,382.0,182.0,382.0,0.0,384.0,382.0,382.0,382.0,384.0,382.0,384.0,184.0,384.0,384.0,382.0,382.0,186.0,182.0,182.0,382.0,382.0,382.0,382.0,382.0,384.0,382.0,384.0,384.0,382.0,382.0,182.0,384.0,182.0,158.0,384.0,382.0,382.0,182.0,382.0,384.0,384.0,382.0,382.0,384.0,384.0,192.0,384.0,382.0,384.0,382.0,384.0,382.0,384.0,384.0,384.0,384.0,384.0,382.0,384.0,382.0,382.0,382.0,382 [...]
+G97DCKS4,384.0,82.0,384.0,150.0,384.0,384.0,68.0,80.0,150.0,384.0,70.0,150.0,384.0,82.0,82.0,384.0,150.0,384.0,384.0,384.0,384.0,384.0,0.0,384.0,384.0,384.0,150.0,384.0,82.0,384.0,60.0,80.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,74.0,384.0,150.0,72.0,384.0,384.0,384.0,150.0,384.0,384.0,150.0,384.0,384.0,384.0,384.0,150.0,68.0,384.0,384.0,80.0,150.0,384.0,150.0,384.0,150.0,384.0,150.0,384.0,82.0,150.0,80.0,82.0,82.0,384.0,150.0,384.0,384.0,384.0,384.0,82.0,150.0,384.0 [...]
+A97DCMBS4,380.0,384.0,336.0,384.0,272.0,334.0,384.0,384.0,384.0,334.0,384.0,384.0,282.0,384.0,384.0,382.0,384.0,334.0,336.0,382.0,376.0,382.0,384.0,0.0,336.0,260.0,384.0,378.0,384.0,382.0,384.0,384.0,346.0,334.0,382.0,382.0,382.0,336.0,334.0,334.0,336.0,272.0,384.0,336.0,384.0,384.0,380.0,376.0,382.0,384.0,382.0,382.0,384.0,380.0,378.0,382.0,334.0,384.0,384.0,272.0,334.0,384.0,384.0,382.0,384.0,334.0,384.0,336.0,384.0,336.0,384.0,384.0,384.0,384.0,384.0,274.0,384.0,334.0,336.0,376.0,378. [...]
+A97DCKMST121,380.0,384.0,242.0,384.0,336.0,336.0,384.0,384.0,384.0,336.0,384.0,384.0,336.0,384.0,384.0,382.0,384.0,336.0,238.0,382.0,376.0,382.0,384.0,336.0,0.0,336.0,384.0,378.0,384.0,382.0,384.0,384.0,346.0,336.0,382.0,382.0,382.0,254.0,336.0,336.0,254.0,336.0,384.0,240.0,384.0,384.0,380.0,376.0,382.0,384.0,382.0,382.0,384.0,380.0,378.0,382.0,336.0,384.0,384.0,336.0,336.0,384.0,384.0,382.0,384.0,336.0,384.0,242.0,384.0,238.0,384.0,384.0,384.0,384.0,384.0,336.0,384.0,336.0,230.0,376.0,3 [...]
+A97DCMBTB29,380.0,384.0,336.0,384.0,272.0,334.0,384.0,384.0,384.0,334.0,384.0,384.0,282.0,384.0,384.0,382.0,384.0,334.0,336.0,382.0,376.0,382.0,384.0,260.0,336.0,0.0,384.0,378.0,384.0,382.0,384.0,384.0,346.0,334.0,382.0,382.0,382.0,336.0,334.0,334.0,336.0,272.0,384.0,336.0,384.0,384.0,380.0,376.0,382.0,384.0,382.0,382.0,384.0,380.0,378.0,382.0,334.0,384.0,384.0,272.0,334.0,384.0,384.0,382.0,384.0,334.0,384.0,336.0,384.0,336.0,384.0,384.0,384.0,384.0,384.0,274.0,384.0,334.0,336.0,376.0,37 [...]
+U97DCKTB17,384.0,150.0,384.0,148.0,384.0,384.0,150.0,150.0,94.0,384.0,150.0,110.0,384.0,150.0,150.0,384.0,94.0,384.0,384.0,384.0,384.0,384.0,150.0,384.0,384.0,384.0,0.0,384.0,150.0,384.0,150.0,150.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,150.0,384.0,148.0,150.0,384.0,384.0,384.0,110.0,384.0,384.0,148.0,384.0,384.0,384.0,384.0,148.0,150.0,384.0,384.0,150.0,94.0,384.0,148.0,384.0,148.0,384.0,94.0,384.0,150.0,110.0,150.0,150.0,150.0,384.0,112.0,384.0,384.0,384.0,384.0,1 [...]
+U97DCKTB119,380.0,384.0,378.0,384.0,378.0,378.0,384.0,384.0,384.0,378.0,384.0,384.0,378.0,384.0,384.0,382.0,384.0,378.0,378.0,382.0,378.0,382.0,384.0,378.0,378.0,378.0,384.0,0.0,384.0,382.0,384.0,384.0,378.0,378.0,382.0,382.0,382.0,378.0,378.0,378.0,378.0,378.0,384.0,378.0,384.0,384.0,380.0,378.0,382.0,384.0,382.0,382.0,384.0,380.0,210.0,382.0,378.0,384.0,384.0,378.0,378.0,384.0,384.0,382.0,384.0,378.0,384.0,378.0,384.0,378.0,384.0,384.0,384.0,384.0,384.0,378.0,384.0,378.0,378.0,378.0,20 [...]
+H97DCKTB176,384.0,26.0,384.0,150.0,384.0,384.0,82.0,82.0,150.0,384.0,82.0,150.0,384.0,30.0,30.0,384.0,150.0,384.0,384.0,384.0,384.0,384.0,82.0,384.0,384.0,384.0,150.0,384.0,0.0,384.0,82.0,82.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,82.0,384.0,150.0,82.0,384.0,384.0,384.0,150.0,384.0,384.0,150.0,384.0,384.0,384.0,384.0,150.0,82.0,384.0,384.0,82.0,150.0,384.0,150.0,384.0,150.0,384.0,150.0,384.0,22.0,150.0,82.0,30.0,30.0,384.0,150.0,384.0,384.0,384.0,384.0,30.0,150.0,38 [...]
+D97DCKS15,382.0,384.0,382.0,384.0,382.0,382.0,384.0,384.0,384.0,382.0,384.0,384.0,382.0,384.0,384.0,184.0,384.0,382.0,382.0,184.0,382.0,184.0,384.0,382.0,382.0,382.0,384.0,382.0,384.0,0.0,384.0,384.0,382.0,382.0,186.0,184.0,184.0,382.0,382.0,382.0,382.0,382.0,384.0,382.0,384.0,384.0,382.0,382.0,184.0,384.0,184.0,184.0,384.0,382.0,382.0,184.0,382.0,384.0,384.0,382.0,382.0,384.0,384.0,192.0,384.0,382.0,384.0,382.0,384.0,382.0,384.0,384.0,384.0,384.0,384.0,382.0,384.0,382.0,382.0,382.0,382. [...]
+G97DCKTB18,384.0,82.0,384.0,150.0,384.0,384.0,68.0,80.0,150.0,384.0,70.0,150.0,384.0,82.0,82.0,384.0,150.0,384.0,384.0,384.0,384.0,384.0,60.0,384.0,384.0,384.0,150.0,384.0,82.0,384.0,0.0,80.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,74.0,384.0,150.0,72.0,384.0,384.0,384.0,150.0,384.0,384.0,150.0,384.0,384.0,384.0,384.0,150.0,68.0,384.0,384.0,80.0,150.0,384.0,150.0,384.0,150.0,384.0,150.0,384.0,82.0,150.0,80.0,82.0,82.0,384.0,150.0,384.0,384.0,384.0,384.0,82.0,150.0,384 [...]
+U97DCKMST120,384.0,82.0,384.0,150.0,384.0,384.0,80.0,44.0,150.0,384.0,80.0,150.0,384.0,82.0,82.0,384.0,150.0,384.0,384.0,384.0,384.0,384.0,80.0,384.0,384.0,384.0,150.0,384.0,82.0,384.0,80.0,0.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,80.0,384.0,150.0,80.0,384.0,384.0,384.0,150.0,384.0,384.0,150.0,384.0,384.0,384.0,384.0,150.0,80.0,384.0,384.0,44.0,150.0,384.0,150.0,384.0,150.0,384.0,150.0,384.0,82.0,150.0,44.0,82.0,82.0,384.0,150.0,384.0,384.0,384.0,384.0,82.0,150.0,3 [...]
+A97DCEQS1,380.0,384.0,346.0,384.0,346.0,346.0,384.0,384.0,384.0,346.0,384.0,384.0,346.0,384.0,384.0,382.0,384.0,346.0,346.0,382.0,376.0,382.0,384.0,346.0,346.0,346.0,384.0,378.0,384.0,382.0,384.0,384.0,0.0,346.0,382.0,382.0,382.0,346.0,346.0,346.0,346.0,346.0,384.0,346.0,384.0,384.0,380.0,376.0,382.0,384.0,382.0,382.0,384.0,380.0,378.0,382.0,346.0,384.0,384.0,346.0,346.0,384.0,384.0,382.0,384.0,346.0,384.0,346.0,384.0,346.0,384.0,384.0,384.0,384.0,384.0,346.0,384.0,346.0,346.0,376.0,378. [...]
+A97DCMBS9,380.0,384.0,336.0,384.0,334.0,320.0,384.0,384.0,384.0,318.0,384.0,384.0,334.0,384.0,384.0,382.0,384.0,318.0,336.0,382.0,376.0,382.0,384.0,334.0,336.0,334.0,384.0,378.0,384.0,382.0,384.0,384.0,346.0,0.0,382.0,382.0,382.0,336.0,304.0,320.0,336.0,334.0,384.0,336.0,384.0,384.0,380.0,376.0,382.0,384.0,382.0,382.0,384.0,380.0,378.0,382.0,320.0,384.0,384.0,334.0,332.0,384.0,384.0,382.0,384.0,320.0,384.0,336.0,384.0,336.0,384.0,384.0,384.0,384.0,384.0,334.0,384.0,332.0,336.0,376.0,378. [...]
+D97DCMBS342,382.0,384.0,382.0,384.0,382.0,382.0,384.0,384.0,384.0,382.0,384.0,384.0,382.0,384.0,384.0,186.0,384.0,382.0,382.0,186.0,382.0,186.0,384.0,382.0,382.0,382.0,384.0,382.0,384.0,186.0,384.0,384.0,382.0,382.0,0.0,186.0,186.0,382.0,382.0,382.0,382.0,382.0,384.0,382.0,384.0,384.0,382.0,382.0,186.0,384.0,186.0,186.0,384.0,382.0,382.0,186.0,382.0,384.0,384.0,382.0,382.0,384.0,384.0,192.0,384.0,382.0,384.0,382.0,384.0,382.0,384.0,384.0,384.0,384.0,384.0,382.0,384.0,382.0,382.0,382.0,38 [...]
+D97DCKP44,382.0,384.0,382.0,384.0,382.0,382.0,384.0,384.0,384.0,382.0,384.0,384.0,382.0,384.0,384.0,182.0,384.0,382.0,382.0,176.0,382.0,182.0,384.0,382.0,382.0,382.0,384.0,382.0,384.0,184.0,384.0,384.0,382.0,382.0,186.0,0.0,174.0,382.0,382.0,382.0,382.0,382.0,384.0,382.0,384.0,384.0,382.0,382.0,178.0,384.0,172.0,182.0,384.0,382.0,382.0,180.0,382.0,384.0,384.0,382.0,382.0,384.0,384.0,192.0,384.0,382.0,384.0,382.0,384.0,382.0,384.0,384.0,384.0,384.0,384.0,382.0,384.0,382.0,382.0,382.0,382. [...]
+D97DCKTB181,382.0,384.0,382.0,384.0,382.0,382.0,384.0,384.0,384.0,382.0,384.0,384.0,382.0,384.0,384.0,182.0,384.0,382.0,382.0,176.0,382.0,182.0,384.0,382.0,382.0,382.0,384.0,382.0,384.0,184.0,384.0,384.0,382.0,382.0,186.0,174.0,0.0,382.0,382.0,382.0,382.0,382.0,384.0,382.0,384.0,384.0,382.0,382.0,178.0,384.0,174.0,182.0,384.0,382.0,382.0,180.0,382.0,384.0,384.0,382.0,382.0,384.0,384.0,192.0,384.0,382.0,384.0,382.0,384.0,382.0,384.0,384.0,384.0,384.0,384.0,382.0,384.0,382.0,382.0,382.0,38 [...]
+A97DCEQTB14,380.0,384.0,254.0,384.0,336.0,336.0,384.0,384.0,384.0,336.0,384.0,384.0,336.0,384.0,384.0,382.0,384.0,336.0,254.0,382.0,376.0,382.0,384.0,336.0,254.0,336.0,384.0,378.0,384.0,382.0,384.0,384.0,346.0,336.0,382.0,382.0,382.0,0.0,336.0,336.0,248.0,336.0,384.0,254.0,384.0,384.0,380.0,376.0,382.0,384.0,382.0,382.0,384.0,380.0,378.0,382.0,336.0,384.0,384.0,336.0,336.0,384.0,384.0,382.0,384.0,336.0,384.0,254.0,384.0,254.0,384.0,384.0,384.0,384.0,384.0,336.0,384.0,336.0,254.0,376.0,37 [...]
+A97DCKTB37,380.0,384.0,336.0,384.0,334.0,320.0,384.0,384.0,384.0,318.0,384.0,384.0,334.0,384.0,384.0,382.0,384.0,318.0,336.0,382.0,376.0,382.0,384.0,334.0,336.0,334.0,384.0,378.0,384.0,382.0,384.0,384.0,346.0,304.0,382.0,382.0,382.0,336.0,0.0,320.0,336.0,334.0,384.0,336.0,384.0,384.0,380.0,376.0,382.0,384.0,382.0,382.0,384.0,380.0,378.0,382.0,320.0,384.0,384.0,334.0,332.0,384.0,384.0,382.0,384.0,320.0,384.0,336.0,384.0,336.0,384.0,384.0,384.0,384.0,384.0,334.0,384.0,332.0,336.0,376.0,378 [...]
+A97DCKFE198,380.0,384.0,336.0,384.0,334.0,294.0,384.0,384.0,384.0,320.0,384.0,384.0,334.0,384.0,384.0,382.0,384.0,320.0,336.0,382.0,376.0,382.0,384.0,334.0,336.0,334.0,384.0,378.0,384.0,382.0,384.0,384.0,346.0,320.0,382.0,382.0,382.0,336.0,320.0,0.0,336.0,334.0,384.0,336.0,384.0,384.0,380.0,376.0,382.0,384.0,382.0,382.0,384.0,380.0,378.0,382.0,286.0,384.0,384.0,334.0,332.0,384.0,384.0,382.0,384.0,288.0,384.0,336.0,384.0,336.0,384.0,384.0,384.0,384.0,384.0,334.0,384.0,332.0,336.0,376.0,37 [...]
+A97DCEQS49,380.0,384.0,254.0,384.0,336.0,336.0,384.0,384.0,384.0,336.0,384.0,384.0,336.0,384.0,384.0,382.0,384.0,336.0,254.0,382.0,376.0,382.0,384.0,336.0,254.0,336.0,384.0,378.0,384.0,382.0,384.0,384.0,346.0,336.0,382.0,382.0,382.0,248.0,336.0,336.0,0.0,336.0,384.0,254.0,384.0,384.0,380.0,376.0,382.0,384.0,382.0,382.0,384.0,380.0,378.0,382.0,336.0,384.0,384.0,336.0,336.0,384.0,384.0,382.0,384.0,336.0,384.0,254.0,384.0,254.0,384.0,384.0,384.0,384.0,384.0,336.0,384.0,336.0,254.0,376.0,378 [...]
+A97DCKP5,380.0,384.0,336.0,384.0,270.0,334.0,384.0,384.0,384.0,334.0,384.0,384.0,282.0,384.0,384.0,382.0,384.0,334.0,336.0,382.0,376.0,382.0,384.0,272.0,336.0,272.0,384.0,378.0,384.0,382.0,384.0,384.0,346.0,334.0,382.0,382.0,382.0,336.0,334.0,334.0,336.0,0.0,384.0,336.0,384.0,384.0,380.0,376.0,382.0,384.0,382.0,382.0,384.0,380.0,378.0,382.0,334.0,384.0,384.0,270.0,334.0,384.0,384.0,382.0,384.0,334.0,384.0,336.0,384.0,336.0,384.0,384.0,384.0,384.0,384.0,274.0,384.0,334.0,336.0,376.0,378.0 [...]
+U97DCKTB22,384.0,82.0,384.0,150.0,384.0,384.0,74.0,80.0,150.0,384.0,74.0,150.0,384.0,82.0,82.0,384.0,150.0,384.0,384.0,384.0,384.0,384.0,74.0,384.0,384.0,384.0,150.0,384.0,82.0,384.0,74.0,80.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,0.0,384.0,150.0,74.0,384.0,384.0,384.0,150.0,384.0,384.0,150.0,384.0,384.0,384.0,384.0,150.0,74.0,384.0,384.0,80.0,150.0,384.0,150.0,384.0,150.0,384.0,150.0,384.0,82.0,150.0,80.0,82.0,82.0,384.0,150.0,384.0,384.0,384.0,384.0,82.0,150.0,384 [...]
+A97DCKFE4,380.0,384.0,242.0,384.0,336.0,336.0,384.0,384.0,384.0,336.0,384.0,384.0,336.0,384.0,384.0,382.0,384.0,336.0,240.0,382.0,376.0,382.0,384.0,336.0,240.0,336.0,384.0,378.0,384.0,382.0,384.0,384.0,346.0,336.0,382.0,382.0,382.0,254.0,336.0,336.0,254.0,336.0,384.0,0.0,384.0,384.0,380.0,376.0,382.0,384.0,382.0,382.0,384.0,380.0,378.0,382.0,336.0,384.0,384.0,336.0,336.0,384.0,384.0,382.0,384.0,336.0,384.0,242.0,384.0,240.0,384.0,384.0,384.0,384.0,384.0,336.0,384.0,336.0,240.0,376.0,378. [...]
+C97DCMBTB11,384.0,150.0,384.0,142.0,384.0,384.0,150.0,150.0,148.0,384.0,150.0,148.0,384.0,150.0,150.0,384.0,148.0,384.0,384.0,384.0,384.0,384.0,150.0,384.0,384.0,384.0,148.0,384.0,150.0,384.0,150.0,150.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,150.0,384.0,0.0,150.0,384.0,384.0,384.0,148.0,384.0,384.0,144.0,384.0,384.0,384.0,384.0,142.0,150.0,384.0,384.0,150.0,148.0,384.0,146.0,384.0,132.0,384.0,148.0,384.0,150.0,148.0,150.0,150.0,150.0,384.0,148.0,384.0,384.0,384.0,38 [...]
+G97DCKS30,384.0,82.0,384.0,150.0,384.0,384.0,72.0,80.0,150.0,384.0,72.0,150.0,384.0,82.0,82.0,384.0,150.0,384.0,384.0,384.0,384.0,384.0,72.0,384.0,384.0,384.0,150.0,384.0,82.0,384.0,72.0,80.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,74.0,384.0,150.0,0.0,384.0,384.0,384.0,150.0,384.0,384.0,150.0,384.0,384.0,384.0,384.0,150.0,72.0,384.0,384.0,80.0,150.0,384.0,150.0,384.0,150.0,384.0,150.0,384.0,82.0,150.0,80.0,82.0,82.0,384.0,150.0,384.0,384.0,384.0,384.0,82.0,150.0,384. [...]
+E97DCEQTB60,204.0,384.0,380.0,384.0,380.0,380.0,384.0,384.0,384.0,380.0,384.0,384.0,380.0,384.0,384.0,382.0,384.0,380.0,380.0,382.0,380.0,382.0,384.0,380.0,380.0,380.0,384.0,380.0,384.0,382.0,384.0,384.0,380.0,380.0,382.0,382.0,382.0,380.0,380.0,380.0,380.0,380.0,384.0,380.0,384.0,384.0,0.0,380.0,382.0,384.0,382.0,382.0,384.0,204.0,380.0,382.0,380.0,384.0,384.0,380.0,380.0,384.0,384.0,382.0,384.0,380.0,384.0,380.0,384.0,380.0,384.0,384.0,384.0,384.0,384.0,380.0,384.0,380.0,380.0,380.0,38 [...]
+A97DCA1EQTB52,380.0,384.0,376.0,384.0,376.0,376.0,384.0,384.0,384.0,376.0,384.0,384.0,376.0,384.0,384.0,382.0,384.0,376.0,376.0,382.0,372.0,382.0,384.0,376.0,376.0,376.0,384.0,378.0,384.0,382.0,384.0,384.0,376.0,376.0,382.0,382.0,382.0,376.0,376.0,376.0,376.0,376.0,384.0,376.0,384.0,384.0,380.0,0.0,382.0,384.0,382.0,382.0,384.0,380.0,378.0,382.0,376.0,384.0,384.0,376.0,376.0,384.0,384.0,382.0,384.0,376.0,384.0,376.0,384.0,376.0,384.0,384.0,384.0,384.0,384.0,376.0,384.0,376.0,376.0,374.0, [...]
+D97DCD2KTB23,382.0,384.0,382.0,384.0,382.0,382.0,384.0,384.0,384.0,382.0,384.0,384.0,382.0,384.0,384.0,182.0,384.0,382.0,382.0,178.0,382.0,182.0,384.0,382.0,382.0,382.0,384.0,382.0,384.0,184.0,384.0,384.0,382.0,382.0,186.0,178.0,178.0,382.0,382.0,382.0,382.0,382.0,384.0,382.0,384.0,384.0,382.0,382.0,0.0,384.0,178.0,182.0,384.0,382.0,382.0,180.0,382.0,384.0,384.0,382.0,382.0,384.0,384.0,192.0,384.0,382.0,384.0,382.0,384.0,382.0,384.0,384.0,384.0,384.0,384.0,382.0,384.0,382.0,382.0,382.0,3 [...]
+F97DCF1MBFE183,384.0,150.0,384.0,148.0,384.0,384.0,150.0,150.0,110.0,384.0,150.0,106.0,384.0,150.0,150.0,384.0,110.0,384.0,384.0,384.0,384.0,384.0,150.0,384.0,384.0,384.0,110.0,384.0,150.0,384.0,150.0,150.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,150.0,384.0,148.0,150.0,384.0,384.0,384.0,0.0,384.0,384.0,148.0,384.0,384.0,384.0,384.0,148.0,150.0,384.0,384.0,150.0,110.0,384.0,148.0,384.0,148.0,384.0,110.0,384.0,150.0,108.0,150.0,150.0,150.0,384.0,112.0,384.0,384.0,384.0 [...]
+D97DCD1KS2,382.0,384.0,382.0,384.0,382.0,382.0,384.0,384.0,384.0,382.0,384.0,384.0,382.0,384.0,384.0,182.0,384.0,382.0,382.0,176.0,382.0,182.0,384.0,382.0,382.0,382.0,384.0,382.0,384.0,184.0,384.0,384.0,382.0,382.0,186.0,172.0,174.0,382.0,382.0,382.0,382.0,382.0,384.0,382.0,384.0,384.0,382.0,382.0,178.0,384.0,0.0,182.0,384.0,382.0,382.0,180.0,382.0,384.0,384.0,382.0,382.0,384.0,384.0,192.0,384.0,382.0,384.0,382.0,384.0,382.0,384.0,384.0,384.0,384.0,384.0,382.0,384.0,382.0,382.0,382.0,382 [...]
+D97DCKTB4,382.0,384.0,382.0,384.0,382.0,382.0,384.0,384.0,384.0,382.0,384.0,384.0,382.0,384.0,384.0,162.0,384.0,382.0,382.0,182.0,382.0,158.0,384.0,382.0,382.0,382.0,384.0,382.0,384.0,184.0,384.0,384.0,382.0,382.0,186.0,182.0,182.0,382.0,382.0,382.0,382.0,382.0,384.0,382.0,384.0,384.0,382.0,382.0,182.0,384.0,182.0,0.0,384.0,382.0,382.0,182.0,382.0,384.0,384.0,382.0,382.0,384.0,384.0,192.0,384.0,382.0,384.0,382.0,384.0,382.0,384.0,384.0,384.0,384.0,384.0,382.0,384.0,382.0,382.0,382.0,382. [...]
+C97DCKCD11,384.0,150.0,384.0,144.0,384.0,384.0,150.0,150.0,148.0,384.0,150.0,148.0,384.0,150.0,150.0,384.0,148.0,384.0,384.0,384.0,384.0,384.0,150.0,384.0,384.0,384.0,148.0,384.0,150.0,384.0,150.0,150.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,150.0,384.0,144.0,150.0,384.0,384.0,384.0,148.0,384.0,384.0,0.0,384.0,384.0,384.0,384.0,144.0,150.0,384.0,384.0,150.0,148.0,384.0,146.0,384.0,144.0,384.0,148.0,384.0,150.0,148.0,150.0,150.0,150.0,384.0,148.0,384.0,384.0,384.0,384 [...]
+U97DCKTB49,196.0,384.0,380.0,384.0,380.0,380.0,384.0,384.0,384.0,380.0,384.0,384.0,380.0,384.0,384.0,382.0,384.0,380.0,380.0,382.0,380.0,382.0,384.0,380.0,380.0,380.0,384.0,380.0,384.0,382.0,384.0,384.0,380.0,380.0,382.0,382.0,382.0,380.0,380.0,380.0,380.0,380.0,384.0,380.0,384.0,384.0,204.0,380.0,382.0,384.0,382.0,382.0,384.0,0.0,380.0,382.0,380.0,384.0,384.0,380.0,380.0,384.0,384.0,382.0,384.0,380.0,384.0,380.0,384.0,380.0,384.0,384.0,384.0,384.0,384.0,380.0,384.0,380.0,380.0,380.0,380 [...]
+U97DCKMST91,380.0,384.0,378.0,384.0,378.0,378.0,384.0,384.0,384.0,378.0,384.0,384.0,378.0,384.0,384.0,382.0,384.0,378.0,378.0,382.0,378.0,382.0,384.0,378.0,378.0,378.0,384.0,210.0,384.0,382.0,384.0,384.0,378.0,378.0,382.0,382.0,382.0,378.0,378.0,378.0,378.0,378.0,384.0,378.0,384.0,384.0,380.0,378.0,382.0,384.0,382.0,382.0,384.0,380.0,0.0,382.0,378.0,384.0,384.0,378.0,378.0,384.0,384.0,382.0,384.0,378.0,384.0,378.0,384.0,378.0,384.0,384.0,384.0,384.0,384.0,378.0,384.0,378.0,378.0,378.0,21 [...]
+D97DCKMST30,382.0,384.0,382.0,384.0,382.0,382.0,384.0,384.0,384.0,382.0,384.0,384.0,382.0,384.0,384.0,182.0,384.0,382.0,382.0,180.0,382.0,182.0,384.0,382.0,382.0,382.0,384.0,382.0,384.0,184.0,384.0,384.0,382.0,382.0,186.0,180.0,180.0,382.0,382.0,382.0,382.0,382.0,384.0,382.0,384.0,384.0,382.0,382.0,180.0,384.0,180.0,182.0,384.0,382.0,382.0,0.0,382.0,384.0,384.0,382.0,382.0,384.0,384.0,192.0,384.0,382.0,384.0,382.0,384.0,382.0,384.0,384.0,384.0,384.0,384.0,382.0,384.0,382.0,382.0,382.0,38 [...]
+A97DCKP77,380.0,384.0,336.0,384.0,334.0,294.0,384.0,384.0,384.0,320.0,384.0,384.0,334.0,384.0,384.0,382.0,384.0,320.0,336.0,382.0,376.0,382.0,384.0,334.0,336.0,334.0,384.0,378.0,384.0,382.0,384.0,384.0,346.0,320.0,382.0,382.0,382.0,336.0,320.0,286.0,336.0,334.0,384.0,336.0,384.0,384.0,380.0,376.0,382.0,384.0,382.0,382.0,384.0,380.0,378.0,382.0,0.0,384.0,384.0,334.0,332.0,384.0,384.0,382.0,384.0,288.0,384.0,336.0,384.0,336.0,384.0,384.0,384.0,384.0,384.0,334.0,384.0,332.0,336.0,376.0,378. [...]
+C97DCMBTB3,384.0,150.0,384.0,116.0,384.0,384.0,150.0,150.0,148.0,384.0,150.0,148.0,384.0,150.0,150.0,384.0,148.0,384.0,384.0,384.0,384.0,384.0,150.0,384.0,384.0,384.0,148.0,384.0,150.0,384.0,150.0,150.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,150.0,384.0,142.0,150.0,384.0,384.0,384.0,148.0,384.0,384.0,144.0,384.0,384.0,384.0,384.0,0.0,150.0,384.0,384.0,150.0,148.0,384.0,146.0,384.0,142.0,384.0,148.0,384.0,150.0,148.0,150.0,150.0,150.0,384.0,148.0,384.0,384.0,384.0,384 [...]
+G97DCKTB56,384.0,82.0,384.0,150.0,384.0,384.0,66.0,80.0,150.0,384.0,70.0,150.0,384.0,82.0,82.0,384.0,150.0,384.0,384.0,384.0,384.0,384.0,68.0,384.0,384.0,384.0,150.0,384.0,82.0,384.0,68.0,80.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,74.0,384.0,150.0,72.0,384.0,384.0,384.0,150.0,384.0,384.0,150.0,384.0,384.0,384.0,384.0,150.0,0.0,384.0,384.0,80.0,150.0,384.0,150.0,384.0,150.0,384.0,150.0,384.0,82.0,150.0,80.0,82.0,82.0,384.0,150.0,384.0,384.0,384.0,384.0,82.0,150.0,384 [...]
+A97DCMBS7,380.0,384.0,336.0,384.0,266.0,334.0,384.0,384.0,384.0,334.0,384.0,384.0,282.0,384.0,384.0,382.0,384.0,334.0,336.0,382.0,376.0,382.0,384.0,272.0,336.0,272.0,384.0,378.0,384.0,382.0,384.0,384.0,346.0,334.0,382.0,382.0,382.0,336.0,334.0,334.0,336.0,270.0,384.0,336.0,384.0,384.0,380.0,376.0,382.0,384.0,382.0,382.0,384.0,380.0,378.0,382.0,334.0,384.0,384.0,0.0,334.0,384.0,384.0,382.0,384.0,334.0,384.0,336.0,384.0,336.0,384.0,384.0,384.0,384.0,384.0,274.0,384.0,334.0,336.0,376.0,378. [...]
+A97DCEQS25,380.0,384.0,336.0,384.0,334.0,332.0,384.0,384.0,384.0,332.0,384.0,384.0,334.0,384.0,384.0,382.0,384.0,332.0,336.0,382.0,376.0,382.0,384.0,334.0,336.0,334.0,384.0,378.0,384.0,382.0,384.0,384.0,346.0,332.0,382.0,382.0,382.0,336.0,332.0,332.0,336.0,334.0,384.0,336.0,384.0,384.0,380.0,376.0,382.0,384.0,382.0,382.0,384.0,380.0,378.0,382.0,332.0,384.0,384.0,334.0,0.0,384.0,384.0,382.0,384.0,332.0,384.0,336.0,384.0,336.0,384.0,384.0,384.0,384.0,384.0,334.0,384.0,326.0,336.0,376.0,378 [...]
+J97DCKFE339,384.0,82.0,384.0,150.0,384.0,384.0,80.0,42.0,150.0,384.0,80.0,150.0,384.0,82.0,82.0,384.0,150.0,384.0,384.0,384.0,384.0,384.0,80.0,384.0,384.0,384.0,150.0,384.0,82.0,384.0,80.0,44.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,80.0,384.0,150.0,80.0,384.0,384.0,384.0,150.0,384.0,384.0,150.0,384.0,384.0,384.0,384.0,150.0,80.0,384.0,384.0,0.0,150.0,384.0,150.0,384.0,150.0,384.0,150.0,384.0,82.0,150.0,40.0,82.0,82.0,384.0,150.0,384.0,384.0,384.0,384.0,82.0,150.0,38 [...]
+K97DCKTB160,384.0,150.0,384.0,148.0,384.0,384.0,150.0,150.0,86.0,384.0,150.0,110.0,384.0,150.0,150.0,384.0,88.0,384.0,384.0,384.0,384.0,384.0,150.0,384.0,384.0,384.0,94.0,384.0,150.0,384.0,150.0,150.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,150.0,384.0,148.0,150.0,384.0,384.0,384.0,110.0,384.0,384.0,148.0,384.0,384.0,384.0,384.0,148.0,150.0,384.0,384.0,150.0,0.0,384.0,148.0,384.0,148.0,384.0,88.0,384.0,150.0,110.0,150.0,150.0,150.0,384.0,112.0,384.0,384.0,384.0,384.0, [...]
+D97DCD1KMST126,382.0,384.0,382.0,384.0,382.0,382.0,384.0,384.0,384.0,382.0,384.0,384.0,382.0,384.0,384.0,192.0,384.0,382.0,382.0,192.0,382.0,192.0,384.0,382.0,382.0,382.0,384.0,382.0,384.0,192.0,384.0,384.0,382.0,382.0,192.0,192.0,192.0,382.0,382.0,382.0,382.0,382.0,384.0,382.0,384.0,384.0,382.0,382.0,192.0,384.0,192.0,192.0,384.0,382.0,382.0,192.0,382.0,384.0,384.0,382.0,382.0,384.0,384.0,0.0,384.0,382.0,384.0,382.0,384.0,382.0,384.0,384.0,384.0,384.0,384.0,382.0,384.0,382.0,382.0,382.0 [...]
+C97DCMBS80,384.0,150.0,384.0,146.0,384.0,384.0,150.0,150.0,148.0,384.0,150.0,148.0,384.0,150.0,150.0,384.0,148.0,384.0,384.0,384.0,384.0,384.0,150.0,384.0,384.0,384.0,148.0,384.0,150.0,384.0,150.0,150.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,150.0,384.0,146.0,150.0,384.0,384.0,384.0,148.0,384.0,384.0,146.0,384.0,384.0,384.0,384.0,146.0,150.0,384.0,384.0,150.0,148.0,384.0,0.0,384.0,146.0,384.0,148.0,384.0,150.0,148.0,150.0,150.0,150.0,384.0,148.0,384.0,384.0,384.0,384 [...]
+A97DCKMST52,380.0,384.0,336.0,384.0,334.0,294.0,384.0,384.0,384.0,320.0,384.0,384.0,334.0,384.0,384.0,382.0,384.0,320.0,336.0,382.0,376.0,382.0,384.0,334.0,336.0,334.0,384.0,378.0,384.0,382.0,384.0,384.0,346.0,320.0,382.0,382.0,382.0,336.0,320.0,288.0,336.0,334.0,384.0,336.0,384.0,384.0,380.0,376.0,382.0,384.0,382.0,382.0,384.0,380.0,378.0,382.0,288.0,384.0,384.0,334.0,332.0,384.0,384.0,382.0,384.0,0.0,384.0,336.0,384.0,336.0,384.0,384.0,384.0,384.0,384.0,334.0,384.0,332.0,336.0,376.0,37 [...]
+C97DCMBFE61,384.0,150.0,384.0,142.0,384.0,384.0,150.0,150.0,148.0,384.0,150.0,148.0,384.0,150.0,150.0,384.0,148.0,384.0,384.0,384.0,384.0,384.0,150.0,384.0,384.0,384.0,148.0,384.0,150.0,384.0,150.0,150.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,150.0,384.0,132.0,150.0,384.0,384.0,384.0,148.0,384.0,384.0,144.0,384.0,384.0,384.0,384.0,142.0,150.0,384.0,384.0,150.0,148.0,384.0,146.0,384.0,0.0,384.0,148.0,384.0,150.0,148.0,150.0,150.0,150.0,384.0,148.0,384.0,384.0,384.0,38 [...]
+A97DCKS14,380.0,384.0,218.0,384.0,336.0,336.0,384.0,384.0,384.0,336.0,384.0,384.0,336.0,384.0,384.0,382.0,384.0,336.0,242.0,382.0,376.0,382.0,384.0,336.0,242.0,336.0,384.0,378.0,384.0,382.0,384.0,384.0,346.0,336.0,382.0,382.0,382.0,254.0,336.0,336.0,254.0,336.0,384.0,242.0,384.0,384.0,380.0,376.0,382.0,384.0,382.0,382.0,384.0,380.0,378.0,382.0,336.0,384.0,384.0,336.0,336.0,384.0,384.0,382.0,384.0,336.0,384.0,0.0,384.0,242.0,384.0,384.0,384.0,384.0,384.0,336.0,384.0,336.0,242.0,376.0,378. [...]
+K97DCKTB111,384.0,150.0,384.0,148.0,384.0,384.0,150.0,150.0,88.0,384.0,150.0,110.0,384.0,150.0,150.0,384.0,84.0,384.0,384.0,384.0,384.0,384.0,150.0,384.0,384.0,384.0,94.0,384.0,150.0,384.0,150.0,150.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,150.0,384.0,148.0,150.0,384.0,384.0,384.0,110.0,384.0,384.0,148.0,384.0,384.0,384.0,384.0,148.0,150.0,384.0,384.0,150.0,88.0,384.0,148.0,384.0,148.0,384.0,0.0,384.0,150.0,110.0,150.0,150.0,150.0,384.0,112.0,384.0,384.0,384.0,384.0, [...]
+A97DCKMST140,380.0,384.0,242.0,384.0,336.0,336.0,384.0,384.0,384.0,336.0,384.0,384.0,336.0,384.0,384.0,382.0,384.0,336.0,236.0,382.0,376.0,382.0,384.0,336.0,238.0,336.0,384.0,378.0,384.0,382.0,384.0,384.0,346.0,336.0,382.0,382.0,382.0,254.0,336.0,336.0,254.0,336.0,384.0,240.0,384.0,384.0,380.0,376.0,382.0,384.0,382.0,382.0,384.0,380.0,378.0,382.0,336.0,384.0,384.0,336.0,336.0,384.0,384.0,382.0,384.0,336.0,384.0,242.0,384.0,0.0,384.0,384.0,384.0,384.0,384.0,336.0,384.0,336.0,238.0,376.0,3 [...]
+H97DCKP63,384.0,26.0,384.0,150.0,384.0,384.0,82.0,82.0,150.0,384.0,82.0,150.0,384.0,30.0,30.0,384.0,150.0,384.0,384.0,384.0,384.0,384.0,82.0,384.0,384.0,384.0,150.0,384.0,22.0,384.0,82.0,82.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,82.0,384.0,150.0,82.0,384.0,384.0,384.0,150.0,384.0,384.0,150.0,384.0,384.0,384.0,384.0,150.0,82.0,384.0,384.0,82.0,150.0,384.0,150.0,384.0,150.0,384.0,150.0,384.0,0.0,150.0,82.0,30.0,30.0,384.0,150.0,384.0,384.0,384.0,384.0,30.0,150.0,384. [...]
+F97DCF1EQS16,384.0,150.0,384.0,148.0,384.0,384.0,150.0,150.0,110.0,384.0,150.0,108.0,384.0,150.0,150.0,384.0,110.0,384.0,384.0,384.0,384.0,384.0,150.0,384.0,384.0,384.0,110.0,384.0,150.0,384.0,150.0,150.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,150.0,384.0,148.0,150.0,384.0,384.0,384.0,108.0,384.0,384.0,148.0,384.0,384.0,384.0,384.0,148.0,150.0,384.0,384.0,150.0,110.0,384.0,148.0,384.0,148.0,384.0,110.0,384.0,150.0,0.0,150.0,150.0,150.0,384.0,112.0,384.0,384.0,384.0,3 [...]
+J97DCKTB147,384.0,82.0,384.0,150.0,384.0,384.0,80.0,42.0,150.0,384.0,80.0,150.0,384.0,82.0,82.0,384.0,150.0,384.0,384.0,384.0,384.0,384.0,80.0,384.0,384.0,384.0,150.0,384.0,82.0,384.0,80.0,44.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,80.0,384.0,150.0,80.0,384.0,384.0,384.0,150.0,384.0,384.0,150.0,384.0,384.0,384.0,384.0,150.0,80.0,384.0,384.0,40.0,150.0,384.0,150.0,384.0,150.0,384.0,150.0,384.0,82.0,150.0,0.0,82.0,82.0,384.0,150.0,384.0,384.0,384.0,384.0,82.0,150.0,38 [...]
+H97DCKCD2,384.0,30.0,384.0,150.0,384.0,384.0,82.0,82.0,150.0,384.0,82.0,150.0,384.0,10.0,14.0,384.0,150.0,384.0,384.0,384.0,384.0,384.0,82.0,384.0,384.0,384.0,150.0,384.0,30.0,384.0,82.0,82.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,82.0,384.0,150.0,82.0,384.0,384.0,384.0,150.0,384.0,384.0,150.0,384.0,384.0,384.0,384.0,150.0,82.0,384.0,384.0,82.0,150.0,384.0,150.0,384.0,150.0,384.0,150.0,384.0,30.0,150.0,82.0,0.0,10.0,384.0,150.0,384.0,384.0,384.0,384.0,10.0,150.0,384. [...]
+H97DCKTB188,384.0,30.0,384.0,150.0,384.0,384.0,82.0,82.0,150.0,384.0,82.0,150.0,384.0,6.0,14.0,384.0,150.0,384.0,384.0,384.0,384.0,384.0,82.0,384.0,384.0,384.0,150.0,384.0,30.0,384.0,82.0,82.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,82.0,384.0,150.0,82.0,384.0,384.0,384.0,150.0,384.0,384.0,150.0,384.0,384.0,384.0,384.0,150.0,82.0,384.0,384.0,82.0,150.0,384.0,150.0,384.0,150.0,384.0,150.0,384.0,30.0,150.0,82.0,10.0,0.0,384.0,150.0,384.0,384.0,384.0,384.0,8.0,150.0,384. [...]
+A97DCMBDS17,380.0,384.0,336.0,384.0,274.0,334.0,384.0,384.0,384.0,334.0,384.0,384.0,282.0,384.0,384.0,382.0,384.0,334.0,336.0,382.0,376.0,382.0,384.0,274.0,336.0,274.0,384.0,378.0,384.0,382.0,384.0,384.0,346.0,334.0,382.0,382.0,382.0,336.0,334.0,334.0,336.0,274.0,384.0,336.0,384.0,384.0,380.0,376.0,382.0,384.0,382.0,382.0,384.0,380.0,378.0,382.0,334.0,384.0,384.0,274.0,334.0,384.0,384.0,382.0,384.0,334.0,384.0,336.0,384.0,336.0,384.0,384.0,384.0,384.0,384.0,0.0,384.0,334.0,336.0,376.0,37 [...]
+U97DCEQS8,384.0,150.0,384.0,148.0,384.0,384.0,150.0,150.0,112.0,384.0,150.0,112.0,384.0,150.0,150.0,384.0,112.0,384.0,384.0,384.0,384.0,384.0,150.0,384.0,384.0,384.0,112.0,384.0,150.0,384.0,150.0,150.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,150.0,384.0,148.0,150.0,384.0,384.0,384.0,112.0,384.0,384.0,148.0,384.0,384.0,384.0,384.0,148.0,150.0,384.0,384.0,150.0,112.0,384.0,148.0,384.0,148.0,384.0,112.0,384.0,150.0,112.0,150.0,150.0,150.0,384.0,0.0,384.0,384.0,384.0,384. [...]
+A97DCKS34,380.0,384.0,336.0,384.0,334.0,332.0,384.0,384.0,384.0,332.0,384.0,384.0,334.0,384.0,384.0,382.0,384.0,332.0,336.0,382.0,376.0,382.0,384.0,334.0,336.0,334.0,384.0,378.0,384.0,382.0,384.0,384.0,346.0,332.0,382.0,382.0,382.0,336.0,332.0,332.0,336.0,334.0,384.0,336.0,384.0,384.0,380.0,376.0,382.0,384.0,382.0,382.0,384.0,380.0,378.0,382.0,332.0,384.0,384.0,334.0,326.0,384.0,384.0,382.0,384.0,332.0,384.0,336.0,384.0,336.0,384.0,384.0,384.0,384.0,384.0,334.0,384.0,0.0,336.0,376.0,378. [...]
+A97DCKP43,380.0,384.0,242.0,384.0,336.0,336.0,384.0,384.0,384.0,336.0,384.0,384.0,336.0,384.0,384.0,382.0,384.0,336.0,238.0,382.0,376.0,382.0,384.0,336.0,230.0,336.0,384.0,378.0,384.0,382.0,384.0,384.0,346.0,336.0,382.0,382.0,382.0,254.0,336.0,336.0,254.0,336.0,384.0,240.0,384.0,384.0,380.0,376.0,382.0,384.0,382.0,382.0,384.0,380.0,378.0,382.0,336.0,384.0,384.0,336.0,336.0,384.0,384.0,382.0,384.0,336.0,384.0,242.0,384.0,238.0,384.0,384.0,384.0,384.0,384.0,336.0,384.0,336.0,0.0,376.0,378. [...]
+A97DCA1KP78,380.0,384.0,376.0,384.0,376.0,376.0,384.0,384.0,384.0,376.0,384.0,384.0,376.0,384.0,384.0,382.0,384.0,376.0,376.0,382.0,374.0,382.0,384.0,376.0,376.0,376.0,384.0,378.0,384.0,382.0,384.0,384.0,376.0,376.0,382.0,382.0,382.0,376.0,376.0,376.0,376.0,376.0,384.0,376.0,384.0,384.0,380.0,374.0,382.0,384.0,382.0,382.0,384.0,380.0,378.0,382.0,376.0,384.0,384.0,376.0,376.0,384.0,384.0,382.0,384.0,376.0,384.0,376.0,384.0,376.0,384.0,384.0,384.0,384.0,384.0,376.0,384.0,376.0,376.0,0.0,37 [...]
+U97DCKFE267,380.0,384.0,378.0,384.0,378.0,378.0,384.0,384.0,384.0,378.0,384.0,384.0,378.0,384.0,384.0,382.0,384.0,378.0,378.0,382.0,378.0,382.0,384.0,378.0,378.0,378.0,384.0,206.0,384.0,382.0,384.0,384.0,378.0,378.0,382.0,382.0,382.0,378.0,378.0,378.0,378.0,378.0,384.0,378.0,384.0,384.0,380.0,378.0,382.0,384.0,382.0,382.0,384.0,380.0,210.0,382.0,378.0,384.0,384.0,378.0,378.0,384.0,384.0,382.0,384.0,378.0,384.0,378.0,384.0,378.0,384.0,384.0,384.0,384.0,384.0,378.0,384.0,378.0,378.0,378.0, [...]
+H97DCKMST43,384.0,30.0,384.0,150.0,384.0,384.0,82.0,82.0,150.0,384.0,82.0,150.0,384.0,8.0,14.0,384.0,150.0,384.0,384.0,384.0,384.0,384.0,82.0,384.0,384.0,384.0,150.0,384.0,30.0,384.0,82.0,82.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,82.0,384.0,150.0,82.0,384.0,384.0,384.0,150.0,384.0,384.0,150.0,384.0,384.0,384.0,384.0,150.0,82.0,384.0,384.0,82.0,150.0,384.0,150.0,384.0,150.0,384.0,150.0,384.0,30.0,150.0,82.0,10.0,8.0,384.0,150.0,384.0,384.0,384.0,384.0,0.0,150.0,384. [...]
+C97DCMBFE34,384.0,150.0,384.0,142.0,384.0,384.0,150.0,150.0,148.0,384.0,150.0,148.0,384.0,150.0,150.0,384.0,148.0,384.0,384.0,384.0,384.0,384.0,150.0,384.0,384.0,384.0,148.0,384.0,150.0,384.0,150.0,150.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,150.0,384.0,132.0,150.0,384.0,384.0,384.0,148.0,384.0,384.0,144.0,384.0,384.0,384.0,384.0,142.0,150.0,384.0,384.0,150.0,148.0,384.0,146.0,384.0,130.0,384.0,148.0,384.0,150.0,148.0,150.0,150.0,150.0,384.0,148.0,384.0,384.0,384.0, [...]
+A97DCKMST147,380.0,384.0,336.0,384.0,334.0,332.0,384.0,384.0,384.0,332.0,384.0,384.0,334.0,384.0,384.0,382.0,384.0,332.0,336.0,382.0,376.0,382.0,384.0,334.0,336.0,334.0,384.0,378.0,384.0,382.0,384.0,384.0,346.0,332.0,382.0,382.0,382.0,336.0,332.0,332.0,336.0,334.0,384.0,336.0,384.0,384.0,380.0,376.0,382.0,384.0,382.0,382.0,384.0,380.0,378.0,382.0,332.0,384.0,384.0,334.0,330.0,384.0,384.0,382.0,384.0,332.0,384.0,336.0,384.0,336.0,384.0,384.0,384.0,384.0,384.0,334.0,384.0,330.0,336.0,376.0 [...]
+A97DCKS55,380.0,384.0,242.0,384.0,336.0,336.0,384.0,384.0,384.0,336.0,384.0,384.0,336.0,384.0,384.0,382.0,384.0,336.0,238.0,382.0,376.0,382.0,384.0,336.0,230.0,336.0,384.0,378.0,384.0,382.0,384.0,384.0,346.0,336.0,382.0,382.0,382.0,254.0,336.0,336.0,254.0,336.0,384.0,240.0,384.0,384.0,380.0,376.0,382.0,384.0,382.0,382.0,384.0,380.0,378.0,382.0,336.0,384.0,384.0,336.0,336.0,384.0,384.0,382.0,384.0,336.0,384.0,242.0,384.0,238.0,384.0,384.0,384.0,384.0,384.0,336.0,384.0,336.0,228.0,376.0,37 [...]
+H97DCEQTB80,384.0,26.0,384.0,150.0,384.0,384.0,82.0,82.0,150.0,384.0,82.0,150.0,384.0,30.0,30.0,384.0,150.0,384.0,384.0,384.0,384.0,384.0,82.0,384.0,384.0,384.0,150.0,384.0,24.0,384.0,82.0,82.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,82.0,384.0,150.0,82.0,384.0,384.0,384.0,150.0,384.0,384.0,150.0,384.0,384.0,384.0,384.0,150.0,82.0,384.0,384.0,82.0,150.0,384.0,150.0,384.0,150.0,384.0,150.0,384.0,24.0,150.0,82.0,30.0,30.0,384.0,150.0,384.0,384.0,384.0,384.0,30.0,150.0,3 [...]
+H97DCKS42,384.0,26.0,384.0,150.0,384.0,384.0,82.0,82.0,150.0,384.0,82.0,150.0,384.0,30.0,30.0,384.0,150.0,384.0,384.0,384.0,384.0,384.0,82.0,384.0,384.0,384.0,150.0,384.0,16.0,384.0,82.0,82.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,82.0,384.0,150.0,82.0,384.0,384.0,384.0,150.0,384.0,384.0,150.0,384.0,384.0,384.0,384.0,150.0,82.0,384.0,384.0,82.0,150.0,384.0,150.0,384.0,150.0,384.0,150.0,384.0,22.0,150.0,82.0,30.0,30.0,384.0,150.0,384.0,384.0,384.0,384.0,30.0,150.0,384 [...]
+E97DCEQS21,204.0,384.0,380.0,384.0,380.0,380.0,384.0,384.0,384.0,380.0,384.0,384.0,380.0,384.0,384.0,382.0,384.0,380.0,380.0,382.0,380.0,382.0,384.0,380.0,380.0,380.0,384.0,380.0,384.0,382.0,384.0,384.0,380.0,380.0,382.0,382.0,382.0,380.0,380.0,380.0,380.0,380.0,384.0,380.0,384.0,384.0,202.0,380.0,382.0,384.0,382.0,382.0,384.0,204.0,380.0,382.0,380.0,384.0,384.0,380.0,380.0,384.0,384.0,382.0,384.0,380.0,384.0,380.0,384.0,380.0,384.0,384.0,384.0,384.0,384.0,380.0,384.0,380.0,380.0,380.0,3 [...]
+A97DCA1MBS12,380.0,384.0,376.0,384.0,376.0,376.0,384.0,384.0,384.0,376.0,384.0,384.0,376.0,384.0,384.0,382.0,384.0,376.0,376.0,382.0,372.0,382.0,384.0,376.0,376.0,376.0,384.0,378.0,384.0,382.0,384.0,384.0,376.0,376.0,382.0,382.0,382.0,376.0,376.0,376.0,376.0,376.0,384.0,376.0,384.0,384.0,380.0,366.0,382.0,384.0,382.0,382.0,384.0,380.0,378.0,382.0,376.0,384.0,384.0,376.0,376.0,384.0,384.0,382.0,384.0,376.0,384.0,376.0,384.0,376.0,384.0,384.0,384.0,384.0,384.0,376.0,384.0,376.0,376.0,374.0 [...]
+F97DCF1KTB50,384.0,150.0,384.0,148.0,384.0,384.0,150.0,150.0,110.0,384.0,150.0,102.0,384.0,150.0,150.0,384.0,110.0,384.0,384.0,384.0,384.0,384.0,150.0,384.0,384.0,384.0,110.0,384.0,150.0,384.0,150.0,150.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,150.0,384.0,148.0,150.0,384.0,384.0,384.0,106.0,384.0,384.0,148.0,384.0,384.0,384.0,384.0,148.0,150.0,384.0,384.0,150.0,110.0,384.0,148.0,384.0,148.0,384.0,110.0,384.0,150.0,108.0,150.0,150.0,150.0,384.0,112.0,384.0,384.0,384.0 [...]
+A97DCA2KP82,380.0,384.0,352.0,384.0,352.0,352.0,384.0,384.0,384.0,352.0,384.0,384.0,352.0,384.0,384.0,382.0,384.0,352.0,352.0,382.0,376.0,382.0,384.0,352.0,352.0,352.0,384.0,378.0,384.0,382.0,384.0,384.0,352.0,352.0,382.0,382.0,382.0,352.0,352.0,352.0,352.0,352.0,384.0,352.0,384.0,384.0,380.0,376.0,382.0,384.0,382.0,382.0,384.0,380.0,378.0,382.0,352.0,384.0,384.0,352.0,352.0,384.0,384.0,382.0,384.0,352.0,384.0,352.0,384.0,352.0,384.0,384.0,384.0,384.0,384.0,352.0,384.0,352.0,352.0,376.0, [...]
+A97DCKMST50,380.0,384.0,218.0,384.0,336.0,336.0,384.0,384.0,384.0,336.0,384.0,384.0,336.0,384.0,384.0,382.0,384.0,336.0,242.0,382.0,376.0,382.0,384.0,336.0,242.0,336.0,384.0,378.0,384.0,382.0,384.0,384.0,346.0,336.0,382.0,382.0,382.0,254.0,336.0,336.0,254.0,336.0,384.0,242.0,384.0,384.0,380.0,376.0,382.0,384.0,382.0,382.0,384.0,380.0,378.0,382.0,336.0,384.0,384.0,336.0,336.0,384.0,384.0,382.0,384.0,336.0,384.0,212.0,384.0,242.0,384.0,384.0,384.0,384.0,384.0,336.0,384.0,336.0,242.0,376.0, [...]
+H97DCKTB32,384.0,30.0,384.0,150.0,384.0,384.0,82.0,82.0,150.0,384.0,82.0,150.0,384.0,14.0,2.0,384.0,150.0,384.0,384.0,384.0,384.0,384.0,82.0,384.0,384.0,384.0,150.0,384.0,30.0,384.0,82.0,82.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,82.0,384.0,150.0,82.0,384.0,384.0,384.0,150.0,384.0,384.0,150.0,384.0,384.0,384.0,384.0,150.0,82.0,384.0,384.0,82.0,150.0,384.0,150.0,384.0,150.0,384.0,150.0,384.0,30.0,150.0,82.0,14.0,14.0,384.0,150.0,384.0,384.0,384.0,384.0,14.0,150.0,384 [...]
+G97DCMBFE91,384.0,82.0,384.0,150.0,384.0,384.0,72.0,80.0,150.0,384.0,72.0,150.0,384.0,82.0,82.0,384.0,150.0,384.0,384.0,384.0,384.0,384.0,72.0,384.0,384.0,384.0,150.0,384.0,82.0,384.0,72.0,80.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,74.0,384.0,150.0,48.0,384.0,384.0,384.0,150.0,384.0,384.0,150.0,384.0,384.0,384.0,384.0,150.0,72.0,384.0,384.0,80.0,150.0,384.0,150.0,384.0,150.0,384.0,150.0,384.0,82.0,150.0,80.0,82.0,82.0,384.0,150.0,384.0,384.0,384.0,384.0,82.0,150.0,3 [...]
+J97DCKTB14,384.0,82.0,384.0,150.0,384.0,384.0,80.0,42.0,150.0,384.0,80.0,150.0,384.0,82.0,82.0,384.0,150.0,384.0,384.0,384.0,384.0,384.0,80.0,384.0,384.0,384.0,150.0,384.0,82.0,384.0,80.0,44.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,80.0,384.0,150.0,80.0,384.0,384.0,384.0,150.0,384.0,384.0,150.0,384.0,384.0,384.0,384.0,150.0,80.0,384.0,384.0,40.0,150.0,384.0,150.0,384.0,150.0,384.0,150.0,384.0,82.0,150.0,36.0,82.0,82.0,384.0,150.0,384.0,384.0,384.0,384.0,82.0,150.0,38 [...]
+A97DCKS56,380.0,384.0,254.0,384.0,336.0,336.0,384.0,384.0,384.0,336.0,384.0,384.0,336.0,384.0,384.0,382.0,384.0,336.0,254.0,382.0,376.0,382.0,384.0,336.0,254.0,336.0,384.0,378.0,384.0,382.0,384.0,384.0,346.0,336.0,382.0,382.0,382.0,248.0,336.0,336.0,246.0,336.0,384.0,254.0,384.0,384.0,380.0,376.0,382.0,384.0,382.0,382.0,384.0,380.0,378.0,382.0,336.0,384.0,384.0,336.0,336.0,384.0,384.0,382.0,384.0,336.0,384.0,254.0,384.0,254.0,384.0,384.0,384.0,384.0,384.0,336.0,384.0,336.0,254.0,376.0,37 [...]
+D97DCMBS56,382.0,384.0,382.0,384.0,382.0,382.0,384.0,384.0,384.0,382.0,384.0,384.0,382.0,384.0,384.0,182.0,384.0,382.0,382.0,168.0,382.0,182.0,384.0,382.0,382.0,382.0,384.0,382.0,384.0,184.0,384.0,384.0,382.0,382.0,186.0,176.0,176.0,382.0,382.0,382.0,382.0,382.0,384.0,382.0,384.0,384.0,382.0,382.0,178.0,384.0,176.0,182.0,384.0,382.0,382.0,180.0,382.0,384.0,384.0,382.0,382.0,384.0,384.0,192.0,384.0,382.0,384.0,382.0,384.0,382.0,384.0,384.0,384.0,384.0,384.0,382.0,384.0,382.0,382.0,382.0,3 [...]
+C97DCMBFE14,384.0,150.0,384.0,142.0,384.0,384.0,150.0,150.0,148.0,384.0,150.0,148.0,384.0,150.0,150.0,384.0,148.0,384.0,384.0,384.0,384.0,384.0,150.0,384.0,384.0,384.0,148.0,384.0,150.0,384.0,150.0,150.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,150.0,384.0,132.0,150.0,384.0,384.0,384.0,148.0,384.0,384.0,144.0,384.0,384.0,384.0,384.0,142.0,150.0,384.0,384.0,150.0,148.0,384.0,146.0,384.0,130.0,384.0,148.0,384.0,150.0,148.0,150.0,150.0,150.0,384.0,148.0,384.0,384.0,384.0, [...]
+A97DCKS10,380.0,384.0,242.0,384.0,336.0,336.0,384.0,384.0,384.0,336.0,384.0,384.0,336.0,384.0,384.0,382.0,384.0,336.0,240.0,382.0,376.0,382.0,384.0,336.0,240.0,336.0,384.0,378.0,384.0,382.0,384.0,384.0,346.0,336.0,382.0,382.0,382.0,254.0,336.0,336.0,254.0,336.0,384.0,220.0,384.0,384.0,380.0,376.0,382.0,384.0,382.0,382.0,384.0,380.0,378.0,382.0,336.0,384.0,384.0,336.0,336.0,384.0,384.0,382.0,384.0,336.0,384.0,242.0,384.0,240.0,384.0,384.0,384.0,384.0,384.0,336.0,384.0,336.0,240.0,376.0,37 [...]
+C97DCMBTB10,384.0,150.0,384.0,142.0,384.0,384.0,150.0,150.0,148.0,384.0,150.0,148.0,384.0,150.0,150.0,384.0,148.0,384.0,384.0,384.0,384.0,384.0,150.0,384.0,384.0,384.0,148.0,384.0,150.0,384.0,150.0,150.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,150.0,384.0,134.0,150.0,384.0,384.0,384.0,148.0,384.0,384.0,144.0,384.0,384.0,384.0,384.0,142.0,150.0,384.0,384.0,150.0,148.0,384.0,146.0,384.0,134.0,384.0,148.0,384.0,150.0,148.0,150.0,150.0,150.0,384.0,148.0,384.0,384.0,384.0, [...]
+A97DCA1MBFE185,380.0,384.0,376.0,384.0,376.0,376.0,384.0,384.0,384.0,376.0,384.0,384.0,376.0,384.0,384.0,382.0,384.0,376.0,376.0,382.0,372.0,382.0,384.0,376.0,376.0,376.0,384.0,378.0,384.0,382.0,384.0,384.0,376.0,376.0,382.0,382.0,382.0,376.0,376.0,376.0,376.0,376.0,384.0,376.0,384.0,384.0,380.0,364.0,382.0,384.0,382.0,382.0,384.0,380.0,378.0,382.0,376.0,384.0,384.0,376.0,376.0,384.0,384.0,382.0,384.0,376.0,384.0,376.0,384.0,376.0,384.0,384.0,384.0,384.0,384.0,376.0,384.0,376.0,376.0,374 [...]
+H97DCKS18,384.0,26.0,384.0,150.0,384.0,384.0,82.0,82.0,150.0,384.0,82.0,150.0,384.0,30.0,30.0,384.0,150.0,384.0,384.0,384.0,384.0,384.0,82.0,384.0,384.0,384.0,150.0,384.0,22.0,384.0,82.0,82.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,82.0,384.0,150.0,82.0,384.0,384.0,384.0,150.0,384.0,384.0,150.0,384.0,384.0,384.0,384.0,150.0,82.0,384.0,384.0,82.0,150.0,384.0,150.0,384.0,150.0,384.0,150.0,384.0,20.0,150.0,82.0,30.0,30.0,384.0,150.0,384.0,384.0,384.0,384.0,30.0,150.0,384 [...]
+D97DCD1KCD4,382.0,384.0,382.0,384.0,382.0,382.0,384.0,384.0,384.0,382.0,384.0,384.0,382.0,384.0,384.0,192.0,384.0,382.0,382.0,192.0,382.0,192.0,384.0,382.0,382.0,382.0,384.0,382.0,384.0,192.0,384.0,384.0,382.0,382.0,192.0,192.0,192.0,382.0,382.0,382.0,382.0,382.0,384.0,382.0,384.0,384.0,382.0,382.0,192.0,384.0,192.0,192.0,384.0,382.0,382.0,192.0,382.0,384.0,384.0,382.0,382.0,384.0,384.0,190.0,384.0,382.0,384.0,382.0,384.0,382.0,384.0,384.0,384.0,384.0,384.0,382.0,384.0,382.0,382.0,382.0, [...]
+U97DCKMST135,384.0,82.0,384.0,150.0,384.0,384.0,76.0,80.0,150.0,384.0,76.0,150.0,384.0,82.0,82.0,384.0,150.0,384.0,384.0,384.0,384.0,384.0,76.0,384.0,384.0,384.0,150.0,384.0,82.0,384.0,76.0,80.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,76.0,384.0,150.0,76.0,384.0,384.0,384.0,150.0,384.0,384.0,150.0,384.0,384.0,384.0,384.0,150.0,76.0,384.0,384.0,80.0,150.0,384.0,150.0,384.0,150.0,384.0,150.0,384.0,82.0,150.0,80.0,82.0,82.0,384.0,150.0,384.0,384.0,384.0,384.0,82.0,150.0, [...]
+A97DCKDS85,380.0,384.0,336.0,384.0,334.0,320.0,384.0,384.0,384.0,312.0,384.0,384.0,334.0,384.0,384.0,382.0,384.0,316.0,336.0,382.0,376.0,382.0,384.0,334.0,336.0,334.0,384.0,378.0,384.0,382.0,384.0,384.0,346.0,318.0,382.0,382.0,382.0,336.0,318.0,320.0,336.0,334.0,384.0,336.0,384.0,384.0,380.0,376.0,382.0,384.0,382.0,382.0,384.0,380.0,378.0,382.0,320.0,384.0,384.0,334.0,332.0,384.0,384.0,382.0,384.0,320.0,384.0,336.0,384.0,336.0,384.0,384.0,384.0,384.0,384.0,334.0,384.0,332.0,336.0,376.0,3 [...]
+G97DCMBTB7,384.0,82.0,384.0,150.0,384.0,384.0,68.0,80.0,150.0,384.0,70.0,150.0,384.0,82.0,82.0,384.0,150.0,384.0,384.0,384.0,384.0,384.0,58.0,384.0,384.0,384.0,150.0,384.0,82.0,384.0,60.0,80.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,74.0,384.0,150.0,72.0,384.0,384.0,384.0,150.0,384.0,384.0,150.0,384.0,384.0,384.0,384.0,150.0,68.0,384.0,384.0,80.0,150.0,384.0,150.0,384.0,150.0,384.0,150.0,384.0,82.0,150.0,80.0,82.0,82.0,384.0,150.0,384.0,384.0,384.0,384.0,82.0,150.0,38 [...]
+A97DCKFE326,380.0,384.0,346.0,384.0,346.0,346.0,384.0,384.0,384.0,346.0,384.0,384.0,346.0,384.0,384.0,382.0,384.0,346.0,346.0,382.0,376.0,382.0,384.0,346.0,346.0,346.0,384.0,378.0,384.0,382.0,384.0,384.0,340.0,346.0,382.0,382.0,382.0,346.0,346.0,346.0,346.0,346.0,384.0,346.0,384.0,384.0,380.0,376.0,382.0,384.0,382.0,382.0,384.0,380.0,378.0,382.0,346.0,384.0,384.0,346.0,346.0,384.0,384.0,382.0,384.0,346.0,384.0,346.0,384.0,346.0,384.0,384.0,384.0,384.0,384.0,346.0,384.0,346.0,346.0,376.0, [...]
+H97DCKTB62,384.0,28.0,384.0,150.0,384.0,384.0,82.0,82.0,150.0,384.0,82.0,150.0,384.0,30.0,30.0,384.0,150.0,384.0,384.0,384.0,384.0,384.0,82.0,384.0,384.0,384.0,150.0,384.0,28.0,384.0,82.0,82.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,82.0,384.0,150.0,82.0,384.0,384.0,384.0,150.0,384.0,384.0,150.0,384.0,384.0,384.0,384.0,150.0,82.0,384.0,384.0,82.0,150.0,384.0,150.0,384.0,150.0,384.0,150.0,384.0,28.0,150.0,82.0,30.0,30.0,384.0,150.0,384.0,384.0,384.0,384.0,30.0,150.0,38 [...]
+A97DCA1MBS30,380.0,384.0,376.0,384.0,376.0,376.0,384.0,384.0,384.0,376.0,384.0,384.0,376.0,384.0,384.0,382.0,384.0,376.0,376.0,382.0,372.0,382.0,384.0,376.0,376.0,376.0,384.0,378.0,384.0,382.0,384.0,384.0,376.0,376.0,382.0,382.0,382.0,376.0,376.0,376.0,376.0,376.0,384.0,376.0,384.0,384.0,380.0,366.0,382.0,384.0,382.0,382.0,384.0,380.0,378.0,382.0,376.0,384.0,384.0,376.0,376.0,384.0,384.0,382.0,384.0,376.0,384.0,376.0,384.0,376.0,384.0,384.0,384.0,384.0,384.0,376.0,384.0,376.0,376.0,374.0 [...]
+J97DCKS22,384.0,82.0,384.0,150.0,384.0,384.0,80.0,42.0,150.0,384.0,80.0,150.0,384.0,82.0,82.0,384.0,150.0,384.0,384.0,384.0,384.0,384.0,80.0,384.0,384.0,384.0,150.0,384.0,82.0,384.0,80.0,44.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,80.0,384.0,150.0,80.0,384.0,384.0,384.0,150.0,384.0,384.0,150.0,384.0,384.0,384.0,384.0,150.0,80.0,384.0,384.0,40.0,150.0,384.0,150.0,384.0,150.0,384.0,150.0,384.0,82.0,150.0,34.0,82.0,82.0,384.0,150.0,384.0,384.0,384.0,384.0,82.0,150.0,384 [...]
+E97DCEQS5,204.0,384.0,380.0,384.0,380.0,380.0,384.0,384.0,384.0,380.0,384.0,384.0,380.0,384.0,384.0,382.0,384.0,380.0,380.0,382.0,380.0,382.0,384.0,380.0,380.0,380.0,384.0,380.0,384.0,382.0,384.0,384.0,380.0,380.0,382.0,382.0,382.0,380.0,380.0,380.0,380.0,380.0,384.0,380.0,384.0,384.0,202.0,380.0,382.0,384.0,382.0,382.0,384.0,204.0,380.0,382.0,380.0,384.0,384.0,380.0,380.0,384.0,384.0,382.0,384.0,380.0,384.0,380.0,384.0,380.0,384.0,384.0,384.0,384.0,384.0,380.0,384.0,380.0,380.0,380.0,38 [...]
+C97DCMBS33,384.0,150.0,384.0,118.0,384.0,384.0,150.0,150.0,148.0,384.0,150.0,148.0,384.0,150.0,150.0,384.0,148.0,384.0,384.0,384.0,384.0,384.0,150.0,384.0,384.0,384.0,148.0,384.0,150.0,384.0,150.0,150.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,150.0,384.0,142.0,150.0,384.0,384.0,384.0,148.0,384.0,384.0,144.0,384.0,384.0,384.0,384.0,118.0,150.0,384.0,384.0,150.0,148.0,384.0,146.0,384.0,142.0,384.0,148.0,384.0,150.0,148.0,150.0,150.0,150.0,384.0,148.0,384.0,384.0,384.0,3 [...]
+A97DCMBS341,380.0,384.0,336.0,384.0,268.0,334.0,384.0,384.0,384.0,334.0,384.0,384.0,282.0,384.0,384.0,382.0,384.0,334.0,336.0,382.0,376.0,382.0,384.0,272.0,336.0,272.0,384.0,378.0,384.0,382.0,384.0,384.0,346.0,334.0,382.0,382.0,382.0,336.0,334.0,334.0,336.0,270.0,384.0,336.0,384.0,384.0,380.0,376.0,382.0,384.0,382.0,382.0,384.0,380.0,378.0,382.0,334.0,384.0,384.0,268.0,334.0,384.0,384.0,382.0,384.0,334.0,384.0,336.0,384.0,336.0,384.0,384.0,384.0,384.0,384.0,274.0,384.0,334.0,336.0,376.0, [...]
+D97DCKMST66,382.0,384.0,382.0,384.0,382.0,382.0,384.0,384.0,384.0,382.0,384.0,384.0,382.0,384.0,384.0,182.0,384.0,382.0,382.0,178.0,382.0,182.0,384.0,382.0,382.0,382.0,384.0,382.0,384.0,184.0,384.0,384.0,382.0,382.0,186.0,178.0,178.0,382.0,382.0,382.0,382.0,382.0,384.0,382.0,384.0,384.0,382.0,382.0,166.0,384.0,178.0,182.0,384.0,382.0,382.0,180.0,382.0,384.0,384.0,382.0,382.0,384.0,384.0,192.0,384.0,382.0,384.0,382.0,384.0,382.0,384.0,384.0,384.0,384.0,384.0,382.0,384.0,382.0,382.0,382.0, [...]
+A97DCEQS18,380.0,384.0,346.0,384.0,346.0,346.0,384.0,384.0,384.0,346.0,384.0,384.0,346.0,384.0,384.0,382.0,384.0,346.0,346.0,382.0,376.0,382.0,384.0,346.0,346.0,346.0,384.0,378.0,384.0,382.0,384.0,384.0,344.0,346.0,382.0,382.0,382.0,346.0,346.0,346.0,346.0,346.0,384.0,346.0,384.0,384.0,380.0,376.0,382.0,384.0,382.0,382.0,384.0,380.0,378.0,382.0,346.0,384.0,384.0,346.0,346.0,384.0,384.0,382.0,384.0,346.0,384.0,346.0,384.0,346.0,384.0,384.0,384.0,384.0,384.0,346.0,384.0,346.0,346.0,376.0,3 [...]
+A97DCKCC2,380.0,384.0,242.0,384.0,336.0,336.0,384.0,384.0,384.0,336.0,384.0,384.0,336.0,384.0,384.0,382.0,384.0,336.0,234.0,382.0,376.0,382.0,384.0,336.0,238.0,336.0,384.0,378.0,384.0,382.0,384.0,384.0,346.0,336.0,382.0,382.0,382.0,254.0,336.0,336.0,254.0,336.0,384.0,240.0,384.0,384.0,380.0,376.0,382.0,384.0,382.0,382.0,384.0,380.0,378.0,382.0,336.0,384.0,384.0,336.0,336.0,384.0,384.0,382.0,384.0,336.0,384.0,242.0,384.0,236.0,384.0,384.0,384.0,384.0,384.0,336.0,384.0,336.0,238.0,376.0,37 [...]
+A97DCA1KCD9,380.0,384.0,376.0,384.0,376.0,376.0,384.0,384.0,384.0,376.0,384.0,384.0,376.0,384.0,384.0,382.0,384.0,376.0,376.0,382.0,372.0,382.0,384.0,376.0,376.0,376.0,384.0,378.0,384.0,382.0,384.0,384.0,376.0,376.0,382.0,382.0,382.0,376.0,376.0,376.0,376.0,376.0,384.0,376.0,384.0,384.0,380.0,370.0,382.0,384.0,382.0,382.0,384.0,380.0,378.0,382.0,376.0,384.0,384.0,376.0,376.0,384.0,384.0,382.0,384.0,376.0,384.0,376.0,384.0,376.0,384.0,384.0,384.0,384.0,384.0,376.0,384.0,376.0,376.0,374.0, [...]
+D97DCKS39,382.0,384.0,382.0,384.0,382.0,382.0,384.0,384.0,384.0,382.0,384.0,384.0,382.0,384.0,384.0,186.0,384.0,382.0,382.0,186.0,382.0,186.0,384.0,382.0,382.0,382.0,384.0,382.0,384.0,186.0,384.0,384.0,382.0,382.0,154.0,186.0,186.0,382.0,382.0,382.0,382.0,382.0,384.0,382.0,384.0,384.0,382.0,382.0,186.0,384.0,186.0,186.0,384.0,382.0,382.0,186.0,382.0,384.0,384.0,382.0,382.0,384.0,384.0,192.0,384.0,382.0,384.0,382.0,384.0,382.0,384.0,384.0,384.0,384.0,384.0,382.0,384.0,382.0,382.0,382.0,38 [...]
+C97DCKFE372,384.0,150.0,384.0,142.0,384.0,384.0,150.0,150.0,148.0,384.0,150.0,148.0,384.0,150.0,150.0,384.0,148.0,384.0,384.0,384.0,384.0,384.0,150.0,384.0,384.0,384.0,148.0,384.0,150.0,384.0,150.0,150.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,150.0,384.0,138.0,150.0,384.0,384.0,384.0,148.0,384.0,384.0,144.0,384.0,384.0,384.0,384.0,142.0,150.0,384.0,384.0,150.0,148.0,384.0,146.0,384.0,138.0,384.0,148.0,384.0,150.0,148.0,150.0,150.0,150.0,384.0,148.0,384.0,384.0,384.0, [...]
+C97DCMBTB13,384.0,150.0,384.0,146.0,384.0,384.0,150.0,150.0,148.0,384.0,150.0,148.0,384.0,150.0,150.0,384.0,148.0,384.0,384.0,384.0,384.0,384.0,150.0,384.0,384.0,384.0,148.0,384.0,150.0,384.0,150.0,150.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,150.0,384.0,146.0,150.0,384.0,384.0,384.0,148.0,384.0,384.0,146.0,384.0,384.0,384.0,384.0,146.0,150.0,384.0,384.0,150.0,148.0,384.0,114.0,384.0,146.0,384.0,148.0,384.0,150.0,148.0,150.0,150.0,150.0,384.0,148.0,384.0,384.0,384.0, [...]
+A97DCKS7,380.0,384.0,336.0,384.0,334.0,294.0,384.0,384.0,384.0,320.0,384.0,384.0,334.0,384.0,384.0,382.0,384.0,320.0,336.0,382.0,376.0,382.0,384.0,334.0,336.0,334.0,384.0,378.0,384.0,382.0,384.0,384.0,346.0,320.0,382.0,382.0,382.0,336.0,320.0,288.0,336.0,334.0,384.0,336.0,384.0,384.0,380.0,376.0,382.0,384.0,382.0,382.0,384.0,380.0,378.0,382.0,288.0,384.0,384.0,334.0,332.0,384.0,384.0,382.0,384.0,284.0,384.0,336.0,384.0,336.0,384.0,384.0,384.0,384.0,384.0,334.0,384.0,332.0,336.0,376.0,378 [...]
+G97DCKMST85,384.0,82.0,384.0,150.0,384.0,384.0,68.0,80.0,150.0,384.0,70.0,150.0,384.0,82.0,82.0,384.0,150.0,384.0,384.0,384.0,384.0,384.0,58.0,384.0,384.0,384.0,150.0,384.0,82.0,384.0,60.0,80.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,74.0,384.0,150.0,72.0,384.0,384.0,384.0,150.0,384.0,384.0,150.0,384.0,384.0,384.0,384.0,150.0,68.0,384.0,384.0,80.0,150.0,384.0,150.0,384.0,150.0,384.0,150.0,384.0,82.0,150.0,80.0,82.0,82.0,384.0,150.0,384.0,384.0,384.0,384.0,82.0,150.0,3 [...]
+A97DCMBP2,380.0,384.0,336.0,384.0,272.0,334.0,384.0,384.0,384.0,334.0,384.0,384.0,282.0,384.0,384.0,382.0,384.0,334.0,336.0,382.0,376.0,382.0,384.0,256.0,336.0,260.0,384.0,378.0,384.0,382.0,384.0,384.0,346.0,334.0,382.0,382.0,382.0,336.0,334.0,334.0,336.0,272.0,384.0,336.0,384.0,384.0,380.0,376.0,382.0,384.0,382.0,382.0,384.0,380.0,378.0,382.0,334.0,384.0,384.0,272.0,334.0,384.0,384.0,382.0,384.0,334.0,384.0,336.0,384.0,336.0,384.0,384.0,384.0,384.0,384.0,274.0,384.0,334.0,336.0,376.0,37 [...]
+K97DCMBFE71,384.0,150.0,384.0,148.0,384.0,384.0,150.0,150.0,90.0,384.0,150.0,110.0,384.0,150.0,150.0,384.0,90.0,384.0,384.0,384.0,384.0,384.0,150.0,384.0,384.0,384.0,94.0,384.0,150.0,384.0,150.0,150.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,150.0,384.0,148.0,150.0,384.0,384.0,384.0,110.0,384.0,384.0,148.0,384.0,384.0,384.0,384.0,148.0,150.0,384.0,384.0,150.0,90.0,384.0,148.0,384.0,148.0,384.0,90.0,384.0,150.0,110.0,150.0,150.0,150.0,384.0,112.0,384.0,384.0,384.0,384.0 [...]
+A97DCKMST89,380.0,384.0,336.0,384.0,334.0,332.0,384.0,384.0,384.0,332.0,384.0,384.0,334.0,384.0,384.0,382.0,384.0,332.0,336.0,382.0,376.0,382.0,384.0,334.0,336.0,334.0,384.0,378.0,384.0,382.0,384.0,384.0,346.0,332.0,382.0,382.0,382.0,336.0,332.0,332.0,336.0,334.0,384.0,336.0,384.0,384.0,380.0,376.0,382.0,384.0,382.0,382.0,384.0,380.0,378.0,382.0,332.0,384.0,384.0,334.0,330.0,384.0,384.0,382.0,384.0,332.0,384.0,336.0,384.0,336.0,384.0,384.0,384.0,384.0,384.0,334.0,384.0,330.0,336.0,376.0, [...]
+J97DCMBTB4,384.0,82.0,384.0,150.0,384.0,384.0,80.0,42.0,150.0,384.0,80.0,150.0,384.0,82.0,82.0,384.0,150.0,384.0,384.0,384.0,384.0,384.0,80.0,384.0,384.0,384.0,150.0,384.0,82.0,384.0,80.0,44.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,80.0,384.0,150.0,80.0,384.0,384.0,384.0,150.0,384.0,384.0,150.0,384.0,384.0,384.0,384.0,150.0,80.0,384.0,384.0,38.0,150.0,384.0,150.0,384.0,150.0,384.0,150.0,384.0,82.0,150.0,40.0,82.0,82.0,384.0,150.0,384.0,384.0,384.0,384.0,82.0,150.0,38 [...]
+C97DCKTB110,384.0,150.0,384.0,142.0,384.0,384.0,150.0,150.0,148.0,384.0,150.0,148.0,384.0,150.0,150.0,384.0,148.0,384.0,384.0,384.0,384.0,384.0,150.0,384.0,384.0,384.0,148.0,384.0,150.0,384.0,150.0,150.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,150.0,384.0,132.0,150.0,384.0,384.0,384.0,148.0,384.0,384.0,144.0,384.0,384.0,384.0,384.0,142.0,150.0,384.0,384.0,150.0,148.0,384.0,146.0,384.0,130.0,384.0,148.0,384.0,150.0,148.0,150.0,150.0,150.0,384.0,148.0,384.0,384.0,384.0, [...]
+A97DCKP36,380.0,384.0,336.0,384.0,282.0,334.0,384.0,384.0,384.0,334.0,384.0,384.0,280.0,384.0,384.0,382.0,384.0,334.0,336.0,382.0,376.0,382.0,384.0,282.0,336.0,282.0,384.0,378.0,384.0,382.0,384.0,384.0,346.0,334.0,382.0,382.0,382.0,336.0,334.0,334.0,336.0,282.0,384.0,336.0,384.0,384.0,380.0,376.0,382.0,384.0,382.0,382.0,384.0,380.0,378.0,382.0,334.0,384.0,384.0,282.0,334.0,384.0,384.0,382.0,384.0,334.0,384.0,336.0,384.0,336.0,384.0,384.0,384.0,384.0,384.0,282.0,384.0,334.0,336.0,376.0,37 [...]
+A97DCKP25,380.0,384.0,336.0,384.0,334.0,320.0,384.0,384.0,384.0,318.0,384.0,384.0,334.0,384.0,384.0,382.0,384.0,318.0,336.0,382.0,376.0,382.0,384.0,334.0,336.0,334.0,384.0,378.0,384.0,382.0,384.0,384.0,346.0,302.0,382.0,382.0,382.0,336.0,304.0,320.0,336.0,334.0,384.0,336.0,384.0,384.0,380.0,376.0,382.0,384.0,382.0,382.0,384.0,380.0,378.0,382.0,320.0,384.0,384.0,334.0,332.0,384.0,384.0,382.0,384.0,320.0,384.0,336.0,384.0,336.0,384.0,384.0,384.0,384.0,384.0,334.0,384.0,332.0,336.0,376.0,37 [...]
+F97DCF1KP35,384.0,150.0,384.0,148.0,384.0,384.0,150.0,150.0,110.0,384.0,150.0,104.0,384.0,150.0,150.0,384.0,110.0,384.0,384.0,384.0,384.0,384.0,150.0,384.0,384.0,384.0,110.0,384.0,150.0,384.0,150.0,150.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,150.0,384.0,148.0,150.0,384.0,384.0,384.0,106.0,384.0,384.0,148.0,384.0,384.0,384.0,384.0,148.0,150.0,384.0,384.0,150.0,110.0,384.0,148.0,384.0,148.0,384.0,110.0,384.0,150.0,108.0,150.0,150.0,150.0,384.0,112.0,384.0,384.0,384.0, [...]
+C97DCMBFE300,384.0,150.0,384.0,142.0,384.0,384.0,150.0,150.0,148.0,384.0,150.0,148.0,384.0,150.0,150.0,384.0,148.0,384.0,384.0,384.0,384.0,384.0,150.0,384.0,384.0,384.0,148.0,384.0,150.0,384.0,150.0,150.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,150.0,384.0,132.0,150.0,384.0,384.0,384.0,148.0,384.0,384.0,144.0,384.0,384.0,384.0,384.0,142.0,150.0,384.0,384.0,150.0,148.0,384.0,146.0,384.0,130.0,384.0,148.0,384.0,150.0,148.0,150.0,150.0,150.0,384.0,148.0,384.0,384.0,384.0 [...]
+A97DCKP79,380.0,384.0,242.0,384.0,336.0,336.0,384.0,384.0,384.0,336.0,384.0,384.0,336.0,384.0,384.0,382.0,384.0,336.0,238.0,382.0,376.0,382.0,384.0,336.0,230.0,336.0,384.0,378.0,384.0,382.0,384.0,384.0,346.0,336.0,382.0,382.0,382.0,254.0,336.0,336.0,254.0,336.0,384.0,240.0,384.0,384.0,380.0,376.0,382.0,384.0,382.0,382.0,384.0,380.0,378.0,382.0,336.0,384.0,384.0,336.0,336.0,384.0,384.0,382.0,384.0,336.0,384.0,242.0,384.0,238.0,384.0,384.0,384.0,384.0,384.0,336.0,384.0,336.0,226.0,376.0,37 [...]
+A97DCKS47,380.0,384.0,336.0,384.0,334.0,332.0,384.0,384.0,384.0,332.0,384.0,384.0,334.0,384.0,384.0,382.0,384.0,332.0,336.0,382.0,376.0,382.0,384.0,334.0,336.0,334.0,384.0,378.0,384.0,382.0,384.0,384.0,346.0,332.0,382.0,382.0,382.0,336.0,332.0,332.0,336.0,334.0,384.0,336.0,384.0,384.0,380.0,376.0,382.0,384.0,382.0,382.0,384.0,380.0,378.0,382.0,332.0,384.0,384.0,334.0,328.0,384.0,384.0,382.0,384.0,332.0,384.0,336.0,384.0,336.0,384.0,384.0,384.0,384.0,384.0,334.0,384.0,328.0,336.0,376.0,37 [...]
+A97DCEQTB44,380.0,384.0,336.0,384.0,334.0,320.0,384.0,384.0,384.0,314.0,384.0,384.0,334.0,384.0,384.0,382.0,384.0,316.0,336.0,382.0,376.0,382.0,384.0,334.0,336.0,334.0,384.0,378.0,384.0,382.0,384.0,384.0,346.0,318.0,382.0,382.0,382.0,336.0,318.0,320.0,336.0,334.0,384.0,336.0,384.0,384.0,380.0,376.0,382.0,384.0,382.0,382.0,384.0,380.0,378.0,382.0,320.0,384.0,384.0,334.0,332.0,384.0,384.0,382.0,384.0,320.0,384.0,336.0,384.0,336.0,384.0,384.0,384.0,384.0,384.0,334.0,384.0,332.0,336.0,376.0, [...]
+A97DCA1MBS63,380.0,384.0,376.0,384.0,376.0,376.0,384.0,384.0,384.0,376.0,384.0,384.0,376.0,384.0,384.0,382.0,384.0,376.0,376.0,382.0,374.0,382.0,384.0,376.0,376.0,376.0,384.0,378.0,384.0,382.0,384.0,384.0,376.0,376.0,382.0,382.0,382.0,376.0,376.0,376.0,376.0,376.0,384.0,376.0,384.0,384.0,380.0,374.0,382.0,384.0,382.0,382.0,384.0,380.0,378.0,382.0,376.0,384.0,384.0,376.0,376.0,384.0,384.0,382.0,384.0,376.0,384.0,376.0,384.0,376.0,384.0,384.0,384.0,384.0,384.0,376.0,384.0,376.0,376.0,354.0 [...]
+H97DCKTB158,384.0,26.0,384.0,150.0,384.0,384.0,82.0,82.0,150.0,384.0,82.0,150.0,384.0,30.0,30.0,384.0,150.0,384.0,384.0,384.0,384.0,384.0,82.0,384.0,384.0,384.0,150.0,384.0,22.0,384.0,82.0,82.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,82.0,384.0,150.0,82.0,384.0,384.0,384.0,150.0,384.0,384.0,150.0,384.0,384.0,384.0,384.0,150.0,82.0,384.0,384.0,82.0,150.0,384.0,150.0,384.0,150.0,384.0,150.0,384.0,18.0,150.0,82.0,30.0,30.0,384.0,150.0,384.0,384.0,384.0,384.0,30.0,150.0,3 [...]
+C97DCMBS37,384.0,150.0,384.0,142.0,384.0,384.0,150.0,150.0,148.0,384.0,150.0,148.0,384.0,150.0,150.0,384.0,148.0,384.0,384.0,384.0,384.0,384.0,150.0,384.0,384.0,384.0,148.0,384.0,150.0,384.0,150.0,150.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,150.0,384.0,132.0,150.0,384.0,384.0,384.0,148.0,384.0,384.0,144.0,384.0,384.0,384.0,384.0,142.0,150.0,384.0,384.0,150.0,148.0,384.0,146.0,384.0,130.0,384.0,148.0,384.0,150.0,148.0,150.0,150.0,150.0,384.0,148.0,384.0,384.0,384.0,3 [...]
+H97DCKS38,384.0,30.0,384.0,150.0,384.0,384.0,82.0,82.0,150.0,384.0,82.0,150.0,384.0,12.0,14.0,384.0,150.0,384.0,384.0,384.0,384.0,384.0,82.0,384.0,384.0,384.0,150.0,384.0,30.0,384.0,82.0,82.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,82.0,384.0,150.0,82.0,384.0,384.0,384.0,150.0,384.0,384.0,150.0,384.0,384.0,384.0,384.0,150.0,82.0,384.0,384.0,82.0,150.0,384.0,150.0,384.0,150.0,384.0,150.0,384.0,30.0,150.0,82.0,12.0,12.0,384.0,150.0,384.0,384.0,384.0,384.0,12.0,150.0,384 [...]
+G97DCKTB142,384.0,82.0,384.0,150.0,384.0,384.0,68.0,80.0,150.0,384.0,70.0,150.0,384.0,82.0,82.0,384.0,150.0,384.0,384.0,384.0,384.0,384.0,60.0,384.0,384.0,384.0,150.0,384.0,82.0,384.0,52.0,80.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,74.0,384.0,150.0,72.0,384.0,384.0,384.0,150.0,384.0,384.0,150.0,384.0,384.0,384.0,384.0,150.0,68.0,384.0,384.0,80.0,150.0,384.0,150.0,384.0,150.0,384.0,150.0,384.0,82.0,150.0,80.0,82.0,82.0,384.0,150.0,384.0,384.0,384.0,384.0,82.0,150.0,3 [...]
+A97DCKTB124,380.0,384.0,242.0,384.0,336.0,336.0,384.0,384.0,384.0,336.0,384.0,384.0,336.0,384.0,384.0,382.0,384.0,336.0,238.0,382.0,376.0,382.0,384.0,336.0,230.0,336.0,384.0,378.0,384.0,382.0,384.0,384.0,346.0,336.0,382.0,382.0,382.0,254.0,336.0,336.0,254.0,336.0,384.0,240.0,384.0,384.0,380.0,376.0,382.0,384.0,382.0,382.0,384.0,380.0,378.0,382.0,336.0,384.0,384.0,336.0,336.0,384.0,384.0,382.0,384.0,336.0,384.0,242.0,384.0,238.0,384.0,384.0,384.0,384.0,384.0,336.0,384.0,336.0,228.0,376.0, [...]
+A97DCSJFE26,380.0,384.0,216.0,384.0,336.0,336.0,384.0,384.0,384.0,336.0,384.0,384.0,336.0,384.0,384.0,382.0,384.0,336.0,242.0,382.0,376.0,382.0,384.0,336.0,242.0,336.0,384.0,378.0,384.0,382.0,384.0,384.0,346.0,336.0,382.0,382.0,382.0,254.0,336.0,336.0,254.0,336.0,384.0,242.0,384.0,384.0,380.0,376.0,382.0,384.0,382.0,382.0,384.0,380.0,378.0,382.0,336.0,384.0,384.0,336.0,336.0,384.0,384.0,382.0,384.0,336.0,384.0,218.0,384.0,242.0,384.0,384.0,384.0,384.0,384.0,336.0,384.0,336.0,242.0,376.0, [...]
+A97DCEQS45,380.0,384.0,254.0,384.0,336.0,336.0,384.0,384.0,384.0,336.0,384.0,384.0,336.0,384.0,384.0,382.0,384.0,336.0,254.0,382.0,376.0,382.0,384.0,336.0,254.0,336.0,384.0,378.0,384.0,382.0,384.0,384.0,346.0,336.0,382.0,382.0,382.0,248.0,336.0,336.0,244.0,336.0,384.0,254.0,384.0,384.0,380.0,376.0,382.0,384.0,382.0,382.0,384.0,380.0,378.0,382.0,336.0,384.0,384.0,336.0,336.0,384.0,384.0,382.0,384.0,336.0,384.0,254.0,384.0,254.0,384.0,384.0,384.0,384.0,384.0,336.0,384.0,336.0,254.0,376.0,3 [...]
+D97DCKS29,382.0,384.0,382.0,384.0,382.0,382.0,384.0,384.0,384.0,382.0,384.0,384.0,382.0,384.0,384.0,188.0,384.0,382.0,382.0,188.0,382.0,188.0,384.0,382.0,382.0,382.0,384.0,382.0,384.0,188.0,384.0,384.0,382.0,382.0,188.0,188.0,188.0,382.0,382.0,382.0,382.0,382.0,384.0,382.0,384.0,384.0,382.0,382.0,188.0,384.0,188.0,188.0,384.0,382.0,382.0,188.0,382.0,384.0,384.0,382.0,382.0,384.0,384.0,192.0,384.0,382.0,384.0,382.0,384.0,382.0,384.0,384.0,384.0,384.0,384.0,382.0,384.0,382.0,382.0,382.0,38 [...]
+A97DCA2KP86,380.0,384.0,352.0,384.0,352.0,352.0,384.0,384.0,384.0,352.0,384.0,384.0,352.0,384.0,384.0,382.0,384.0,352.0,352.0,382.0,376.0,382.0,384.0,352.0,352.0,352.0,384.0,378.0,384.0,382.0,384.0,384.0,352.0,352.0,382.0,382.0,382.0,352.0,352.0,352.0,352.0,352.0,384.0,352.0,384.0,384.0,380.0,376.0,382.0,384.0,382.0,382.0,384.0,380.0,378.0,382.0,352.0,384.0,384.0,352.0,352.0,384.0,384.0,382.0,384.0,352.0,384.0,352.0,384.0,352.0,384.0,384.0,384.0,384.0,384.0,352.0,384.0,352.0,352.0,376.0, [...]
+H97DCKTB52,384.0,30.0,384.0,150.0,384.0,384.0,82.0,82.0,150.0,384.0,82.0,150.0,384.0,14.0,4.0,384.0,150.0,384.0,384.0,384.0,384.0,384.0,82.0,384.0,384.0,384.0,150.0,384.0,30.0,384.0,82.0,82.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,82.0,384.0,150.0,82.0,384.0,384.0,384.0,150.0,384.0,384.0,150.0,384.0,384.0,384.0,384.0,150.0,82.0,384.0,384.0,82.0,150.0,384.0,150.0,384.0,150.0,384.0,150.0,384.0,30.0,150.0,82.0,14.0,14.0,384.0,150.0,384.0,384.0,384.0,384.0,14.0,150.0,384 [...]
+G97DCKS27,384.0,82.0,384.0,150.0,384.0,384.0,72.0,80.0,150.0,384.0,72.0,150.0,384.0,82.0,82.0,384.0,150.0,384.0,384.0,384.0,384.0,384.0,72.0,384.0,384.0,384.0,150.0,384.0,82.0,384.0,72.0,80.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,74.0,384.0,150.0,50.0,384.0,384.0,384.0,150.0,384.0,384.0,150.0,384.0,384.0,384.0,384.0,150.0,72.0,384.0,384.0,80.0,150.0,384.0,150.0,384.0,150.0,384.0,150.0,384.0,82.0,150.0,80.0,82.0,82.0,384.0,150.0,384.0,384.0,384.0,384.0,82.0,150.0,384 [...]
+F97DCF1KS50,384.0,150.0,384.0,148.0,384.0,384.0,150.0,150.0,110.0,384.0,150.0,106.0,384.0,150.0,150.0,384.0,110.0,384.0,384.0,384.0,384.0,384.0,150.0,384.0,384.0,384.0,110.0,384.0,150.0,384.0,150.0,150.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,150.0,384.0,148.0,150.0,384.0,384.0,384.0,98.0,384.0,384.0,148.0,384.0,384.0,384.0,384.0,148.0,150.0,384.0,384.0,150.0,110.0,384.0,148.0,384.0,148.0,384.0,110.0,384.0,150.0,108.0,150.0,150.0,150.0,384.0,112.0,384.0,384.0,384.0,3 [...]
+A97DCKTB48,380.0,384.0,242.0,384.0,336.0,336.0,384.0,384.0,384.0,336.0,384.0,384.0,336.0,384.0,384.0,382.0,384.0,336.0,240.0,382.0,376.0,382.0,384.0,336.0,240.0,336.0,384.0,378.0,384.0,382.0,384.0,384.0,346.0,336.0,382.0,382.0,382.0,254.0,336.0,336.0,254.0,336.0,384.0,222.0,384.0,384.0,380.0,376.0,382.0,384.0,382.0,382.0,384.0,380.0,378.0,382.0,336.0,384.0,384.0,336.0,336.0,384.0,384.0,382.0,384.0,336.0,384.0,242.0,384.0,240.0,384.0,384.0,384.0,384.0,384.0,336.0,384.0,336.0,240.0,376.0,3 [...]
+A97DCA1KP28,380.0,384.0,376.0,384.0,376.0,376.0,384.0,384.0,384.0,376.0,384.0,384.0,376.0,384.0,384.0,382.0,384.0,376.0,376.0,382.0,374.0,382.0,384.0,376.0,376.0,376.0,384.0,378.0,384.0,382.0,384.0,384.0,376.0,376.0,382.0,382.0,382.0,376.0,376.0,376.0,376.0,376.0,384.0,376.0,384.0,384.0,380.0,374.0,382.0,384.0,382.0,382.0,384.0,380.0,378.0,382.0,376.0,384.0,384.0,376.0,376.0,384.0,384.0,382.0,384.0,376.0,384.0,376.0,384.0,376.0,384.0,384.0,384.0,384.0,384.0,376.0,384.0,376.0,376.0,356.0, [...]
+C97DCSJFE59,384.0,150.0,384.0,142.0,384.0,384.0,150.0,150.0,148.0,384.0,150.0,148.0,384.0,150.0,150.0,384.0,148.0,384.0,384.0,384.0,384.0,384.0,150.0,384.0,384.0,384.0,148.0,384.0,150.0,384.0,150.0,150.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,150.0,384.0,140.0,150.0,384.0,384.0,384.0,148.0,384.0,384.0,144.0,384.0,384.0,384.0,384.0,142.0,150.0,384.0,384.0,150.0,148.0,384.0,146.0,384.0,140.0,384.0,148.0,384.0,150.0,148.0,150.0,150.0,150.0,384.0,148.0,384.0,384.0,384.0, [...]
+A97DCMBFE244,380.0,384.0,336.0,384.0,262.0,334.0,384.0,384.0,384.0,334.0,384.0,384.0,282.0,384.0,384.0,382.0,384.0,334.0,336.0,382.0,376.0,382.0,384.0,272.0,336.0,272.0,384.0,378.0,384.0,382.0,384.0,384.0,346.0,334.0,382.0,382.0,382.0,336.0,334.0,334.0,336.0,270.0,384.0,336.0,384.0,384.0,380.0,376.0,382.0,384.0,382.0,382.0,384.0,380.0,378.0,382.0,334.0,384.0,384.0,266.0,334.0,384.0,384.0,382.0,384.0,334.0,384.0,336.0,384.0,336.0,384.0,384.0,384.0,384.0,384.0,274.0,384.0,334.0,336.0,376.0 [...]
+G97DCKFE77,384.0,82.0,384.0,150.0,384.0,384.0,62.0,80.0,150.0,384.0,70.0,150.0,384.0,82.0,82.0,384.0,150.0,384.0,384.0,384.0,384.0,384.0,68.0,384.0,384.0,384.0,150.0,384.0,82.0,384.0,68.0,80.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,74.0,384.0,150.0,72.0,384.0,384.0,384.0,150.0,384.0,384.0,150.0,384.0,384.0,384.0,384.0,150.0,66.0,384.0,384.0,80.0,150.0,384.0,150.0,384.0,150.0,384.0,150.0,384.0,82.0,150.0,80.0,82.0,82.0,384.0,150.0,384.0,384.0,384.0,384.0,82.0,150.0,38 [...]
+A97DCKTB44,380.0,384.0,254.0,384.0,336.0,336.0,384.0,384.0,384.0,336.0,384.0,384.0,336.0,384.0,384.0,382.0,384.0,336.0,254.0,382.0,376.0,382.0,384.0,336.0,254.0,336.0,384.0,378.0,384.0,382.0,384.0,384.0,346.0,336.0,382.0,382.0,382.0,252.0,336.0,336.0,252.0,336.0,384.0,254.0,384.0,384.0,380.0,376.0,382.0,384.0,382.0,382.0,384.0,380.0,378.0,382.0,336.0,384.0,384.0,336.0,336.0,384.0,384.0,382.0,384.0,336.0,384.0,254.0,384.0,254.0,384.0,384.0,384.0,384.0,384.0,336.0,384.0,336.0,254.0,376.0,3 [...]
+C97DCMBFE92,384.0,150.0,384.0,142.0,384.0,384.0,150.0,150.0,148.0,384.0,150.0,148.0,384.0,150.0,150.0,384.0,148.0,384.0,384.0,384.0,384.0,384.0,150.0,384.0,384.0,384.0,148.0,384.0,150.0,384.0,150.0,150.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,150.0,384.0,138.0,150.0,384.0,384.0,384.0,148.0,384.0,384.0,144.0,384.0,384.0,384.0,384.0,142.0,150.0,384.0,384.0,150.0,148.0,384.0,146.0,384.0,138.0,384.0,148.0,384.0,150.0,148.0,150.0,150.0,150.0,384.0,148.0,384.0,384.0,384.0, [...]
+A97DCMBS32,380.0,384.0,346.0,384.0,346.0,346.0,384.0,384.0,384.0,346.0,384.0,384.0,346.0,384.0,384.0,382.0,384.0,346.0,346.0,382.0,376.0,382.0,384.0,346.0,346.0,346.0,384.0,378.0,384.0,382.0,384.0,384.0,342.0,346.0,382.0,382.0,382.0,346.0,346.0,346.0,346.0,346.0,384.0,346.0,384.0,384.0,380.0,376.0,382.0,384.0,382.0,382.0,384.0,380.0,378.0,382.0,346.0,384.0,384.0,346.0,346.0,384.0,384.0,382.0,384.0,346.0,384.0,346.0,384.0,346.0,384.0,384.0,384.0,384.0,384.0,346.0,384.0,346.0,346.0,376.0,3 [...]
+A97DCA1SJDS17,380.0,384.0,376.0,384.0,376.0,376.0,384.0,384.0,384.0,376.0,384.0,384.0,376.0,384.0,384.0,382.0,384.0,376.0,376.0,382.0,372.0,382.0,384.0,376.0,376.0,376.0,384.0,378.0,384.0,382.0,384.0,384.0,376.0,376.0,382.0,382.0,382.0,376.0,376.0,376.0,376.0,376.0,384.0,376.0,384.0,384.0,380.0,368.0,382.0,384.0,382.0,382.0,384.0,380.0,378.0,382.0,376.0,384.0,384.0,376.0,376.0,384.0,384.0,382.0,384.0,376.0,384.0,376.0,384.0,376.0,384.0,384.0,384.0,384.0,384.0,376.0,384.0,376.0,376.0,374. [...]
+A97DCKTB118,380.0,384.0,336.0,384.0,334.0,320.0,384.0,384.0,384.0,316.0,384.0,384.0,334.0,384.0,384.0,382.0,384.0,308.0,336.0,382.0,376.0,382.0,384.0,334.0,336.0,334.0,384.0,378.0,384.0,382.0,384.0,384.0,346.0,318.0,382.0,382.0,382.0,336.0,318.0,320.0,336.0,334.0,384.0,336.0,384.0,384.0,380.0,376.0,382.0,384.0,382.0,382.0,384.0,380.0,378.0,382.0,320.0,384.0,384.0,334.0,332.0,384.0,384.0,382.0,384.0,320.0,384.0,336.0,384.0,336.0,384.0,384.0,384.0,384.0,384.0,334.0,384.0,332.0,336.0,376.0, [...]
+D97DCKS11,382.0,384.0,382.0,384.0,382.0,382.0,384.0,384.0,384.0,382.0,384.0,384.0,382.0,384.0,384.0,160.0,384.0,382.0,382.0,182.0,382.0,162.0,384.0,382.0,382.0,382.0,384.0,382.0,384.0,184.0,384.0,384.0,382.0,382.0,186.0,182.0,182.0,382.0,382.0,382.0,382.0,382.0,384.0,382.0,384.0,384.0,382.0,382.0,182.0,384.0,182.0,162.0,384.0,382.0,382.0,182.0,382.0,384.0,384.0,382.0,382.0,384.0,384.0,192.0,384.0,382.0,384.0,382.0,384.0,382.0,384.0,384.0,384.0,384.0,384.0,382.0,384.0,382.0,382.0,382.0,38 [...]
+A97DCKP72,380.0,384.0,346.0,384.0,346.0,346.0,384.0,384.0,384.0,346.0,384.0,384.0,346.0,384.0,384.0,382.0,384.0,346.0,346.0,382.0,376.0,382.0,384.0,346.0,346.0,346.0,384.0,378.0,384.0,382.0,384.0,384.0,344.0,346.0,382.0,382.0,382.0,346.0,346.0,346.0,346.0,346.0,384.0,346.0,384.0,384.0,380.0,376.0,382.0,384.0,382.0,382.0,384.0,380.0,378.0,382.0,346.0,384.0,384.0,346.0,346.0,384.0,384.0,382.0,384.0,346.0,384.0,346.0,384.0,346.0,384.0,384.0,384.0,384.0,384.0,346.0,384.0,346.0,346.0,376.0,37 [...]
+A97DCKCC3,380.0,384.0,242.0,384.0,336.0,336.0,384.0,384.0,384.0,336.0,384.0,384.0,336.0,384.0,384.0,382.0,384.0,336.0,234.0,382.0,376.0,382.0,384.0,336.0,238.0,336.0,384.0,378.0,384.0,382.0,384.0,384.0,346.0,336.0,382.0,382.0,382.0,254.0,336.0,336.0,254.0,336.0,384.0,240.0,384.0,384.0,380.0,376.0,382.0,384.0,382.0,382.0,384.0,380.0,378.0,382.0,336.0,384.0,384.0,336.0,336.0,384.0,384.0,382.0,384.0,336.0,384.0,242.0,384.0,236.0,384.0,384.0,384.0,384.0,384.0,336.0,384.0,336.0,238.0,376.0,37 [...]
+A97DCA1KTB185,380.0,384.0,376.0,384.0,376.0,376.0,384.0,384.0,384.0,376.0,384.0,384.0,376.0,384.0,384.0,382.0,384.0,376.0,376.0,382.0,372.0,382.0,384.0,376.0,376.0,376.0,384.0,378.0,384.0,382.0,384.0,384.0,376.0,376.0,382.0,382.0,382.0,376.0,376.0,376.0,376.0,376.0,384.0,376.0,384.0,384.0,380.0,370.0,382.0,384.0,382.0,382.0,384.0,380.0,378.0,382.0,376.0,384.0,384.0,376.0,376.0,384.0,384.0,382.0,384.0,376.0,384.0,376.0,384.0,376.0,384.0,384.0,384.0,384.0,384.0,376.0,384.0,376.0,376.0,374. [...]
+U97DCEQS29,384.0,82.0,384.0,150.0,384.0,384.0,78.0,80.0,150.0,384.0,78.0,150.0,384.0,82.0,82.0,384.0,150.0,384.0,384.0,384.0,384.0,384.0,78.0,384.0,384.0,384.0,150.0,384.0,82.0,384.0,78.0,80.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,78.0,384.0,150.0,78.0,384.0,384.0,384.0,150.0,384.0,384.0,150.0,384.0,384.0,384.0,384.0,150.0,78.0,384.0,384.0,80.0,150.0,384.0,150.0,384.0,150.0,384.0,150.0,384.0,82.0,150.0,80.0,82.0,82.0,384.0,150.0,384.0,384.0,384.0,384.0,82.0,150.0,38 [...]
+A97DCKTB36,380.0,384.0,336.0,384.0,334.0,296.0,384.0,384.0,384.0,320.0,384.0,384.0,334.0,384.0,384.0,382.0,384.0,320.0,336.0,382.0,376.0,382.0,384.0,334.0,336.0,334.0,384.0,378.0,384.0,382.0,384.0,384.0,346.0,320.0,382.0,382.0,382.0,336.0,320.0,296.0,336.0,334.0,384.0,336.0,384.0,384.0,380.0,376.0,382.0,384.0,382.0,382.0,384.0,380.0,378.0,382.0,296.0,384.0,384.0,334.0,332.0,384.0,384.0,382.0,384.0,296.0,384.0,336.0,384.0,336.0,384.0,384.0,384.0,384.0,384.0,334.0,384.0,332.0,336.0,376.0,3 [...]
+J97DCMBS41,384.0,82.0,384.0,150.0,384.0,384.0,80.0,42.0,150.0,384.0,80.0,150.0,384.0,82.0,82.0,384.0,150.0,384.0,384.0,384.0,384.0,384.0,80.0,384.0,384.0,384.0,150.0,384.0,82.0,384.0,80.0,44.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,80.0,384.0,150.0,80.0,384.0,384.0,384.0,150.0,384.0,384.0,150.0,384.0,384.0,384.0,384.0,150.0,80.0,384.0,384.0,40.0,150.0,384.0,150.0,384.0,150.0,384.0,150.0,384.0,82.0,150.0,34.0,82.0,82.0,384.0,150.0,384.0,384.0,384.0,384.0,82.0,150.0,38 [...]
+E97DCKP14,204.0,384.0,380.0,384.0,380.0,380.0,384.0,384.0,384.0,380.0,384.0,384.0,380.0,384.0,384.0,382.0,384.0,380.0,380.0,382.0,380.0,382.0,384.0,380.0,380.0,380.0,384.0,380.0,384.0,382.0,384.0,384.0,380.0,380.0,382.0,382.0,382.0,380.0,380.0,380.0,380.0,380.0,384.0,380.0,384.0,384.0,202.0,380.0,382.0,384.0,382.0,382.0,384.0,204.0,380.0,382.0,380.0,384.0,384.0,380.0,380.0,384.0,384.0,382.0,384.0,380.0,384.0,380.0,384.0,380.0,384.0,384.0,384.0,384.0,384.0,380.0,384.0,380.0,380.0,380.0,38 [...]
+A97DCKCC4,380.0,384.0,336.0,384.0,334.0,320.0,384.0,384.0,384.0,318.0,384.0,384.0,334.0,384.0,384.0,382.0,384.0,318.0,336.0,382.0,376.0,382.0,384.0,334.0,336.0,334.0,384.0,378.0,384.0,382.0,384.0,384.0,346.0,306.0,382.0,382.0,382.0,336.0,306.0,320.0,336.0,334.0,384.0,336.0,384.0,384.0,380.0,376.0,382.0,384.0,382.0,382.0,384.0,380.0,378.0,382.0,320.0,384.0,384.0,334.0,332.0,384.0,384.0,382.0,384.0,320.0,384.0,336.0,384.0,336.0,384.0,384.0,384.0,384.0,384.0,334.0,384.0,332.0,336.0,376.0,37 [...]
+A97DCA1KP18,380.0,384.0,376.0,384.0,376.0,376.0,384.0,384.0,384.0,376.0,384.0,384.0,376.0,384.0,384.0,382.0,384.0,376.0,376.0,382.0,374.0,382.0,384.0,376.0,376.0,376.0,384.0,378.0,384.0,382.0,384.0,384.0,376.0,376.0,382.0,382.0,382.0,376.0,376.0,376.0,376.0,376.0,384.0,376.0,384.0,384.0,380.0,374.0,382.0,384.0,382.0,382.0,384.0,380.0,378.0,382.0,376.0,384.0,384.0,376.0,376.0,384.0,384.0,382.0,384.0,376.0,384.0,376.0,384.0,376.0,384.0,384.0,384.0,384.0,384.0,376.0,384.0,376.0,376.0,358.0, [...]
+K97DCKTB1,384.0,150.0,384.0,148.0,384.0,384.0,150.0,150.0,92.0,384.0,150.0,110.0,384.0,150.0,150.0,384.0,92.0,384.0,384.0,384.0,384.0,384.0,150.0,384.0,384.0,384.0,94.0,384.0,150.0,384.0,150.0,150.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,150.0,384.0,148.0,150.0,384.0,384.0,384.0,110.0,384.0,384.0,148.0,384.0,384.0,384.0,384.0,148.0,150.0,384.0,384.0,150.0,92.0,384.0,148.0,384.0,148.0,384.0,92.0,384.0,150.0,110.0,150.0,150.0,150.0,384.0,112.0,384.0,384.0,384.0,384.0,1 [...]
+D97DCKP1,382.0,384.0,382.0,384.0,382.0,382.0,384.0,384.0,384.0,382.0,384.0,384.0,382.0,384.0,384.0,182.0,384.0,382.0,382.0,180.0,382.0,182.0,384.0,382.0,382.0,382.0,384.0,382.0,384.0,184.0,384.0,384.0,382.0,382.0,186.0,180.0,180.0,382.0,382.0,382.0,382.0,382.0,384.0,382.0,384.0,384.0,382.0,382.0,180.0,384.0,180.0,182.0,384.0,382.0,382.0,164.0,382.0,384.0,384.0,382.0,382.0,384.0,384.0,192.0,384.0,382.0,384.0,382.0,384.0,382.0,384.0,384.0,384.0,384.0,384.0,382.0,384.0,382.0,382.0,382.0,382 [...]
+A97DCMBFE5,380.0,384.0,216.0,384.0,336.0,336.0,384.0,384.0,384.0,336.0,384.0,384.0,336.0,384.0,384.0,382.0,384.0,336.0,242.0,382.0,376.0,382.0,384.0,336.0,242.0,336.0,384.0,378.0,384.0,382.0,384.0,384.0,346.0,336.0,382.0,382.0,382.0,254.0,336.0,336.0,254.0,336.0,384.0,242.0,384.0,384.0,380.0,376.0,382.0,384.0,382.0,382.0,384.0,380.0,378.0,382.0,336.0,384.0,384.0,336.0,336.0,384.0,384.0,382.0,384.0,336.0,384.0,218.0,384.0,242.0,384.0,384.0,384.0,384.0,384.0,336.0,384.0,336.0,242.0,376.0,3 [...]
+D97DCD2KS26,382.0,384.0,382.0,384.0,382.0,382.0,384.0,384.0,384.0,382.0,384.0,384.0,382.0,384.0,384.0,184.0,384.0,382.0,382.0,184.0,382.0,184.0,384.0,382.0,382.0,382.0,384.0,382.0,384.0,156.0,384.0,384.0,382.0,382.0,186.0,184.0,184.0,382.0,382.0,382.0,382.0,382.0,384.0,382.0,384.0,384.0,382.0,382.0,184.0,384.0,184.0,184.0,384.0,382.0,382.0,184.0,382.0,384.0,384.0,382.0,382.0,384.0,384.0,192.0,384.0,382.0,384.0,382.0,384.0,382.0,384.0,384.0,384.0,384.0,384.0,382.0,384.0,382.0,382.0,382.0, [...]
+U97DCMBFE250,380.0,384.0,378.0,384.0,378.0,378.0,384.0,384.0,384.0,378.0,384.0,384.0,378.0,384.0,384.0,382.0,384.0,378.0,378.0,382.0,378.0,382.0,384.0,378.0,378.0,378.0,384.0,208.0,384.0,382.0,384.0,384.0,378.0,378.0,382.0,382.0,382.0,378.0,378.0,378.0,378.0,378.0,384.0,378.0,384.0,384.0,380.0,378.0,382.0,384.0,382.0,382.0,384.0,380.0,210.0,382.0,378.0,384.0,384.0,378.0,378.0,384.0,384.0,382.0,384.0,378.0,384.0,378.0,384.0,378.0,384.0,384.0,384.0,384.0,384.0,378.0,384.0,378.0,378.0,378.0 [...]
+A97DCKTB16,380.0,384.0,336.0,384.0,282.0,334.0,384.0,384.0,384.0,334.0,384.0,384.0,280.0,384.0,384.0,382.0,384.0,334.0,336.0,382.0,376.0,382.0,384.0,282.0,336.0,282.0,384.0,378.0,384.0,382.0,384.0,384.0,346.0,334.0,382.0,382.0,382.0,336.0,334.0,334.0,336.0,282.0,384.0,336.0,384.0,384.0,380.0,376.0,382.0,384.0,382.0,382.0,384.0,380.0,378.0,382.0,334.0,384.0,384.0,282.0,334.0,384.0,384.0,382.0,384.0,334.0,384.0,336.0,384.0,336.0,384.0,384.0,384.0,384.0,384.0,282.0,384.0,334.0,336.0,376.0,3 [...]
+A97DCKTB7,380.0,384.0,336.0,384.0,334.0,320.0,384.0,384.0,384.0,318.0,384.0,384.0,334.0,384.0,384.0,382.0,384.0,318.0,336.0,382.0,376.0,382.0,384.0,334.0,336.0,334.0,384.0,378.0,384.0,382.0,384.0,384.0,346.0,302.0,382.0,382.0,382.0,336.0,304.0,320.0,336.0,334.0,384.0,336.0,384.0,384.0,380.0,376.0,382.0,384.0,382.0,382.0,384.0,380.0,378.0,382.0,320.0,384.0,384.0,334.0,332.0,384.0,384.0,382.0,384.0,320.0,384.0,336.0,384.0,336.0,384.0,384.0,384.0,384.0,384.0,334.0,384.0,332.0,336.0,376.0,37 [...]
+A97DCMBS26,380.0,384.0,336.0,384.0,334.0,320.0,384.0,384.0,384.0,312.0,384.0,384.0,334.0,384.0,384.0,382.0,384.0,316.0,336.0,382.0,376.0,382.0,384.0,334.0,336.0,334.0,384.0,378.0,384.0,382.0,384.0,384.0,346.0,318.0,382.0,382.0,382.0,336.0,318.0,320.0,336.0,334.0,384.0,336.0,384.0,384.0,380.0,376.0,382.0,384.0,382.0,382.0,384.0,380.0,378.0,382.0,320.0,384.0,384.0,334.0,332.0,384.0,384.0,382.0,384.0,320.0,384.0,336.0,384.0,336.0,384.0,384.0,384.0,384.0,384.0,334.0,384.0,332.0,336.0,376.0,3 [...]
+G97DCKMST100,384.0,82.0,384.0,150.0,384.0,384.0,68.0,80.0,150.0,384.0,70.0,150.0,384.0,82.0,82.0,384.0,150.0,384.0,384.0,384.0,384.0,384.0,58.0,384.0,384.0,384.0,150.0,384.0,82.0,384.0,60.0,80.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,74.0,384.0,150.0,72.0,384.0,384.0,384.0,150.0,384.0,384.0,150.0,384.0,384.0,384.0,384.0,150.0,68.0,384.0,384.0,80.0,150.0,384.0,150.0,384.0,150.0,384.0,150.0,384.0,82.0,150.0,80.0,82.0,82.0,384.0,150.0,384.0,384.0,384.0,384.0,82.0,150.0, [...]
+D97DCKP54,382.0,384.0,382.0,384.0,382.0,382.0,384.0,384.0,384.0,382.0,384.0,384.0,382.0,384.0,384.0,182.0,384.0,382.0,382.0,176.0,382.0,182.0,384.0,382.0,382.0,382.0,384.0,382.0,384.0,184.0,384.0,384.0,382.0,382.0,186.0,172.0,174.0,382.0,382.0,382.0,382.0,382.0,384.0,382.0,384.0,384.0,382.0,382.0,178.0,384.0,170.0,182.0,384.0,382.0,382.0,180.0,382.0,384.0,384.0,382.0,382.0,384.0,384.0,192.0,384.0,382.0,384.0,382.0,384.0,382.0,384.0,384.0,384.0,384.0,384.0,382.0,384.0,382.0,382.0,382.0,38 [...]
+F97DCF1KP40,384.0,150.0,384.0,148.0,384.0,384.0,150.0,150.0,110.0,384.0,150.0,100.0,384.0,150.0,150.0,384.0,110.0,384.0,384.0,384.0,384.0,384.0,150.0,384.0,384.0,384.0,110.0,384.0,150.0,384.0,150.0,150.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,150.0,384.0,148.0,150.0,384.0,384.0,384.0,106.0,384.0,384.0,148.0,384.0,384.0,384.0,384.0,148.0,150.0,384.0,384.0,150.0,110.0,384.0,148.0,384.0,148.0,384.0,110.0,384.0,150.0,108.0,150.0,150.0,150.0,384.0,112.0,384.0,384.0,384.0, [...]
+A97DCMBTB54,380.0,384.0,336.0,384.0,282.0,334.0,384.0,384.0,384.0,334.0,384.0,384.0,276.0,384.0,384.0,382.0,384.0,334.0,336.0,382.0,376.0,382.0,384.0,282.0,336.0,282.0,384.0,378.0,384.0,382.0,384.0,384.0,346.0,334.0,382.0,382.0,382.0,336.0,334.0,334.0,336.0,282.0,384.0,336.0,384.0,384.0,380.0,376.0,382.0,384.0,382.0,382.0,384.0,380.0,378.0,382.0,334.0,384.0,384.0,282.0,334.0,384.0,384.0,382.0,384.0,334.0,384.0,336.0,384.0,336.0,384.0,384.0,384.0,384.0,384.0,282.0,384.0,334.0,336.0,376.0, [...]
+A97DCKS36,380.0,384.0,336.0,384.0,334.0,320.0,384.0,384.0,384.0,318.0,384.0,384.0,334.0,384.0,384.0,382.0,384.0,318.0,336.0,382.0,376.0,382.0,384.0,334.0,336.0,334.0,384.0,378.0,384.0,382.0,384.0,384.0,346.0,304.0,382.0,382.0,382.0,336.0,298.0,320.0,336.0,334.0,384.0,336.0,384.0,384.0,380.0,376.0,382.0,384.0,382.0,382.0,384.0,380.0,378.0,382.0,320.0,384.0,384.0,334.0,332.0,384.0,384.0,382.0,384.0,320.0,384.0,336.0,384.0,336.0,384.0,384.0,384.0,384.0,384.0,334.0,384.0,332.0,336.0,376.0,37 [...]
+G97DCKMST10,384.0,82.0,384.0,150.0,384.0,384.0,72.0,80.0,150.0,384.0,72.0,150.0,384.0,82.0,82.0,384.0,150.0,384.0,384.0,384.0,384.0,384.0,72.0,384.0,384.0,384.0,150.0,384.0,82.0,384.0,72.0,80.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,74.0,384.0,150.0,46.0,384.0,384.0,384.0,150.0,384.0,384.0,150.0,384.0,384.0,384.0,384.0,150.0,72.0,384.0,384.0,80.0,150.0,384.0,150.0,384.0,150.0,384.0,150.0,384.0,82.0,150.0,80.0,82.0,82.0,384.0,150.0,384.0,384.0,384.0,384.0,82.0,150.0,3 [...]
+D97DCKMST144,382.0,384.0,382.0,384.0,382.0,382.0,384.0,384.0,384.0,382.0,384.0,384.0,382.0,384.0,384.0,188.0,384.0,382.0,382.0,188.0,382.0,188.0,384.0,382.0,382.0,382.0,384.0,382.0,384.0,188.0,384.0,384.0,382.0,382.0,188.0,188.0,188.0,382.0,382.0,382.0,382.0,382.0,384.0,382.0,384.0,384.0,382.0,382.0,188.0,384.0,188.0,188.0,384.0,382.0,382.0,188.0,382.0,384.0,384.0,382.0,382.0,384.0,384.0,192.0,384.0,382.0,384.0,382.0,384.0,382.0,384.0,384.0,384.0,384.0,384.0,382.0,384.0,382.0,382.0,382.0 [...]
+A97DCMBFE149,380.0,384.0,336.0,384.0,334.0,290.0,384.0,384.0,384.0,320.0,384.0,384.0,334.0,384.0,384.0,382.0,384.0,320.0,336.0,382.0,376.0,382.0,384.0,334.0,336.0,334.0,384.0,378.0,384.0,382.0,384.0,384.0,346.0,320.0,382.0,382.0,382.0,336.0,320.0,294.0,336.0,334.0,384.0,336.0,384.0,384.0,380.0,376.0,382.0,384.0,382.0,382.0,384.0,380.0,378.0,382.0,294.0,384.0,384.0,334.0,332.0,384.0,384.0,382.0,384.0,294.0,384.0,336.0,384.0,336.0,384.0,384.0,384.0,384.0,384.0,334.0,384.0,332.0,336.0,376.0 [...]
+A97DCKTB6,380.0,384.0,336.0,384.0,334.0,332.0,384.0,384.0,384.0,332.0,384.0,384.0,334.0,384.0,384.0,382.0,384.0,332.0,336.0,382.0,376.0,382.0,384.0,334.0,336.0,334.0,384.0,378.0,384.0,382.0,384.0,384.0,346.0,332.0,382.0,382.0,382.0,336.0,332.0,332.0,336.0,334.0,384.0,336.0,384.0,384.0,380.0,376.0,382.0,384.0,382.0,382.0,384.0,380.0,378.0,382.0,332.0,384.0,384.0,334.0,330.0,384.0,384.0,382.0,384.0,332.0,384.0,336.0,384.0,336.0,384.0,384.0,384.0,384.0,384.0,334.0,384.0,330.0,336.0,376.0,37 [...]
+A97DCKTB157,380.0,384.0,336.0,384.0,272.0,334.0,384.0,384.0,384.0,334.0,384.0,384.0,282.0,384.0,384.0,382.0,384.0,334.0,336.0,382.0,376.0,382.0,384.0,258.0,336.0,260.0,384.0,378.0,384.0,382.0,384.0,384.0,346.0,334.0,382.0,382.0,382.0,336.0,334.0,334.0,336.0,272.0,384.0,336.0,384.0,384.0,380.0,376.0,382.0,384.0,382.0,382.0,384.0,380.0,378.0,382.0,334.0,384.0,384.0,272.0,334.0,384.0,384.0,382.0,384.0,334.0,384.0,336.0,384.0,336.0,384.0,384.0,384.0,384.0,384.0,274.0,384.0,334.0,336.0,376.0, [...]
+C97DCMBTB58,384.0,150.0,384.0,142.0,384.0,384.0,150.0,150.0,148.0,384.0,150.0,148.0,384.0,150.0,150.0,384.0,148.0,384.0,384.0,384.0,384.0,384.0,150.0,384.0,384.0,384.0,148.0,384.0,150.0,384.0,150.0,150.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,150.0,384.0,132.0,150.0,384.0,384.0,384.0,148.0,384.0,384.0,144.0,384.0,384.0,384.0,384.0,142.0,150.0,384.0,384.0,150.0,148.0,384.0,146.0,384.0,120.0,384.0,148.0,384.0,150.0,148.0,150.0,150.0,150.0,384.0,148.0,384.0,384.0,384.0, [...]
+D97DCKFE53,382.0,384.0,382.0,384.0,382.0,382.0,384.0,384.0,384.0,382.0,384.0,384.0,382.0,384.0,384.0,194.0,384.0,382.0,382.0,194.0,382.0,194.0,384.0,382.0,382.0,382.0,384.0,382.0,384.0,194.0,384.0,384.0,382.0,382.0,194.0,194.0,194.0,382.0,382.0,382.0,382.0,382.0,384.0,382.0,384.0,384.0,382.0,382.0,194.0,384.0,194.0,194.0,384.0,382.0,382.0,194.0,382.0,384.0,384.0,382.0,382.0,384.0,384.0,194.0,384.0,382.0,384.0,382.0,384.0,382.0,384.0,384.0,384.0,384.0,384.0,382.0,384.0,382.0,382.0,382.0,3 [...]
+A97DCA2MBCD5,380.0,384.0,352.0,384.0,352.0,352.0,384.0,384.0,384.0,352.0,384.0,384.0,352.0,384.0,384.0,382.0,384.0,352.0,352.0,382.0,376.0,382.0,384.0,352.0,352.0,352.0,384.0,378.0,384.0,382.0,384.0,384.0,352.0,352.0,382.0,382.0,382.0,352.0,352.0,352.0,352.0,352.0,384.0,352.0,384.0,384.0,380.0,376.0,382.0,384.0,382.0,382.0,384.0,380.0,378.0,382.0,352.0,384.0,384.0,352.0,352.0,384.0,384.0,382.0,384.0,352.0,384.0,352.0,384.0,352.0,384.0,384.0,384.0,384.0,384.0,352.0,384.0,352.0,352.0,376.0 [...]
+G97DCKFE181,384.0,82.0,384.0,150.0,384.0,384.0,66.0,80.0,150.0,384.0,70.0,150.0,384.0,82.0,82.0,384.0,150.0,384.0,384.0,384.0,384.0,384.0,68.0,384.0,384.0,384.0,150.0,384.0,82.0,384.0,68.0,80.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,74.0,384.0,150.0,72.0,384.0,384.0,384.0,150.0,384.0,384.0,150.0,384.0,384.0,384.0,384.0,150.0,64.0,384.0,384.0,80.0,150.0,384.0,150.0,384.0,150.0,384.0,150.0,384.0,82.0,150.0,80.0,82.0,82.0,384.0,150.0,384.0,384.0,384.0,384.0,82.0,150.0,3 [...]
+A97DCKCD6,380.0,384.0,336.0,384.0,334.0,292.0,384.0,384.0,384.0,320.0,384.0,384.0,334.0,384.0,384.0,382.0,384.0,320.0,336.0,382.0,376.0,382.0,384.0,334.0,336.0,334.0,384.0,378.0,384.0,382.0,384.0,384.0,346.0,320.0,382.0,382.0,382.0,336.0,320.0,294.0,336.0,334.0,384.0,336.0,384.0,384.0,380.0,376.0,382.0,384.0,382.0,382.0,384.0,380.0,378.0,382.0,294.0,384.0,384.0,334.0,332.0,384.0,384.0,382.0,384.0,294.0,384.0,336.0,384.0,336.0,384.0,384.0,384.0,384.0,384.0,334.0,384.0,332.0,336.0,376.0,37 [...]
+F97DCF1KTB165,384.0,150.0,384.0,148.0,384.0,384.0,150.0,150.0,110.0,384.0,150.0,106.0,384.0,150.0,150.0,384.0,110.0,384.0,384.0,384.0,384.0,384.0,150.0,384.0,384.0,384.0,110.0,384.0,150.0,384.0,150.0,150.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,384.0,150.0,384.0,148.0,150.0,384.0,384.0,384.0,98.0,384.0,384.0,148.0,384.0,384.0,384.0,384.0,148.0,150.0,384.0,384.0,150.0,110.0,384.0,148.0,384.0,148.0,384.0,110.0,384.0,150.0,108.0,150.0,150.0,150.0,384.0,112.0,384.0,384.0,384.0 [...]
+A97DCKTB20,380.0,384.0,254.0,384.0,336.0,336.0,384.0,384.0,384.0,336.0,384.0,384.0,336.0,384.0,384.0,382.0,384.0,336.0,254.0,382.0,376.0,382.0,384.0,336.0,254.0,336.0,384.0,378.0,384.0,382.0,384.0,384.0,346.0,336.0,382.0,382.0,382.0,250.0,336.0,336.0,250.0,336.0,384.0,254.0,384.0,384.0,380.0,376.0,382.0,384.0,382.0,382.0,384.0,380.0,378.0,382.0,336.0,384.0,384.0,336.0,336.0,384.0,384.0,382.0,384.0,336.0,384.0,254.0,384.0,254.0,384.0,384.0,384.0,384.0,384.0,336.0,384.0,336.0,254.0,376.0,3 [...]
+A97DCMBFE155,380.0,384.0,336.0,384.0,264.0,334.0,384.0,384.0,384.0,334.0,384.0,384.0,282.0,384.0,384.0,382.0,384.0,334.0,336.0,382.0,376.0,382.0,384.0,272.0,336.0,272.0,384.0,378.0,384.0,382.0,384.0,384.0,346.0,334.0,382.0,382.0,382.0,336.0,334.0,334.0,336.0,270.0,384.0,336.0,384.0,384.0,380.0,376.0,382.0,384.0,382.0,382.0,384.0,380.0,378.0,382.0,334.0,384.0,384.0,266.0,334.0,384.0,384.0,382.0,384.0,334.0,384.0,336.0,384.0,336.0,384.0,384.0,384.0,384.0,384.0,274.0,384.0,334.0,336.0,376.0 [...]
diff --git a/dendropy/test/data/other/hiv1.node-to-node-dists.csv b/dendropy/test/data/other/hiv1.node-to-node-dists.csv
new file mode 100644
index 0000000..16a9bd7
--- /dev/null
+++ b/dendropy/test/data/other/hiv1.node-to-node-dists.csv
@@ -0,0 +1,386 @@
+"","1","2","3","4","5","6","7","8","9","10","11","12","13","14","15","16","17","18","19","20","21","22","23","24","25","26","27","28","29","30","31","32","33","34","35","36","37","38","39","40","41","42","43","44","45","46","47","48","49","50","51","52","53","54","55","56","57","58","59","60","61","62","63","64","65","66","67","68","69","70","71","72","73","74","75","76","77","78","79","80","81","82","83","84","85","86","87","88","89","90","91","92","93","94","95","96","97","98","99","10 [...]
+"1",0,364,366,366,368,370,370,372,374,374,374,374,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,378,378,378,378,380,380,380,380,380,380,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,384,384,384,384,384,38 [...]
+"2",364,0,366,366,368,370,370,372,374,374,374,374,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,378,378,378,378,380,380,380,380,380,380,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,384,384,384,384,384,38 [...]
+"3",366,366,0,362,368,370,370,372,374,374,374,374,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,378,378,378,378,380,380,380,380,380,380,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,384,384,384,384,384,38 [...]
+"4",366,366,362,0,368,370,370,372,374,374,374,374,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,378,378,378,378,380,380,380,380,380,380,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,384,384,384,384,384,38 [...]
+"5",368,368,368,368,0,370,370,372,374,374,374,374,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,378,378,378,378,380,380,380,380,380,380,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,384,384,384,384,384,38 [...]
+"6",370,370,370,370,370,0,360,372,374,374,374,374,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,378,378,378,378,380,380,380,380,380,380,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,384,384,384,384,384,38 [...]
+"7",370,370,370,370,370,360,0,372,374,374,374,374,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,378,378,378,378,380,380,380,380,380,380,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,384,384,384,384,384,38 [...]
+"8",372,372,372,372,372,372,372,0,374,374,374,374,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,378,378,378,378,380,380,380,380,380,380,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,384,384,384,384,384,38 [...]
+"9",374,374,374,374,374,374,374,374,0,358,358,358,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,378,378,378,378,380,380,380,380,380,380,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,384,384,384,384,384,38 [...]
+"10",374,374,374,374,374,374,374,374,358,0,356,356,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,378,378,378,378,380,380,380,380,380,380,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,384,384,384,384,384,3 [...]
+"11",374,374,374,374,374,374,374,374,358,356,0,354,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,378,378,378,378,380,380,380,380,380,380,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,384,384,384,384,384,3 [...]
+"12",374,374,374,374,374,374,374,374,358,356,354,0,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,378,378,378,378,380,380,380,380,380,380,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,384,384,384,384,384,3 [...]
+"13",376,376,376,376,376,376,376,376,376,376,376,376,0,348,350,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,378,378,378,378,380,380,380,380,380,380,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,384,384,384,384,384,3 [...]
+"14",376,376,376,376,376,376,376,376,376,376,376,376,348,0,350,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,378,378,378,378,380,380,380,380,380,380,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,384,384,384,384,384,3 [...]
+"15",376,376,376,376,376,376,376,376,376,376,376,376,350,350,0,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,378,378,378,378,380,380,380,380,380,380,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,384,384,384,384,384,3 [...]
+"16",376,376,376,376,376,376,376,376,376,376,376,376,352,352,352,0,340,342,344,344,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,378,378,378,378,380,380,380,380,380,380,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,384,384,384,384,384,3 [...]
+"17",376,376,376,376,376,376,376,376,376,376,376,376,352,352,352,340,0,342,344,344,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,378,378,378,378,380,380,380,380,380,380,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,384,384,384,384,384,3 [...]
+"18",376,376,376,376,376,376,376,376,376,376,376,376,352,352,352,342,342,0,344,344,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,378,378,378,378,380,380,380,380,380,380,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,384,384,384,384,384,3 [...]
+"19",376,376,376,376,376,376,376,376,376,376,376,376,352,352,352,344,344,344,0,338,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,378,378,378,378,380,380,380,380,380,380,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,384,384,384,384,384,3 [...]
+"20",376,376,376,376,376,376,376,376,376,376,376,376,352,352,352,344,344,344,338,0,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,378,378,378,378,380,380,380,380,380,380,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,384,384,384,384,384,3 [...]
+"21",376,376,376,376,376,376,376,376,376,376,376,376,352,352,352,346,346,346,346,346,0,326,328,330,330,330,332,332,332,332,332,332,332,332,332,332,332,332,332,332,332,332,332,332,332,332,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,378,378,378,378,380,380,380,380,380,380,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,384,384,384,384,384,3 [...]
+"22",376,376,376,376,376,376,376,376,376,376,376,376,352,352,352,346,346,346,346,346,326,0,328,330,330,330,332,332,332,332,332,332,332,332,332,332,332,332,332,332,332,332,332,332,332,332,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,378,378,378,378,380,380,380,380,380,380,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,384,384,384,384,384,3 [...]
+"23",376,376,376,376,376,376,376,376,376,376,376,376,352,352,352,346,346,346,346,346,328,328,0,330,330,330,332,332,332,332,332,332,332,332,332,332,332,332,332,332,332,332,332,332,332,332,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,378,378,378,378,380,380,380,380,380,380,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,384,384,384,384,384,3 [...]
+"24",376,376,376,376,376,376,376,376,376,376,376,376,352,352,352,346,346,346,346,346,330,330,330,0,324,324,332,332,332,332,332,332,332,332,332,332,332,332,332,332,332,332,332,332,332,332,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,378,378,378,378,380,380,380,380,380,380,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,384,384,384,384,384,3 [...]
+"25",376,376,376,376,376,376,376,376,376,376,376,376,352,352,352,346,346,346,346,346,330,330,330,324,0,322,332,332,332,332,332,332,332,332,332,332,332,332,332,332,332,332,332,332,332,332,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,378,378,378,378,380,380,380,380,380,380,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,384,384,384,384,384,3 [...]
+"26",376,376,376,376,376,376,376,376,376,376,376,376,352,352,352,346,346,346,346,346,330,330,330,324,322,0,332,332,332,332,332,332,332,332,332,332,332,332,332,332,332,332,332,332,332,332,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,378,378,378,378,380,380,380,380,380,380,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,384,384,384,384,384,3 [...]
+"27",376,376,376,376,376,376,376,376,376,376,376,376,352,352,352,346,346,346,346,346,332,332,332,332,332,332,0,314,314,314,316,316,318,318,318,318,318,318,320,320,320,320,320,320,320,320,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,378,378,378,378,380,380,380,380,380,380,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,384,384,384,384,384,3 [...]
+"28",376,376,376,376,376,376,376,376,376,376,376,376,352,352,352,346,346,346,346,346,332,332,332,332,332,332,314,0,310,312,316,316,318,318,318,318,318,318,320,320,320,320,320,320,320,320,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,378,378,378,378,380,380,380,380,380,380,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,384,384,384,384,384,3 [...]
+"29",376,376,376,376,376,376,376,376,376,376,376,376,352,352,352,346,346,346,346,346,332,332,332,332,332,332,314,310,0,312,316,316,318,318,318,318,318,318,320,320,320,320,320,320,320,320,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,378,378,378,378,380,380,380,380,380,380,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,384,384,384,384,384,3 [...]
+"30",376,376,376,376,376,376,376,376,376,376,376,376,352,352,352,346,346,346,346,346,332,332,332,332,332,332,314,312,312,0,316,316,318,318,318,318,318,318,320,320,320,320,320,320,320,320,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,378,378,378,378,380,380,380,380,380,380,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,384,384,384,384,384,3 [...]
+"31",376,376,376,376,376,376,376,376,376,376,376,376,352,352,352,346,346,346,346,346,332,332,332,332,332,332,316,316,316,316,0,308,318,318,318,318,318,318,320,320,320,320,320,320,320,320,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,378,378,378,378,380,380,380,380,380,380,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,384,384,384,384,384,3 [...]
+"32",376,376,376,376,376,376,376,376,376,376,376,376,352,352,352,346,346,346,346,346,332,332,332,332,332,332,316,316,316,316,308,0,318,318,318,318,318,318,320,320,320,320,320,320,320,320,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,378,378,378,378,380,380,380,380,380,380,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,384,384,384,384,384,3 [...]
+"33",376,376,376,376,376,376,376,376,376,376,376,376,352,352,352,346,346,346,346,346,332,332,332,332,332,332,318,318,318,318,318,318,0,306,306,306,306,306,320,320,320,320,320,320,320,320,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,378,378,378,378,380,380,380,380,380,380,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,384,384,384,384,384,3 [...]
+"34",376,376,376,376,376,376,376,376,376,376,376,376,352,352,352,346,346,346,346,346,332,332,332,332,332,332,318,318,318,318,318,318,306,0,300,302,304,304,320,320,320,320,320,320,320,320,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,378,378,378,378,380,380,380,380,380,380,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,384,384,384,384,384,3 [...]
+"35",376,376,376,376,376,376,376,376,376,376,376,376,352,352,352,346,346,346,346,346,332,332,332,332,332,332,318,318,318,318,318,318,306,300,0,302,304,304,320,320,320,320,320,320,320,320,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,378,378,378,378,380,380,380,380,380,380,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,384,384,384,384,384,3 [...]
+"36",376,376,376,376,376,376,376,376,376,376,376,376,352,352,352,346,346,346,346,346,332,332,332,332,332,332,318,318,318,318,318,318,306,302,302,0,304,304,320,320,320,320,320,320,320,320,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,378,378,378,378,380,380,380,380,380,380,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,384,384,384,384,384,3 [...]
+"37",376,376,376,376,376,376,376,376,376,376,376,376,352,352,352,346,346,346,346,346,332,332,332,332,332,332,318,318,318,318,318,318,306,304,304,304,0,298,320,320,320,320,320,320,320,320,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,378,378,378,378,380,380,380,380,380,380,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,384,384,384,384,384,3 [...]
+"38",376,376,376,376,376,376,376,376,376,376,376,376,352,352,352,346,346,346,346,346,332,332,332,332,332,332,318,318,318,318,318,318,306,304,304,304,298,0,320,320,320,320,320,320,320,320,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,378,378,378,378,380,380,380,380,380,380,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,384,384,384,384,384,3 [...]
+"39",376,376,376,376,376,376,376,376,376,376,376,376,352,352,352,346,346,346,346,346,332,332,332,332,332,332,320,320,320,320,320,320,320,320,320,320,320,320,0,292,292,294,294,294,294,296,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,378,378,378,378,380,380,380,380,380,380,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,384,384,384,384,384,3 [...]
+"40",376,376,376,376,376,376,376,376,376,376,376,376,352,352,352,346,346,346,346,346,332,332,332,332,332,332,320,320,320,320,320,320,320,320,320,320,320,320,292,0,290,294,294,294,294,296,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,378,378,378,378,380,380,380,380,380,380,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,384,384,384,384,384,3 [...]
+"41",376,376,376,376,376,376,376,376,376,376,376,376,352,352,352,346,346,346,346,346,332,332,332,332,332,332,320,320,320,320,320,320,320,320,320,320,320,320,292,290,0,294,294,294,294,296,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,378,378,378,378,380,380,380,380,380,380,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,384,384,384,384,384,3 [...]
+"42",376,376,376,376,376,376,376,376,376,376,376,376,352,352,352,346,346,346,346,346,332,332,332,332,332,332,320,320,320,320,320,320,320,320,320,320,320,320,294,294,294,0,286,288,288,296,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,378,378,378,378,380,380,380,380,380,380,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,384,384,384,384,384,3 [...]
+"43",376,376,376,376,376,376,376,376,376,376,376,376,352,352,352,346,346,346,346,346,332,332,332,332,332,332,320,320,320,320,320,320,320,320,320,320,320,320,294,294,294,286,0,288,288,296,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,378,378,378,378,380,380,380,380,380,380,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,384,384,384,384,384,3 [...]
+"44",376,376,376,376,376,376,376,376,376,376,376,376,352,352,352,346,346,346,346,346,332,332,332,332,332,332,320,320,320,320,320,320,320,320,320,320,320,320,294,294,294,288,288,0,284,296,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,378,378,378,378,380,380,380,380,380,380,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,384,384,384,384,384,3 [...]
+"45",376,376,376,376,376,376,376,376,376,376,376,376,352,352,352,346,346,346,346,346,332,332,332,332,332,332,320,320,320,320,320,320,320,320,320,320,320,320,294,294,294,288,288,284,0,296,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,378,378,378,378,380,380,380,380,380,380,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,384,384,384,384,384,3 [...]
+"46",376,376,376,376,376,376,376,376,376,376,376,376,352,352,352,346,346,346,346,346,332,332,332,332,332,332,320,320,320,320,320,320,320,320,320,320,320,320,296,296,296,296,296,296,296,0,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,378,378,378,378,380,380,380,380,380,380,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,384,384,384,384,384,3 [...]
+"47",376,376,376,376,376,376,376,376,376,376,376,376,352,352,352,346,346,346,346,346,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,0,278,280,280,282,282,282,282,282,282,282,282,282,282,282,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,378,378,378,378,380,380,380,380,380,380,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,384,384,384,384,384,3 [...]
+"48",376,376,376,376,376,376,376,376,376,376,376,376,352,352,352,346,346,346,346,346,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,278,0,280,280,282,282,282,282,282,282,282,282,282,282,282,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,378,378,378,378,380,380,380,380,380,380,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,384,384,384,384,384,3 [...]
+"49",376,376,376,376,376,376,376,376,376,376,376,376,352,352,352,346,346,346,346,346,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,280,280,0,276,282,282,282,282,282,282,282,282,282,282,282,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,378,378,378,378,380,380,380,380,380,380,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,384,384,384,384,384,3 [...]
+"50",376,376,376,376,376,376,376,376,376,376,376,376,352,352,352,346,346,346,346,346,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,280,280,276,0,282,282,282,282,282,282,282,282,282,282,282,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,378,378,378,378,380,380,380,380,380,380,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,384,384,384,384,384,3 [...]
+"51",376,376,376,376,376,376,376,376,376,376,376,376,352,352,352,346,346,346,346,346,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,282,282,282,282,0,270,270,270,270,270,272,272,272,272,274,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,378,378,378,378,380,380,380,380,380,380,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,384,384,384,384,384,3 [...]
+"52",376,376,376,376,376,376,376,376,376,376,376,376,352,352,352,346,346,346,346,346,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,282,282,282,282,270,0,264,264,266,268,272,272,272,272,274,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,378,378,378,378,380,380,380,380,380,380,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,384,384,384,384,384,3 [...]
+"53",376,376,376,376,376,376,376,376,376,376,376,376,352,352,352,346,346,346,346,346,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,282,282,282,282,270,264,0,262,266,268,272,272,272,272,274,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,378,378,378,378,380,380,380,380,380,380,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,384,384,384,384,384,3 [...]
+"54",376,376,376,376,376,376,376,376,376,376,376,376,352,352,352,346,346,346,346,346,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,282,282,282,282,270,264,262,0,266,268,272,272,272,272,274,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,378,378,378,378,380,380,380,380,380,380,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,384,384,384,384,384,3 [...]
+"55",376,376,376,376,376,376,376,376,376,376,376,376,352,352,352,346,346,346,346,346,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,282,282,282,282,270,266,266,266,0,268,272,272,272,272,274,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,378,378,378,378,380,380,380,380,380,380,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,384,384,384,384,384,3 [...]
+"56",376,376,376,376,376,376,376,376,376,376,376,376,352,352,352,346,346,346,346,346,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,282,282,282,282,270,268,268,268,268,0,272,272,272,272,274,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,378,378,378,378,380,380,380,380,380,380,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,384,384,384,384,384,3 [...]
+"57",376,376,376,376,376,376,376,376,376,376,376,376,352,352,352,346,346,346,346,346,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,282,282,282,282,272,272,272,272,272,272,0,258,258,260,274,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,378,378,378,378,380,380,380,380,380,380,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,384,384,384,384,384,3 [...]
+"58",376,376,376,376,376,376,376,376,376,376,376,376,352,352,352,346,346,346,346,346,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,282,282,282,282,272,272,272,272,272,272,258,0,256,260,274,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,378,378,378,378,380,380,380,380,380,380,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,384,384,384,384,384,3 [...]
+"59",376,376,376,376,376,376,376,376,376,376,376,376,352,352,352,346,346,346,346,346,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,282,282,282,282,272,272,272,272,272,272,258,256,0,260,274,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,378,378,378,378,380,380,380,380,380,380,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,384,384,384,384,384,3 [...]
+"60",376,376,376,376,376,376,376,376,376,376,376,376,352,352,352,346,346,346,346,346,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,282,282,282,282,272,272,272,272,272,272,260,260,260,0,274,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,378,378,378,378,380,380,380,380,380,380,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,384,384,384,384,384,3 [...]
+"61",376,376,376,376,376,376,376,376,376,376,376,376,352,352,352,346,346,346,346,346,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,282,282,282,282,274,274,274,274,274,274,274,274,274,274,0,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,378,378,378,378,380,380,380,380,380,380,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,384,384,384,384,384,3 [...]
+"62",376,376,376,376,376,376,376,376,376,376,376,376,352,352,352,346,346,346,346,346,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,0,244,246,248,250,252,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,378,378,378,378,380,380,380,380,380,380,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,384,384,384,384,384,3 [...]
+"63",376,376,376,376,376,376,376,376,376,376,376,376,352,352,352,346,346,346,346,346,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,244,0,246,248,250,252,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,378,378,378,378,380,380,380,380,380,380,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,384,384,384,384,384,3 [...]
+"64",376,376,376,376,376,376,376,376,376,376,376,376,352,352,352,346,346,346,346,346,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,246,246,0,248,250,252,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,378,378,378,378,380,380,380,380,380,380,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,384,384,384,384,384,3 [...]
+"65",376,376,376,376,376,376,376,376,376,376,376,376,352,352,352,346,346,346,346,346,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,248,248,248,0,250,252,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,378,378,378,378,380,380,380,380,380,380,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,384,384,384,384,384,3 [...]
+"66",376,376,376,376,376,376,376,376,376,376,376,376,352,352,352,346,346,346,346,346,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,250,250,250,250,0,252,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,378,378,378,378,380,380,380,380,380,380,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,384,384,384,384,384,3 [...]
+"67",376,376,376,376,376,376,376,376,376,376,376,376,352,352,352,346,346,346,346,346,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,252,252,252,252,252,0,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,378,378,378,378,380,380,380,380,380,380,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,384,384,384,384,384,3 [...]
+"68",376,376,376,376,376,376,376,376,376,376,376,376,352,352,352,346,346,346,346,346,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,254,254,254,254,254,254,0,232,234,236,238,238,238,238,238,240,240,240,242,242,242,242,242,378,378,378,378,380,380,380,380,380,380,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,384,384,384,384,384,3 [...]
+"69",376,376,376,376,376,376,376,376,376,376,376,376,352,352,352,346,346,346,346,346,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,254,254,254,254,254,254,232,0,234,236,238,238,238,238,238,240,240,240,242,242,242,242,242,378,378,378,378,380,380,380,380,380,380,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,384,384,384,384,384,3 [...]
+"70",376,376,376,376,376,376,376,376,376,376,376,376,352,352,352,346,346,346,346,346,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,254,254,254,254,254,254,234,234,0,236,238,238,238,238,238,240,240,240,242,242,242,242,242,378,378,378,378,380,380,380,380,380,380,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,384,384,384,384,384,3 [...]
+"71",376,376,376,376,376,376,376,376,376,376,376,376,352,352,352,346,346,346,346,346,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,254,254,254,254,254,254,236,236,236,0,238,238,238,238,238,240,240,240,242,242,242,242,242,378,378,378,378,380,380,380,380,380,380,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,384,384,384,384,384,3 [...]
+"72",376,376,376,376,376,376,376,376,376,376,376,376,352,352,352,346,346,346,346,346,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,254,254,254,254,254,254,238,238,238,238,0,230,230,230,230,240,240,240,242,242,242,242,242,378,378,378,378,380,380,380,380,380,380,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,384,384,384,384,384,3 [...]
+"73",376,376,376,376,376,376,376,376,376,376,376,376,352,352,352,346,346,346,346,346,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,254,254,254,254,254,254,238,238,238,238,230,0,226,228,228,240,240,240,242,242,242,242,242,378,378,378,378,380,380,380,380,380,380,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,384,384,384,384,384,3 [...]
+"74",376,376,376,376,376,376,376,376,376,376,376,376,352,352,352,346,346,346,346,346,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,254,254,254,254,254,254,238,238,238,238,230,226,0,228,228,240,240,240,242,242,242,242,242,378,378,378,378,380,380,380,380,380,380,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,384,384,384,384,384,3 [...]
+"75",376,376,376,376,376,376,376,376,376,376,376,376,352,352,352,346,346,346,346,346,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,254,254,254,254,254,254,238,238,238,238,230,228,228,0,224,240,240,240,242,242,242,242,242,378,378,378,378,380,380,380,380,380,380,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,384,384,384,384,384,3 [...]
+"76",376,376,376,376,376,376,376,376,376,376,376,376,352,352,352,346,346,346,346,346,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,254,254,254,254,254,254,238,238,238,238,230,228,228,224,0,240,240,240,242,242,242,242,242,378,378,378,378,380,380,380,380,380,380,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,384,384,384,384,384,3 [...]
+"77",376,376,376,376,376,376,376,376,376,376,376,376,352,352,352,346,346,346,346,346,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,254,254,254,254,254,254,240,240,240,240,240,240,240,240,240,0,220,222,242,242,242,242,242,378,378,378,378,380,380,380,380,380,380,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,384,384,384,384,384,3 [...]
+"78",376,376,376,376,376,376,376,376,376,376,376,376,352,352,352,346,346,346,346,346,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,254,254,254,254,254,254,240,240,240,240,240,240,240,240,240,220,0,222,242,242,242,242,242,378,378,378,378,380,380,380,380,380,380,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,384,384,384,384,384,3 [...]
+"79",376,376,376,376,376,376,376,376,376,376,376,376,352,352,352,346,346,346,346,346,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,254,254,254,254,254,254,240,240,240,240,240,240,240,240,240,222,222,0,242,242,242,242,242,378,378,378,378,380,380,380,380,380,380,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,384,384,384,384,384,3 [...]
+"80",376,376,376,376,376,376,376,376,376,376,376,376,352,352,352,346,346,346,346,346,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,254,254,254,254,254,254,242,242,242,242,242,242,242,242,242,242,242,242,0,216,216,218,218,378,378,378,378,380,380,380,380,380,380,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,384,384,384,384,384,3 [...]
+"81",376,376,376,376,376,376,376,376,376,376,376,376,352,352,352,346,346,346,346,346,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,254,254,254,254,254,254,242,242,242,242,242,242,242,242,242,242,242,242,216,0,214,218,218,378,378,378,378,380,380,380,380,380,380,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,384,384,384,384,384,3 [...]
+"82",376,376,376,376,376,376,376,376,376,376,376,376,352,352,352,346,346,346,346,346,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,254,254,254,254,254,254,242,242,242,242,242,242,242,242,242,242,242,242,216,214,0,218,218,378,378,378,378,380,380,380,380,380,380,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,384,384,384,384,384,3 [...]
+"83",376,376,376,376,376,376,376,376,376,376,376,376,352,352,352,346,346,346,346,346,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,254,254,254,254,254,254,242,242,242,242,242,242,242,242,242,242,242,242,218,218,218,0,212,378,378,378,378,380,380,380,380,380,380,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,384,384,384,384,384,3 [...]
+"84",376,376,376,376,376,376,376,376,376,376,376,376,352,352,352,346,346,346,346,346,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,254,254,254,254,254,254,242,242,242,242,242,242,242,242,242,242,242,242,218,218,218,212,0,378,378,378,378,380,380,380,380,380,380,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,384,384,384,384,384,3 [...]
+"85",378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,0,206,208,210,380,380,380,380,380,380,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,384,384,384,384,384,3 [...]
+"86",378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,206,0,208,210,380,380,380,380,380,380,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,384,384,384,384,384,3 [...]
+"87",378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,208,208,0,210,380,380,380,380,380,380,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,384,384,384,384,384,3 [...]
+"88",378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,210,210,210,0,380,380,380,380,380,380,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,384,384,384,384,384,3 [...]
+"89",380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,0,200,200,202,204,204,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,384,384,384,384,384,3 [...]
+"90",380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,200,0,198,202,204,204,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,384,384,384,384,384,3 [...]
+"91",380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,200,198,0,202,204,204,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,384,384,384,384,384,3 [...]
+"92",380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,202,202,202,0,204,204,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,384,384,384,384,384,3 [...]
+"93",380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,204,204,204,204,0,196,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,384,384,384,384,384,3 [...]
+"94",380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,204,204,204,204,196,0,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,384,384,384,384,384,3 [...]
+"95",382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,0,190,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,194,384,384,384,384,384,3 [...]
+"96",382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,190,0,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,194,384,384,384,384,384,3 [...]
+"97",382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,192,192,0,170,172,174,176,176,178,178,180,180,182,182,182,182,184,184,186,186,188,188,194,384,384,384,384,384,3 [...]
+"98",382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,192,192,170,0,172,174,176,176,178,178,180,180,182,182,182,182,184,184,186,186,188,188,194,384,384,384,384,384,3 [...]
+"99",382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,192,192,172,172,0,174,176,176,178,178,180,180,182,182,182,182,184,184,186,186,188,188,194,384,384,384,384,384,3 [...]
+"100",382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,192,192,174,174,174,0,176,176,178,178,180,180,182,182,182,182,184,184,186,186,188,188,194,384,384,384,384,384, [...]
+"101",382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,192,192,176,176,176,176,0,168,178,178,180,180,182,182,182,182,184,184,186,186,188,188,194,384,384,384,384,384, [...]
+"102",382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,192,192,176,176,176,176,168,0,178,178,180,180,182,182,182,182,184,184,186,186,188,188,194,384,384,384,384,384, [...]
+"103",382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,192,192,178,178,178,178,178,178,0,166,180,180,182,182,182,182,184,184,186,186,188,188,194,384,384,384,384,384, [...]
+"104",382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,192,192,178,178,178,178,178,178,166,0,180,180,182,182,182,182,184,184,186,186,188,188,194,384,384,384,384,384, [...]
+"105",382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,192,192,180,180,180,180,180,180,180,180,0,164,182,182,182,182,184,184,186,186,188,188,194,384,384,384,384,384, [...]
+"106",382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,192,192,180,180,180,180,180,180,180,180,164,0,182,182,182,182,184,184,186,186,188,188,194,384,384,384,384,384, [...]
+"107",382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,192,192,182,182,182,182,182,182,182,182,182,182,0,160,162,162,184,184,186,186,188,188,194,384,384,384,384,384, [...]
+"108",382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,192,192,182,182,182,182,182,182,182,182,182,182,160,0,162,162,184,184,186,186,188,188,194,384,384,384,384,384, [...]
+"109",382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,192,192,182,182,182,182,182,182,182,182,182,182,162,162,0,158,184,184,186,186,188,188,194,384,384,384,384,384, [...]
+"110",382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,192,192,182,182,182,182,182,182,182,182,182,182,162,162,158,0,184,184,186,186,188,188,194,384,384,384,384,384, [...]
+"111",382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,192,192,184,184,184,184,184,184,184,184,184,184,184,184,184,184,0,156,186,186,188,188,194,384,384,384,384,384, [...]
+"112",382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,192,192,184,184,184,184,184,184,184,184,184,184,184,184,184,184,156,0,186,186,188,188,194,384,384,384,384,384, [...]
+"113",382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,192,192,186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,0,154,188,188,194,384,384,384,384,384, [...]
+"114",382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,192,192,186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,154,0,188,188,194,384,384,384,384,384, [...]
+"115",382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,192,192,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,0,152,194,384,384,384,384,384, [...]
+"116",382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,192,192,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,152,0,194,384,384,384,384,384, [...]
+"117",382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,0,384,384,384,384,384, [...]
+"118",384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,0,144,144,144,144, [...]
+"119",384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,144,0,136,138,138, [...]
+"120",384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,144,136,0,138,138, [...]
+"121",384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,144,138,138,0,128, [...]
+"122",384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,144,138,138,128,0, [...]
+"123",384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,144,138,138,128,12 [...]
+"124",384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,144,138,138,128,12 [...]
+"125",384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,144,138,138,128,12 [...]
+"126",384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,144,138,138,130,13 [...]
+"127",384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,144,138,138,130,13 [...]
+"128",384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,144,138,138,132,13 [...]
+"129",384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,144,138,138,134,13 [...]
+"130",384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,144,140,140,140,14 [...]
+"131",384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,144,142,142,142,14 [...]
+"132",384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,144,142,142,142,14 [...]
+"133",384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,144,142,142,142,14 [...]
+"134",384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,146,146,146,146,14 [...]
+"135",384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,146,146,146,146,14 [...]
+"136",384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,148,148,148,148,14 [...]
+"137",384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,148,148,148,148,14 [...]
+"138",384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,148,148,148,148,14 [...]
+"139",384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,148,148,148,148,14 [...]
+"140",384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,148,148,148,148,14 [...]
+"141",384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,148,148,148,148,14 [...]
+"142",384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,148,148,148,148,14 [...]
+"143",384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,148,148,148,148,14 [...]
+"144",384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,148,148,148,148,14 [...]
+"145",384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,148,148,148,148,14 [...]
+"146",384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,148,148,148,148,14 [...]
+"147",384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,148,148,148,148,14 [...]
+"148",384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,148,148,148,148,14 [...]
+"149",384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,148,148,148,148,14 [...]
+"150",384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,148,148,148,148,14 [...]
+"151",384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,148,148,148,148,14 [...]
+"152",384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,150,150,150,150,15 [...]
+"153",384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,150,150,150,150,15 [...]
+"154",384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,150,150,150,150,15 [...]
+"155",384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,150,150,150,150,15 [...]
+"156",384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,150,150,150,150,15 [...]
+"157",384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,150,150,150,150,15 [...]
+"158",384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,150,150,150,150,15 [...]
+"159",384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,150,150,150,150,15 [...]
+"160",384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,150,150,150,150,15 [...]
+"161",384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,150,150,150,150,15 [...]
+"162",384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,150,150,150,150,15 [...]
+"163",384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,150,150,150,150,15 [...]
+"164",384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,150,150,150,150,15 [...]
+"165",384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,150,150,150,150,15 [...]
+"166",384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,150,150,150,150,15 [...]
+"167",384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,150,150,150,150,15 [...]
+"168",384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,150,150,150,150,15 [...]
+"169",384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,150,150,150,150,15 [...]
+"170",384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,150,150,150,150,15 [...]
+"171",384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,150,150,150,150,15 [...]
+"172",384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,150,150,150,150,15 [...]
+"173",384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,150,150,150,150,15 [...]
+"174",384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,150,150,150,150,15 [...]
+"175",384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,150,150,150,150,15 [...]
+"176",384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,150,150,150,150,15 [...]
+"177",384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,150,150,150,150,15 [...]
+"178",384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,150,150,150,150,15 [...]
+"179",384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,150,150,150,150,15 [...]
+"180",384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,150,150,150,150,15 [...]
+"181",384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,150,150,150,150,15 [...]
+"182",384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,150,150,150,150,15 [...]
+"183",384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,150,150,150,150,15 [...]
+"184",384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,150,150,150,150,15 [...]
+"185",384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,150,150,150,150,15 [...]
+"186",384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,150,150,150,150,15 [...]
+"187",384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,150,150,150,150,15 [...]
+"188",384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,150,150,150,150,15 [...]
+"189",384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,150,150,150,150,15 [...]
+"190",384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,150,150,150,150,15 [...]
+"191",384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,150,150,150,150,15 [...]
+"192",384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,150,150,150,150,15 [...]
+"193",384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,150,150,150,150,15 [...]
+"194",192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,19 [...]
+"195",191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,193,193,193,193,19 [...]
+"196",190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,194,194,194,194,19 [...]
+"197",189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,191,191,191,191,191,191,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,195,195,195,195,19 [...]
+"198",188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,190,190,190,190,192,192,192,192,192,192,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,196,196,196,196,19 [...]
+"199",187,187,187,187,187,187,187,187,187,187,187,187,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,191,191,191,191,193,193,193,193,193,193,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,197,197,197,197,19 [...]
+"200",186,186,186,186,186,186,186,186,188,188,188,188,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,192,192,192,192,194,194,194,194,194,194,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,198,198,198,198,19 [...]
+"201",185,185,185,185,185,185,185,187,189,189,189,189,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,193,193,193,193,195,195,195,195,195,195,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,199,199,199,199,19 [...]
+"202",184,184,184,184,184,186,186,188,190,190,190,190,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,194,194,194,194,196,196,196,196,196,196,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,200,200,200,200,20 [...]
+"203",183,183,183,183,185,187,187,189,191,191,191,191,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,195,195,195,195,197,197,197,197,197,197,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,201,201,201,201,20 [...]
+"204",182,182,184,184,186,188,188,190,192,192,192,192,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,196,196,196,196,198,198,198,198,198,198,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,202,202,202,202,20 [...]
+"205",185,185,181,181,187,189,189,191,193,193,193,193,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,197,197,197,197,199,199,199,199,199,199,201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,203,203,203,203,20 [...]
+"206",190,190,190,190,190,180,180,192,194,194,194,194,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,198,198,198,198,200,200,200,200,200,200,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,204,204,204,204,20 [...]
+"207",195,195,195,195,195,195,195,195,179,179,179,179,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,199,199,199,199,201,201,201,201,201,201,203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,205,205,205,205,20 [...]
+"208",196,196,196,196,196,196,196,196,180,178,178,178,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,200,200,200,200,202,202,202,202,202,202,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,206,206,206,206,20 [...]
+"209",197,197,197,197,197,197,197,197,181,179,177,177,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,201,201,201,201,203,203,203,203,203,203,205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,207,207,207,207,20 [...]
+"210",200,200,200,200,200,200,200,200,200,200,200,200,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,202,202,202,202,204,204,204,204,204,204,206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,208,208,208,208,20 [...]
+"211",201,201,201,201,201,201,201,201,201,201,201,201,175,175,175,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,203,203,203,203,205,205,205,205,205,205,207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,209,209,209,209,20 [...]
+"212",202,202,202,202,202,202,202,202,202,202,202,202,174,174,176,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,204,204,204,204,206,206,206,206,206,206,208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,210,210,210,210,21 [...]
+"213",203,203,203,203,203,203,203,203,203,203,203,203,179,179,179,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,205,205,205,205,207,207,207,207,207,207,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,211,211,211,211,21 [...]
+"214",204,204,204,204,204,204,204,204,204,204,204,204,180,180,180,172,172,172,172,172,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,206,206,206,206,208,208,208,208,208,208,210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,212,212,212,212,21 [...]
+"215",205,205,205,205,205,205,205,205,205,205,205,205,181,181,181,171,171,171,173,173,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,207,207,207,207,209,209,209,209,209,209,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,213,213,213,213,21 [...]
+"216",206,206,206,206,206,206,206,206,206,206,206,206,182,182,182,170,170,172,174,174,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,208,208,208,208,210,210,210,210,210,210,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,214,214,214,214,21 [...]
+"217",207,207,207,207,207,207,207,207,207,207,207,207,183,183,183,175,175,175,169,169,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,209,209,209,209,211,211,211,211,211,211,213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,215,215,215,215,21 [...]
+"218",208,208,208,208,208,208,208,208,208,208,208,208,184,184,184,178,178,178,178,178,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,210,210,210,210,212,212,212,212,212,212,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,216,216,216,216,21 [...]
+"219",209,209,209,209,209,209,209,209,209,209,209,209,185,185,185,179,179,179,179,179,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,211,211,211,211,213,213,213,213,213,213,215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,217,217,217,217,21 [...]
+"220",210,210,210,210,210,210,210,210,210,210,210,210,186,186,186,180,180,180,180,180,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,212,212,212,212,214,214,214,214,214,214,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,218,218,218,218,21 [...]
+"221",211,211,211,211,211,211,211,211,211,211,211,211,187,187,187,181,181,181,181,181,165,165,165,165,165,165,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,213,213,213,213,215,215,215,215,215,215,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,219,219,219,219,21 [...]
+"222",212,212,212,212,212,212,212,212,212,212,212,212,188,188,188,182,182,182,182,182,164,164,164,166,166,166,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,214,214,214,214,216,216,216,216,216,216,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,220,220,220,220,22 [...]
+"223",213,213,213,213,213,213,213,213,213,213,213,213,189,189,189,183,183,183,183,183,163,163,165,167,167,167,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,215,215,215,215,217,217,217,217,217,217,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,221,221,221,221,22 [...]
+"224",214,214,214,214,214,214,214,214,214,214,214,214,190,190,190,184,184,184,184,184,168,168,168,162,162,162,170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,216,216,216,216,218,218,218,218,218,218,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,222,222,222,222,22 [...]
+"225",215,215,215,215,215,215,215,215,215,215,215,215,191,191,191,185,185,185,185,185,169,169,169,163,161,161,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,217,217,217,217,219,219,219,219,219,219,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,223,223,223,223,22 [...]
+"226",216,216,216,216,216,216,216,216,216,216,216,216,192,192,192,186,186,186,186,186,172,172,172,172,172,172,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,218,218,218,218,220,220,220,220,220,220,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,224,224,224,224,22 [...]
+"227",217,217,217,217,217,217,217,217,217,217,217,217,193,193,193,187,187,187,187,187,173,173,173,173,173,173,159,159,159,159,159,159,159,159,159,159,159,159,161,161,161,161,161,161,161,161,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,219,219,219,219,221,221,221,221,221,221,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,225,225,225,225,22 [...]
+"228",218,218,218,218,218,218,218,218,218,218,218,218,194,194,194,188,188,188,188,188,174,174,174,174,174,174,158,158,158,158,158,158,160,160,160,160,160,160,162,162,162,162,162,162,162,162,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,220,220,220,220,222,222,222,222,222,222,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,226,226,226,226,22 [...]
+"229",219,219,219,219,219,219,219,219,219,219,219,219,195,195,195,189,189,189,189,189,175,175,175,175,175,175,157,157,157,157,159,159,161,161,161,161,161,161,163,163,163,163,163,163,163,163,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,221,221,221,221,223,223,223,223,223,223,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,227,227,227,227,22 [...]
+"230",220,220,220,220,220,220,220,220,220,220,220,220,196,196,196,190,190,190,190,190,176,176,176,176,176,176,158,156,156,156,160,160,162,162,162,162,162,162,164,164,164,164,164,164,164,164,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,222,222,222,222,224,224,224,224,224,224,226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,228,228,228,228,22 [...]
+"231",221,221,221,221,221,221,221,221,221,221,221,221,197,197,197,191,191,191,191,191,177,177,177,177,177,177,159,155,155,157,161,161,163,163,163,163,163,163,165,165,165,165,165,165,165,165,179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,223,223,223,223,225,225,225,225,225,225,227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,229,229,229,229,22 [...]
+"232",222,222,222,222,222,222,222,222,222,222,222,222,198,198,198,192,192,192,192,192,178,178,178,178,178,178,162,162,162,162,154,154,164,164,164,164,164,164,166,166,166,166,166,166,166,166,180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,224,224,224,224,226,226,226,226,226,226,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,230,230,230,230,23 [...]
+"233",223,223,223,223,223,223,223,223,223,223,223,223,199,199,199,193,193,193,193,193,179,179,179,179,179,179,165,165,165,165,165,165,153,153,153,153,153,153,167,167,167,167,167,167,167,167,181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,225,225,225,225,227,227,227,227,227,227,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,231,231,231,231,23 [...]
+"234",224,224,224,224,224,224,224,224,224,224,224,224,200,200,200,194,194,194,194,194,180,180,180,180,180,180,166,166,166,166,166,166,154,152,152,152,152,152,168,168,168,168,168,168,168,168,182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,226,226,226,226,228,228,228,228,228,228,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,232,232,232,232,23 [...]
+"235",225,225,225,225,225,225,225,225,225,225,225,225,201,201,201,195,195,195,195,195,181,181,181,181,181,181,167,167,167,167,167,167,155,151,151,151,153,153,169,169,169,169,169,169,169,169,183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,227,227,227,227,229,229,229,229,229,229,231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,233,233,233,233,23 [...]
+"236",226,226,226,226,226,226,226,226,226,226,226,226,202,202,202,196,196,196,196,196,182,182,182,182,182,182,168,168,168,168,168,168,156,150,150,152,154,154,170,170,170,170,170,170,170,170,184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,228,228,228,228,230,230,230,230,230,230,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,234,234,234,234,23 [...]
+"237",227,227,227,227,227,227,227,227,227,227,227,227,203,203,203,197,197,197,197,197,183,183,183,183,183,183,169,169,169,169,169,169,157,155,155,155,149,149,171,171,171,171,171,171,171,171,185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,229,229,229,229,231,231,231,231,231,231,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,235,235,235,235,23 [...]
+"238",228,228,228,228,228,228,228,228,228,228,228,228,204,204,204,198,198,198,198,198,184,184,184,184,184,184,172,172,172,172,172,172,172,172,172,172,172,172,148,148,148,148,148,148,148,148,186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,230,230,230,230,232,232,232,232,232,232,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,236,236,236,236,23 [...]
+"239",229,229,229,229,229,229,229,229,229,229,229,229,205,205,205,199,199,199,199,199,185,185,185,185,185,185,173,173,173,173,173,173,173,173,173,173,173,173,147,147,147,147,147,147,147,149,187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,231,231,231,231,233,233,233,233,233,233,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,237,237,237,237,23 [...]
+"240",230,230,230,230,230,230,230,230,230,230,230,230,206,206,206,200,200,200,200,200,186,186,186,186,186,186,174,174,174,174,174,174,174,174,174,174,174,174,146,146,146,148,148,148,148,150,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,232,232,232,232,234,234,234,234,234,234,236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,238,238,238,238,23 [...]
+"241",231,231,231,231,231,231,231,231,231,231,231,231,207,207,207,201,201,201,201,201,187,187,187,187,187,187,175,175,175,175,175,175,175,175,175,175,175,175,147,145,145,149,149,149,149,151,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,233,233,233,233,235,235,235,235,235,235,237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,239,239,239,239,23 [...]
+"242",232,232,232,232,232,232,232,232,232,232,232,232,208,208,208,202,202,202,202,202,188,188,188,188,188,188,176,176,176,176,176,176,176,176,176,176,176,176,150,150,150,144,144,144,144,152,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,234,234,234,234,236,236,236,236,236,236,238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,240,240,240,240,24 [...]
+"243",233,233,233,233,233,233,233,233,233,233,233,233,209,209,209,203,203,203,203,203,189,189,189,189,189,189,177,177,177,177,177,177,177,177,177,177,177,177,151,151,151,143,143,145,145,153,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,235,235,235,235,237,237,237,237,237,237,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,241,241,241,241,24 [...]
+"244",234,234,234,234,234,234,234,234,234,234,234,234,210,210,210,204,204,204,204,204,190,190,190,190,190,190,178,178,178,178,178,178,178,178,178,178,178,178,152,152,152,146,146,142,142,154,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,236,236,236,236,238,238,238,238,238,238,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,242,242,242,242,24 [...]
+"245",235,235,235,235,235,235,235,235,235,235,235,235,211,211,211,205,205,205,205,205,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,237,237,237,237,239,239,239,239,239,239,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,243,243,243,243,24 [...]
+"246",236,236,236,236,236,236,236,236,236,236,236,236,212,212,212,206,206,206,206,206,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,140,140,140,140,142,142,142,142,142,142,142,142,142,142,142,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,238,238,238,238,240,240,240,240,240,240,242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,244,244,244,244,24 [...]
+"247",237,237,237,237,237,237,237,237,237,237,237,237,213,213,213,207,207,207,207,207,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,139,139,141,141,143,143,143,143,143,143,143,143,143,143,143,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,239,239,239,239,241,241,241,241,241,241,243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,245,245,245,245,24 [...]
+"248",238,238,238,238,238,238,238,238,238,238,238,238,214,214,214,208,208,208,208,208,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,142,142,138,138,144,144,144,144,144,144,144,144,144,144,144,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,240,240,240,240,242,242,242,242,242,242,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,246,246,246,246,24 [...]
+"249",239,239,239,239,239,239,239,239,239,239,239,239,215,215,215,209,209,209,209,209,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,145,145,145,145,137,137,137,137,137,137,137,137,137,137,137,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,241,241,241,241,243,243,243,243,243,243,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,247,247,247,247,24 [...]
+"250",240,240,240,240,240,240,240,240,240,240,240,240,216,216,216,210,210,210,210,210,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,146,146,146,146,136,136,136,136,136,136,136,136,136,136,138,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,242,242,242,242,244,244,244,244,244,244,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,248,248,248,248,24 [...]
+"251",241,241,241,241,241,241,241,241,241,241,241,241,217,217,217,211,211,211,211,211,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,147,147,147,147,135,135,135,135,135,135,137,137,137,137,139,201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,243,243,243,243,245,245,245,245,245,245,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,249,249,249,249,24 [...]
+"252",242,242,242,242,242,242,242,242,242,242,242,242,218,218,218,212,212,212,212,212,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,148,148,148,148,136,134,134,134,134,134,138,138,138,138,140,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,244,244,244,244,246,246,246,246,246,246,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,250,250,250,250,25 [...]
+"253",243,243,243,243,243,243,243,243,243,243,243,243,219,219,219,213,213,213,213,213,201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,149,149,149,149,137,133,133,133,133,135,139,139,139,139,141,203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,245,245,245,245,247,247,247,247,247,247,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,251,251,251,251,25 [...]
+"254",244,244,244,244,244,244,244,244,244,244,244,244,220,220,220,214,214,214,214,214,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,150,150,150,150,138,132,132,132,134,136,140,140,140,140,142,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,246,246,246,246,248,248,248,248,248,248,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,252,252,252,252,25 [...]
+"255",245,245,245,245,245,245,245,245,245,245,245,245,221,221,221,215,215,215,215,215,203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,151,151,151,151,139,133,131,131,135,137,141,141,141,141,143,205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,247,247,247,247,249,249,249,249,249,249,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,253,253,253,253,25 [...]
+"256",246,246,246,246,246,246,246,246,246,246,246,246,222,222,222,216,216,216,216,216,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,152,152,152,152,142,142,142,142,142,142,130,130,130,130,144,206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,248,248,248,248,250,250,250,250,250,250,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,254,254,254,254,25 [...]
+"257",247,247,247,247,247,247,247,247,247,247,247,247,223,223,223,217,217,217,217,217,205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,153,153,153,153,143,143,143,143,143,143,129,129,129,131,145,207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,249,249,249,249,251,251,251,251,251,251,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,255,255,255,255,25 [...]
+"258",248,248,248,248,248,248,248,248,248,248,248,248,224,224,224,218,218,218,218,218,206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,154,154,154,154,144,144,144,144,144,144,130,128,128,132,146,208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,250,250,250,250,252,252,252,252,252,252,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,256,256,256,256,25 [...]
+"259",249,249,249,249,249,249,249,249,249,249,249,249,225,225,225,219,219,219,219,219,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,251,251,251,251,253,253,253,253,253,253,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,257,257,257,257,25 [...]
+"260",250,250,250,250,250,250,250,250,250,250,250,250,226,226,226,220,220,220,220,220,210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,126,126,126,126,126,126,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,252,252,252,252,254,254,254,254,254,254,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,258,258,258,258,25 [...]
+"261",251,251,251,251,251,251,251,251,251,251,251,251,227,227,227,221,221,221,221,221,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,125,125,125,125,125,127,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,253,253,253,253,255,255,255,255,255,255,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,259,259,259,259,25 [...]
+"262",252,252,252,252,252,252,252,252,252,252,252,252,228,228,228,222,222,222,222,222,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,124,124,124,124,126,128,130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,254,254,254,254,256,256,256,256,256,256,258,258,258,258,258,258,258,258,258,258,258,258,258,258,258,258,258,258,258,258,258,258,258,260,260,260,260,26 [...]
+"263",253,253,253,253,253,253,253,253,253,253,253,253,229,229,229,223,223,223,223,223,213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,123,123,123,125,127,129,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,255,255,255,255,257,257,257,257,257,257,259,259,259,259,259,259,259,259,259,259,259,259,259,259,259,259,259,259,259,259,259,259,259,261,261,261,261,26 [...]
+"264",254,254,254,254,254,254,254,254,254,254,254,254,230,230,230,224,224,224,224,224,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,122,122,124,126,128,130,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,256,256,256,256,258,258,258,258,258,258,260,260,260,260,260,260,260,260,260,260,260,260,260,260,260,260,260,260,260,260,260,260,260,262,262,262,262,26 [...]
+"265",255,255,255,255,255,255,255,255,255,255,255,255,231,231,231,225,225,225,225,225,215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,133,133,133,133,133,133,121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,257,257,257,257,259,259,259,259,259,259,261,261,261,261,261,261,261,261,261,261,261,261,261,261,261,261,261,261,261,261,261,261,261,263,263,263,263,26 [...]
+"266",256,256,256,256,256,256,256,256,256,256,256,256,232,232,232,226,226,226,226,226,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,134,134,134,134,134,134,120,120,120,120,120,120,120,120,120,120,120,120,122,122,122,122,122,258,258,258,258,260,260,260,260,260,260,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,264,264,264,264,26 [...]
+"267",257,257,257,257,257,257,257,257,257,257,257,257,233,233,233,227,227,227,227,227,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,135,135,135,135,135,135,119,119,119,119,119,119,119,119,119,121,121,121,123,123,123,123,123,259,259,259,259,261,261,261,261,261,261,263,263,263,263,263,263,263,263,263,263,263,263,263,263,263,263,263,263,263,263,263,263,263,265,265,265,265,26 [...]
+"268",258,258,258,258,258,258,258,258,258,258,258,258,234,234,234,228,228,228,228,228,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,136,136,136,136,136,136,118,118,118,118,120,120,120,120,120,122,122,122,124,124,124,124,124,260,260,260,260,262,262,262,262,262,262,264,264,264,264,264,264,264,264,264,264,264,264,264,264,264,264,264,264,264,264,264,264,264,266,266,266,266,26 [...]
+"269",259,259,259,259,259,259,259,259,259,259,259,259,235,235,235,229,229,229,229,229,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,137,137,137,137,137,137,117,117,117,119,121,121,121,121,121,123,123,123,125,125,125,125,125,261,261,261,261,263,263,263,263,263,263,265,265,265,265,265,265,265,265,265,265,265,265,265,265,265,265,265,265,265,265,265,265,265,267,267,267,267,26 [...]
+"270",260,260,260,260,260,260,260,260,260,260,260,260,236,236,236,230,230,230,230,230,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,138,138,138,138,138,138,116,116,118,120,122,122,122,122,122,124,124,124,126,126,126,126,126,262,262,262,262,264,264,264,264,264,264,266,266,266,266,266,266,266,266,266,266,266,266,266,266,266,266,266,266,266,266,266,266,266,268,268,268,268,26 [...]
+"271",261,261,261,261,261,261,261,261,261,261,261,261,237,237,237,231,231,231,231,231,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,139,139,139,139,139,139,123,123,123,123,115,115,115,115,115,125,125,125,127,127,127,127,127,263,263,263,263,265,265,265,265,265,265,267,267,267,267,267,267,267,267,267,267,267,267,267,267,267,267,267,267,267,267,267,267,267,269,269,269,269,26 [...]
+"272",262,262,262,262,262,262,262,262,262,262,262,262,238,238,238,232,232,232,232,232,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,140,140,140,140,140,140,124,124,124,124,116,114,114,114,114,126,126,126,128,128,128,128,128,264,264,264,264,266,266,266,266,266,266,268,268,268,268,268,268,268,268,268,268,268,268,268,268,268,268,268,268,268,268,268,268,268,270,270,270,270,27 [...]
+"273",263,263,263,263,263,263,263,263,263,263,263,263,239,239,239,233,233,233,233,233,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,141,141,141,141,141,141,125,125,125,125,117,113,113,115,115,127,127,127,129,129,129,129,129,265,265,265,265,267,267,267,267,267,267,269,269,269,269,269,269,269,269,269,269,269,269,269,269,269,269,269,269,269,269,269,269,269,271,271,271,271,27 [...]
+"274",264,264,264,264,264,264,264,264,264,264,264,264,240,240,240,234,234,234,234,234,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,142,142,142,142,142,142,126,126,126,126,118,116,116,112,112,128,128,128,130,130,130,130,130,266,266,266,266,268,268,268,268,268,268,270,270,270,270,270,270,270,270,270,270,270,270,270,270,270,270,270,270,270,270,270,270,270,272,272,272,272,27 [...]
+"275",265,265,265,265,265,265,265,265,265,265,265,265,241,241,241,235,235,235,235,235,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,143,143,143,143,143,143,129,129,129,129,129,129,129,129,129,111,111,111,131,131,131,131,131,267,267,267,267,269,269,269,269,269,269,271,271,271,271,271,271,271,271,271,271,271,271,271,271,271,271,271,271,271,271,271,271,271,273,273,273,273,27 [...]
+"276",266,266,266,266,266,266,266,266,266,266,266,266,242,242,242,236,236,236,236,236,226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,144,144,144,144,144,144,130,130,130,130,130,130,130,130,130,110,110,112,132,132,132,132,132,268,268,268,268,270,270,270,270,270,270,272,272,272,272,272,272,272,272,272,272,272,272,272,272,272,272,272,272,272,272,272,272,272,274,274,274,274,27 [...]
+"277",267,267,267,267,267,267,267,267,267,267,267,267,243,243,243,237,237,237,237,237,227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,145,145,145,145,145,145,133,133,133,133,133,133,133,133,133,133,133,133,109,109,109,109,109,269,269,269,269,271,271,271,271,271,271,273,273,273,273,273,273,273,273,273,273,273,273,273,273,273,273,273,273,273,273,273,273,273,275,275,275,275,27 [...]
+"278",268,268,268,268,268,268,268,268,268,268,268,268,244,244,244,238,238,238,238,238,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,146,146,146,146,146,146,134,134,134,134,134,134,134,134,134,134,134,134,108,108,108,110,110,270,270,270,270,272,272,272,272,272,272,274,274,274,274,274,274,274,274,274,274,274,274,274,274,274,274,274,274,274,274,274,274,274,276,276,276,276,27 [...]
+"279",269,269,269,269,269,269,269,269,269,269,269,269,245,245,245,239,239,239,239,239,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,147,147,147,147,147,147,135,135,135,135,135,135,135,135,135,135,135,135,109,107,107,111,111,271,271,271,271,273,273,273,273,273,273,275,275,275,275,275,275,275,275,275,275,275,275,275,275,275,275,275,275,275,275,275,275,275,277,277,277,277,27 [...]
+"280",270,270,270,270,270,270,270,270,270,270,270,270,246,246,246,240,240,240,240,240,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,148,148,148,148,148,148,136,136,136,136,136,136,136,136,136,136,136,136,112,112,112,106,106,272,272,272,272,274,274,274,274,274,274,276,276,276,276,276,276,276,276,276,276,276,276,276,276,276,276,276,276,276,276,276,276,276,278,278,278,278,27 [...]
+"281",273,273,273,273,273,273,273,273,273,273,273,273,273,273,273,273,273,273,273,273,273,273,273,273,273,273,273,273,273,273,273,273,273,273,273,273,273,273,273,273,273,273,273,273,273,273,273,273,273,273,273,273,273,273,273,273,273,273,273,273,273,273,273,273,273,273,273,273,273,273,273,273,273,273,273,273,273,273,273,273,273,273,273,273,105,105,105,105,275,275,275,275,275,275,277,277,277,277,277,277,277,277,277,277,277,277,277,277,277,277,277,277,277,277,277,277,277,279,279,279,279,27 [...]
+"282",274,274,274,274,274,274,274,274,274,274,274,274,274,274,274,274,274,274,274,274,274,274,274,274,274,274,274,274,274,274,274,274,274,274,274,274,274,274,274,274,274,274,274,274,274,274,274,274,274,274,274,274,274,274,274,274,274,274,274,274,274,274,274,274,274,274,274,274,274,274,274,274,274,274,274,274,274,274,274,274,274,274,274,274,104,104,104,106,276,276,276,276,276,276,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,280,280,280,280,28 [...]
+"283",275,275,275,275,275,275,275,275,275,275,275,275,275,275,275,275,275,275,275,275,275,275,275,275,275,275,275,275,275,275,275,275,275,275,275,275,275,275,275,275,275,275,275,275,275,275,275,275,275,275,275,275,275,275,275,275,275,275,275,275,275,275,275,275,275,275,275,275,275,275,275,275,275,275,275,275,275,275,275,275,275,275,275,275,103,103,105,107,277,277,277,277,277,277,279,279,279,279,279,279,279,279,279,279,279,279,279,279,279,279,279,279,279,279,279,279,279,281,281,281,281,28 [...]
+"284",278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,102,102,102,102,102,102,280,280,280,280,280,280,280,280,280,280,280,280,280,280,280,280,280,280,280,280,280,280,280,282,282,282,282,28 [...]
+"285",279,279,279,279,279,279,279,279,279,279,279,279,279,279,279,279,279,279,279,279,279,279,279,279,279,279,279,279,279,279,279,279,279,279,279,279,279,279,279,279,279,279,279,279,279,279,279,279,279,279,279,279,279,279,279,279,279,279,279,279,279,279,279,279,279,279,279,279,279,279,279,279,279,279,279,279,279,279,279,279,279,279,279,279,279,279,279,279,101,101,101,101,103,103,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,283,283,283,283,28 [...]
+"286",280,280,280,280,280,280,280,280,280,280,280,280,280,280,280,280,280,280,280,280,280,280,280,280,280,280,280,280,280,280,280,280,280,280,280,280,280,280,280,280,280,280,280,280,280,280,280,280,280,280,280,280,280,280,280,280,280,280,280,280,280,280,280,280,280,280,280,280,280,280,280,280,280,280,280,280,280,280,280,280,280,280,280,280,280,280,280,280,100,100,100,102,104,104,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,284,284,284,284,28 [...]
+"287",281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,101,99,99,103,105,105,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,285,285,285,285,285, [...]
+"288",282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,106,106,106,106,98,98,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,286,286,286,286,286, [...]
+"289",285,285,285,285,285,285,285,285,285,285,285,285,285,285,285,285,285,285,285,285,285,285,285,285,285,285,285,285,285,285,285,285,285,285,285,285,285,285,285,285,285,285,285,285,285,285,285,285,285,285,285,285,285,285,285,285,285,285,285,285,285,285,285,285,285,285,285,285,285,285,285,285,285,285,285,285,285,285,285,285,285,285,285,285,285,285,285,285,285,285,285,285,285,285,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,287,287,287,287,287,287,287,287,287,287,2 [...]
+"290",286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,98,288,288,288,288,288,288,288,288,288,288,2 [...]
+"291",287,287,287,287,287,287,287,287,287,287,287,287,287,287,287,287,287,287,287,287,287,287,287,287,287,287,287,287,287,287,287,287,287,287,287,287,287,287,287,287,287,287,287,287,287,287,287,287,287,287,287,287,287,287,287,287,287,287,287,287,287,287,287,287,287,287,287,287,287,287,287,287,287,287,287,287,287,287,287,287,287,287,287,287,287,287,287,287,287,287,287,287,287,287,95,95,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,99,289,289,289,289,289,289,289,289,289,289,2 [...]
+"292",288,288,288,288,288,288,288,288,288,288,288,288,288,288,288,288,288,288,288,288,288,288,288,288,288,288,288,288,288,288,288,288,288,288,288,288,288,288,288,288,288,288,288,288,288,288,288,288,288,288,288,288,288,288,288,288,288,288,288,288,288,288,288,288,288,288,288,288,288,288,288,288,288,288,288,288,288,288,288,288,288,288,288,288,288,288,288,288,288,288,288,288,288,288,98,98,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,100,290,290,290,290,290,290,290,290,290,290, [...]
+"293",289,289,289,289,289,289,289,289,289,289,289,289,289,289,289,289,289,289,289,289,289,289,289,289,289,289,289,289,289,289,289,289,289,289,289,289,289,289,289,289,289,289,289,289,289,289,289,289,289,289,289,289,289,289,289,289,289,289,289,289,289,289,289,289,289,289,289,289,289,289,289,289,289,289,289,289,289,289,289,289,289,289,289,289,289,289,289,289,289,289,289,289,289,289,99,99,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,95,95,101,291,291,291,291,291,291,291,291,291,291, [...]
+"294",290,290,290,290,290,290,290,290,290,290,290,290,290,290,290,290,290,290,290,290,290,290,290,290,290,290,290,290,290,290,290,290,290,290,290,290,290,290,290,290,290,290,290,290,290,290,290,290,290,290,290,290,290,290,290,290,290,290,290,290,290,290,290,290,290,290,290,290,290,290,290,290,290,290,290,290,290,290,290,290,290,290,290,290,290,290,290,290,290,290,290,290,290,290,100,100,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,94,94,96,96,102,292,292,292,292,292,292,292,292,292,29 [...]
+"295",291,291,291,291,291,291,291,291,291,291,291,291,291,291,291,291,291,291,291,291,291,291,291,291,291,291,291,291,291,291,291,291,291,291,291,291,291,291,291,291,291,291,291,291,291,291,291,291,291,291,291,291,291,291,291,291,291,291,291,291,291,291,291,291,291,291,291,291,291,291,291,291,291,291,291,291,291,291,291,291,291,291,291,291,291,291,291,291,291,291,291,291,291,291,101,101,91,91,91,91,91,91,91,91,91,91,91,91,91,91,93,93,95,95,97,97,103,293,293,293,293,293,293,293,293,293,29 [...]
+"296",292,292,292,292,292,292,292,292,292,292,292,292,292,292,292,292,292,292,292,292,292,292,292,292,292,292,292,292,292,292,292,292,292,292,292,292,292,292,292,292,292,292,292,292,292,292,292,292,292,292,292,292,292,292,292,292,292,292,292,292,292,292,292,292,292,292,292,292,292,292,292,292,292,292,292,292,292,292,292,292,292,292,292,292,292,292,292,292,292,292,292,292,292,292,102,102,90,90,90,90,90,90,90,90,90,90,92,92,92,92,94,94,96,96,98,98,104,294,294,294,294,294,294,294,294,294,29 [...]
+"297",293,293,293,293,293,293,293,293,293,293,293,293,293,293,293,293,293,293,293,293,293,293,293,293,293,293,293,293,293,293,293,293,293,293,293,293,293,293,293,293,293,293,293,293,293,293,293,293,293,293,293,293,293,293,293,293,293,293,293,293,293,293,293,293,293,293,293,293,293,293,293,293,293,293,293,293,293,293,293,293,293,293,293,293,293,293,293,293,293,293,293,293,293,293,103,103,89,89,89,89,89,89,89,89,91,91,93,93,93,93,95,95,97,97,99,99,105,295,295,295,295,295,295,295,295,295,29 [...]
+"298",294,294,294,294,294,294,294,294,294,294,294,294,294,294,294,294,294,294,294,294,294,294,294,294,294,294,294,294,294,294,294,294,294,294,294,294,294,294,294,294,294,294,294,294,294,294,294,294,294,294,294,294,294,294,294,294,294,294,294,294,294,294,294,294,294,294,294,294,294,294,294,294,294,294,294,294,294,294,294,294,294,294,294,294,294,294,294,294,294,294,294,294,294,294,104,104,88,88,88,88,88,88,90,90,92,92,94,94,94,94,96,96,98,98,100,100,106,296,296,296,296,296,296,296,296,296, [...]
+"299",295,295,295,295,295,295,295,295,295,295,295,295,295,295,295,295,295,295,295,295,295,295,295,295,295,295,295,295,295,295,295,295,295,295,295,295,295,295,295,295,295,295,295,295,295,295,295,295,295,295,295,295,295,295,295,295,295,295,295,295,295,295,295,295,295,295,295,295,295,295,295,295,295,295,295,295,295,295,295,295,295,295,295,295,295,295,295,295,295,295,295,295,295,295,105,105,87,87,87,87,89,89,91,91,93,93,95,95,95,95,97,97,99,99,101,101,107,297,297,297,297,297,297,297,297,297, [...]
+"300",296,296,296,296,296,296,296,296,296,296,296,296,296,296,296,296,296,296,296,296,296,296,296,296,296,296,296,296,296,296,296,296,296,296,296,296,296,296,296,296,296,296,296,296,296,296,296,296,296,296,296,296,296,296,296,296,296,296,296,296,296,296,296,296,296,296,296,296,296,296,296,296,296,296,296,296,296,296,296,296,296,296,296,296,296,296,296,296,296,296,296,296,296,296,106,106,86,86,86,88,90,90,92,92,94,94,96,96,96,96,98,98,100,100,102,102,108,298,298,298,298,298,298,298,298,29 [...]
+"301",297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,107,107,85,85,87,89,91,91,93,93,95,95,97,97,97,97,99,99,101,101,103,103,109,299,299,299,299,299,299,299,299,29 [...]
+"302",298,298,298,298,298,298,298,298,298,298,298,298,298,298,298,298,298,298,298,298,298,298,298,298,298,298,298,298,298,298,298,298,298,298,298,298,298,298,298,298,298,298,298,298,298,298,298,298,298,298,298,298,298,298,298,298,298,298,298,298,298,298,298,298,298,298,298,298,298,298,298,298,298,298,298,298,298,298,298,298,298,298,298,298,298,298,298,298,298,298,298,298,298,298,108,108,92,92,92,92,84,84,94,94,96,96,98,98,98,98,100,100,102,102,104,104,110,300,300,300,300,300,300,300,300, [...]
+"303",299,299,299,299,299,299,299,299,299,299,299,299,299,299,299,299,299,299,299,299,299,299,299,299,299,299,299,299,299,299,299,299,299,299,299,299,299,299,299,299,299,299,299,299,299,299,299,299,299,299,299,299,299,299,299,299,299,299,299,299,299,299,299,299,299,299,299,299,299,299,299,299,299,299,299,299,299,299,299,299,299,299,299,299,299,299,299,299,299,299,299,299,299,299,109,109,95,95,95,95,95,95,83,83,97,97,99,99,99,99,101,101,103,103,105,105,111,301,301,301,301,301,301,301,301, [...]
+"304",300,300,300,300,300,300,300,300,300,300,300,300,300,300,300,300,300,300,300,300,300,300,300,300,300,300,300,300,300,300,300,300,300,300,300,300,300,300,300,300,300,300,300,300,300,300,300,300,300,300,300,300,300,300,300,300,300,300,300,300,300,300,300,300,300,300,300,300,300,300,300,300,300,300,300,300,300,300,300,300,300,300,300,300,300,300,300,300,300,300,300,300,300,300,110,110,98,98,98,98,98,98,98,98,82,82,100,100,100,100,102,102,104,104,106,106,112,302,302,302,302,302,302,302, [...]
+"305",301,301,301,301,301,301,301,301,301,301,301,301,301,301,301,301,301,301,301,301,301,301,301,301,301,301,301,301,301,301,301,301,301,301,301,301,301,301,301,301,301,301,301,301,301,301,301,301,301,301,301,301,301,301,301,301,301,301,301,301,301,301,301,301,301,301,301,301,301,301,301,301,301,301,301,301,301,301,301,301,301,301,301,301,301,301,301,301,301,301,301,301,301,301,111,111,101,101,101,101,101,101,101,101,101,101,81,81,81,81,103,103,105,105,107,107,113,303,303,303,303,303,30 [...]
+"306",302,302,302,302,302,302,302,302,302,302,302,302,302,302,302,302,302,302,302,302,302,302,302,302,302,302,302,302,302,302,302,302,302,302,302,302,302,302,302,302,302,302,302,302,302,302,302,302,302,302,302,302,302,302,302,302,302,302,302,302,302,302,302,302,302,302,302,302,302,302,302,302,302,302,302,302,302,302,302,302,302,302,302,302,302,302,302,302,302,302,302,302,302,302,112,112,102,102,102,102,102,102,102,102,102,102,80,80,82,82,104,104,106,106,108,108,114,304,304,304,304,304,30 [...]
+"307",303,303,303,303,303,303,303,303,303,303,303,303,303,303,303,303,303,303,303,303,303,303,303,303,303,303,303,303,303,303,303,303,303,303,303,303,303,303,303,303,303,303,303,303,303,303,303,303,303,303,303,303,303,303,303,303,303,303,303,303,303,303,303,303,303,303,303,303,303,303,303,303,303,303,303,303,303,303,303,303,303,303,303,303,303,303,303,303,303,303,303,303,303,303,113,113,103,103,103,103,103,103,103,103,103,103,83,83,79,79,105,105,107,107,109,109,115,305,305,305,305,305,30 [...]
+"308",304,304,304,304,304,304,304,304,304,304,304,304,304,304,304,304,304,304,304,304,304,304,304,304,304,304,304,304,304,304,304,304,304,304,304,304,304,304,304,304,304,304,304,304,304,304,304,304,304,304,304,304,304,304,304,304,304,304,304,304,304,304,304,304,304,304,304,304,304,304,304,304,304,304,304,304,304,304,304,304,304,304,304,304,304,304,304,304,304,304,304,304,304,304,114,114,106,106,106,106,106,106,106,106,106,106,106,106,106,106,78,78,108,108,110,110,116,306,306,306,306,306, [...]
+"309",305,305,305,305,305,305,305,305,305,305,305,305,305,305,305,305,305,305,305,305,305,305,305,305,305,305,305,305,305,305,305,305,305,305,305,305,305,305,305,305,305,305,305,305,305,305,305,305,305,305,305,305,305,305,305,305,305,305,305,305,305,305,305,305,305,305,305,305,305,305,305,305,305,305,305,305,305,305,305,305,305,305,305,305,305,305,305,305,305,305,305,305,305,305,115,115,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,77,77,111,111,117,307,307,307,307,307, [...]
+"310",306,306,306,306,306,306,306,306,306,306,306,306,306,306,306,306,306,306,306,306,306,306,306,306,306,306,306,306,306,306,306,306,306,306,306,306,306,306,306,306,306,306,306,306,306,306,306,306,306,306,306,306,306,306,306,306,306,306,306,306,306,306,306,306,306,306,306,306,306,306,306,306,306,306,306,306,306,306,306,306,306,306,306,306,306,306,306,306,306,306,306,306,306,306,116,116,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,76,76,118,308,308,308,308,308, [...]
+"311",309,309,309,309,309,309,309,309,309,309,309,309,309,309,309,309,309,309,309,309,309,309,309,309,309,309,309,309,309,309,309,309,309,309,309,309,309,309,309,309,309,309,309,309,309,309,309,309,309,309,309,309,309,309,309,309,309,309,309,309,309,309,309,309,309,309,309,309,309,309,309,309,309,309,309,309,309,309,309,309,309,309,309,309,309,309,309,309,309,309,309,309,309,309,309,309,309,309,309,309,309,309,309,309,309,309,309,309,309,309,309,309,309,309,309,309,309,75,75,75,75,75,75, [...]
+"312",310,310,310,310,310,310,310,310,310,310,310,310,310,310,310,310,310,310,310,310,310,310,310,310,310,310,310,310,310,310,310,310,310,310,310,310,310,310,310,310,310,310,310,310,310,310,310,310,310,310,310,310,310,310,310,310,310,310,310,310,310,310,310,310,310,310,310,310,310,310,310,310,310,310,310,310,310,310,310,310,310,310,310,310,310,310,310,310,310,310,310,310,310,310,310,310,310,310,310,310,310,310,310,310,310,310,310,310,310,310,310,310,310,310,310,310,310,74,74,74,74,74,74, [...]
+"313",311,311,311,311,311,311,311,311,311,311,311,311,311,311,311,311,311,311,311,311,311,311,311,311,311,311,311,311,311,311,311,311,311,311,311,311,311,311,311,311,311,311,311,311,311,311,311,311,311,311,311,311,311,311,311,311,311,311,311,311,311,311,311,311,311,311,311,311,311,311,311,311,311,311,311,311,311,311,311,311,311,311,311,311,311,311,311,311,311,311,311,311,311,311,311,311,311,311,311,311,311,311,311,311,311,311,311,311,311,311,311,311,311,311,311,311,311,73,73,73,73,73,73, [...]
+"314",312,312,312,312,312,312,312,312,312,312,312,312,312,312,312,312,312,312,312,312,312,312,312,312,312,312,312,312,312,312,312,312,312,312,312,312,312,312,312,312,312,312,312,312,312,312,312,312,312,312,312,312,312,312,312,312,312,312,312,312,312,312,312,312,312,312,312,312,312,312,312,312,312,312,312,312,312,312,312,312,312,312,312,312,312,312,312,312,312,312,312,312,312,312,312,312,312,312,312,312,312,312,312,312,312,312,312,312,312,312,312,312,312,312,312,312,312,72,72,72,72,72,72, [...]
+"315",313,313,313,313,313,313,313,313,313,313,313,313,313,313,313,313,313,313,313,313,313,313,313,313,313,313,313,313,313,313,313,313,313,313,313,313,313,313,313,313,313,313,313,313,313,313,313,313,313,313,313,313,313,313,313,313,313,313,313,313,313,313,313,313,313,313,313,313,313,313,313,313,313,313,313,313,313,313,313,313,313,313,313,313,313,313,313,313,313,313,313,313,313,313,313,313,313,313,313,313,313,313,313,313,313,313,313,313,313,313,313,313,313,313,313,313,313,73,71,71,71,71,71, [...]
+"316",314,314,314,314,314,314,314,314,314,314,314,314,314,314,314,314,314,314,314,314,314,314,314,314,314,314,314,314,314,314,314,314,314,314,314,314,314,314,314,314,314,314,314,314,314,314,314,314,314,314,314,314,314,314,314,314,314,314,314,314,314,314,314,314,314,314,314,314,314,314,314,314,314,314,314,314,314,314,314,314,314,314,314,314,314,314,314,314,314,314,314,314,314,314,314,314,314,314,314,314,314,314,314,314,314,314,314,314,314,314,314,314,314,314,314,314,314,74,70,70,70,70,70, [...]
+"317",315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,75,69,69,69,69,69, [...]
+"318",316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,76,68,68,70,70,70, [...]
+"319",317,317,317,317,317,317,317,317,317,317,317,317,317,317,317,317,317,317,317,317,317,317,317,317,317,317,317,317,317,317,317,317,317,317,317,317,317,317,317,317,317,317,317,317,317,317,317,317,317,317,317,317,317,317,317,317,317,317,317,317,317,317,317,317,317,317,317,317,317,317,317,317,317,317,317,317,317,317,317,317,317,317,317,317,317,317,317,317,317,317,317,317,317,317,317,317,317,317,317,317,317,317,317,317,317,317,317,317,317,317,317,317,317,317,317,317,317,77,71,71,67,67,67, [...]
+"320",318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,78,72,72,66,66,66, [...]
+"321",319,319,319,319,319,319,319,319,319,319,319,319,319,319,319,319,319,319,319,319,319,319,319,319,319,319,319,319,319,319,319,319,319,319,319,319,319,319,319,319,319,319,319,319,319,319,319,319,319,319,319,319,319,319,319,319,319,319,319,319,319,319,319,319,319,319,319,319,319,319,319,319,319,319,319,319,319,319,319,319,319,319,319,319,319,319,319,319,319,319,319,319,319,319,319,319,319,319,319,319,319,319,319,319,319,319,319,319,319,319,319,319,319,319,319,319,319,79,73,73,65,65,65, [...]
+"322",320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,80,74,74,64,64,64, [...]
+"323",321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,81,75,75,65,63,63, [...]
+"324",322,322,322,322,322,322,322,322,322,322,322,322,322,322,322,322,322,322,322,322,322,322,322,322,322,322,322,322,322,322,322,322,322,322,322,322,322,322,322,322,322,322,322,322,322,322,322,322,322,322,322,322,322,322,322,322,322,322,322,322,322,322,322,322,322,322,322,322,322,322,322,322,322,322,322,322,322,322,322,322,322,322,322,322,322,322,322,322,322,322,322,322,322,322,322,322,322,322,322,322,322,322,322,322,322,322,322,322,322,322,322,322,322,322,322,322,322,82,76,76,66,64,62, [...]
+"325",323,323,323,323,323,323,323,323,323,323,323,323,323,323,323,323,323,323,323,323,323,323,323,323,323,323,323,323,323,323,323,323,323,323,323,323,323,323,323,323,323,323,323,323,323,323,323,323,323,323,323,323,323,323,323,323,323,323,323,323,323,323,323,323,323,323,323,323,323,323,323,323,323,323,323,323,323,323,323,323,323,323,323,323,323,323,323,323,323,323,323,323,323,323,323,323,323,323,323,323,323,323,323,323,323,323,323,323,323,323,323,323,323,323,323,323,323,83,77,77,67,65,63, [...]
+"326",324,324,324,324,324,324,324,324,324,324,324,324,324,324,324,324,324,324,324,324,324,324,324,324,324,324,324,324,324,324,324,324,324,324,324,324,324,324,324,324,324,324,324,324,324,324,324,324,324,324,324,324,324,324,324,324,324,324,324,324,324,324,324,324,324,324,324,324,324,324,324,324,324,324,324,324,324,324,324,324,324,324,324,324,324,324,324,324,324,324,324,324,324,324,324,324,324,324,324,324,324,324,324,324,324,324,324,324,324,324,324,324,324,324,324,324,324,84,78,78,70,70,70, [...]
+"327",325,325,325,325,325,325,325,325,325,325,325,325,325,325,325,325,325,325,325,325,325,325,325,325,325,325,325,325,325,325,325,325,325,325,325,325,325,325,325,325,325,325,325,325,325,325,325,325,325,325,325,325,325,325,325,325,325,325,325,325,325,325,325,325,325,325,325,325,325,325,325,325,325,325,325,325,325,325,325,325,325,325,325,325,325,325,325,325,325,325,325,325,325,325,325,325,325,325,325,325,325,325,325,325,325,325,325,325,325,325,325,325,325,325,325,325,325,85,83,83,83,83,83, [...]
+"328",326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,86,84,84,84,84,84, [...]
+"329",327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,89,89,89,89,89,89, [...]
+"330",328,328,328,328,328,328,328,328,328,328,328,328,328,328,328,328,328,328,328,328,328,328,328,328,328,328,328,328,328,328,328,328,328,328,328,328,328,328,328,328,328,328,328,328,328,328,328,328,328,328,328,328,328,328,328,328,328,328,328,328,328,328,328,328,328,328,328,328,328,328,328,328,328,328,328,328,328,328,328,328,328,328,328,328,328,328,328,328,328,328,328,328,328,328,328,328,328,328,328,328,328,328,328,328,328,328,328,328,328,328,328,328,328,328,328,328,328,92,92,92,92,92,92, [...]
+"331",329,329,329,329,329,329,329,329,329,329,329,329,329,329,329,329,329,329,329,329,329,329,329,329,329,329,329,329,329,329,329,329,329,329,329,329,329,329,329,329,329,329,329,329,329,329,329,329,329,329,329,329,329,329,329,329,329,329,329,329,329,329,329,329,329,329,329,329,329,329,329,329,329,329,329,329,329,329,329,329,329,329,329,329,329,329,329,329,329,329,329,329,329,329,329,329,329,329,329,329,329,329,329,329,329,329,329,329,329,329,329,329,329,329,329,329,329,93,93,93,93,93,93, [...]
+"332",330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,94,94,94,94,94,94, [...]
+"333",331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,95,95,95,95,95,95, [...]
+"334",332,332,332,332,332,332,332,332,332,332,332,332,332,332,332,332,332,332,332,332,332,332,332,332,332,332,332,332,332,332,332,332,332,332,332,332,332,332,332,332,332,332,332,332,332,332,332,332,332,332,332,332,332,332,332,332,332,332,332,332,332,332,332,332,332,332,332,332,332,332,332,332,332,332,332,332,332,332,332,332,332,332,332,332,332,332,332,332,332,332,332,332,332,332,332,332,332,332,332,332,332,332,332,332,332,332,332,332,332,332,332,332,332,332,332,332,332,96,96,96,96,96,96, [...]
+"335",333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,97,97,97,97,97,97, [...]
+"336",334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,98,98,98,98,98,98, [...]
+"337",335,335,335,335,335,335,335,335,335,335,335,335,335,335,335,335,335,335,335,335,335,335,335,335,335,335,335,335,335,335,335,335,335,335,335,335,335,335,335,335,335,335,335,335,335,335,335,335,335,335,335,335,335,335,335,335,335,335,335,335,335,335,335,335,335,335,335,335,335,335,335,335,335,335,335,335,335,335,335,335,335,335,335,335,335,335,335,335,335,335,335,335,335,335,335,335,335,335,335,335,335,335,335,335,335,335,335,335,335,335,335,335,335,335,335,335,335,99,99,99,99,99,99, [...]
+"338",336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,100,100,100,100,10 [...]
+"339",337,337,337,337,337,337,337,337,337,337,337,337,337,337,337,337,337,337,337,337,337,337,337,337,337,337,337,337,337,337,337,337,337,337,337,337,337,337,337,337,337,337,337,337,337,337,337,337,337,337,337,337,337,337,337,337,337,337,337,337,337,337,337,337,337,337,337,337,337,337,337,337,337,337,337,337,337,337,337,337,337,337,337,337,337,337,337,337,337,337,337,337,337,337,337,337,337,337,337,337,337,337,337,337,337,337,337,337,337,337,337,337,337,337,337,337,337,101,101,101,101,10 [...]
+"340",338,338,338,338,338,338,338,338,338,338,338,338,338,338,338,338,338,338,338,338,338,338,338,338,338,338,338,338,338,338,338,338,338,338,338,338,338,338,338,338,338,338,338,338,338,338,338,338,338,338,338,338,338,338,338,338,338,338,338,338,338,338,338,338,338,338,338,338,338,338,338,338,338,338,338,338,338,338,338,338,338,338,338,338,338,338,338,338,338,338,338,338,338,338,338,338,338,338,338,338,338,338,338,338,338,338,338,338,338,338,338,338,338,338,338,338,338,102,102,102,102,10 [...]
+"341",339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,103,103,103,103,10 [...]
+"342",340,340,340,340,340,340,340,340,340,340,340,340,340,340,340,340,340,340,340,340,340,340,340,340,340,340,340,340,340,340,340,340,340,340,340,340,340,340,340,340,340,340,340,340,340,340,340,340,340,340,340,340,340,340,340,340,340,340,340,340,340,340,340,340,340,340,340,340,340,340,340,340,340,340,340,340,340,340,340,340,340,340,340,340,340,340,340,340,340,340,340,340,340,340,340,340,340,340,340,340,340,340,340,340,340,340,340,340,340,340,340,340,340,340,340,340,340,104,104,104,104,10 [...]
+"343",341,341,341,341,341,341,341,341,341,341,341,341,341,341,341,341,341,341,341,341,341,341,341,341,341,341,341,341,341,341,341,341,341,341,341,341,341,341,341,341,341,341,341,341,341,341,341,341,341,341,341,341,341,341,341,341,341,341,341,341,341,341,341,341,341,341,341,341,341,341,341,341,341,341,341,341,341,341,341,341,341,341,341,341,341,341,341,341,341,341,341,341,341,341,341,341,341,341,341,341,341,341,341,341,341,341,341,341,341,341,341,341,341,341,341,341,341,105,105,105,105,10 [...]
+"344",342,342,342,342,342,342,342,342,342,342,342,342,342,342,342,342,342,342,342,342,342,342,342,342,342,342,342,342,342,342,342,342,342,342,342,342,342,342,342,342,342,342,342,342,342,342,342,342,342,342,342,342,342,342,342,342,342,342,342,342,342,342,342,342,342,342,342,342,342,342,342,342,342,342,342,342,342,342,342,342,342,342,342,342,342,342,342,342,342,342,342,342,342,342,342,342,342,342,342,342,342,342,342,342,342,342,342,342,342,342,342,342,342,342,342,342,342,106,106,106,106,10 [...]
+"345",343,343,343,343,343,343,343,343,343,343,343,343,343,343,343,343,343,343,343,343,343,343,343,343,343,343,343,343,343,343,343,343,343,343,343,343,343,343,343,343,343,343,343,343,343,343,343,343,343,343,343,343,343,343,343,343,343,343,343,343,343,343,343,343,343,343,343,343,343,343,343,343,343,343,343,343,343,343,343,343,343,343,343,343,343,343,343,343,343,343,343,343,343,343,343,343,343,343,343,343,343,343,343,343,343,343,343,343,343,343,343,343,343,343,343,343,343,109,109,109,109,10 [...]
+"346",344,344,344,344,344,344,344,344,344,344,344,344,344,344,344,344,344,344,344,344,344,344,344,344,344,344,344,344,344,344,344,344,344,344,344,344,344,344,344,344,344,344,344,344,344,344,344,344,344,344,344,344,344,344,344,344,344,344,344,344,344,344,344,344,344,344,344,344,344,344,344,344,344,344,344,344,344,344,344,344,344,344,344,344,344,344,344,344,344,344,344,344,344,344,344,344,344,344,344,344,344,344,344,344,344,344,344,344,344,344,344,344,344,344,344,344,344,110,110,110,110,11 [...]
+"347",345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,111,111,111,111,11 [...]
+"348",346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,112,112,112,112,11 [...]
+"349",347,347,347,347,347,347,347,347,347,347,347,347,347,347,347,347,347,347,347,347,347,347,347,347,347,347,347,347,347,347,347,347,347,347,347,347,347,347,347,347,347,347,347,347,347,347,347,347,347,347,347,347,347,347,347,347,347,347,347,347,347,347,347,347,347,347,347,347,347,347,347,347,347,347,347,347,347,347,347,347,347,347,347,347,347,347,347,347,347,347,347,347,347,347,347,347,347,347,347,347,347,347,347,347,347,347,347,347,347,347,347,347,347,347,347,347,347,113,113,113,113,11 [...]
+"350",348,348,348,348,348,348,348,348,348,348,348,348,348,348,348,348,348,348,348,348,348,348,348,348,348,348,348,348,348,348,348,348,348,348,348,348,348,348,348,348,348,348,348,348,348,348,348,348,348,348,348,348,348,348,348,348,348,348,348,348,348,348,348,348,348,348,348,348,348,348,348,348,348,348,348,348,348,348,348,348,348,348,348,348,348,348,348,348,348,348,348,348,348,348,348,348,348,348,348,348,348,348,348,348,348,348,348,348,348,348,348,348,348,348,348,348,348,114,114,114,114,11 [...]
+"351",349,349,349,349,349,349,349,349,349,349,349,349,349,349,349,349,349,349,349,349,349,349,349,349,349,349,349,349,349,349,349,349,349,349,349,349,349,349,349,349,349,349,349,349,349,349,349,349,349,349,349,349,349,349,349,349,349,349,349,349,349,349,349,349,349,349,349,349,349,349,349,349,349,349,349,349,349,349,349,349,349,349,349,349,349,349,349,349,349,349,349,349,349,349,349,349,349,349,349,349,349,349,349,349,349,349,349,349,349,349,349,349,349,349,349,349,349,115,115,115,115,11 [...]
+"352",350,350,350,350,350,350,350,350,350,350,350,350,350,350,350,350,350,350,350,350,350,350,350,350,350,350,350,350,350,350,350,350,350,350,350,350,350,350,350,350,350,350,350,350,350,350,350,350,350,350,350,350,350,350,350,350,350,350,350,350,350,350,350,350,350,350,350,350,350,350,350,350,350,350,350,350,350,350,350,350,350,350,350,350,350,350,350,350,350,350,350,350,350,350,350,350,350,350,350,350,350,350,350,350,350,350,350,350,350,350,350,350,350,350,350,350,350,116,116,116,116,11 [...]
+"353",351,351,351,351,351,351,351,351,351,351,351,351,351,351,351,351,351,351,351,351,351,351,351,351,351,351,351,351,351,351,351,351,351,351,351,351,351,351,351,351,351,351,351,351,351,351,351,351,351,351,351,351,351,351,351,351,351,351,351,351,351,351,351,351,351,351,351,351,351,351,351,351,351,351,351,351,351,351,351,351,351,351,351,351,351,351,351,351,351,351,351,351,351,351,351,351,351,351,351,351,351,351,351,351,351,351,351,351,351,351,351,351,351,351,351,351,351,117,117,117,117,11 [...]
+"354",352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,118,118,118,118,11 [...]
+"355",353,353,353,353,353,353,353,353,353,353,353,353,353,353,353,353,353,353,353,353,353,353,353,353,353,353,353,353,353,353,353,353,353,353,353,353,353,353,353,353,353,353,353,353,353,353,353,353,353,353,353,353,353,353,353,353,353,353,353,353,353,353,353,353,353,353,353,353,353,353,353,353,353,353,353,353,353,353,353,353,353,353,353,353,353,353,353,353,353,353,353,353,353,353,353,353,353,353,353,353,353,353,353,353,353,353,353,353,353,353,353,353,353,353,353,353,353,119,119,119,119,11 [...]
+"356",354,354,354,354,354,354,354,354,354,354,354,354,354,354,354,354,354,354,354,354,354,354,354,354,354,354,354,354,354,354,354,354,354,354,354,354,354,354,354,354,354,354,354,354,354,354,354,354,354,354,354,354,354,354,354,354,354,354,354,354,354,354,354,354,354,354,354,354,354,354,354,354,354,354,354,354,354,354,354,354,354,354,354,354,354,354,354,354,354,354,354,354,354,354,354,354,354,354,354,354,354,354,354,354,354,354,354,354,354,354,354,354,354,354,354,354,354,120,120,120,120,12 [...]
+"357",355,355,355,355,355,355,355,355,355,355,355,355,355,355,355,355,355,355,355,355,355,355,355,355,355,355,355,355,355,355,355,355,355,355,355,355,355,355,355,355,355,355,355,355,355,355,355,355,355,355,355,355,355,355,355,355,355,355,355,355,355,355,355,355,355,355,355,355,355,355,355,355,355,355,355,355,355,355,355,355,355,355,355,355,355,355,355,355,355,355,355,355,355,355,355,355,355,355,355,355,355,355,355,355,355,355,355,355,355,355,355,355,355,355,355,355,355,121,121,121,121,12 [...]
+"358",356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,122,122,122,122,12 [...]
+"359",357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,123,123,123,123,12 [...]
+"360",358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,124,124,124,124,12 [...]
+"361",359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,125,125,125,125,12 [...]
+"362",360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,126,126,126,126,12 [...]
+"363",361,361,361,361,361,361,361,361,361,361,361,361,361,361,361,361,361,361,361,361,361,361,361,361,361,361,361,361,361,361,361,361,361,361,361,361,361,361,361,361,361,361,361,361,361,361,361,361,361,361,361,361,361,361,361,361,361,361,361,361,361,361,361,361,361,361,361,361,361,361,361,361,361,361,361,361,361,361,361,361,361,361,361,361,361,361,361,361,361,361,361,361,361,361,361,361,361,361,361,361,361,361,361,361,361,361,361,361,361,361,361,361,361,361,361,361,361,127,127,127,127,12 [...]
+"364",362,362,362,362,362,362,362,362,362,362,362,362,362,362,362,362,362,362,362,362,362,362,362,362,362,362,362,362,362,362,362,362,362,362,362,362,362,362,362,362,362,362,362,362,362,362,362,362,362,362,362,362,362,362,362,362,362,362,362,362,362,362,362,362,362,362,362,362,362,362,362,362,362,362,362,362,362,362,362,362,362,362,362,362,362,362,362,362,362,362,362,362,362,362,362,362,362,362,362,362,362,362,362,362,362,362,362,362,362,362,362,362,362,362,362,362,362,128,128,128,128,12 [...]
+"365",363,363,363,363,363,363,363,363,363,363,363,363,363,363,363,363,363,363,363,363,363,363,363,363,363,363,363,363,363,363,363,363,363,363,363,363,363,363,363,363,363,363,363,363,363,363,363,363,363,363,363,363,363,363,363,363,363,363,363,363,363,363,363,363,363,363,363,363,363,363,363,363,363,363,363,363,363,363,363,363,363,363,363,363,363,363,363,363,363,363,363,363,363,363,363,363,363,363,363,363,363,363,363,363,363,363,363,363,363,363,363,363,363,363,363,363,363,129,129,129,129,12 [...]
+"366",364,364,364,364,364,364,364,364,364,364,364,364,364,364,364,364,364,364,364,364,364,364,364,364,364,364,364,364,364,364,364,364,364,364,364,364,364,364,364,364,364,364,364,364,364,364,364,364,364,364,364,364,364,364,364,364,364,364,364,364,364,364,364,364,364,364,364,364,364,364,364,364,364,364,364,364,364,364,364,364,364,364,364,364,364,364,364,364,364,364,364,364,364,364,364,364,364,364,364,364,364,364,364,364,364,364,364,364,364,364,364,364,364,364,364,364,364,130,130,130,130,13 [...]
+"367",365,365,365,365,365,365,365,365,365,365,365,365,365,365,365,365,365,365,365,365,365,365,365,365,365,365,365,365,365,365,365,365,365,365,365,365,365,365,365,365,365,365,365,365,365,365,365,365,365,365,365,365,365,365,365,365,365,365,365,365,365,365,365,365,365,365,365,365,365,365,365,365,365,365,365,365,365,365,365,365,365,365,365,365,365,365,365,365,365,365,365,365,365,365,365,365,365,365,365,365,365,365,365,365,365,365,365,365,365,365,365,365,365,365,365,365,365,131,131,131,131,13 [...]
+"368",366,366,366,366,366,366,366,366,366,366,366,366,366,366,366,366,366,366,366,366,366,366,366,366,366,366,366,366,366,366,366,366,366,366,366,366,366,366,366,366,366,366,366,366,366,366,366,366,366,366,366,366,366,366,366,366,366,366,366,366,366,366,366,366,366,366,366,366,366,366,366,366,366,366,366,366,366,366,366,366,366,366,366,366,366,366,366,366,366,366,366,366,366,366,366,366,366,366,366,366,366,366,366,366,366,366,366,366,366,366,366,366,366,366,366,366,366,132,132,132,132,13 [...]
+"369",367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,133,133,133,133,13 [...]
+"370",368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,134,134,134,134,13 [...]
+"371",369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,135,135,135,135,13 [...]
+"372",370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,136,136,136,136,13 [...]
+"373",371,371,371,371,371,371,371,371,371,371,371,371,371,371,371,371,371,371,371,371,371,371,371,371,371,371,371,371,371,371,371,371,371,371,371,371,371,371,371,371,371,371,371,371,371,371,371,371,371,371,371,371,371,371,371,371,371,371,371,371,371,371,371,371,371,371,371,371,371,371,371,371,371,371,371,371,371,371,371,371,371,371,371,371,371,371,371,371,371,371,371,371,371,371,371,371,371,371,371,371,371,371,371,371,371,371,371,371,371,371,371,371,371,371,371,371,371,137,137,137,137,13 [...]
+"374",372,372,372,372,372,372,372,372,372,372,372,372,372,372,372,372,372,372,372,372,372,372,372,372,372,372,372,372,372,372,372,372,372,372,372,372,372,372,372,372,372,372,372,372,372,372,372,372,372,372,372,372,372,372,372,372,372,372,372,372,372,372,372,372,372,372,372,372,372,372,372,372,372,372,372,372,372,372,372,372,372,372,372,372,372,372,372,372,372,372,372,372,372,372,372,372,372,372,372,372,372,372,372,372,372,372,372,372,372,372,372,372,372,372,372,372,372,138,138,138,138,13 [...]
+"375",373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,139,139,139,139,13 [...]
+"376",374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,140,140,140,140,14 [...]
+"377",375,375,375,375,375,375,375,375,375,375,375,375,375,375,375,375,375,375,375,375,375,375,375,375,375,375,375,375,375,375,375,375,375,375,375,375,375,375,375,375,375,375,375,375,375,375,375,375,375,375,375,375,375,375,375,375,375,375,375,375,375,375,375,375,375,375,375,375,375,375,375,375,375,375,375,375,375,375,375,375,375,375,375,375,375,375,375,375,375,375,375,375,375,375,375,375,375,375,375,375,375,375,375,375,375,375,375,375,375,375,375,375,375,375,375,375,375,141,141,141,141,14 [...]
+"378",376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,142,142,142,142,14 [...]
+"379",377,377,377,377,377,377,377,377,377,377,377,377,377,377,377,377,377,377,377,377,377,377,377,377,377,377,377,377,377,377,377,377,377,377,377,377,377,377,377,377,377,377,377,377,377,377,377,377,377,377,377,377,377,377,377,377,377,377,377,377,377,377,377,377,377,377,377,377,377,377,377,377,377,377,377,377,377,377,377,377,377,377,377,377,377,377,377,377,377,377,377,377,377,377,377,377,377,377,377,377,377,377,377,377,377,377,377,377,377,377,377,377,377,377,377,377,377,143,143,143,143,14 [...]
+"380",378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,144,144,144,144,14 [...]
+"381",379,379,379,379,379,379,379,379,379,379,379,379,379,379,379,379,379,379,379,379,379,379,379,379,379,379,379,379,379,379,379,379,379,379,379,379,379,379,379,379,379,379,379,379,379,379,379,379,379,379,379,379,379,379,379,379,379,379,379,379,379,379,379,379,379,379,379,379,379,379,379,379,379,379,379,379,379,379,379,379,379,379,379,379,379,379,379,379,379,379,379,379,379,379,379,379,379,379,379,379,379,379,379,379,379,379,379,379,379,379,379,379,379,379,379,379,379,145,145,145,145,14 [...]
+"382",380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,146,146,146,146,14 [...]
+"383",381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,147,147,147,147,14 [...]
+"384",382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,148,148,148,148,14 [...]
+"385",383,383,383,383,383,383,383,383,383,383,383,383,383,383,383,383,383,383,383,383,383,383,383,383,383,383,383,383,383,383,383,383,383,383,383,383,383,383,383,383,383,383,383,383,383,383,383,383,383,383,383,383,383,383,383,383,383,383,383,383,383,383,383,383,383,383,383,383,383,383,383,383,383,383,383,383,383,383,383,383,383,383,383,383,383,383,383,383,383,383,383,383,383,383,383,383,383,383,383,383,383,383,383,383,383,383,383,383,383,383,383,383,383,383,383,383,383,149,149,149,149,14 [...]
diff --git a/dendropy/test/data/other/hiv1.unweighted.node-to-node-dists.csv b/dendropy/test/data/other/hiv1.unweighted.node-to-node-dists.csv
new file mode 100644
index 0000000..4933ee0
--- /dev/null
+++ b/dendropy/test/data/other/hiv1.unweighted.node-to-node-dists.csv
@@ -0,0 +1,386 @@
+"","1","2","3","4","5","6","7","8","9","10","11","12","13","14","15","16","17","18","19","20","21","22","23","24","25","26","27","28","29","30","31","32","33","34","35","36","37","38","39","40","41","42","43","44","45","46","47","48","49","50","51","52","53","54","55","56","57","58","59","60","61","62","63","64","65","66","67","68","69","70","71","72","73","74","75","76","77","78","79","80","81","82","83","84","85","86","87","88","89","90","91","92","93","94","95","96","97","98","99","10 [...]
+"1",0,2,4,4,4,6,6,6,8,9,10,10,11,11,10,13,13,12,12,12,16,16,15,15,16,16,17,19,19,18,17,17,16,19,19,18,18,18,17,18,18,18,18,18,18,15,15,15,15,15,16,19,20,20,18,17,17,18,18,16,14,17,17,16,15,14,13,18,18,17,16,16,18,18,18,18,16,16,15,15,16,16,15,15,12,12,11,10,13,14,14,12,12,12,14,14,23,23,22,21,21,21,20,20,19,19,19,19,19,19,17,17,16,16,15,15,12,16,20,20,23,24,25,26,26,23,23,21,20,18,19,19,18,16,16,17,19,21,21,20,20,20,19,21,21,21,21,19,18,17,15,20,23,23,23,23,25,25,24,23,23,23,22,22,21,20, [...]
+"2",2,0,4,4,4,6,6,6,8,9,10,10,11,11,10,13,13,12,12,12,16,16,15,15,16,16,17,19,19,18,17,17,16,19,19,18,18,18,17,18,18,18,18,18,18,15,15,15,15,15,16,19,20,20,18,17,17,18,18,16,14,17,17,16,15,14,13,18,18,17,16,16,18,18,18,18,16,16,15,15,16,16,15,15,12,12,11,10,13,14,14,12,12,12,14,14,23,23,22,21,21,21,20,20,19,19,19,19,19,19,17,17,16,16,15,15,12,16,20,20,23,24,25,26,26,23,23,21,20,18,19,19,18,16,16,17,19,21,21,20,20,20,19,21,21,21,21,19,18,17,15,20,23,23,23,23,25,25,24,23,23,23,22,22,21,20, [...]
+"3",4,4,0,2,4,6,6,6,8,9,10,10,11,11,10,13,13,12,12,12,16,16,15,15,16,16,17,19,19,18,17,17,16,19,19,18,18,18,17,18,18,18,18,18,18,15,15,15,15,15,16,19,20,20,18,17,17,18,18,16,14,17,17,16,15,14,13,18,18,17,16,16,18,18,18,18,16,16,15,15,16,16,15,15,12,12,11,10,13,14,14,12,12,12,14,14,23,23,22,21,21,21,20,20,19,19,19,19,19,19,17,17,16,16,15,15,12,16,20,20,23,24,25,26,26,23,23,21,20,18,19,19,18,16,16,17,19,21,21,20,20,20,19,21,21,21,21,19,18,17,15,20,23,23,23,23,25,25,24,23,23,23,22,22,21,20, [...]
+"4",4,4,2,0,4,6,6,6,8,9,10,10,11,11,10,13,13,12,12,12,16,16,15,15,16,16,17,19,19,18,17,17,16,19,19,18,18,18,17,18,18,18,18,18,18,15,15,15,15,15,16,19,20,20,18,17,17,18,18,16,14,17,17,16,15,14,13,18,18,17,16,16,18,18,18,18,16,16,15,15,16,16,15,15,12,12,11,10,13,14,14,12,12,12,14,14,23,23,22,21,21,21,20,20,19,19,19,19,19,19,17,17,16,16,15,15,12,16,20,20,23,24,25,26,26,23,23,21,20,18,19,19,18,16,16,17,19,21,21,20,20,20,19,21,21,21,21,19,18,17,15,20,23,23,23,23,25,25,24,23,23,23,22,22,21,20, [...]
+"5",4,4,4,4,0,4,4,4,6,7,8,8,9,9,8,11,11,10,10,10,14,14,13,13,14,14,15,17,17,16,15,15,14,17,17,16,16,16,15,16,16,16,16,16,16,13,13,13,13,13,14,17,18,18,16,15,15,16,16,14,12,15,15,14,13,12,11,16,16,15,14,14,16,16,16,16,14,14,13,13,14,14,13,13,10,10,9,8,11,12,12,10,10,10,12,12,21,21,20,19,19,19,18,18,17,17,17,17,17,17,15,15,14,14,13,13,10,14,18,18,21,22,23,24,24,21,21,19,18,16,17,17,16,14,14,15,17,19,19,18,18,18,17,19,19,19,19,17,16,15,13,18,21,21,21,21,23,23,22,21,21,21,20,20,19,18,16,15,1 [...]
+"6",6,6,6,6,4,0,2,4,6,7,8,8,9,9,8,11,11,10,10,10,14,14,13,13,14,14,15,17,17,16,15,15,14,17,17,16,16,16,15,16,16,16,16,16,16,13,13,13,13,13,14,17,18,18,16,15,15,16,16,14,12,15,15,14,13,12,11,16,16,15,14,14,16,16,16,16,14,14,13,13,14,14,13,13,10,10,9,8,11,12,12,10,10,10,12,12,21,21,20,19,19,19,18,18,17,17,17,17,17,17,15,15,14,14,13,13,10,14,18,18,21,22,23,24,24,21,21,19,18,16,17,17,16,14,14,15,17,19,19,18,18,18,17,19,19,19,19,17,16,15,13,18,21,21,21,21,23,23,22,21,21,21,20,20,19,18,16,15,1 [...]
+"7",6,6,6,6,4,2,0,4,6,7,8,8,9,9,8,11,11,10,10,10,14,14,13,13,14,14,15,17,17,16,15,15,14,17,17,16,16,16,15,16,16,16,16,16,16,13,13,13,13,13,14,17,18,18,16,15,15,16,16,14,12,15,15,14,13,12,11,16,16,15,14,14,16,16,16,16,14,14,13,13,14,14,13,13,10,10,9,8,11,12,12,10,10,10,12,12,21,21,20,19,19,19,18,18,17,17,17,17,17,17,15,15,14,14,13,13,10,14,18,18,21,22,23,24,24,21,21,19,18,16,17,17,16,14,14,15,17,19,19,18,18,18,17,19,19,19,19,17,16,15,13,18,21,21,21,21,23,23,22,21,21,21,20,20,19,18,16,15,1 [...]
+"8",6,6,6,6,4,4,4,0,4,5,6,6,7,7,6,9,9,8,8,8,12,12,11,11,12,12,13,15,15,14,13,13,12,15,15,14,14,14,13,14,14,14,14,14,14,11,11,11,11,11,12,15,16,16,14,13,13,14,14,12,10,13,13,12,11,10,9,14,14,13,12,12,14,14,14,14,12,12,11,11,12,12,11,11,8,8,7,6,9,10,10,8,8,8,10,10,19,19,18,17,17,17,16,16,15,15,15,15,15,15,13,13,12,12,11,11,8,12,16,16,19,20,21,22,22,19,19,17,16,14,15,15,14,12,12,13,15,17,17,16,16,16,15,17,17,17,17,15,14,13,11,16,19,19,19,19,21,21,20,19,19,19,18,18,17,16,14,13,12,15,15,17,17 [...]
+"9",8,8,8,8,6,6,6,4,0,3,4,4,7,7,6,9,9,8,8,8,12,12,11,11,12,12,13,15,15,14,13,13,12,15,15,14,14,14,13,14,14,14,14,14,14,11,11,11,11,11,12,15,16,16,14,13,13,14,14,12,10,13,13,12,11,10,9,14,14,13,12,12,14,14,14,14,12,12,11,11,12,12,11,11,8,8,7,6,9,10,10,8,8,8,10,10,19,19,18,17,17,17,16,16,15,15,15,15,15,15,13,13,12,12,11,11,8,12,16,16,19,20,21,22,22,19,19,17,16,14,15,15,14,12,12,13,15,17,17,16,16,16,15,17,17,17,17,15,14,13,11,16,19,19,19,19,21,21,20,19,19,19,18,18,17,16,14,13,12,15,15,17,17 [...]
+"10",9,9,9,9,7,7,7,5,3,0,3,3,8,8,7,10,10,9,9,9,13,13,12,12,13,13,14,16,16,15,14,14,13,16,16,15,15,15,14,15,15,15,15,15,15,12,12,12,12,12,13,16,17,17,15,14,14,15,15,13,11,14,14,13,12,11,10,15,15,14,13,13,15,15,15,15,13,13,12,12,13,13,12,12,9,9,8,7,10,11,11,9,9,9,11,11,20,20,19,18,18,18,17,17,16,16,16,16,16,16,14,14,13,13,12,12,9,13,17,17,20,21,22,23,23,20,20,18,17,15,16,16,15,13,13,14,16,18,18,17,17,17,16,18,18,18,18,16,15,14,12,17,20,20,20,20,22,22,21,20,20,20,19,19,18,17,15,14,13,16,16, [...]
+"11",10,10,10,10,8,8,8,6,4,3,0,2,9,9,8,11,11,10,10,10,14,14,13,13,14,14,15,17,17,16,15,15,14,17,17,16,16,16,15,16,16,16,16,16,16,13,13,13,13,13,14,17,18,18,16,15,15,16,16,14,12,15,15,14,13,12,11,16,16,15,14,14,16,16,16,16,14,14,13,13,14,14,13,13,10,10,9,8,11,12,12,10,10,10,12,12,21,21,20,19,19,19,18,18,17,17,17,17,17,17,15,15,14,14,13,13,10,14,18,18,21,22,23,24,24,21,21,19,18,16,17,17,16,14,14,15,17,19,19,18,18,18,17,19,19,19,19,17,16,15,13,18,21,21,21,21,23,23,22,21,21,21,20,20,19,18,16 [...]
+"12",10,10,10,10,8,8,8,6,4,3,2,0,9,9,8,11,11,10,10,10,14,14,13,13,14,14,15,17,17,16,15,15,14,17,17,16,16,16,15,16,16,16,16,16,16,13,13,13,13,13,14,17,18,18,16,15,15,16,16,14,12,15,15,14,13,12,11,16,16,15,14,14,16,16,16,16,14,14,13,13,14,14,13,13,10,10,9,8,11,12,12,10,10,10,12,12,21,21,20,19,19,19,18,18,17,17,17,17,17,17,15,15,14,14,13,13,10,14,18,18,21,22,23,24,24,21,21,19,18,16,17,17,16,14,14,15,17,19,19,18,18,18,17,19,19,19,19,17,16,15,13,18,21,21,21,21,23,23,22,21,21,21,20,20,19,18,16 [...]
+"13",11,11,11,11,9,9,9,7,7,8,9,9,0,2,3,8,8,7,7,7,11,11,10,10,11,11,12,14,14,13,12,12,11,14,14,13,13,13,12,13,13,13,13,13,13,10,10,10,10,10,11,14,15,15,13,12,12,13,13,11,9,12,12,11,10,9,8,13,13,12,11,11,13,13,13,13,11,11,10,10,11,11,10,10,9,9,8,7,10,11,11,9,9,9,11,11,20,20,19,18,18,18,17,17,16,16,16,16,16,16,14,14,13,13,12,12,9,13,17,17,20,21,22,23,23,20,20,18,17,15,16,16,15,13,13,14,16,18,18,17,17,17,16,18,18,18,18,16,15,14,12,17,20,20,20,20,22,22,21,20,20,20,19,19,18,17,15,14,13,16,16,1 [...]
+"14",11,11,11,11,9,9,9,7,7,8,9,9,2,0,3,8,8,7,7,7,11,11,10,10,11,11,12,14,14,13,12,12,11,14,14,13,13,13,12,13,13,13,13,13,13,10,10,10,10,10,11,14,15,15,13,12,12,13,13,11,9,12,12,11,10,9,8,13,13,12,11,11,13,13,13,13,11,11,10,10,11,11,10,10,9,9,8,7,10,11,11,9,9,9,11,11,20,20,19,18,18,18,17,17,16,16,16,16,16,16,14,14,13,13,12,12,9,13,17,17,20,21,22,23,23,20,20,18,17,15,16,16,15,13,13,14,16,18,18,17,17,17,16,18,18,18,18,16,15,14,12,17,20,20,20,20,22,22,21,20,20,20,19,19,18,17,15,14,13,16,16,1 [...]
+"15",10,10,10,10,8,8,8,6,6,7,8,8,3,3,0,7,7,6,6,6,10,10,9,9,10,10,11,13,13,12,11,11,10,13,13,12,12,12,11,12,12,12,12,12,12,9,9,9,9,9,10,13,14,14,12,11,11,12,12,10,8,11,11,10,9,8,7,12,12,11,10,10,12,12,12,12,10,10,9,9,10,10,9,9,8,8,7,6,9,10,10,8,8,8,10,10,19,19,18,17,17,17,16,16,15,15,15,15,15,15,13,13,12,12,11,11,8,12,16,16,19,20,21,22,22,19,19,17,16,14,15,15,14,12,12,13,15,17,17,16,16,16,15,17,17,17,17,15,14,13,11,16,19,19,19,19,21,21,20,19,19,19,18,18,17,16,14,13,12,15,15,17,17,16,15,13 [...]
+"16",13,13,13,13,11,11,11,9,9,10,11,11,8,8,7,0,2,3,5,5,11,11,10,10,11,11,12,14,14,13,12,12,11,14,14,13,13,13,12,13,13,13,13,13,13,10,10,10,10,10,11,14,15,15,13,12,12,13,13,11,9,12,12,11,10,9,8,13,13,12,11,11,13,13,13,13,11,11,10,10,11,11,10,10,11,11,10,9,12,13,13,11,11,11,13,13,22,22,21,20,20,20,19,19,18,18,18,18,18,18,16,16,15,15,14,14,11,15,19,19,22,23,24,25,25,22,22,20,19,17,18,18,17,15,15,16,18,20,20,19,19,19,18,20,20,20,20,18,17,16,14,19,22,22,22,22,24,24,23,22,22,22,21,21,20,19,17, [...]
+"17",13,13,13,13,11,11,11,9,9,10,11,11,8,8,7,2,0,3,5,5,11,11,10,10,11,11,12,14,14,13,12,12,11,14,14,13,13,13,12,13,13,13,13,13,13,10,10,10,10,10,11,14,15,15,13,12,12,13,13,11,9,12,12,11,10,9,8,13,13,12,11,11,13,13,13,13,11,11,10,10,11,11,10,10,11,11,10,9,12,13,13,11,11,11,13,13,22,22,21,20,20,20,19,19,18,18,18,18,18,18,16,16,15,15,14,14,11,15,19,19,22,23,24,25,25,22,22,20,19,17,18,18,17,15,15,16,18,20,20,19,19,19,18,20,20,20,20,18,17,16,14,19,22,22,22,22,24,24,23,22,22,22,21,21,20,19,17, [...]
+"18",12,12,12,12,10,10,10,8,8,9,10,10,7,7,6,3,3,0,4,4,10,10,9,9,10,10,11,13,13,12,11,11,10,13,13,12,12,12,11,12,12,12,12,12,12,9,9,9,9,9,10,13,14,14,12,11,11,12,12,10,8,11,11,10,9,8,7,12,12,11,10,10,12,12,12,12,10,10,9,9,10,10,9,9,10,10,9,8,11,12,12,10,10,10,12,12,21,21,20,19,19,19,18,18,17,17,17,17,17,17,15,15,14,14,13,13,10,14,18,18,21,22,23,24,24,21,21,19,18,16,17,17,16,14,14,15,17,19,19,18,18,18,17,19,19,19,19,17,16,15,13,18,21,21,21,21,23,23,22,21,21,21,20,20,19,18,16,15,14,17,17,19 [...]
+"19",12,12,12,12,10,10,10,8,8,9,10,10,7,7,6,5,5,4,0,2,10,10,9,9,10,10,11,13,13,12,11,11,10,13,13,12,12,12,11,12,12,12,12,12,12,9,9,9,9,9,10,13,14,14,12,11,11,12,12,10,8,11,11,10,9,8,7,12,12,11,10,10,12,12,12,12,10,10,9,9,10,10,9,9,10,10,9,8,11,12,12,10,10,10,12,12,21,21,20,19,19,19,18,18,17,17,17,17,17,17,15,15,14,14,13,13,10,14,18,18,21,22,23,24,24,21,21,19,18,16,17,17,16,14,14,15,17,19,19,18,18,18,17,19,19,19,19,17,16,15,13,18,21,21,21,21,23,23,22,21,21,21,20,20,19,18,16,15,14,17,17,19 [...]
+"20",12,12,12,12,10,10,10,8,8,9,10,10,7,7,6,5,5,4,2,0,10,10,9,9,10,10,11,13,13,12,11,11,10,13,13,12,12,12,11,12,12,12,12,12,12,9,9,9,9,9,10,13,14,14,12,11,11,12,12,10,8,11,11,10,9,8,7,12,12,11,10,10,12,12,12,12,10,10,9,9,10,10,9,9,10,10,9,8,11,12,12,10,10,10,12,12,21,21,20,19,19,19,18,18,17,17,17,17,17,17,15,15,14,14,13,13,10,14,18,18,21,22,23,24,24,21,21,19,18,16,17,17,16,14,14,15,17,19,19,18,18,18,17,19,19,19,19,17,16,15,13,18,21,21,21,21,23,23,22,21,21,21,20,20,19,18,16,15,14,17,17,19 [...]
+"21",16,16,16,16,14,14,14,12,12,13,14,14,11,11,10,11,11,10,10,10,0,2,3,5,6,6,9,11,11,10,9,9,8,11,11,10,10,10,9,10,10,10,10,10,10,7,9,9,9,9,10,13,14,14,12,11,11,12,12,10,8,13,13,12,11,10,9,14,14,13,12,12,14,14,14,14,12,12,11,11,12,12,11,11,14,14,13,12,15,16,16,14,14,14,16,16,25,25,24,23,23,23,22,22,21,21,21,21,21,21,19,19,18,18,17,17,14,18,22,22,25,26,27,28,28,25,25,23,22,20,21,21,20,18,18,19,21,23,23,22,22,22,21,23,23,23,23,21,20,19,17,22,25,25,25,25,27,27,26,25,25,25,24,24,23,22,20,19,1 [...]
+"22",16,16,16,16,14,14,14,12,12,13,14,14,11,11,10,11,11,10,10,10,2,0,3,5,6,6,9,11,11,10,9,9,8,11,11,10,10,10,9,10,10,10,10,10,10,7,9,9,9,9,10,13,14,14,12,11,11,12,12,10,8,13,13,12,11,10,9,14,14,13,12,12,14,14,14,14,12,12,11,11,12,12,11,11,14,14,13,12,15,16,16,14,14,14,16,16,25,25,24,23,23,23,22,22,21,21,21,21,21,21,19,19,18,18,17,17,14,18,22,22,25,26,27,28,28,25,25,23,22,20,21,21,20,18,18,19,21,23,23,22,22,22,21,23,23,23,23,21,20,19,17,22,25,25,25,25,27,27,26,25,25,25,24,24,23,22,20,19,1 [...]
+"23",15,15,15,15,13,13,13,11,11,12,13,13,10,10,9,10,10,9,9,9,3,3,0,4,5,5,8,10,10,9,8,8,7,10,10,9,9,9,8,9,9,9,9,9,9,6,8,8,8,8,9,12,13,13,11,10,10,11,11,9,7,12,12,11,10,9,8,13,13,12,11,11,13,13,13,13,11,11,10,10,11,11,10,10,13,13,12,11,14,15,15,13,13,13,15,15,24,24,23,22,22,22,21,21,20,20,20,20,20,20,18,18,17,17,16,16,13,17,21,21,24,25,26,27,27,24,24,22,21,19,20,20,19,17,17,18,20,22,22,21,21,21,20,22,22,22,22,20,19,18,16,21,24,24,24,24,26,26,25,24,24,24,23,23,22,21,19,18,17,20,20,22,22,21, [...]
+"24",15,15,15,15,13,13,13,11,11,12,13,13,10,10,9,10,10,9,9,9,5,5,4,0,3,3,8,10,10,9,8,8,7,10,10,9,9,9,8,9,9,9,9,9,9,6,8,8,8,8,9,12,13,13,11,10,10,11,11,9,7,12,12,11,10,9,8,13,13,12,11,11,13,13,13,13,11,11,10,10,11,11,10,10,13,13,12,11,14,15,15,13,13,13,15,15,24,24,23,22,22,22,21,21,20,20,20,20,20,20,18,18,17,17,16,16,13,17,21,21,24,25,26,27,27,24,24,22,21,19,20,20,19,17,17,18,20,22,22,21,21,21,20,22,22,22,22,20,19,18,16,21,24,24,24,24,26,26,25,24,24,24,23,23,22,21,19,18,17,20,20,22,22,21, [...]
+"25",16,16,16,16,14,14,14,12,12,13,14,14,11,11,10,11,11,10,10,10,6,6,5,3,0,2,9,11,11,10,9,9,8,11,11,10,10,10,9,10,10,10,10,10,10,7,9,9,9,9,10,13,14,14,12,11,11,12,12,10,8,13,13,12,11,10,9,14,14,13,12,12,14,14,14,14,12,12,11,11,12,12,11,11,14,14,13,12,15,16,16,14,14,14,16,16,25,25,24,23,23,23,22,22,21,21,21,21,21,21,19,19,18,18,17,17,14,18,22,22,25,26,27,28,28,25,25,23,22,20,21,21,20,18,18,19,21,23,23,22,22,22,21,23,23,23,23,21,20,19,17,22,25,25,25,25,27,27,26,25,25,25,24,24,23,22,20,19,1 [...]
+"26",16,16,16,16,14,14,14,12,12,13,14,14,11,11,10,11,11,10,10,10,6,6,5,3,2,0,9,11,11,10,9,9,8,11,11,10,10,10,9,10,10,10,10,10,10,7,9,9,9,9,10,13,14,14,12,11,11,12,12,10,8,13,13,12,11,10,9,14,14,13,12,12,14,14,14,14,12,12,11,11,12,12,11,11,14,14,13,12,15,16,16,14,14,14,16,16,25,25,24,23,23,23,22,22,21,21,21,21,21,21,19,19,18,18,17,17,14,18,22,22,25,26,27,28,28,25,25,23,22,20,21,21,20,18,18,19,21,23,23,22,22,22,21,23,23,23,23,21,20,19,17,22,25,25,25,25,27,27,26,25,25,25,24,24,23,22,20,19,1 [...]
+"27",17,17,17,17,15,15,15,13,13,14,15,15,12,12,11,12,12,11,11,11,9,9,8,8,9,9,0,4,4,3,4,4,5,8,8,7,7,7,8,9,9,9,9,9,9,6,10,10,10,10,11,14,15,15,13,12,12,13,13,11,9,14,14,13,12,11,10,15,15,14,13,13,15,15,15,15,13,13,12,12,13,13,12,12,15,15,14,13,16,17,17,15,15,15,17,17,26,26,25,24,24,24,23,23,22,22,22,22,22,22,20,20,19,19,18,18,15,19,23,23,26,27,28,29,29,26,26,24,23,21,22,22,21,19,19,20,22,24,24,23,23,23,22,24,24,24,24,22,21,20,18,23,26,26,26,26,28,28,27,26,26,26,25,25,24,23,21,20,19,22,22,2 [...]
+"28",19,19,19,19,17,17,17,15,15,16,17,17,14,14,13,14,14,13,13,13,11,11,10,10,11,11,4,0,2,3,6,6,7,10,10,9,9,9,10,11,11,11,11,11,11,8,12,12,12,12,13,16,17,17,15,14,14,15,15,13,11,16,16,15,14,13,12,17,17,16,15,15,17,17,17,17,15,15,14,14,15,15,14,14,17,17,16,15,18,19,19,17,17,17,19,19,28,28,27,26,26,26,25,25,24,24,24,24,24,24,22,22,21,21,20,20,17,21,25,25,28,29,30,31,31,28,28,26,25,23,24,24,23,21,21,22,24,26,26,25,25,25,24,26,26,26,26,24,23,22,20,25,28,28,28,28,30,30,29,28,28,28,27,27,26,25, [...]
+"29",19,19,19,19,17,17,17,15,15,16,17,17,14,14,13,14,14,13,13,13,11,11,10,10,11,11,4,2,0,3,6,6,7,10,10,9,9,9,10,11,11,11,11,11,11,8,12,12,12,12,13,16,17,17,15,14,14,15,15,13,11,16,16,15,14,13,12,17,17,16,15,15,17,17,17,17,15,15,14,14,15,15,14,14,17,17,16,15,18,19,19,17,17,17,19,19,28,28,27,26,26,26,25,25,24,24,24,24,24,24,22,22,21,21,20,20,17,21,25,25,28,29,30,31,31,28,28,26,25,23,24,24,23,21,21,22,24,26,26,25,25,25,24,26,26,26,26,24,23,22,20,25,28,28,28,28,30,30,29,28,28,28,27,27,26,25, [...]
+"30",18,18,18,18,16,16,16,14,14,15,16,16,13,13,12,13,13,12,12,12,10,10,9,9,10,10,3,3,3,0,5,5,6,9,9,8,8,8,9,10,10,10,10,10,10,7,11,11,11,11,12,15,16,16,14,13,13,14,14,12,10,15,15,14,13,12,11,16,16,15,14,14,16,16,16,16,14,14,13,13,14,14,13,13,16,16,15,14,17,18,18,16,16,16,18,18,27,27,26,25,25,25,24,24,23,23,23,23,23,23,21,21,20,20,19,19,16,20,24,24,27,28,29,30,30,27,27,25,24,22,23,23,22,20,20,21,23,25,25,24,24,24,23,25,25,25,25,23,22,21,19,24,27,27,27,27,29,29,28,27,27,27,26,26,25,24,22,21 [...]
+"31",17,17,17,17,15,15,15,13,13,14,15,15,12,12,11,12,12,11,11,11,9,9,8,8,9,9,4,6,6,5,0,2,5,8,8,7,7,7,8,9,9,9,9,9,9,6,10,10,10,10,11,14,15,15,13,12,12,13,13,11,9,14,14,13,12,11,10,15,15,14,13,13,15,15,15,15,13,13,12,12,13,13,12,12,15,15,14,13,16,17,17,15,15,15,17,17,26,26,25,24,24,24,23,23,22,22,22,22,22,22,20,20,19,19,18,18,15,19,23,23,26,27,28,29,29,26,26,24,23,21,22,22,21,19,19,20,22,24,24,23,23,23,22,24,24,24,24,22,21,20,18,23,26,26,26,26,28,28,27,26,26,26,25,25,24,23,21,20,19,22,22,2 [...]
+"32",17,17,17,17,15,15,15,13,13,14,15,15,12,12,11,12,12,11,11,11,9,9,8,8,9,9,4,6,6,5,2,0,5,8,8,7,7,7,8,9,9,9,9,9,9,6,10,10,10,10,11,14,15,15,13,12,12,13,13,11,9,14,14,13,12,11,10,15,15,14,13,13,15,15,15,15,13,13,12,12,13,13,12,12,15,15,14,13,16,17,17,15,15,15,17,17,26,26,25,24,24,24,23,23,22,22,22,22,22,22,20,20,19,19,18,18,15,19,23,23,26,27,28,29,29,26,26,24,23,21,22,22,21,19,19,20,22,24,24,23,23,23,22,24,24,24,24,22,21,20,18,23,26,26,26,26,28,28,27,26,26,26,25,25,24,23,21,20,19,22,22,2 [...]
+"33",16,16,16,16,14,14,14,12,12,13,14,14,11,11,10,11,11,10,10,10,8,8,7,7,8,8,5,7,7,6,5,5,0,5,5,4,4,4,7,8,8,8,8,8,8,5,9,9,9,9,10,13,14,14,12,11,11,12,12,10,8,13,13,12,11,10,9,14,14,13,12,12,14,14,14,14,12,12,11,11,12,12,11,11,14,14,13,12,15,16,16,14,14,14,16,16,25,25,24,23,23,23,22,22,21,21,21,21,21,21,19,19,18,18,17,17,14,18,22,22,25,26,27,28,28,25,25,23,22,20,21,21,20,18,18,19,21,23,23,22,22,22,21,23,23,23,23,21,20,19,17,22,25,25,25,25,27,27,26,25,25,25,24,24,23,22,20,19,18,21,21,23,23, [...]
+"34",19,19,19,19,17,17,17,15,15,16,17,17,14,14,13,14,14,13,13,13,11,11,10,10,11,11,8,10,10,9,8,8,5,0,2,3,5,5,10,11,11,11,11,11,11,8,12,12,12,12,13,16,17,17,15,14,14,15,15,13,11,16,16,15,14,13,12,17,17,16,15,15,17,17,17,17,15,15,14,14,15,15,14,14,17,17,16,15,18,19,19,17,17,17,19,19,28,28,27,26,26,26,25,25,24,24,24,24,24,24,22,22,21,21,20,20,17,21,25,25,28,29,30,31,31,28,28,26,25,23,24,24,23,21,21,22,24,26,26,25,25,25,24,26,26,26,26,24,23,22,20,25,28,28,28,28,30,30,29,28,28,28,27,27,26,25, [...]
+"35",19,19,19,19,17,17,17,15,15,16,17,17,14,14,13,14,14,13,13,13,11,11,10,10,11,11,8,10,10,9,8,8,5,2,0,3,5,5,10,11,11,11,11,11,11,8,12,12,12,12,13,16,17,17,15,14,14,15,15,13,11,16,16,15,14,13,12,17,17,16,15,15,17,17,17,17,15,15,14,14,15,15,14,14,17,17,16,15,18,19,19,17,17,17,19,19,28,28,27,26,26,26,25,25,24,24,24,24,24,24,22,22,21,21,20,20,17,21,25,25,28,29,30,31,31,28,28,26,25,23,24,24,23,21,21,22,24,26,26,25,25,25,24,26,26,26,26,24,23,22,20,25,28,28,28,28,30,30,29,28,28,28,27,27,26,25, [...]
+"36",18,18,18,18,16,16,16,14,14,15,16,16,13,13,12,13,13,12,12,12,10,10,9,9,10,10,7,9,9,8,7,7,4,3,3,0,4,4,9,10,10,10,10,10,10,7,11,11,11,11,12,15,16,16,14,13,13,14,14,12,10,15,15,14,13,12,11,16,16,15,14,14,16,16,16,16,14,14,13,13,14,14,13,13,16,16,15,14,17,18,18,16,16,16,18,18,27,27,26,25,25,25,24,24,23,23,23,23,23,23,21,21,20,20,19,19,16,20,24,24,27,28,29,30,30,27,27,25,24,22,23,23,22,20,20,21,23,25,25,24,24,24,23,25,25,25,25,23,22,21,19,24,27,27,27,27,29,29,28,27,27,27,26,26,25,24,22,21 [...]
+"37",18,18,18,18,16,16,16,14,14,15,16,16,13,13,12,13,13,12,12,12,10,10,9,9,10,10,7,9,9,8,7,7,4,5,5,4,0,2,9,10,10,10,10,10,10,7,11,11,11,11,12,15,16,16,14,13,13,14,14,12,10,15,15,14,13,12,11,16,16,15,14,14,16,16,16,16,14,14,13,13,14,14,13,13,16,16,15,14,17,18,18,16,16,16,18,18,27,27,26,25,25,25,24,24,23,23,23,23,23,23,21,21,20,20,19,19,16,20,24,24,27,28,29,30,30,27,27,25,24,22,23,23,22,20,20,21,23,25,25,24,24,24,23,25,25,25,25,23,22,21,19,24,27,27,27,27,29,29,28,27,27,27,26,26,25,24,22,21 [...]
+"38",18,18,18,18,16,16,16,14,14,15,16,16,13,13,12,13,13,12,12,12,10,10,9,9,10,10,7,9,9,8,7,7,4,5,5,4,2,0,9,10,10,10,10,10,10,7,11,11,11,11,12,15,16,16,14,13,13,14,14,12,10,15,15,14,13,12,11,16,16,15,14,14,16,16,16,16,14,14,13,13,14,14,13,13,16,16,15,14,17,18,18,16,16,16,18,18,27,27,26,25,25,25,24,24,23,23,23,23,23,23,21,21,20,20,19,19,16,20,24,24,27,28,29,30,30,27,27,25,24,22,23,23,22,20,20,21,23,25,25,24,24,24,23,25,25,25,25,23,22,21,19,24,27,27,27,27,29,29,28,27,27,27,26,26,25,24,22,21 [...]
+"39",17,17,17,17,15,15,15,13,13,14,15,15,12,12,11,12,12,11,11,11,9,9,8,8,9,9,8,10,10,9,8,8,7,10,10,9,9,9,0,3,3,5,5,5,5,4,10,10,10,10,11,14,15,15,13,12,12,13,13,11,9,14,14,13,12,11,10,15,15,14,13,13,15,15,15,15,13,13,12,12,13,13,12,12,15,15,14,13,16,17,17,15,15,15,17,17,26,26,25,24,24,24,23,23,22,22,22,22,22,22,20,20,19,19,18,18,15,19,23,23,26,27,28,29,29,26,26,24,23,21,22,22,21,19,19,20,22,24,24,23,23,23,22,24,24,24,24,22,21,20,18,23,26,26,26,26,28,28,27,26,26,26,25,25,24,23,21,20,19,22, [...]
+"40",18,18,18,18,16,16,16,14,14,15,16,16,13,13,12,13,13,12,12,12,10,10,9,9,10,10,9,11,11,10,9,9,8,11,11,10,10,10,3,0,2,6,6,6,6,5,11,11,11,11,12,15,16,16,14,13,13,14,14,12,10,15,15,14,13,12,11,16,16,15,14,14,16,16,16,16,14,14,13,13,14,14,13,13,16,16,15,14,17,18,18,16,16,16,18,18,27,27,26,25,25,25,24,24,23,23,23,23,23,23,21,21,20,20,19,19,16,20,24,24,27,28,29,30,30,27,27,25,24,22,23,23,22,20,20,21,23,25,25,24,24,24,23,25,25,25,25,23,22,21,19,24,27,27,27,27,29,29,28,27,27,27,26,26,25,24,22, [...]
+"41",18,18,18,18,16,16,16,14,14,15,16,16,13,13,12,13,13,12,12,12,10,10,9,9,10,10,9,11,11,10,9,9,8,11,11,10,10,10,3,2,0,6,6,6,6,5,11,11,11,11,12,15,16,16,14,13,13,14,14,12,10,15,15,14,13,12,11,16,16,15,14,14,16,16,16,16,14,14,13,13,14,14,13,13,16,16,15,14,17,18,18,16,16,16,18,18,27,27,26,25,25,25,24,24,23,23,23,23,23,23,21,21,20,20,19,19,16,20,24,24,27,28,29,30,30,27,27,25,24,22,23,23,22,20,20,21,23,25,25,24,24,24,23,25,25,25,25,23,22,21,19,24,27,27,27,27,29,29,28,27,27,27,26,26,25,24,22, [...]
+"42",18,18,18,18,16,16,16,14,14,15,16,16,13,13,12,13,13,12,12,12,10,10,9,9,10,10,9,11,11,10,9,9,8,11,11,10,10,10,5,6,6,0,2,4,4,5,11,11,11,11,12,15,16,16,14,13,13,14,14,12,10,15,15,14,13,12,11,16,16,15,14,14,16,16,16,16,14,14,13,13,14,14,13,13,16,16,15,14,17,18,18,16,16,16,18,18,27,27,26,25,25,25,24,24,23,23,23,23,23,23,21,21,20,20,19,19,16,20,24,24,27,28,29,30,30,27,27,25,24,22,23,23,22,20,20,21,23,25,25,24,24,24,23,25,25,25,25,23,22,21,19,24,27,27,27,27,29,29,28,27,27,27,26,26,25,24,22, [...]
+"43",18,18,18,18,16,16,16,14,14,15,16,16,13,13,12,13,13,12,12,12,10,10,9,9,10,10,9,11,11,10,9,9,8,11,11,10,10,10,5,6,6,2,0,4,4,5,11,11,11,11,12,15,16,16,14,13,13,14,14,12,10,15,15,14,13,12,11,16,16,15,14,14,16,16,16,16,14,14,13,13,14,14,13,13,16,16,15,14,17,18,18,16,16,16,18,18,27,27,26,25,25,25,24,24,23,23,23,23,23,23,21,21,20,20,19,19,16,20,24,24,27,28,29,30,30,27,27,25,24,22,23,23,22,20,20,21,23,25,25,24,24,24,23,25,25,25,25,23,22,21,19,24,27,27,27,27,29,29,28,27,27,27,26,26,25,24,22, [...]
+"44",18,18,18,18,16,16,16,14,14,15,16,16,13,13,12,13,13,12,12,12,10,10,9,9,10,10,9,11,11,10,9,9,8,11,11,10,10,10,5,6,6,4,4,0,2,5,11,11,11,11,12,15,16,16,14,13,13,14,14,12,10,15,15,14,13,12,11,16,16,15,14,14,16,16,16,16,14,14,13,13,14,14,13,13,16,16,15,14,17,18,18,16,16,16,18,18,27,27,26,25,25,25,24,24,23,23,23,23,23,23,21,21,20,20,19,19,16,20,24,24,27,28,29,30,30,27,27,25,24,22,23,23,22,20,20,21,23,25,25,24,24,24,23,25,25,25,25,23,22,21,19,24,27,27,27,27,29,29,28,27,27,27,26,26,25,24,22, [...]
+"45",18,18,18,18,16,16,16,14,14,15,16,16,13,13,12,13,13,12,12,12,10,10,9,9,10,10,9,11,11,10,9,9,8,11,11,10,10,10,5,6,6,4,4,2,0,5,11,11,11,11,12,15,16,16,14,13,13,14,14,12,10,15,15,14,13,12,11,16,16,15,14,14,16,16,16,16,14,14,13,13,14,14,13,13,16,16,15,14,17,18,18,16,16,16,18,18,27,27,26,25,25,25,24,24,23,23,23,23,23,23,21,21,20,20,19,19,16,20,24,24,27,28,29,30,30,27,27,25,24,22,23,23,22,20,20,21,23,25,25,24,24,24,23,25,25,25,25,23,22,21,19,24,27,27,27,27,29,29,28,27,27,27,26,26,25,24,22, [...]
+"46",15,15,15,15,13,13,13,11,11,12,13,13,10,10,9,10,10,9,9,9,7,7,6,6,7,7,6,8,8,7,6,6,5,8,8,7,7,7,4,5,5,5,5,5,5,0,8,8,8,8,9,12,13,13,11,10,10,11,11,9,7,12,12,11,10,9,8,13,13,12,11,11,13,13,13,13,11,11,10,10,11,11,10,10,13,13,12,11,14,15,15,13,13,13,15,15,24,24,23,22,22,22,21,21,20,20,20,20,20,20,18,18,17,17,16,16,13,17,21,21,24,25,26,27,27,24,24,22,21,19,20,20,19,17,17,18,20,22,22,21,21,21,20,22,22,22,22,20,19,18,16,21,24,24,24,24,26,26,25,24,24,24,23,23,22,21,19,18,17,20,20,22,22,21,20,1 [...]
+"47",15,15,15,15,13,13,13,11,11,12,13,13,10,10,9,10,10,9,9,9,9,9,8,8,9,9,10,12,12,11,10,10,9,12,12,11,11,11,10,11,11,11,11,11,11,8,0,2,4,4,7,10,11,11,9,8,8,9,9,7,5,12,12,11,10,9,8,13,13,12,11,11,13,13,13,13,11,11,10,10,11,11,10,10,13,13,12,11,14,15,15,13,13,13,15,15,24,24,23,22,22,22,21,21,20,20,20,20,20,20,18,18,17,17,16,16,13,17,21,21,24,25,26,27,27,24,24,22,21,19,20,20,19,17,17,18,20,22,22,21,21,21,20,22,22,22,22,20,19,18,16,21,24,24,24,24,26,26,25,24,24,24,23,23,22,21,19,18,17,20,20, [...]
+"48",15,15,15,15,13,13,13,11,11,12,13,13,10,10,9,10,10,9,9,9,9,9,8,8,9,9,10,12,12,11,10,10,9,12,12,11,11,11,10,11,11,11,11,11,11,8,2,0,4,4,7,10,11,11,9,8,8,9,9,7,5,12,12,11,10,9,8,13,13,12,11,11,13,13,13,13,11,11,10,10,11,11,10,10,13,13,12,11,14,15,15,13,13,13,15,15,24,24,23,22,22,22,21,21,20,20,20,20,20,20,18,18,17,17,16,16,13,17,21,21,24,25,26,27,27,24,24,22,21,19,20,20,19,17,17,18,20,22,22,21,21,21,20,22,22,22,22,20,19,18,16,21,24,24,24,24,26,26,25,24,24,24,23,23,22,21,19,18,17,20,20, [...]
+"49",15,15,15,15,13,13,13,11,11,12,13,13,10,10,9,10,10,9,9,9,9,9,8,8,9,9,10,12,12,11,10,10,9,12,12,11,11,11,10,11,11,11,11,11,11,8,4,4,0,2,7,10,11,11,9,8,8,9,9,7,5,12,12,11,10,9,8,13,13,12,11,11,13,13,13,13,11,11,10,10,11,11,10,10,13,13,12,11,14,15,15,13,13,13,15,15,24,24,23,22,22,22,21,21,20,20,20,20,20,20,18,18,17,17,16,16,13,17,21,21,24,25,26,27,27,24,24,22,21,19,20,20,19,17,17,18,20,22,22,21,21,21,20,22,22,22,22,20,19,18,16,21,24,24,24,24,26,26,25,24,24,24,23,23,22,21,19,18,17,20,20, [...]
+"50",15,15,15,15,13,13,13,11,11,12,13,13,10,10,9,10,10,9,9,9,9,9,8,8,9,9,10,12,12,11,10,10,9,12,12,11,11,11,10,11,11,11,11,11,11,8,4,4,2,0,7,10,11,11,9,8,8,9,9,7,5,12,12,11,10,9,8,13,13,12,11,11,13,13,13,13,11,11,10,10,11,11,10,10,13,13,12,11,14,15,15,13,13,13,15,15,24,24,23,22,22,22,21,21,20,20,20,20,20,20,18,18,17,17,16,16,13,17,21,21,24,25,26,27,27,24,24,22,21,19,20,20,19,17,17,18,20,22,22,21,21,21,20,22,22,22,22,20,19,18,16,21,24,24,24,24,26,26,25,24,24,24,23,23,22,21,19,18,17,20,20, [...]
+"51",16,16,16,16,14,14,14,12,12,13,14,14,11,11,10,11,11,10,10,10,10,10,9,9,10,10,11,13,13,12,11,11,10,13,13,12,12,12,11,12,12,12,12,12,12,9,7,7,7,7,0,5,6,6,4,3,5,6,6,4,4,13,13,12,11,10,9,14,14,13,12,12,14,14,14,14,12,12,11,11,12,12,11,11,14,14,13,12,15,16,16,14,14,14,16,16,25,25,24,23,23,23,22,22,21,21,21,21,21,21,19,19,18,18,17,17,14,18,22,22,25,26,27,28,28,25,25,23,22,20,21,21,20,18,18,19,21,23,23,22,22,22,21,23,23,23,23,21,20,19,17,22,25,25,25,25,27,27,26,25,25,25,24,24,23,22,20,19,18 [...]
+"52",19,19,19,19,17,17,17,15,15,16,17,17,14,14,13,14,14,13,13,13,13,13,12,12,13,13,14,16,16,15,14,14,13,16,16,15,15,15,14,15,15,15,15,15,15,12,10,10,10,10,5,0,3,3,3,4,8,9,9,7,7,16,16,15,14,13,12,17,17,16,15,15,17,17,17,17,15,15,14,14,15,15,14,14,17,17,16,15,18,19,19,17,17,17,19,19,28,28,27,26,26,26,25,25,24,24,24,24,24,24,22,22,21,21,20,20,17,21,25,25,28,29,30,31,31,28,28,26,25,23,24,24,23,21,21,22,24,26,26,25,25,25,24,26,26,26,26,24,23,22,20,25,28,28,28,28,30,30,29,28,28,28,27,27,26,25, [...]
+"53",20,20,20,20,18,18,18,16,16,17,18,18,15,15,14,15,15,14,14,14,14,14,13,13,14,14,15,17,17,16,15,15,14,17,17,16,16,16,15,16,16,16,16,16,16,13,11,11,11,11,6,3,0,2,4,5,9,10,10,8,8,17,17,16,15,14,13,18,18,17,16,16,18,18,18,18,16,16,15,15,16,16,15,15,18,18,17,16,19,20,20,18,18,18,20,20,29,29,28,27,27,27,26,26,25,25,25,25,25,25,23,23,22,22,21,21,18,22,26,26,29,30,31,32,32,29,29,27,26,24,25,25,24,22,22,23,25,27,27,26,26,26,25,27,27,27,27,25,24,23,21,26,29,29,29,29,31,31,30,29,29,29,28,28,27,2 [...]
+"54",20,20,20,20,18,18,18,16,16,17,18,18,15,15,14,15,15,14,14,14,14,14,13,13,14,14,15,17,17,16,15,15,14,17,17,16,16,16,15,16,16,16,16,16,16,13,11,11,11,11,6,3,2,0,4,5,9,10,10,8,8,17,17,16,15,14,13,18,18,17,16,16,18,18,18,18,16,16,15,15,16,16,15,15,18,18,17,16,19,20,20,18,18,18,20,20,29,29,28,27,27,27,26,26,25,25,25,25,25,25,23,23,22,22,21,21,18,22,26,26,29,30,31,32,32,29,29,27,26,24,25,25,24,22,22,23,25,27,27,26,26,26,25,27,27,27,27,25,24,23,21,26,29,29,29,29,31,31,30,29,29,29,28,28,27,2 [...]
+"55",18,18,18,18,16,16,16,14,14,15,16,16,13,13,12,13,13,12,12,12,12,12,11,11,12,12,13,15,15,14,13,13,12,15,15,14,14,14,13,14,14,14,14,14,14,11,9,9,9,9,4,3,4,4,0,3,7,8,8,6,6,15,15,14,13,12,11,16,16,15,14,14,16,16,16,16,14,14,13,13,14,14,13,13,16,16,15,14,17,18,18,16,16,16,18,18,27,27,26,25,25,25,24,24,23,23,23,23,23,23,21,21,20,20,19,19,16,20,24,24,27,28,29,30,30,27,27,25,24,22,23,23,22,20,20,21,23,25,25,24,24,24,23,25,25,25,25,23,22,21,19,24,27,27,27,27,29,29,28,27,27,27,26,26,25,24,22,2 [...]
+"56",17,17,17,17,15,15,15,13,13,14,15,15,12,12,11,12,12,11,11,11,11,11,10,10,11,11,12,14,14,13,12,12,11,14,14,13,13,13,12,13,13,13,13,13,13,10,8,8,8,8,3,4,5,5,3,0,6,7,7,5,5,14,14,13,12,11,10,15,15,14,13,13,15,15,15,15,13,13,12,12,13,13,12,12,15,15,14,13,16,17,17,15,15,15,17,17,26,26,25,24,24,24,23,23,22,22,22,22,22,22,20,20,19,19,18,18,15,19,23,23,26,27,28,29,29,26,26,24,23,21,22,22,21,19,19,20,22,24,24,23,23,23,22,24,24,24,24,22,21,20,18,23,26,26,26,26,28,28,27,26,26,26,25,25,24,23,21,2 [...]
+"57",17,17,17,17,15,15,15,13,13,14,15,15,12,12,11,12,12,11,11,11,11,11,10,10,11,11,12,14,14,13,12,12,11,14,14,13,13,13,12,13,13,13,13,13,13,10,8,8,8,8,5,8,9,9,7,6,0,3,3,3,5,14,14,13,12,11,10,15,15,14,13,13,15,15,15,15,13,13,12,12,13,13,12,12,15,15,14,13,16,17,17,15,15,15,17,17,26,26,25,24,24,24,23,23,22,22,22,22,22,22,20,20,19,19,18,18,15,19,23,23,26,27,28,29,29,26,26,24,23,21,22,22,21,19,19,20,22,24,24,23,23,23,22,24,24,24,24,22,21,20,18,23,26,26,26,26,28,28,27,26,26,26,25,25,24,23,21,2 [...]
+"58",18,18,18,18,16,16,16,14,14,15,16,16,13,13,12,13,13,12,12,12,12,12,11,11,12,12,13,15,15,14,13,13,12,15,15,14,14,14,13,14,14,14,14,14,14,11,9,9,9,9,6,9,10,10,8,7,3,0,2,4,6,15,15,14,13,12,11,16,16,15,14,14,16,16,16,16,14,14,13,13,14,14,13,13,16,16,15,14,17,18,18,16,16,16,18,18,27,27,26,25,25,25,24,24,23,23,23,23,23,23,21,21,20,20,19,19,16,20,24,24,27,28,29,30,30,27,27,25,24,22,23,23,22,20,20,21,23,25,25,24,24,24,23,25,25,25,25,23,22,21,19,24,27,27,27,27,29,29,28,27,27,27,26,26,25,24,22 [...]
+"59",18,18,18,18,16,16,16,14,14,15,16,16,13,13,12,13,13,12,12,12,12,12,11,11,12,12,13,15,15,14,13,13,12,15,15,14,14,14,13,14,14,14,14,14,14,11,9,9,9,9,6,9,10,10,8,7,3,2,0,4,6,15,15,14,13,12,11,16,16,15,14,14,16,16,16,16,14,14,13,13,14,14,13,13,16,16,15,14,17,18,18,16,16,16,18,18,27,27,26,25,25,25,24,24,23,23,23,23,23,23,21,21,20,20,19,19,16,20,24,24,27,28,29,30,30,27,27,25,24,22,23,23,22,20,20,21,23,25,25,24,24,24,23,25,25,25,25,23,22,21,19,24,27,27,27,27,29,29,28,27,27,27,26,26,25,24,22 [...]
+"60",16,16,16,16,14,14,14,12,12,13,14,14,11,11,10,11,11,10,10,10,10,10,9,9,10,10,11,13,13,12,11,11,10,13,13,12,12,12,11,12,12,12,12,12,12,9,7,7,7,7,4,7,8,8,6,5,3,4,4,0,4,13,13,12,11,10,9,14,14,13,12,12,14,14,14,14,12,12,11,11,12,12,11,11,14,14,13,12,15,16,16,14,14,14,16,16,25,25,24,23,23,23,22,22,21,21,21,21,21,21,19,19,18,18,17,17,14,18,22,22,25,26,27,28,28,25,25,23,22,20,21,21,20,18,18,19,21,23,23,22,22,22,21,23,23,23,23,21,20,19,17,22,25,25,25,25,27,27,26,25,25,25,24,24,23,22,20,19,18 [...]
+"61",14,14,14,14,12,12,12,10,10,11,12,12,9,9,8,9,9,8,8,8,8,8,7,7,8,8,9,11,11,10,9,9,8,11,11,10,10,10,9,10,10,10,10,10,10,7,5,5,5,5,4,7,8,8,6,5,5,6,6,4,0,11,11,10,9,8,7,12,12,11,10,10,12,12,12,12,10,10,9,9,10,10,9,9,12,12,11,10,13,14,14,12,12,12,14,14,23,23,22,21,21,21,20,20,19,19,19,19,19,19,17,17,16,16,15,15,12,16,20,20,23,24,25,26,26,23,23,21,20,18,19,19,18,16,16,17,19,21,21,20,20,20,19,21,21,21,21,19,18,17,15,20,23,23,23,23,25,25,24,23,23,23,22,22,21,20,18,17,16,19,19,21,21,20,19,17,1 [...]
+"62",17,17,17,17,15,15,15,13,13,14,15,15,12,12,11,12,12,11,11,11,13,13,12,12,13,13,14,16,16,15,14,14,13,16,16,15,15,15,14,15,15,15,15,15,15,12,12,12,12,12,13,16,17,17,15,14,14,15,15,13,11,0,2,3,4,5,6,13,13,12,11,11,13,13,13,13,11,11,10,10,11,11,10,10,15,15,14,13,16,17,17,15,15,15,17,17,26,26,25,24,24,24,23,23,22,22,22,22,22,22,20,20,19,19,18,18,15,19,23,23,26,27,28,29,29,26,26,24,23,21,22,22,21,19,19,20,22,24,24,23,23,23,22,24,24,24,24,22,21,20,18,23,26,26,26,26,28,28,27,26,26,26,25,25,2 [...]
+"63",17,17,17,17,15,15,15,13,13,14,15,15,12,12,11,12,12,11,11,11,13,13,12,12,13,13,14,16,16,15,14,14,13,16,16,15,15,15,14,15,15,15,15,15,15,12,12,12,12,12,13,16,17,17,15,14,14,15,15,13,11,2,0,3,4,5,6,13,13,12,11,11,13,13,13,13,11,11,10,10,11,11,10,10,15,15,14,13,16,17,17,15,15,15,17,17,26,26,25,24,24,24,23,23,22,22,22,22,22,22,20,20,19,19,18,18,15,19,23,23,26,27,28,29,29,26,26,24,23,21,22,22,21,19,19,20,22,24,24,23,23,23,22,24,24,24,24,22,21,20,18,23,26,26,26,26,28,28,27,26,26,26,25,25,2 [...]
+"64",16,16,16,16,14,14,14,12,12,13,14,14,11,11,10,11,11,10,10,10,12,12,11,11,12,12,13,15,15,14,13,13,12,15,15,14,14,14,13,14,14,14,14,14,14,11,11,11,11,11,12,15,16,16,14,13,13,14,14,12,10,3,3,0,3,4,5,12,12,11,10,10,12,12,12,12,10,10,9,9,10,10,9,9,14,14,13,12,15,16,16,14,14,14,16,16,25,25,24,23,23,23,22,22,21,21,21,21,21,21,19,19,18,18,17,17,14,18,22,22,25,26,27,28,28,25,25,23,22,20,21,21,20,18,18,19,21,23,23,22,22,22,21,23,23,23,23,21,20,19,17,22,25,25,25,25,27,27,26,25,25,25,24,24,23,22 [...]
+"65",15,15,15,15,13,13,13,11,11,12,13,13,10,10,9,10,10,9,9,9,11,11,10,10,11,11,12,14,14,13,12,12,11,14,14,13,13,13,12,13,13,13,13,13,13,10,10,10,10,10,11,14,15,15,13,12,12,13,13,11,9,4,4,3,0,3,4,11,11,10,9,9,11,11,11,11,9,9,8,8,9,9,8,8,13,13,12,11,14,15,15,13,13,13,15,15,24,24,23,22,22,22,21,21,20,20,20,20,20,20,18,18,17,17,16,16,13,17,21,21,24,25,26,27,27,24,24,22,21,19,20,20,19,17,17,18,20,22,22,21,21,21,20,22,22,22,22,20,19,18,16,21,24,24,24,24,26,26,25,24,24,24,23,23,22,21,19,18,17,2 [...]
+"66",14,14,14,14,12,12,12,10,10,11,12,12,9,9,8,9,9,8,8,8,10,10,9,9,10,10,11,13,13,12,11,11,10,13,13,12,12,12,11,12,12,12,12,12,12,9,9,9,9,9,10,13,14,14,12,11,11,12,12,10,8,5,5,4,3,0,3,10,10,9,8,8,10,10,10,10,8,8,7,7,8,8,7,7,12,12,11,10,13,14,14,12,12,12,14,14,23,23,22,21,21,21,20,20,19,19,19,19,19,19,17,17,16,16,15,15,12,16,20,20,23,24,25,26,26,23,23,21,20,18,19,19,18,16,16,17,19,21,21,20,20,20,19,21,21,21,21,19,18,17,15,20,23,23,23,23,25,25,24,23,23,23,22,22,21,20,18,17,16,19,19,21,21,2 [...]
+"67",13,13,13,13,11,11,11,9,9,10,11,11,8,8,7,8,8,7,7,7,9,9,8,8,9,9,10,12,12,11,10,10,9,12,12,11,11,11,10,11,11,11,11,11,11,8,8,8,8,8,9,12,13,13,11,10,10,11,11,9,7,6,6,5,4,3,0,9,9,8,7,7,9,9,9,9,7,7,6,6,7,7,6,6,11,11,10,9,12,13,13,11,11,11,13,13,22,22,21,20,20,20,19,19,18,18,18,18,18,18,16,16,15,15,14,14,11,15,19,19,22,23,24,25,25,22,22,20,19,17,18,18,17,15,15,16,18,20,20,19,19,19,18,20,20,20,20,18,17,16,14,19,22,22,22,22,24,24,23,22,22,22,21,21,20,19,17,16,15,18,18,20,20,19,18,16,15,16,17 [...]
+"68",18,18,18,18,16,16,16,14,14,15,16,16,13,13,12,13,13,12,12,12,14,14,13,13,14,14,15,17,17,16,15,15,14,17,17,16,16,16,15,16,16,16,16,16,16,13,13,13,13,13,14,17,18,18,16,15,15,16,16,14,12,13,13,12,11,10,9,0,2,3,4,6,8,8,8,8,8,8,7,9,10,10,9,9,16,16,15,14,17,18,18,16,16,16,18,18,27,27,26,25,25,25,24,24,23,23,23,23,23,23,21,21,20,20,19,19,16,20,24,24,27,28,29,30,30,27,27,25,24,22,23,23,22,20,20,21,23,25,25,24,24,24,23,25,25,25,25,23,22,21,19,24,27,27,27,27,29,29,28,27,27,27,26,26,25,24,22,21 [...]
+"69",18,18,18,18,16,16,16,14,14,15,16,16,13,13,12,13,13,12,12,12,14,14,13,13,14,14,15,17,17,16,15,15,14,17,17,16,16,16,15,16,16,16,16,16,16,13,13,13,13,13,14,17,18,18,16,15,15,16,16,14,12,13,13,12,11,10,9,2,0,3,4,6,8,8,8,8,8,8,7,9,10,10,9,9,16,16,15,14,17,18,18,16,16,16,18,18,27,27,26,25,25,25,24,24,23,23,23,23,23,23,21,21,20,20,19,19,16,20,24,24,27,28,29,30,30,27,27,25,24,22,23,23,22,20,20,21,23,25,25,24,24,24,23,25,25,25,25,23,22,21,19,24,27,27,27,27,29,29,28,27,27,27,26,26,25,24,22,21 [...]
+"70",17,17,17,17,15,15,15,13,13,14,15,15,12,12,11,12,12,11,11,11,13,13,12,12,13,13,14,16,16,15,14,14,13,16,16,15,15,15,14,15,15,15,15,15,15,12,12,12,12,12,13,16,17,17,15,14,14,15,15,13,11,12,12,11,10,9,8,3,3,0,3,5,7,7,7,7,7,7,6,8,9,9,8,8,15,15,14,13,16,17,17,15,15,15,17,17,26,26,25,24,24,24,23,23,22,22,22,22,22,22,20,20,19,19,18,18,15,19,23,23,26,27,28,29,29,26,26,24,23,21,22,22,21,19,19,20,22,24,24,23,23,23,22,24,24,24,24,22,21,20,18,23,26,26,26,26,28,28,27,26,26,26,25,25,24,23,21,20,19 [...]
+"71",16,16,16,16,14,14,14,12,12,13,14,14,11,11,10,11,11,10,10,10,12,12,11,11,12,12,13,15,15,14,13,13,12,15,15,14,14,14,13,14,14,14,14,14,14,11,11,11,11,11,12,15,16,16,14,13,13,14,14,12,10,11,11,10,9,8,7,4,4,3,0,4,6,6,6,6,6,6,5,7,8,8,7,7,14,14,13,12,15,16,16,14,14,14,16,16,25,25,24,23,23,23,22,22,21,21,21,21,21,21,19,19,18,18,17,17,14,18,22,22,25,26,27,28,28,25,25,23,22,20,21,21,20,18,18,19,21,23,23,22,22,22,21,23,23,23,23,21,20,19,17,22,25,25,25,25,27,27,26,25,25,25,24,24,23,22,20,19,18, [...]
+"72",16,16,16,16,14,14,14,12,12,13,14,14,11,11,10,11,11,10,10,10,12,12,11,11,12,12,13,15,15,14,13,13,12,15,15,14,14,14,13,14,14,14,14,14,14,11,11,11,11,11,12,15,16,16,14,13,13,14,14,12,10,11,11,10,9,8,7,6,6,5,4,0,4,4,4,4,6,6,5,7,8,8,7,7,14,14,13,12,15,16,16,14,14,14,16,16,25,25,24,23,23,23,22,22,21,21,21,21,21,21,19,19,18,18,17,17,14,18,22,22,25,26,27,28,28,25,25,23,22,20,21,21,20,18,18,19,21,23,23,22,22,22,21,23,23,23,23,21,20,19,17,22,25,25,25,25,27,27,26,25,25,25,24,24,23,22,20,19,18, [...]
+"73",18,18,18,18,16,16,16,14,14,15,16,16,13,13,12,13,13,12,12,12,14,14,13,13,14,14,15,17,17,16,15,15,14,17,17,16,16,16,15,16,16,16,16,16,16,13,13,13,13,13,14,17,18,18,16,15,15,16,16,14,12,13,13,12,11,10,9,8,8,7,6,4,0,2,4,4,8,8,7,9,10,10,9,9,16,16,15,14,17,18,18,16,16,16,18,18,27,27,26,25,25,25,24,24,23,23,23,23,23,23,21,21,20,20,19,19,16,20,24,24,27,28,29,30,30,27,27,25,24,22,23,23,22,20,20,21,23,25,25,24,24,24,23,25,25,25,25,23,22,21,19,24,27,27,27,27,29,29,28,27,27,27,26,26,25,24,22,21 [...]
+"74",18,18,18,18,16,16,16,14,14,15,16,16,13,13,12,13,13,12,12,12,14,14,13,13,14,14,15,17,17,16,15,15,14,17,17,16,16,16,15,16,16,16,16,16,16,13,13,13,13,13,14,17,18,18,16,15,15,16,16,14,12,13,13,12,11,10,9,8,8,7,6,4,2,0,4,4,8,8,7,9,10,10,9,9,16,16,15,14,17,18,18,16,16,16,18,18,27,27,26,25,25,25,24,24,23,23,23,23,23,23,21,21,20,20,19,19,16,20,24,24,27,28,29,30,30,27,27,25,24,22,23,23,22,20,20,21,23,25,25,24,24,24,23,25,25,25,25,23,22,21,19,24,27,27,27,27,29,29,28,27,27,27,26,26,25,24,22,21 [...]
+"75",18,18,18,18,16,16,16,14,14,15,16,16,13,13,12,13,13,12,12,12,14,14,13,13,14,14,15,17,17,16,15,15,14,17,17,16,16,16,15,16,16,16,16,16,16,13,13,13,13,13,14,17,18,18,16,15,15,16,16,14,12,13,13,12,11,10,9,8,8,7,6,4,4,4,0,2,8,8,7,9,10,10,9,9,16,16,15,14,17,18,18,16,16,16,18,18,27,27,26,25,25,25,24,24,23,23,23,23,23,23,21,21,20,20,19,19,16,20,24,24,27,28,29,30,30,27,27,25,24,22,23,23,22,20,20,21,23,25,25,24,24,24,23,25,25,25,25,23,22,21,19,24,27,27,27,27,29,29,28,27,27,27,26,26,25,24,22,21 [...]
+"76",18,18,18,18,16,16,16,14,14,15,16,16,13,13,12,13,13,12,12,12,14,14,13,13,14,14,15,17,17,16,15,15,14,17,17,16,16,16,15,16,16,16,16,16,16,13,13,13,13,13,14,17,18,18,16,15,15,16,16,14,12,13,13,12,11,10,9,8,8,7,6,4,4,4,2,0,8,8,7,9,10,10,9,9,16,16,15,14,17,18,18,16,16,16,18,18,27,27,26,25,25,25,24,24,23,23,23,23,23,23,21,21,20,20,19,19,16,20,24,24,27,28,29,30,30,27,27,25,24,22,23,23,22,20,20,21,23,25,25,24,24,24,23,25,25,25,25,23,22,21,19,24,27,27,27,27,29,29,28,27,27,27,26,26,25,24,22,21 [...]
+"77",16,16,16,16,14,14,14,12,12,13,14,14,11,11,10,11,11,10,10,10,12,12,11,11,12,12,13,15,15,14,13,13,12,15,15,14,14,14,13,14,14,14,14,14,14,11,11,11,11,11,12,15,16,16,14,13,13,14,14,12,10,11,11,10,9,8,7,8,8,7,6,6,8,8,8,8,0,2,3,7,8,8,7,7,14,14,13,12,15,16,16,14,14,14,16,16,25,25,24,23,23,23,22,22,21,21,21,21,21,21,19,19,18,18,17,17,14,18,22,22,25,26,27,28,28,25,25,23,22,20,21,21,20,18,18,19,21,23,23,22,22,22,21,23,23,23,23,21,20,19,17,22,25,25,25,25,27,27,26,25,25,25,24,24,23,22,20,19,18, [...]
+"78",16,16,16,16,14,14,14,12,12,13,14,14,11,11,10,11,11,10,10,10,12,12,11,11,12,12,13,15,15,14,13,13,12,15,15,14,14,14,13,14,14,14,14,14,14,11,11,11,11,11,12,15,16,16,14,13,13,14,14,12,10,11,11,10,9,8,7,8,8,7,6,6,8,8,8,8,2,0,3,7,8,8,7,7,14,14,13,12,15,16,16,14,14,14,16,16,25,25,24,23,23,23,22,22,21,21,21,21,21,21,19,19,18,18,17,17,14,18,22,22,25,26,27,28,28,25,25,23,22,20,21,21,20,18,18,19,21,23,23,22,22,22,21,23,23,23,23,21,20,19,17,22,25,25,25,25,27,27,26,25,25,25,24,24,23,22,20,19,18, [...]
+"79",15,15,15,15,13,13,13,11,11,12,13,13,10,10,9,10,10,9,9,9,11,11,10,10,11,11,12,14,14,13,12,12,11,14,14,13,13,13,12,13,13,13,13,13,13,10,10,10,10,10,11,14,15,15,13,12,12,13,13,11,9,10,10,9,8,7,6,7,7,6,5,5,7,7,7,7,3,3,0,6,7,7,6,6,13,13,12,11,14,15,15,13,13,13,15,15,24,24,23,22,22,22,21,21,20,20,20,20,20,20,18,18,17,17,16,16,13,17,21,21,24,25,26,27,27,24,24,22,21,19,20,20,19,17,17,18,20,22,22,21,21,21,20,22,22,22,22,20,19,18,16,21,24,24,24,24,26,26,25,24,24,24,23,23,22,21,19,18,17,20,20, [...]
+"80",15,15,15,15,13,13,13,11,11,12,13,13,10,10,9,10,10,9,9,9,11,11,10,10,11,11,12,14,14,13,12,12,11,14,14,13,13,13,12,13,13,13,13,13,13,10,10,10,10,10,11,14,15,15,13,12,12,13,13,11,9,10,10,9,8,7,6,9,9,8,7,7,9,9,9,9,7,7,6,0,3,3,4,4,13,13,12,11,14,15,15,13,13,13,15,15,24,24,23,22,22,22,21,21,20,20,20,20,20,20,18,18,17,17,16,16,13,17,21,21,24,25,26,27,27,24,24,22,21,19,20,20,19,17,17,18,20,22,22,21,21,21,20,22,22,22,22,20,19,18,16,21,24,24,24,24,26,26,25,24,24,24,23,23,22,21,19,18,17,20,20, [...]
+"81",16,16,16,16,14,14,14,12,12,13,14,14,11,11,10,11,11,10,10,10,12,12,11,11,12,12,13,15,15,14,13,13,12,15,15,14,14,14,13,14,14,14,14,14,14,11,11,11,11,11,12,15,16,16,14,13,13,14,14,12,10,11,11,10,9,8,7,10,10,9,8,8,10,10,10,10,8,8,7,3,0,2,5,5,14,14,13,12,15,16,16,14,14,14,16,16,25,25,24,23,23,23,22,22,21,21,21,21,21,21,19,19,18,18,17,17,14,18,22,22,25,26,27,28,28,25,25,23,22,20,21,21,20,18,18,19,21,23,23,22,22,22,21,23,23,23,23,21,20,19,17,22,25,25,25,25,27,27,26,25,25,25,24,24,23,22,20, [...]
+"82",16,16,16,16,14,14,14,12,12,13,14,14,11,11,10,11,11,10,10,10,12,12,11,11,12,12,13,15,15,14,13,13,12,15,15,14,14,14,13,14,14,14,14,14,14,11,11,11,11,11,12,15,16,16,14,13,13,14,14,12,10,11,11,10,9,8,7,10,10,9,8,8,10,10,10,10,8,8,7,3,2,0,5,5,14,14,13,12,15,16,16,14,14,14,16,16,25,25,24,23,23,23,22,22,21,21,21,21,21,21,19,19,18,18,17,17,14,18,22,22,25,26,27,28,28,25,25,23,22,20,21,21,20,18,18,19,21,23,23,22,22,22,21,23,23,23,23,21,20,19,17,22,25,25,25,25,27,27,26,25,25,25,24,24,23,22,20, [...]
+"83",15,15,15,15,13,13,13,11,11,12,13,13,10,10,9,10,10,9,9,9,11,11,10,10,11,11,12,14,14,13,12,12,11,14,14,13,13,13,12,13,13,13,13,13,13,10,10,10,10,10,11,14,15,15,13,12,12,13,13,11,9,10,10,9,8,7,6,9,9,8,7,7,9,9,9,9,7,7,6,4,5,5,0,2,13,13,12,11,14,15,15,13,13,13,15,15,24,24,23,22,22,22,21,21,20,20,20,20,20,20,18,18,17,17,16,16,13,17,21,21,24,25,26,27,27,24,24,22,21,19,20,20,19,17,17,18,20,22,22,21,21,21,20,22,22,22,22,20,19,18,16,21,24,24,24,24,26,26,25,24,24,24,23,23,22,21,19,18,17,20,20, [...]
+"84",15,15,15,15,13,13,13,11,11,12,13,13,10,10,9,10,10,9,9,9,11,11,10,10,11,11,12,14,14,13,12,12,11,14,14,13,13,13,12,13,13,13,13,13,13,10,10,10,10,10,11,14,15,15,13,12,12,13,13,11,9,10,10,9,8,7,6,9,9,8,7,7,9,9,9,9,7,7,6,4,5,5,2,0,13,13,12,11,14,15,15,13,13,13,15,15,24,24,23,22,22,22,21,21,20,20,20,20,20,20,18,18,17,17,16,16,13,17,21,21,24,25,26,27,27,24,24,22,21,19,20,20,19,17,17,18,20,22,22,21,21,21,20,22,22,22,22,20,19,18,16,21,24,24,24,24,26,26,25,24,24,24,23,23,22,21,19,18,17,20,20, [...]
+"85",12,12,12,12,10,10,10,8,8,9,10,10,9,9,8,11,11,10,10,10,14,14,13,13,14,14,15,17,17,16,15,15,14,17,17,16,16,16,15,16,16,16,16,16,16,13,13,13,13,13,14,17,18,18,16,15,15,16,16,14,12,15,15,14,13,12,11,16,16,15,14,14,16,16,16,16,14,14,13,13,14,14,13,13,0,2,3,4,9,10,10,8,8,8,10,10,19,19,18,17,17,17,16,16,15,15,15,15,15,15,13,13,12,12,11,11,8,12,16,16,19,20,21,22,22,19,19,17,16,14,15,15,14,12,12,13,15,17,17,16,16,16,15,17,17,17,17,15,14,13,11,16,19,19,19,19,21,21,20,19,19,19,18,18,17,16,14,1 [...]
+"86",12,12,12,12,10,10,10,8,8,9,10,10,9,9,8,11,11,10,10,10,14,14,13,13,14,14,15,17,17,16,15,15,14,17,17,16,16,16,15,16,16,16,16,16,16,13,13,13,13,13,14,17,18,18,16,15,15,16,16,14,12,15,15,14,13,12,11,16,16,15,14,14,16,16,16,16,14,14,13,13,14,14,13,13,2,0,3,4,9,10,10,8,8,8,10,10,19,19,18,17,17,17,16,16,15,15,15,15,15,15,13,13,12,12,11,11,8,12,16,16,19,20,21,22,22,19,19,17,16,14,15,15,14,12,12,13,15,17,17,16,16,16,15,17,17,17,17,15,14,13,11,16,19,19,19,19,21,21,20,19,19,19,18,18,17,16,14,1 [...]
+"87",11,11,11,11,9,9,9,7,7,8,9,9,8,8,7,10,10,9,9,9,13,13,12,12,13,13,14,16,16,15,14,14,13,16,16,15,15,15,14,15,15,15,15,15,15,12,12,12,12,12,13,16,17,17,15,14,14,15,15,13,11,14,14,13,12,11,10,15,15,14,13,13,15,15,15,15,13,13,12,12,13,13,12,12,3,3,0,3,8,9,9,7,7,7,9,9,18,18,17,16,16,16,15,15,14,14,14,14,14,14,12,12,11,11,10,10,7,11,15,15,18,19,20,21,21,18,18,16,15,13,14,14,13,11,11,12,14,16,16,15,15,15,14,16,16,16,16,14,13,12,10,15,18,18,18,18,20,20,19,18,18,18,17,17,16,15,13,12,11,14,14,1 [...]
+"88",10,10,10,10,8,8,8,6,6,7,8,8,7,7,6,9,9,8,8,8,12,12,11,11,12,12,13,15,15,14,13,13,12,15,15,14,14,14,13,14,14,14,14,14,14,11,11,11,11,11,12,15,16,16,14,13,13,14,14,12,10,13,13,12,11,10,9,14,14,13,12,12,14,14,14,14,12,12,11,11,12,12,11,11,4,4,3,0,7,8,8,6,6,6,8,8,17,17,16,15,15,15,14,14,13,13,13,13,13,13,11,11,10,10,9,9,6,10,14,14,17,18,19,20,20,17,17,15,14,12,13,13,12,10,10,11,13,15,15,14,14,14,13,15,15,15,15,13,12,11,9,14,17,17,17,17,19,19,18,17,17,17,16,16,15,14,12,11,10,13,13,15,15,1 [...]
+"89",13,13,13,13,11,11,11,9,9,10,11,11,10,10,9,12,12,11,11,11,15,15,14,14,15,15,16,18,18,17,16,16,15,18,18,17,17,17,16,17,17,17,17,17,17,14,14,14,14,14,15,18,19,19,17,16,16,17,17,15,13,16,16,15,14,13,12,17,17,16,15,15,17,17,17,17,15,15,14,14,15,15,14,14,9,9,8,7,0,3,3,3,5,5,9,9,18,18,17,16,16,16,15,15,14,14,14,14,14,14,12,12,11,11,10,10,7,11,15,15,18,19,20,21,21,18,18,16,15,13,14,14,13,11,11,12,14,16,16,15,15,15,14,16,16,16,16,14,13,12,10,15,18,18,18,18,20,20,19,18,18,18,17,17,16,15,13,12 [...]
+"90",14,14,14,14,12,12,12,10,10,11,12,12,11,11,10,13,13,12,12,12,16,16,15,15,16,16,17,19,19,18,17,17,16,19,19,18,18,18,17,18,18,18,18,18,18,15,15,15,15,15,16,19,20,20,18,17,17,18,18,16,14,17,17,16,15,14,13,18,18,17,16,16,18,18,18,18,16,16,15,15,16,16,15,15,10,10,9,8,3,0,2,4,6,6,10,10,19,19,18,17,17,17,16,16,15,15,15,15,15,15,13,13,12,12,11,11,8,12,16,16,19,20,21,22,22,19,19,17,16,14,15,15,14,12,12,13,15,17,17,16,16,16,15,17,17,17,17,15,14,13,11,16,19,19,19,19,21,21,20,19,19,19,18,18,17,1 [...]
+"91",14,14,14,14,12,12,12,10,10,11,12,12,11,11,10,13,13,12,12,12,16,16,15,15,16,16,17,19,19,18,17,17,16,19,19,18,18,18,17,18,18,18,18,18,18,15,15,15,15,15,16,19,20,20,18,17,17,18,18,16,14,17,17,16,15,14,13,18,18,17,16,16,18,18,18,18,16,16,15,15,16,16,15,15,10,10,9,8,3,2,0,4,6,6,10,10,19,19,18,17,17,17,16,16,15,15,15,15,15,15,13,13,12,12,11,11,8,12,16,16,19,20,21,22,22,19,19,17,16,14,15,15,14,12,12,13,15,17,17,16,16,16,15,17,17,17,17,15,14,13,11,16,19,19,19,19,21,21,20,19,19,19,18,18,17,1 [...]
+"92",12,12,12,12,10,10,10,8,8,9,10,10,9,9,8,11,11,10,10,10,14,14,13,13,14,14,15,17,17,16,15,15,14,17,17,16,16,16,15,16,16,16,16,16,16,13,13,13,13,13,14,17,18,18,16,15,15,16,16,14,12,15,15,14,13,12,11,16,16,15,14,14,16,16,16,16,14,14,13,13,14,14,13,13,8,8,7,6,3,4,4,0,4,4,8,8,17,17,16,15,15,15,14,14,13,13,13,13,13,13,11,11,10,10,9,9,6,10,14,14,17,18,19,20,20,17,17,15,14,12,13,13,12,10,10,11,13,15,15,14,14,14,13,15,15,15,15,13,12,11,9,14,17,17,17,17,19,19,18,17,17,17,16,16,15,14,12,11,10,13 [...]
+"93",12,12,12,12,10,10,10,8,8,9,10,10,9,9,8,11,11,10,10,10,14,14,13,13,14,14,15,17,17,16,15,15,14,17,17,16,16,16,15,16,16,16,16,16,16,13,13,13,13,13,14,17,18,18,16,15,15,16,16,14,12,15,15,14,13,12,11,16,16,15,14,14,16,16,16,16,14,14,13,13,14,14,13,13,8,8,7,6,5,6,6,4,0,2,8,8,17,17,16,15,15,15,14,14,13,13,13,13,13,13,11,11,10,10,9,9,6,10,14,14,17,18,19,20,20,17,17,15,14,12,13,13,12,10,10,11,13,15,15,14,14,14,13,15,15,15,15,13,12,11,9,14,17,17,17,17,19,19,18,17,17,17,16,16,15,14,12,11,10,13 [...]
+"94",12,12,12,12,10,10,10,8,8,9,10,10,9,9,8,11,11,10,10,10,14,14,13,13,14,14,15,17,17,16,15,15,14,17,17,16,16,16,15,16,16,16,16,16,16,13,13,13,13,13,14,17,18,18,16,15,15,16,16,14,12,15,15,14,13,12,11,16,16,15,14,14,16,16,16,16,14,14,13,13,14,14,13,13,8,8,7,6,5,6,6,4,2,0,8,8,17,17,16,15,15,15,14,14,13,13,13,13,13,13,11,11,10,10,9,9,6,10,14,14,17,18,19,20,20,17,17,15,14,12,13,13,12,10,10,11,13,15,15,14,14,14,13,15,15,15,15,13,12,11,9,14,17,17,17,17,19,19,18,17,17,17,16,16,15,14,12,11,10,13 [...]
+"95",14,14,14,14,12,12,12,10,10,11,12,12,11,11,10,13,13,12,12,12,16,16,15,15,16,16,17,19,19,18,17,17,16,19,19,18,18,18,17,18,18,18,18,18,18,15,15,15,15,15,16,19,20,20,18,17,17,18,18,16,14,17,17,16,15,14,13,18,18,17,16,16,18,18,18,18,16,16,15,15,16,16,15,15,10,10,9,8,9,10,10,8,8,8,0,2,13,13,12,11,11,11,10,10,9,9,9,9,9,9,7,7,6,6,5,5,4,10,14,14,17,18,19,20,20,17,17,15,14,12,13,13,12,10,10,11,13,15,15,14,14,14,13,15,15,15,15,13,12,11,9,14,17,17,17,17,19,19,18,17,17,17,16,16,15,14,12,11,10,13 [...]
+"96",14,14,14,14,12,12,12,10,10,11,12,12,11,11,10,13,13,12,12,12,16,16,15,15,16,16,17,19,19,18,17,17,16,19,19,18,18,18,17,18,18,18,18,18,18,15,15,15,15,15,16,19,20,20,18,17,17,18,18,16,14,17,17,16,15,14,13,18,18,17,16,16,18,18,18,18,16,16,15,15,16,16,15,15,10,10,9,8,9,10,10,8,8,8,2,0,13,13,12,11,11,11,10,10,9,9,9,9,9,9,7,7,6,6,5,5,4,10,14,14,17,18,19,20,20,17,17,15,14,12,13,13,12,10,10,11,13,15,15,14,14,14,13,15,15,15,15,13,12,11,9,14,17,17,17,17,19,19,18,17,17,17,16,16,15,14,12,11,10,13 [...]
+"97",23,23,23,23,21,21,21,19,19,20,21,21,20,20,19,22,22,21,21,21,25,25,24,24,25,25,26,28,28,27,26,26,25,28,28,27,27,27,26,27,27,27,27,27,27,24,24,24,24,24,25,28,29,29,27,26,26,27,27,25,23,26,26,25,24,23,22,27,27,26,25,25,27,27,27,27,25,25,24,24,25,25,24,24,19,19,18,17,18,19,19,17,17,17,13,13,0,2,3,4,6,6,7,7,8,8,10,10,10,10,10,10,11,11,12,12,13,19,23,23,26,27,28,29,29,26,26,24,23,21,22,22,21,19,19,20,22,24,24,23,23,23,22,24,24,24,24,22,21,20,18,23,26,26,26,26,28,28,27,26,26,26,25,25,24,23 [...]
+"98",23,23,23,23,21,21,21,19,19,20,21,21,20,20,19,22,22,21,21,21,25,25,24,24,25,25,26,28,28,27,26,26,25,28,28,27,27,27,26,27,27,27,27,27,27,24,24,24,24,24,25,28,29,29,27,26,26,27,27,25,23,26,26,25,24,23,22,27,27,26,25,25,27,27,27,27,25,25,24,24,25,25,24,24,19,19,18,17,18,19,19,17,17,17,13,13,2,0,3,4,6,6,7,7,8,8,10,10,10,10,10,10,11,11,12,12,13,19,23,23,26,27,28,29,29,26,26,24,23,21,22,22,21,19,19,20,22,24,24,23,23,23,22,24,24,24,24,22,21,20,18,23,26,26,26,26,28,28,27,26,26,26,25,25,24,23 [...]
+"99",22,22,22,22,20,20,20,18,18,19,20,20,19,19,18,21,21,20,20,20,24,24,23,23,24,24,25,27,27,26,25,25,24,27,27,26,26,26,25,26,26,26,26,26,26,23,23,23,23,23,24,27,28,28,26,25,25,26,26,24,22,25,25,24,23,22,21,26,26,25,24,24,26,26,26,26,24,24,23,23,24,24,23,23,18,18,17,16,17,18,18,16,16,16,12,12,3,3,0,3,5,5,6,6,7,7,9,9,9,9,9,9,10,10,11,11,12,18,22,22,25,26,27,28,28,25,25,23,22,20,21,21,20,18,18,19,21,23,23,22,22,22,21,23,23,23,23,21,20,19,17,22,25,25,25,25,27,27,26,25,25,25,24,24,23,22,20,19 [...]
+"100",21,21,21,21,19,19,19,17,17,18,19,19,18,18,17,20,20,19,19,19,23,23,22,22,23,23,24,26,26,25,24,24,23,26,26,25,25,25,24,25,25,25,25,25,25,22,22,22,22,22,23,26,27,27,25,24,24,25,25,23,21,24,24,23,22,21,20,25,25,24,23,23,25,25,25,25,23,23,22,22,23,23,22,22,17,17,16,15,16,17,17,15,15,15,11,11,4,4,3,0,4,4,5,5,6,6,8,8,8,8,8,8,9,9,10,10,11,17,21,21,24,25,26,27,27,24,24,22,21,19,20,20,19,17,17,18,20,22,22,21,21,21,20,22,22,22,22,20,19,18,16,21,24,24,24,24,26,26,25,24,24,24,23,23,22,21,19,18, [...]
+"101",21,21,21,21,19,19,19,17,17,18,19,19,18,18,17,20,20,19,19,19,23,23,22,22,23,23,24,26,26,25,24,24,23,26,26,25,25,25,24,25,25,25,25,25,25,22,22,22,22,22,23,26,27,27,25,24,24,25,25,23,21,24,24,23,22,21,20,25,25,24,23,23,25,25,25,25,23,23,22,22,23,23,22,22,17,17,16,15,16,17,17,15,15,15,11,11,6,6,5,4,0,2,5,5,6,6,8,8,8,8,8,8,9,9,10,10,11,17,21,21,24,25,26,27,27,24,24,22,21,19,20,20,19,17,17,18,20,22,22,21,21,21,20,22,22,22,22,20,19,18,16,21,24,24,24,24,26,26,25,24,24,24,23,23,22,21,19,18, [...]
+"102",21,21,21,21,19,19,19,17,17,18,19,19,18,18,17,20,20,19,19,19,23,23,22,22,23,23,24,26,26,25,24,24,23,26,26,25,25,25,24,25,25,25,25,25,25,22,22,22,22,22,23,26,27,27,25,24,24,25,25,23,21,24,24,23,22,21,20,25,25,24,23,23,25,25,25,25,23,23,22,22,23,23,22,22,17,17,16,15,16,17,17,15,15,15,11,11,6,6,5,4,2,0,5,5,6,6,8,8,8,8,8,8,9,9,10,10,11,17,21,21,24,25,26,27,27,24,24,22,21,19,20,20,19,17,17,18,20,22,22,21,21,21,20,22,22,22,22,20,19,18,16,21,24,24,24,24,26,26,25,24,24,24,23,23,22,21,19,18, [...]
+"103",20,20,20,20,18,18,18,16,16,17,18,18,17,17,16,19,19,18,18,18,22,22,21,21,22,22,23,25,25,24,23,23,22,25,25,24,24,24,23,24,24,24,24,24,24,21,21,21,21,21,22,25,26,26,24,23,23,24,24,22,20,23,23,22,21,20,19,24,24,23,22,22,24,24,24,24,22,22,21,21,22,22,21,21,16,16,15,14,15,16,16,14,14,14,10,10,7,7,6,5,5,5,0,2,5,5,7,7,7,7,7,7,8,8,9,9,10,16,20,20,23,24,25,26,26,23,23,21,20,18,19,19,18,16,16,17,19,21,21,20,20,20,19,21,21,21,21,19,18,17,15,20,23,23,23,23,25,25,24,23,23,23,22,22,21,20,18,17,16 [...]
+"104",20,20,20,20,18,18,18,16,16,17,18,18,17,17,16,19,19,18,18,18,22,22,21,21,22,22,23,25,25,24,23,23,22,25,25,24,24,24,23,24,24,24,24,24,24,21,21,21,21,21,22,25,26,26,24,23,23,24,24,22,20,23,23,22,21,20,19,24,24,23,22,22,24,24,24,24,22,22,21,21,22,22,21,21,16,16,15,14,15,16,16,14,14,14,10,10,7,7,6,5,5,5,2,0,5,5,7,7,7,7,7,7,8,8,9,9,10,16,20,20,23,24,25,26,26,23,23,21,20,18,19,19,18,16,16,17,19,21,21,20,20,20,19,21,21,21,21,19,18,17,15,20,23,23,23,23,25,25,24,23,23,23,22,22,21,20,18,17,16 [...]
+"105",19,19,19,19,17,17,17,15,15,16,17,17,16,16,15,18,18,17,17,17,21,21,20,20,21,21,22,24,24,23,22,22,21,24,24,23,23,23,22,23,23,23,23,23,23,20,20,20,20,20,21,24,25,25,23,22,22,23,23,21,19,22,22,21,20,19,18,23,23,22,21,21,23,23,23,23,21,21,20,20,21,21,20,20,15,15,14,13,14,15,15,13,13,13,9,9,8,8,7,6,6,6,5,5,0,2,6,6,6,6,6,6,7,7,8,8,9,15,19,19,22,23,24,25,25,22,22,20,19,17,18,18,17,15,15,16,18,20,20,19,19,19,18,20,20,20,20,18,17,16,14,19,22,22,22,22,24,24,23,22,22,22,21,21,20,19,17,16,15,18 [...]
+"106",19,19,19,19,17,17,17,15,15,16,17,17,16,16,15,18,18,17,17,17,21,21,20,20,21,21,22,24,24,23,22,22,21,24,24,23,23,23,22,23,23,23,23,23,23,20,20,20,20,20,21,24,25,25,23,22,22,23,23,21,19,22,22,21,20,19,18,23,23,22,21,21,23,23,23,23,21,21,20,20,21,21,20,20,15,15,14,13,14,15,15,13,13,13,9,9,8,8,7,6,6,6,5,5,2,0,6,6,6,6,6,6,7,7,8,8,9,15,19,19,22,23,24,25,25,22,22,20,19,17,18,18,17,15,15,16,18,20,20,19,19,19,18,20,20,20,20,18,17,16,14,19,22,22,22,22,24,24,23,22,22,22,21,21,20,19,17,16,15,18 [...]
+"107",19,19,19,19,17,17,17,15,15,16,17,17,16,16,15,18,18,17,17,17,21,21,20,20,21,21,22,24,24,23,22,22,21,24,24,23,23,23,22,23,23,23,23,23,23,20,20,20,20,20,21,24,25,25,23,22,22,23,23,21,19,22,22,21,20,19,18,23,23,22,21,21,23,23,23,23,21,21,20,20,21,21,20,20,15,15,14,13,14,15,15,13,13,13,9,9,10,10,9,8,8,8,7,7,6,6,0,2,4,4,6,6,7,7,8,8,9,15,19,19,22,23,24,25,25,22,22,20,19,17,18,18,17,15,15,16,18,20,20,19,19,19,18,20,20,20,20,18,17,16,14,19,22,22,22,22,24,24,23,22,22,22,21,21,20,19,17,16,15, [...]
+"108",19,19,19,19,17,17,17,15,15,16,17,17,16,16,15,18,18,17,17,17,21,21,20,20,21,21,22,24,24,23,22,22,21,24,24,23,23,23,22,23,23,23,23,23,23,20,20,20,20,20,21,24,25,25,23,22,22,23,23,21,19,22,22,21,20,19,18,23,23,22,21,21,23,23,23,23,21,21,20,20,21,21,20,20,15,15,14,13,14,15,15,13,13,13,9,9,10,10,9,8,8,8,7,7,6,6,2,0,4,4,6,6,7,7,8,8,9,15,19,19,22,23,24,25,25,22,22,20,19,17,18,18,17,15,15,16,18,20,20,19,19,19,18,20,20,20,20,18,17,16,14,19,22,22,22,22,24,24,23,22,22,22,21,21,20,19,17,16,15, [...]
+"109",19,19,19,19,17,17,17,15,15,16,17,17,16,16,15,18,18,17,17,17,21,21,20,20,21,21,22,24,24,23,22,22,21,24,24,23,23,23,22,23,23,23,23,23,23,20,20,20,20,20,21,24,25,25,23,22,22,23,23,21,19,22,22,21,20,19,18,23,23,22,21,21,23,23,23,23,21,21,20,20,21,21,20,20,15,15,14,13,14,15,15,13,13,13,9,9,10,10,9,8,8,8,7,7,6,6,4,4,0,2,6,6,7,7,8,8,9,15,19,19,22,23,24,25,25,22,22,20,19,17,18,18,17,15,15,16,18,20,20,19,19,19,18,20,20,20,20,18,17,16,14,19,22,22,22,22,24,24,23,22,22,22,21,21,20,19,17,16,15, [...]
+"110",19,19,19,19,17,17,17,15,15,16,17,17,16,16,15,18,18,17,17,17,21,21,20,20,21,21,22,24,24,23,22,22,21,24,24,23,23,23,22,23,23,23,23,23,23,20,20,20,20,20,21,24,25,25,23,22,22,23,23,21,19,22,22,21,20,19,18,23,23,22,21,21,23,23,23,23,21,21,20,20,21,21,20,20,15,15,14,13,14,15,15,13,13,13,9,9,10,10,9,8,8,8,7,7,6,6,4,4,2,0,6,6,7,7,8,8,9,15,19,19,22,23,24,25,25,22,22,20,19,17,18,18,17,15,15,16,18,20,20,19,19,19,18,20,20,20,20,18,17,16,14,19,22,22,22,22,24,24,23,22,22,22,21,21,20,19,17,16,15, [...]
+"111",17,17,17,17,15,15,15,13,13,14,15,15,14,14,13,16,16,15,15,15,19,19,18,18,19,19,20,22,22,21,20,20,19,22,22,21,21,21,20,21,21,21,21,21,21,18,18,18,18,18,19,22,23,23,21,20,20,21,21,19,17,20,20,19,18,17,16,21,21,20,19,19,21,21,21,21,19,19,18,18,19,19,18,18,13,13,12,11,12,13,13,11,11,11,7,7,10,10,9,8,8,8,7,7,6,6,6,6,6,6,0,2,5,5,6,6,7,13,17,17,20,21,22,23,23,20,20,18,17,15,16,16,15,13,13,14,16,18,18,17,17,17,16,18,18,18,18,16,15,14,12,17,20,20,20,20,22,22,21,20,20,20,19,19,18,17,15,14,13, [...]
+"112",17,17,17,17,15,15,15,13,13,14,15,15,14,14,13,16,16,15,15,15,19,19,18,18,19,19,20,22,22,21,20,20,19,22,22,21,21,21,20,21,21,21,21,21,21,18,18,18,18,18,19,22,23,23,21,20,20,21,21,19,17,20,20,19,18,17,16,21,21,20,19,19,21,21,21,21,19,19,18,18,19,19,18,18,13,13,12,11,12,13,13,11,11,11,7,7,10,10,9,8,8,8,7,7,6,6,6,6,6,6,2,0,5,5,6,6,7,13,17,17,20,21,22,23,23,20,20,18,17,15,16,16,15,13,13,14,16,18,18,17,17,17,16,18,18,18,18,16,15,14,12,17,20,20,20,20,22,22,21,20,20,20,19,19,18,17,15,14,13, [...]
+"113",16,16,16,16,14,14,14,12,12,13,14,14,13,13,12,15,15,14,14,14,18,18,17,17,18,18,19,21,21,20,19,19,18,21,21,20,20,20,19,20,20,20,20,20,20,17,17,17,17,17,18,21,22,22,20,19,19,20,20,18,16,19,19,18,17,16,15,20,20,19,18,18,20,20,20,20,18,18,17,17,18,18,17,17,12,12,11,10,11,12,12,10,10,10,6,6,11,11,10,9,9,9,8,8,7,7,7,7,7,7,5,5,0,2,5,5,6,12,16,16,19,20,21,22,22,19,19,17,16,14,15,15,14,12,12,13,15,17,17,16,16,16,15,17,17,17,17,15,14,13,11,16,19,19,19,19,21,21,20,19,19,19,18,18,17,16,14,13,12 [...]
+"114",16,16,16,16,14,14,14,12,12,13,14,14,13,13,12,15,15,14,14,14,18,18,17,17,18,18,19,21,21,20,19,19,18,21,21,20,20,20,19,20,20,20,20,20,20,17,17,17,17,17,18,21,22,22,20,19,19,20,20,18,16,19,19,18,17,16,15,20,20,19,18,18,20,20,20,20,18,18,17,17,18,18,17,17,12,12,11,10,11,12,12,10,10,10,6,6,11,11,10,9,9,9,8,8,7,7,7,7,7,7,5,5,2,0,5,5,6,12,16,16,19,20,21,22,22,19,19,17,16,14,15,15,14,12,12,13,15,17,17,16,16,16,15,17,17,17,17,15,14,13,11,16,19,19,19,19,21,21,20,19,19,19,18,18,17,16,14,13,12 [...]
+"115",15,15,15,15,13,13,13,11,11,12,13,13,12,12,11,14,14,13,13,13,17,17,16,16,17,17,18,20,20,19,18,18,17,20,20,19,19,19,18,19,19,19,19,19,19,16,16,16,16,16,17,20,21,21,19,18,18,19,19,17,15,18,18,17,16,15,14,19,19,18,17,17,19,19,19,19,17,17,16,16,17,17,16,16,11,11,10,9,10,11,11,9,9,9,5,5,12,12,11,10,10,10,9,9,8,8,8,8,8,8,6,6,5,5,0,2,5,11,15,15,18,19,20,21,21,18,18,16,15,13,14,14,13,11,11,12,14,16,16,15,15,15,14,16,16,16,16,14,13,12,10,15,18,18,18,18,20,20,19,18,18,18,17,17,16,15,13,12,11, [...]
+"116",15,15,15,15,13,13,13,11,11,12,13,13,12,12,11,14,14,13,13,13,17,17,16,16,17,17,18,20,20,19,18,18,17,20,20,19,19,19,18,19,19,19,19,19,19,16,16,16,16,16,17,20,21,21,19,18,18,19,19,17,15,18,18,17,16,15,14,19,19,18,17,17,19,19,19,19,17,17,16,16,17,17,16,16,11,11,10,9,10,11,11,9,9,9,5,5,12,12,11,10,10,10,9,9,8,8,8,8,8,8,6,6,5,5,2,0,5,11,15,15,18,19,20,21,21,18,18,16,15,13,14,14,13,11,11,12,14,16,16,15,15,15,14,16,16,16,16,14,13,12,10,15,18,18,18,18,20,20,19,18,18,18,17,17,16,15,13,12,11, [...]
+"117",12,12,12,12,10,10,10,8,8,9,10,10,9,9,8,11,11,10,10,10,14,14,13,13,14,14,15,17,17,16,15,15,14,17,17,16,16,16,15,16,16,16,16,16,16,13,13,13,13,13,14,17,18,18,16,15,15,16,16,14,12,15,15,14,13,12,11,16,16,15,14,14,16,16,16,16,14,14,13,13,14,14,13,13,8,8,7,6,7,8,8,6,6,6,4,4,13,13,12,11,11,11,10,10,9,9,9,9,9,9,7,7,6,6,5,5,0,8,12,12,15,16,17,18,18,15,15,13,12,10,11,11,10,8,8,9,11,13,13,12,12,12,11,13,13,13,13,11,10,9,7,12,15,15,15,15,17,17,16,15,15,15,14,14,13,12,10,9,8,11,11,13,13,12,11, [...]
+"118",16,16,16,16,14,14,14,12,12,13,14,14,13,13,12,15,15,14,14,14,18,18,17,17,18,18,19,21,21,20,19,19,18,21,21,20,20,20,19,20,20,20,20,20,20,17,17,17,17,17,18,21,22,22,20,19,19,20,20,18,16,19,19,18,17,16,15,20,20,19,18,18,20,20,20,20,18,18,17,17,18,18,17,17,12,12,11,10,11,12,12,10,10,10,10,10,19,19,18,17,17,17,16,16,15,15,15,15,15,15,13,13,12,12,11,11,8,0,6,6,9,10,11,12,12,9,9,7,6,4,5,5,4,4,4,7,9,11,11,10,10,10,9,11,11,11,11,9,8,7,5,12,15,15,15,15,17,17,16,15,15,15,14,14,13,12,10,9,8,11, [...]
+"119",20,20,20,20,18,18,18,16,16,17,18,18,17,17,16,19,19,18,18,18,22,22,21,21,22,22,23,25,25,24,23,23,22,25,25,24,24,24,23,24,24,24,24,24,24,21,21,21,21,21,22,25,26,26,24,23,23,24,24,22,20,23,23,22,21,20,19,24,24,23,22,22,24,24,24,24,22,22,21,21,22,22,21,21,16,16,15,14,15,16,16,14,14,14,14,14,23,23,22,21,21,21,20,20,19,19,19,19,19,19,17,17,16,16,15,15,12,6,0,2,7,8,9,10,10,7,7,5,4,4,7,7,6,8,8,11,13,15,15,14,14,14,13,15,15,15,15,13,12,11,9,16,19,19,19,19,21,21,20,19,19,19,18,18,17,16,14,13 [...]
+"120",20,20,20,20,18,18,18,16,16,17,18,18,17,17,16,19,19,18,18,18,22,22,21,21,22,22,23,25,25,24,23,23,22,25,25,24,24,24,23,24,24,24,24,24,24,21,21,21,21,21,22,25,26,26,24,23,23,24,24,22,20,23,23,22,21,20,19,24,24,23,22,22,24,24,24,24,22,22,21,21,22,22,21,21,16,16,15,14,15,16,16,14,14,14,14,14,23,23,22,21,21,21,20,20,19,19,19,19,19,19,17,17,16,16,15,15,12,6,2,0,7,8,9,10,10,7,7,5,4,4,7,7,6,8,8,11,13,15,15,14,14,14,13,15,15,15,15,13,12,11,9,16,19,19,19,19,21,21,20,19,19,19,18,18,17,16,14,13 [...]
+"121",23,23,23,23,21,21,21,19,19,20,21,21,20,20,19,22,22,21,21,21,25,25,24,24,25,25,26,28,28,27,26,26,25,28,28,27,27,27,26,27,27,27,27,27,27,24,24,24,24,24,25,28,29,29,27,26,26,27,27,25,23,26,26,25,24,23,22,27,27,26,25,25,27,27,27,27,25,25,24,24,25,25,24,24,19,19,18,17,18,19,19,17,17,17,17,17,26,26,25,24,24,24,23,23,22,22,22,22,22,22,20,20,19,19,18,18,15,9,7,7,0,3,4,5,5,4,4,4,5,7,10,10,9,11,11,14,16,18,18,17,17,17,16,18,18,18,18,16,15,14,12,19,22,22,22,22,24,24,23,22,22,22,21,21,20,19,17 [...]
+"122",24,24,24,24,22,22,22,20,20,21,22,22,21,21,20,23,23,22,22,22,26,26,25,25,26,26,27,29,29,28,27,27,26,29,29,28,28,28,27,28,28,28,28,28,28,25,25,25,25,25,26,29,30,30,28,27,27,28,28,26,24,27,27,26,25,24,23,28,28,27,26,26,28,28,28,28,26,26,25,25,26,26,25,25,20,20,19,18,19,20,20,18,18,18,18,18,27,27,26,25,25,25,24,24,23,23,23,23,23,23,21,21,20,20,19,19,16,10,8,8,3,0,3,4,4,5,5,5,6,8,11,11,10,12,12,15,17,19,19,18,18,18,17,19,19,19,19,17,16,15,13,20,23,23,23,23,25,25,24,23,23,23,22,22,21,20, [...]
+"123",25,25,25,25,23,23,23,21,21,22,23,23,22,22,21,24,24,23,23,23,27,27,26,26,27,27,28,30,30,29,28,28,27,30,30,29,29,29,28,29,29,29,29,29,29,26,26,26,26,26,27,30,31,31,29,28,28,29,29,27,25,28,28,27,26,25,24,29,29,28,27,27,29,29,29,29,27,27,26,26,27,27,26,26,21,21,20,19,20,21,21,19,19,19,19,19,28,28,27,26,26,26,25,25,24,24,24,24,24,24,22,22,21,21,20,20,17,11,9,9,4,3,0,3,3,6,6,6,7,9,12,12,11,13,13,16,18,20,20,19,19,19,18,20,20,20,20,18,17,16,14,21,24,24,24,24,26,26,25,24,24,24,23,23,22,21, [...]
+"124",26,26,26,26,24,24,24,22,22,23,24,24,23,23,22,25,25,24,24,24,28,28,27,27,28,28,29,31,31,30,29,29,28,31,31,30,30,30,29,30,30,30,30,30,30,27,27,27,27,27,28,31,32,32,30,29,29,30,30,28,26,29,29,28,27,26,25,30,30,29,28,28,30,30,30,30,28,28,27,27,28,28,27,27,22,22,21,20,21,22,22,20,20,20,20,20,29,29,28,27,27,27,26,26,25,25,25,25,25,25,23,23,22,22,21,21,18,12,10,10,5,4,3,0,2,7,7,7,8,10,13,13,12,14,14,17,19,21,21,20,20,20,19,21,21,21,21,19,18,17,15,22,25,25,25,25,27,27,26,25,25,25,24,24,23, [...]
+"125",26,26,26,26,24,24,24,22,22,23,24,24,23,23,22,25,25,24,24,24,28,28,27,27,28,28,29,31,31,30,29,29,28,31,31,30,30,30,29,30,30,30,30,30,30,27,27,27,27,27,28,31,32,32,30,29,29,30,30,28,26,29,29,28,27,26,25,30,30,29,28,28,30,30,30,30,28,28,27,27,28,28,27,27,22,22,21,20,21,22,22,20,20,20,20,20,29,29,28,27,27,27,26,26,25,25,25,25,25,25,23,23,22,22,21,21,18,12,10,10,5,4,3,2,0,7,7,7,8,10,13,13,12,14,14,17,19,21,21,20,20,20,19,21,21,21,21,19,18,17,15,22,25,25,25,25,27,27,26,25,25,25,24,24,23, [...]
+"126",23,23,23,23,21,21,21,19,19,20,21,21,20,20,19,22,22,21,21,21,25,25,24,24,25,25,26,28,28,27,26,26,25,28,28,27,27,27,26,27,27,27,27,27,27,24,24,24,24,24,25,28,29,29,27,26,26,27,27,25,23,26,26,25,24,23,22,27,27,26,25,25,27,27,27,27,25,25,24,24,25,25,24,24,19,19,18,17,18,19,19,17,17,17,17,17,26,26,25,24,24,24,23,23,22,22,22,22,22,22,20,20,19,19,18,18,15,9,7,7,4,5,6,7,7,0,2,4,5,7,10,10,9,11,11,14,16,18,18,17,17,17,16,18,18,18,18,16,15,14,12,19,22,22,22,22,24,24,23,22,22,22,21,21,20,19,17 [...]
+"127",23,23,23,23,21,21,21,19,19,20,21,21,20,20,19,22,22,21,21,21,25,25,24,24,25,25,26,28,28,27,26,26,25,28,28,27,27,27,26,27,27,27,27,27,27,24,24,24,24,24,25,28,29,29,27,26,26,27,27,25,23,26,26,25,24,23,22,27,27,26,25,25,27,27,27,27,25,25,24,24,25,25,24,24,19,19,18,17,18,19,19,17,17,17,17,17,26,26,25,24,24,24,23,23,22,22,22,22,22,22,20,20,19,19,18,18,15,9,7,7,4,5,6,7,7,2,0,4,5,7,10,10,9,11,11,14,16,18,18,17,17,17,16,18,18,18,18,16,15,14,12,19,22,22,22,22,24,24,23,22,22,22,21,21,20,19,17 [...]
+"128",21,21,21,21,19,19,19,17,17,18,19,19,18,18,17,20,20,19,19,19,23,23,22,22,23,23,24,26,26,25,24,24,23,26,26,25,25,25,24,25,25,25,25,25,25,22,22,22,22,22,23,26,27,27,25,24,24,25,25,23,21,24,24,23,22,21,20,25,25,24,23,23,25,25,25,25,23,23,22,22,23,23,22,22,17,17,16,15,16,17,17,15,15,15,15,15,24,24,23,22,22,22,21,21,20,20,20,20,20,20,18,18,17,17,16,16,13,7,5,5,4,5,6,7,7,4,4,0,3,5,8,8,7,9,9,12,14,16,16,15,15,15,14,16,16,16,16,14,13,12,10,17,20,20,20,20,22,22,21,20,20,20,19,19,18,17,15,14, [...]
+"129",20,20,20,20,18,18,18,16,16,17,18,18,17,17,16,19,19,18,18,18,22,22,21,21,22,22,23,25,25,24,23,23,22,25,25,24,24,24,23,24,24,24,24,24,24,21,21,21,21,21,22,25,26,26,24,23,23,24,24,22,20,23,23,22,21,20,19,24,24,23,22,22,24,24,24,24,22,22,21,21,22,22,21,21,16,16,15,14,15,16,16,14,14,14,14,14,23,23,22,21,21,21,20,20,19,19,19,19,19,19,17,17,16,16,15,15,12,6,4,4,5,6,7,8,8,5,5,3,0,4,7,7,6,8,8,11,13,15,15,14,14,14,13,15,15,15,15,13,12,11,9,16,19,19,19,19,21,21,20,19,19,19,18,18,17,16,14,13,1 [...]
+"130",18,18,18,18,16,16,16,14,14,15,16,16,15,15,14,17,17,16,16,16,20,20,19,19,20,20,21,23,23,22,21,21,20,23,23,22,22,22,21,22,22,22,22,22,22,19,19,19,19,19,20,23,24,24,22,21,21,22,22,20,18,21,21,20,19,18,17,22,22,21,20,20,22,22,22,22,20,20,19,19,20,20,19,19,14,14,13,12,13,14,14,12,12,12,12,12,21,21,20,19,19,19,18,18,17,17,17,17,17,17,15,15,14,14,13,13,10,4,4,4,7,8,9,10,10,7,7,5,4,0,5,5,4,6,6,9,11,13,13,12,12,12,11,13,13,13,13,11,10,9,7,14,17,17,17,17,19,19,18,17,17,17,16,16,15,14,12,11,1 [...]
+"131",19,19,19,19,17,17,17,15,15,16,17,17,16,16,15,18,18,17,17,17,21,21,20,20,21,21,22,24,24,23,22,22,21,24,24,23,23,23,22,23,23,23,23,23,23,20,20,20,20,20,21,24,25,25,23,22,22,23,23,21,19,22,22,21,20,19,18,23,23,22,21,21,23,23,23,23,21,21,20,20,21,21,20,20,15,15,14,13,14,15,15,13,13,13,13,13,22,22,21,20,20,20,19,19,18,18,18,18,18,18,16,16,15,15,14,14,11,5,7,7,10,11,12,13,13,10,10,8,7,5,0,2,3,7,7,10,12,14,14,13,13,13,12,14,14,14,14,12,11,10,8,15,18,18,18,18,20,20,19,18,18,18,17,17,16,15, [...]
+"132",19,19,19,19,17,17,17,15,15,16,17,17,16,16,15,18,18,17,17,17,21,21,20,20,21,21,22,24,24,23,22,22,21,24,24,23,23,23,22,23,23,23,23,23,23,20,20,20,20,20,21,24,25,25,23,22,22,23,23,21,19,22,22,21,20,19,18,23,23,22,21,21,23,23,23,23,21,21,20,20,21,21,20,20,15,15,14,13,14,15,15,13,13,13,13,13,22,22,21,20,20,20,19,19,18,18,18,18,18,18,16,16,15,15,14,14,11,5,7,7,10,11,12,13,13,10,10,8,7,5,2,0,3,7,7,10,12,14,14,13,13,13,12,14,14,14,14,12,11,10,8,15,18,18,18,18,20,20,19,18,18,18,17,17,16,15, [...]
+"133",18,18,18,18,16,16,16,14,14,15,16,16,15,15,14,17,17,16,16,16,20,20,19,19,20,20,21,23,23,22,21,21,20,23,23,22,22,22,21,22,22,22,22,22,22,19,19,19,19,19,20,23,24,24,22,21,21,22,22,20,18,21,21,20,19,18,17,22,22,21,20,20,22,22,22,22,20,20,19,19,20,20,19,19,14,14,13,12,13,14,14,12,12,12,12,12,21,21,20,19,19,19,18,18,17,17,17,17,17,17,15,15,14,14,13,13,10,4,6,6,9,10,11,12,12,9,9,7,6,4,3,3,0,6,6,9,11,13,13,12,12,12,11,13,13,13,13,11,10,9,7,14,17,17,17,17,19,19,18,17,17,17,16,16,15,14,12,11 [...]
+"134",16,16,16,16,14,14,14,12,12,13,14,14,13,13,12,15,15,14,14,14,18,18,17,17,18,18,19,21,21,20,19,19,18,21,21,20,20,20,19,20,20,20,20,20,20,17,17,17,17,17,18,21,22,22,20,19,19,20,20,18,16,19,19,18,17,16,15,20,20,19,18,18,20,20,20,20,18,18,17,17,18,18,17,17,12,12,11,10,11,12,12,10,10,10,10,10,19,19,18,17,17,17,16,16,15,15,15,15,15,15,13,13,12,12,11,11,8,4,8,8,11,12,13,14,14,11,11,9,8,6,7,7,6,0,2,7,9,11,11,10,10,10,9,11,11,11,11,9,8,7,5,12,15,15,15,15,17,17,16,15,15,15,14,14,13,12,10,9,8, [...]
+"135",16,16,16,16,14,14,14,12,12,13,14,14,13,13,12,15,15,14,14,14,18,18,17,17,18,18,19,21,21,20,19,19,18,21,21,20,20,20,19,20,20,20,20,20,20,17,17,17,17,17,18,21,22,22,20,19,19,20,20,18,16,19,19,18,17,16,15,20,20,19,18,18,20,20,20,20,18,18,17,17,18,18,17,17,12,12,11,10,11,12,12,10,10,10,10,10,19,19,18,17,17,17,16,16,15,15,15,15,15,15,13,13,12,12,11,11,8,4,8,8,11,12,13,14,14,11,11,9,8,6,7,7,6,2,0,7,9,11,11,10,10,10,9,11,11,11,11,9,8,7,5,12,15,15,15,15,17,17,16,15,15,15,14,14,13,12,10,9,8, [...]
+"136",17,17,17,17,15,15,15,13,13,14,15,15,14,14,13,16,16,15,15,15,19,19,18,18,19,19,20,22,22,21,20,20,19,22,22,21,21,21,20,21,21,21,21,21,21,18,18,18,18,18,19,22,23,23,21,20,20,21,21,19,17,20,20,19,18,17,16,21,21,20,19,19,21,21,21,21,19,19,18,18,19,19,18,18,13,13,12,11,12,13,13,11,11,11,11,11,20,20,19,18,18,18,17,17,16,16,16,16,16,16,14,14,13,13,12,12,9,7,11,11,14,15,16,17,17,14,14,12,11,9,10,10,9,7,7,0,4,6,6,5,5,5,4,8,8,8,8,6,5,4,4,13,16,16,16,16,18,18,17,16,16,16,15,15,14,13,11,10,9,12 [...]
+"137",19,19,19,19,17,17,17,15,15,16,17,17,16,16,15,18,18,17,17,17,21,21,20,20,21,21,22,24,24,23,22,22,21,24,24,23,23,23,22,23,23,23,23,23,23,20,20,20,20,20,21,24,25,25,23,22,22,23,23,21,19,22,22,21,20,19,18,23,23,22,21,21,23,23,23,23,21,21,20,20,21,21,20,20,15,15,14,13,14,15,15,13,13,13,13,13,22,22,21,20,20,20,19,19,18,18,18,18,18,18,16,16,15,15,14,14,11,9,13,13,16,17,18,19,19,16,16,14,13,11,12,12,11,9,9,4,0,4,4,3,5,5,4,10,10,10,10,8,7,6,6,15,18,18,18,18,20,20,19,18,18,18,17,17,16,15,13, [...]
+"138",21,21,21,21,19,19,19,17,17,18,19,19,18,18,17,20,20,19,19,19,23,23,22,22,23,23,24,26,26,25,24,24,23,26,26,25,25,25,24,25,25,25,25,25,25,22,22,22,22,22,23,26,27,27,25,24,24,25,25,23,21,24,24,23,22,21,20,25,25,24,23,23,25,25,25,25,23,23,22,22,23,23,22,22,17,17,16,15,16,17,17,15,15,15,15,15,24,24,23,22,22,22,21,21,20,20,20,20,20,20,18,18,17,17,16,16,13,11,15,15,18,19,20,21,21,18,18,16,15,13,14,14,13,11,11,6,4,0,2,3,7,7,6,12,12,12,12,10,9,8,8,17,20,20,20,20,22,22,21,20,20,20,19,19,18,17 [...]
+"139",21,21,21,21,19,19,19,17,17,18,19,19,18,18,17,20,20,19,19,19,23,23,22,22,23,23,24,26,26,25,24,24,23,26,26,25,25,25,24,25,25,25,25,25,25,22,22,22,22,22,23,26,27,27,25,24,24,25,25,23,21,24,24,23,22,21,20,25,25,24,23,23,25,25,25,25,23,23,22,22,23,23,22,22,17,17,16,15,16,17,17,15,15,15,15,15,24,24,23,22,22,22,21,21,20,20,20,20,20,20,18,18,17,17,16,16,13,11,15,15,18,19,20,21,21,18,18,16,15,13,14,14,13,11,11,6,4,2,0,3,7,7,6,12,12,12,12,10,9,8,8,17,20,20,20,20,22,22,21,20,20,20,19,19,18,17 [...]
+"140",20,20,20,20,18,18,18,16,16,17,18,18,17,17,16,19,19,18,18,18,22,22,21,21,22,22,23,25,25,24,23,23,22,25,25,24,24,24,23,24,24,24,24,24,24,21,21,21,21,21,22,25,26,26,24,23,23,24,24,22,20,23,23,22,21,20,19,24,24,23,22,22,24,24,24,24,22,22,21,21,22,22,21,21,16,16,15,14,15,16,16,14,14,14,14,14,23,23,22,21,21,21,20,20,19,19,19,19,19,19,17,17,16,16,15,15,12,10,14,14,17,18,19,20,20,17,17,15,14,12,13,13,12,10,10,5,3,3,3,0,6,6,5,11,11,11,11,9,8,7,7,16,19,19,19,19,21,21,20,19,19,19,18,18,17,16, [...]
+"141",20,20,20,20,18,18,18,16,16,17,18,18,17,17,16,19,19,18,18,18,22,22,21,21,22,22,23,25,25,24,23,23,22,25,25,24,24,24,23,24,24,24,24,24,24,21,21,21,21,21,22,25,26,26,24,23,23,24,24,22,20,23,23,22,21,20,19,24,24,23,22,22,24,24,24,24,22,22,21,21,22,22,21,21,16,16,15,14,15,16,16,14,14,14,14,14,23,23,22,21,21,21,20,20,19,19,19,19,19,19,17,17,16,16,15,15,12,10,14,14,17,18,19,20,20,17,17,15,14,12,13,13,12,10,10,5,5,7,7,6,0,2,3,11,11,11,11,9,8,7,7,16,19,19,19,19,21,21,20,19,19,19,18,18,17,16, [...]
+"142",20,20,20,20,18,18,18,16,16,17,18,18,17,17,16,19,19,18,18,18,22,22,21,21,22,22,23,25,25,24,23,23,22,25,25,24,24,24,23,24,24,24,24,24,24,21,21,21,21,21,22,25,26,26,24,23,23,24,24,22,20,23,23,22,21,20,19,24,24,23,22,22,24,24,24,24,22,22,21,21,22,22,21,21,16,16,15,14,15,16,16,14,14,14,14,14,23,23,22,21,21,21,20,20,19,19,19,19,19,19,17,17,16,16,15,15,12,10,14,14,17,18,19,20,20,17,17,15,14,12,13,13,12,10,10,5,5,7,7,6,2,0,3,11,11,11,11,9,8,7,7,16,19,19,19,19,21,21,20,19,19,19,18,18,17,16, [...]
+"143",19,19,19,19,17,17,17,15,15,16,17,17,16,16,15,18,18,17,17,17,21,21,20,20,21,21,22,24,24,23,22,22,21,24,24,23,23,23,22,23,23,23,23,23,23,20,20,20,20,20,21,24,25,25,23,22,22,23,23,21,19,22,22,21,20,19,18,23,23,22,21,21,23,23,23,23,21,21,20,20,21,21,20,20,15,15,14,13,14,15,15,13,13,13,13,13,22,22,21,20,20,20,19,19,18,18,18,18,18,18,16,16,15,15,14,14,11,9,13,13,16,17,18,19,19,16,16,14,13,11,12,12,11,9,9,4,4,6,6,5,3,3,0,10,10,10,10,8,7,6,6,15,18,18,18,18,20,20,19,18,18,18,17,17,16,15,13, [...]
+"144",21,21,21,21,19,19,19,17,17,18,19,19,18,18,17,20,20,19,19,19,23,23,22,22,23,23,24,26,26,25,24,24,23,26,26,25,25,25,24,25,25,25,25,25,25,22,22,22,22,22,23,26,27,27,25,24,24,25,25,23,21,24,24,23,22,21,20,25,25,24,23,23,25,25,25,25,23,23,22,22,23,23,22,22,17,17,16,15,16,17,17,15,15,15,15,15,24,24,23,22,22,22,21,21,20,20,20,20,20,20,18,18,17,17,16,16,13,11,15,15,18,19,20,21,21,18,18,16,15,13,14,14,13,11,11,8,10,12,12,11,11,11,10,0,2,4,4,4,5,6,8,17,20,20,20,20,22,22,21,20,20,20,19,19,18, [...]
+"145",21,21,21,21,19,19,19,17,17,18,19,19,18,18,17,20,20,19,19,19,23,23,22,22,23,23,24,26,26,25,24,24,23,26,26,25,25,25,24,25,25,25,25,25,25,22,22,22,22,22,23,26,27,27,25,24,24,25,25,23,21,24,24,23,22,21,20,25,25,24,23,23,25,25,25,25,23,23,22,22,23,23,22,22,17,17,16,15,16,17,17,15,15,15,15,15,24,24,23,22,22,22,21,21,20,20,20,20,20,20,18,18,17,17,16,16,13,11,15,15,18,19,20,21,21,18,18,16,15,13,14,14,13,11,11,8,10,12,12,11,11,11,10,2,0,4,4,4,5,6,8,17,20,20,20,20,22,22,21,20,20,20,19,19,18, [...]
+"146",21,21,21,21,19,19,19,17,17,18,19,19,18,18,17,20,20,19,19,19,23,23,22,22,23,23,24,26,26,25,24,24,23,26,26,25,25,25,24,25,25,25,25,25,25,22,22,22,22,22,23,26,27,27,25,24,24,25,25,23,21,24,24,23,22,21,20,25,25,24,23,23,25,25,25,25,23,23,22,22,23,23,22,22,17,17,16,15,16,17,17,15,15,15,15,15,24,24,23,22,22,22,21,21,20,20,20,20,20,20,18,18,17,17,16,16,13,11,15,15,18,19,20,21,21,18,18,16,15,13,14,14,13,11,11,8,10,12,12,11,11,11,10,4,4,0,2,4,5,6,8,17,20,20,20,20,22,22,21,20,20,20,19,19,18, [...]
+"147",21,21,21,21,19,19,19,17,17,18,19,19,18,18,17,20,20,19,19,19,23,23,22,22,23,23,24,26,26,25,24,24,23,26,26,25,25,25,24,25,25,25,25,25,25,22,22,22,22,22,23,26,27,27,25,24,24,25,25,23,21,24,24,23,22,21,20,25,25,24,23,23,25,25,25,25,23,23,22,22,23,23,22,22,17,17,16,15,16,17,17,15,15,15,15,15,24,24,23,22,22,22,21,21,20,20,20,20,20,20,18,18,17,17,16,16,13,11,15,15,18,19,20,21,21,18,18,16,15,13,14,14,13,11,11,8,10,12,12,11,11,11,10,4,4,2,0,4,5,6,8,17,20,20,20,20,22,22,21,20,20,20,19,19,18, [...]
+"148",19,19,19,19,17,17,17,15,15,16,17,17,16,16,15,18,18,17,17,17,21,21,20,20,21,21,22,24,24,23,22,22,21,24,24,23,23,23,22,23,23,23,23,23,23,20,20,20,20,20,21,24,25,25,23,22,22,23,23,21,19,22,22,21,20,19,18,23,23,22,21,21,23,23,23,23,21,21,20,20,21,21,20,20,15,15,14,13,14,15,15,13,13,13,13,13,22,22,21,20,20,20,19,19,18,18,18,18,18,18,16,16,15,15,14,14,11,9,13,13,16,17,18,19,19,16,16,14,13,11,12,12,11,9,9,6,8,10,10,9,9,9,8,4,4,4,4,0,3,4,6,15,18,18,18,18,20,20,19,18,18,18,17,17,16,15,13,12 [...]
+"149",18,18,18,18,16,16,16,14,14,15,16,16,15,15,14,17,17,16,16,16,20,20,19,19,20,20,21,23,23,22,21,21,20,23,23,22,22,22,21,22,22,22,22,22,22,19,19,19,19,19,20,23,24,24,22,21,21,22,22,20,18,21,21,20,19,18,17,22,22,21,20,20,22,22,22,22,20,20,19,19,20,20,19,19,14,14,13,12,13,14,14,12,12,12,12,12,21,21,20,19,19,19,18,18,17,17,17,17,17,17,15,15,14,14,13,13,10,8,12,12,15,16,17,18,18,15,15,13,12,10,11,11,10,8,8,5,7,9,9,8,8,8,7,5,5,5,5,3,0,3,5,14,17,17,17,17,19,19,18,17,17,17,16,16,15,14,12,11,1 [...]
+"150",17,17,17,17,15,15,15,13,13,14,15,15,14,14,13,16,16,15,15,15,19,19,18,18,19,19,20,22,22,21,20,20,19,22,22,21,21,21,20,21,21,21,21,21,21,18,18,18,18,18,19,22,23,23,21,20,20,21,21,19,17,20,20,19,18,17,16,21,21,20,19,19,21,21,21,21,19,19,18,18,19,19,18,18,13,13,12,11,12,13,13,11,11,11,11,11,20,20,19,18,18,18,17,17,16,16,16,16,16,16,14,14,13,13,12,12,9,7,11,11,14,15,16,17,17,14,14,12,11,9,10,10,9,7,7,4,6,8,8,7,7,7,6,6,6,6,6,4,3,0,4,13,16,16,16,16,18,18,17,16,16,16,15,15,14,13,11,10,9,12 [...]
+"151",15,15,15,15,13,13,13,11,11,12,13,13,12,12,11,14,14,13,13,13,17,17,16,16,17,17,18,20,20,19,18,18,17,20,20,19,19,19,18,19,19,19,19,19,19,16,16,16,16,16,17,20,21,21,19,18,18,19,19,17,15,18,18,17,16,15,14,19,19,18,17,17,19,19,19,19,17,17,16,16,17,17,16,16,11,11,10,9,10,11,11,9,9,9,9,9,18,18,17,16,16,16,15,15,14,14,14,14,14,14,12,12,11,11,10,10,7,5,9,9,12,13,14,15,15,12,12,10,9,7,8,8,7,5,5,4,6,8,8,7,7,7,6,8,8,8,8,6,5,4,0,11,14,14,14,14,16,16,15,14,14,14,13,13,12,11,9,8,7,10,10,12,12,11, [...]
+"152",20,20,20,20,18,18,18,16,16,17,18,18,17,17,16,19,19,18,18,18,22,22,21,21,22,22,23,25,25,24,23,23,22,25,25,24,24,24,23,24,24,24,24,24,24,21,21,21,21,21,22,25,26,26,24,23,23,24,24,22,20,23,23,22,21,20,19,24,24,23,22,22,24,24,24,24,22,22,21,21,22,22,21,21,16,16,15,14,15,16,16,14,14,14,14,14,23,23,22,21,21,21,20,20,19,19,19,19,19,19,17,17,16,16,15,15,12,12,16,16,19,20,21,22,22,19,19,17,16,14,15,15,14,12,12,13,15,17,17,16,16,16,15,17,17,17,17,15,14,13,11,0,5,5,5,5,7,7,6,5,5,5,6,6,5,4,4,5 [...]
+"153",23,23,23,23,21,21,21,19,19,20,21,21,20,20,19,22,22,21,21,21,25,25,24,24,25,25,26,28,28,27,26,26,25,28,28,27,27,27,26,27,27,27,27,27,27,24,24,24,24,24,25,28,29,29,27,26,26,27,27,25,23,26,26,25,24,23,22,27,27,26,25,25,27,27,27,27,25,25,24,24,25,25,24,24,19,19,18,17,18,19,19,17,17,17,17,17,26,26,25,24,24,24,23,23,22,22,22,22,22,22,20,20,19,19,18,18,15,15,19,19,22,23,24,25,25,22,22,20,19,17,18,18,17,15,15,16,18,20,20,19,19,19,18,20,20,20,20,18,17,16,14,5,0,2,4,4,8,8,7,6,6,6,9,9,8,7,7,8 [...]
+"154",23,23,23,23,21,21,21,19,19,20,21,21,20,20,19,22,22,21,21,21,25,25,24,24,25,25,26,28,28,27,26,26,25,28,28,27,27,27,26,27,27,27,27,27,27,24,24,24,24,24,25,28,29,29,27,26,26,27,27,25,23,26,26,25,24,23,22,27,27,26,25,25,27,27,27,27,25,25,24,24,25,25,24,24,19,19,18,17,18,19,19,17,17,17,17,17,26,26,25,24,24,24,23,23,22,22,22,22,22,22,20,20,19,19,18,18,15,15,19,19,22,23,24,25,25,22,22,20,19,17,18,18,17,15,15,16,18,20,20,19,19,19,18,20,20,20,20,18,17,16,14,5,2,0,4,4,8,8,7,6,6,6,9,9,8,7,7,8 [...]
+"155",23,23,23,23,21,21,21,19,19,20,21,21,20,20,19,22,22,21,21,21,25,25,24,24,25,25,26,28,28,27,26,26,25,28,28,27,27,27,26,27,27,27,27,27,27,24,24,24,24,24,25,28,29,29,27,26,26,27,27,25,23,26,26,25,24,23,22,27,27,26,25,25,27,27,27,27,25,25,24,24,25,25,24,24,19,19,18,17,18,19,19,17,17,17,17,17,26,26,25,24,24,24,23,23,22,22,22,22,22,22,20,20,19,19,18,18,15,15,19,19,22,23,24,25,25,22,22,20,19,17,18,18,17,15,15,16,18,20,20,19,19,19,18,20,20,20,20,18,17,16,14,5,4,4,0,2,8,8,7,6,6,6,9,9,8,7,7,8 [...]
+"156",23,23,23,23,21,21,21,19,19,20,21,21,20,20,19,22,22,21,21,21,25,25,24,24,25,25,26,28,28,27,26,26,25,28,28,27,27,27,26,27,27,27,27,27,27,24,24,24,24,24,25,28,29,29,27,26,26,27,27,25,23,26,26,25,24,23,22,27,27,26,25,25,27,27,27,27,25,25,24,24,25,25,24,24,19,19,18,17,18,19,19,17,17,17,17,17,26,26,25,24,24,24,23,23,22,22,22,22,22,22,20,20,19,19,18,18,15,15,19,19,22,23,24,25,25,22,22,20,19,17,18,18,17,15,15,16,18,20,20,19,19,19,18,20,20,20,20,18,17,16,14,5,4,4,2,0,8,8,7,6,6,6,9,9,8,7,7,8 [...]
+"157",25,25,25,25,23,23,23,21,21,22,23,23,22,22,21,24,24,23,23,23,27,27,26,26,27,27,28,30,30,29,28,28,27,30,30,29,29,29,28,29,29,29,29,29,29,26,26,26,26,26,27,30,31,31,29,28,28,29,29,27,25,28,28,27,26,25,24,29,29,28,27,27,29,29,29,29,27,27,26,26,27,27,26,26,21,21,20,19,20,21,21,19,19,19,19,19,28,28,27,26,26,26,25,25,24,24,24,24,24,24,22,22,21,21,20,20,17,17,21,21,24,25,26,27,27,24,24,22,21,19,20,20,19,17,17,18,20,22,22,21,21,21,20,22,22,22,22,20,19,18,16,7,8,8,8,8,0,2,3,4,6,6,11,11,10,9, [...]
+"158",25,25,25,25,23,23,23,21,21,22,23,23,22,22,21,24,24,23,23,23,27,27,26,26,27,27,28,30,30,29,28,28,27,30,30,29,29,29,28,29,29,29,29,29,29,26,26,26,26,26,27,30,31,31,29,28,28,29,29,27,25,28,28,27,26,25,24,29,29,28,27,27,29,29,29,29,27,27,26,26,27,27,26,26,21,21,20,19,20,21,21,19,19,19,19,19,28,28,27,26,26,26,25,25,24,24,24,24,24,24,22,22,21,21,20,20,17,17,21,21,24,25,26,27,27,24,24,22,21,19,20,20,19,17,17,18,20,22,22,21,21,21,20,22,22,22,22,20,19,18,16,7,8,8,8,8,2,0,3,4,6,6,11,11,10,9, [...]
+"159",24,24,24,24,22,22,22,20,20,21,22,22,21,21,20,23,23,22,22,22,26,26,25,25,26,26,27,29,29,28,27,27,26,29,29,28,28,28,27,28,28,28,28,28,28,25,25,25,25,25,26,29,30,30,28,27,27,28,28,26,24,27,27,26,25,24,23,28,28,27,26,26,28,28,28,28,26,26,25,25,26,26,25,25,20,20,19,18,19,20,20,18,18,18,18,18,27,27,26,25,25,25,24,24,23,23,23,23,23,23,21,21,20,20,19,19,16,16,20,20,23,24,25,26,26,23,23,21,20,18,19,19,18,16,16,17,19,21,21,20,20,20,19,21,21,21,21,19,18,17,15,6,7,7,7,7,3,3,0,3,5,5,10,10,9,8,8 [...]
+"160",23,23,23,23,21,21,21,19,19,20,21,21,20,20,19,22,22,21,21,21,25,25,24,24,25,25,26,28,28,27,26,26,25,28,28,27,27,27,26,27,27,27,27,27,27,24,24,24,24,24,25,28,29,29,27,26,26,27,27,25,23,26,26,25,24,23,22,27,27,26,25,25,27,27,27,27,25,25,24,24,25,25,24,24,19,19,18,17,18,19,19,17,17,17,17,17,26,26,25,24,24,24,23,23,22,22,22,22,22,22,20,20,19,19,18,18,15,15,19,19,22,23,24,25,25,22,22,20,19,17,18,18,17,15,15,16,18,20,20,19,19,19,18,20,20,20,20,18,17,16,14,5,6,6,6,6,4,4,3,0,4,4,9,9,8,7,7,8 [...]
+"161",23,23,23,23,21,21,21,19,19,20,21,21,20,20,19,22,22,21,21,21,25,25,24,24,25,25,26,28,28,27,26,26,25,28,28,27,27,27,26,27,27,27,27,27,27,24,24,24,24,24,25,28,29,29,27,26,26,27,27,25,23,26,26,25,24,23,22,27,27,26,25,25,27,27,27,27,25,25,24,24,25,25,24,24,19,19,18,17,18,19,19,17,17,17,17,17,26,26,25,24,24,24,23,23,22,22,22,22,22,22,20,20,19,19,18,18,15,15,19,19,22,23,24,25,25,22,22,20,19,17,18,18,17,15,15,16,18,20,20,19,19,19,18,20,20,20,20,18,17,16,14,5,6,6,6,6,6,6,5,4,0,2,9,9,8,7,7,8 [...]
+"162",23,23,23,23,21,21,21,19,19,20,21,21,20,20,19,22,22,21,21,21,25,25,24,24,25,25,26,28,28,27,26,26,25,28,28,27,27,27,26,27,27,27,27,27,27,24,24,24,24,24,25,28,29,29,27,26,26,27,27,25,23,26,26,25,24,23,22,27,27,26,25,25,27,27,27,27,25,25,24,24,25,25,24,24,19,19,18,17,18,19,19,17,17,17,17,17,26,26,25,24,24,24,23,23,22,22,22,22,22,22,20,20,19,19,18,18,15,15,19,19,22,23,24,25,25,22,22,20,19,17,18,18,17,15,15,16,18,20,20,19,19,19,18,20,20,20,20,18,17,16,14,5,6,6,6,6,6,6,5,4,2,0,9,9,8,7,7,8 [...]
+"163",22,22,22,22,20,20,20,18,18,19,20,20,19,19,18,21,21,20,20,20,24,24,23,23,24,24,25,27,27,26,25,25,24,27,27,26,26,26,25,26,26,26,26,26,26,23,23,23,23,23,24,27,28,28,26,25,25,26,26,24,22,25,25,24,23,22,21,26,26,25,24,24,26,26,26,26,24,24,23,23,24,24,23,23,18,18,17,16,17,18,18,16,16,16,16,16,25,25,24,23,23,23,22,22,21,21,21,21,21,21,19,19,18,18,17,17,14,14,18,18,21,22,23,24,24,21,21,19,18,16,17,17,16,14,14,15,17,19,19,18,18,18,17,19,19,19,19,17,16,15,13,6,9,9,9,9,11,11,10,9,9,9,0,2,3,4, [...]
+"164",22,22,22,22,20,20,20,18,18,19,20,20,19,19,18,21,21,20,20,20,24,24,23,23,24,24,25,27,27,26,25,25,24,27,27,26,26,26,25,26,26,26,26,26,26,23,23,23,23,23,24,27,28,28,26,25,25,26,26,24,22,25,25,24,23,22,21,26,26,25,24,24,26,26,26,26,24,24,23,23,24,24,23,23,18,18,17,16,17,18,18,16,16,16,16,16,25,25,24,23,23,23,22,22,21,21,21,21,21,21,19,19,18,18,17,17,14,14,18,18,21,22,23,24,24,21,21,19,18,16,17,17,16,14,14,15,17,19,19,18,18,18,17,19,19,19,19,17,16,15,13,6,9,9,9,9,11,11,10,9,9,9,2,0,3,4, [...]
+"165",21,21,21,21,19,19,19,17,17,18,19,19,18,18,17,20,20,19,19,19,23,23,22,22,23,23,24,26,26,25,24,24,23,26,26,25,25,25,24,25,25,25,25,25,25,22,22,22,22,22,23,26,27,27,25,24,24,25,25,23,21,24,24,23,22,21,20,25,25,24,23,23,25,25,25,25,23,23,22,22,23,23,22,22,17,17,16,15,16,17,17,15,15,15,15,15,24,24,23,22,22,22,21,21,20,20,20,20,20,20,18,18,17,17,16,16,13,13,17,17,20,21,22,23,23,20,20,18,17,15,16,16,15,13,13,14,16,18,18,17,17,17,16,18,18,18,18,16,15,14,12,5,8,8,8,8,10,10,9,8,8,8,3,3,0,3,5 [...]
+"166",20,20,20,20,18,18,18,16,16,17,18,18,17,17,16,19,19,18,18,18,22,22,21,21,22,22,23,25,25,24,23,23,22,25,25,24,24,24,23,24,24,24,24,24,24,21,21,21,21,21,22,25,26,26,24,23,23,24,24,22,20,23,23,22,21,20,19,24,24,23,22,22,24,24,24,24,22,22,21,21,22,22,21,21,16,16,15,14,15,16,16,14,14,14,14,14,23,23,22,21,21,21,20,20,19,19,19,19,19,19,17,17,16,16,15,15,12,12,16,16,19,20,21,22,22,19,19,17,16,14,15,15,14,12,12,13,15,17,17,16,16,16,15,17,17,17,17,15,14,13,11,4,7,7,7,7,9,9,8,7,7,7,4,4,3,0,4,5 [...]
+"167",18,18,18,18,16,16,16,14,14,15,16,16,15,15,14,17,17,16,16,16,20,20,19,19,20,20,21,23,23,22,21,21,20,23,23,22,22,22,21,22,22,22,22,22,22,19,19,19,19,19,20,23,24,24,22,21,21,22,22,20,18,21,21,20,19,18,17,22,22,21,20,20,22,22,22,22,20,20,19,19,20,20,19,19,14,14,13,12,13,14,14,12,12,12,12,12,21,21,20,19,19,19,18,18,17,17,17,17,17,17,15,15,14,14,13,13,10,10,14,14,17,18,19,20,20,17,17,15,14,12,13,13,12,10,10,11,13,15,15,14,14,14,13,15,15,15,15,13,12,11,9,4,7,7,7,7,9,9,8,7,7,7,6,6,5,4,0,3, [...]
+"168",17,17,17,17,15,15,15,13,13,14,15,15,14,14,13,16,16,15,15,15,19,19,18,18,19,19,20,22,22,21,20,20,19,22,22,21,21,21,20,21,21,21,21,21,21,18,18,18,18,18,19,22,23,23,21,20,20,21,21,19,17,20,20,19,18,17,16,21,21,20,19,19,21,21,21,21,19,19,18,18,19,19,18,18,13,13,12,11,12,13,13,11,11,11,11,11,20,20,19,18,18,18,17,17,16,16,16,16,16,16,14,14,13,13,12,12,9,9,13,13,16,17,18,19,19,16,16,14,13,11,12,12,11,9,9,10,12,14,14,13,13,13,12,14,14,14,14,12,11,10,8,5,8,8,8,8,10,10,9,8,8,8,7,7,6,5,3,0,3, [...]
+"169",16,16,16,16,14,14,14,12,12,13,14,14,13,13,12,15,15,14,14,14,18,18,17,17,18,18,19,21,21,20,19,19,18,21,21,20,20,20,19,20,20,20,20,20,20,17,17,17,17,17,18,21,22,22,20,19,19,20,20,18,16,19,19,18,17,16,15,20,20,19,18,18,20,20,20,20,18,18,17,17,18,18,17,17,12,12,11,10,11,12,12,10,10,10,10,10,19,19,18,17,17,17,16,16,15,15,15,15,15,15,13,13,12,12,11,11,8,8,12,12,15,16,17,18,18,15,15,13,12,10,11,11,10,8,8,9,11,13,13,12,12,12,11,13,13,13,13,11,10,9,7,6,9,9,9,9,11,11,10,9,9,9,8,8,7,6,4,3,0,7 [...]
+"170",19,19,19,19,17,17,17,15,15,16,17,17,16,16,15,18,18,17,17,17,21,21,20,20,21,21,22,24,24,23,22,22,21,24,24,23,23,23,22,23,23,23,23,23,23,20,20,20,20,20,21,24,25,25,23,22,22,23,23,21,19,22,22,21,20,19,18,23,23,22,21,21,23,23,23,23,21,21,20,20,21,21,20,20,15,15,14,13,14,15,15,13,13,13,13,13,22,22,21,20,20,20,19,19,18,18,18,18,18,18,16,16,15,15,14,14,11,11,15,15,18,19,20,21,21,18,18,16,15,13,14,14,13,11,11,12,14,16,16,15,15,15,14,16,16,16,16,14,13,12,10,11,14,14,14,14,16,16,15,14,14,14, [...]
+"171",19,19,19,19,17,17,17,15,15,16,17,17,16,16,15,18,18,17,17,17,21,21,20,20,21,21,22,24,24,23,22,22,21,24,24,23,23,23,22,23,23,23,23,23,23,20,20,20,20,20,21,24,25,25,23,22,22,23,23,21,19,22,22,21,20,19,18,23,23,22,21,21,23,23,23,23,21,21,20,20,21,21,20,20,15,15,14,13,14,15,15,13,13,13,13,13,22,22,21,20,20,20,19,19,18,18,18,18,18,18,16,16,15,15,14,14,11,11,15,15,18,19,20,21,21,18,18,16,15,13,14,14,13,11,11,12,14,16,16,15,15,15,14,16,16,16,16,14,13,12,10,11,14,14,14,14,16,16,15,14,14,14, [...]
+"172",21,21,21,21,19,19,19,17,17,18,19,19,18,18,17,20,20,19,19,19,23,23,22,22,23,23,24,26,26,25,24,24,23,26,26,25,25,25,24,25,25,25,25,25,25,22,22,22,22,22,23,26,27,27,25,24,24,25,25,23,21,24,24,23,22,21,20,25,25,24,23,23,25,25,25,25,23,23,22,22,23,23,22,22,17,17,16,15,16,17,17,15,15,15,15,15,24,24,23,22,22,22,21,21,20,20,20,20,20,20,18,18,17,17,16,16,13,13,17,17,20,21,22,23,23,20,20,18,17,15,16,16,15,13,13,14,16,18,18,17,17,17,16,18,18,18,18,16,15,14,12,13,16,16,16,16,18,18,17,16,16,16, [...]
+"173",21,21,21,21,19,19,19,17,17,18,19,19,18,18,17,20,20,19,19,19,23,23,22,22,23,23,24,26,26,25,24,24,23,26,26,25,25,25,24,25,25,25,25,25,25,22,22,22,22,22,23,26,27,27,25,24,24,25,25,23,21,24,24,23,22,21,20,25,25,24,23,23,25,25,25,25,23,23,22,22,23,23,22,22,17,17,16,15,16,17,17,15,15,15,15,15,24,24,23,22,22,22,21,21,20,20,20,20,20,20,18,18,17,17,16,16,13,13,17,17,20,21,22,23,23,20,20,18,17,15,16,16,15,13,13,14,16,18,18,17,17,17,16,18,18,18,18,16,15,14,12,13,16,16,16,16,18,18,17,16,16,16, [...]
+"174",20,20,20,20,18,18,18,16,16,17,18,18,17,17,16,19,19,18,18,18,22,22,21,21,22,22,23,25,25,24,23,23,22,25,25,24,24,24,23,24,24,24,24,24,24,21,21,21,21,21,22,25,26,26,24,23,23,24,24,22,20,23,23,22,21,20,19,24,24,23,22,22,24,24,24,24,22,22,21,21,22,22,21,21,16,16,15,14,15,16,16,14,14,14,14,14,23,23,22,21,21,21,20,20,19,19,19,19,19,19,17,17,16,16,15,15,12,12,16,16,19,20,21,22,22,19,19,17,16,14,15,15,14,12,12,13,15,17,17,16,16,16,15,17,17,17,17,15,14,13,11,12,15,15,15,15,17,17,16,15,15,15, [...]
+"175",19,19,19,19,17,17,17,15,15,16,17,17,16,16,15,18,18,17,17,17,21,21,20,20,21,21,22,24,24,23,22,22,21,24,24,23,23,23,22,23,23,23,23,23,23,20,20,20,20,20,21,24,25,25,23,22,22,23,23,21,19,22,22,21,20,19,18,23,23,22,21,21,23,23,23,23,21,21,20,20,21,21,20,20,15,15,14,13,14,15,15,13,13,13,13,13,22,22,21,20,20,20,19,19,18,18,18,18,18,18,16,16,15,15,14,14,11,11,15,15,18,19,20,21,21,18,18,16,15,13,14,14,13,11,11,12,14,16,16,15,15,15,14,16,16,16,16,14,13,12,10,11,14,14,14,14,16,16,15,14,14,14, [...]
+"176",17,17,17,17,15,15,15,13,13,14,15,15,14,14,13,16,16,15,15,15,19,19,18,18,19,19,20,22,22,21,20,20,19,22,22,21,21,21,20,21,21,21,21,21,21,18,18,18,18,18,19,22,23,23,21,20,20,21,21,19,17,20,20,19,18,17,16,21,21,20,19,19,21,21,21,21,19,19,18,18,19,19,18,18,13,13,12,11,12,13,13,11,11,11,11,11,20,20,19,18,18,18,17,17,16,16,16,16,16,16,14,14,13,13,12,12,9,9,13,13,16,17,18,19,19,16,16,14,13,11,12,12,11,9,9,10,12,14,14,13,13,13,12,14,14,14,14,12,11,10,8,9,12,12,12,12,14,14,13,12,12,12,11,11, [...]
+"177",16,16,16,16,14,14,14,12,12,13,14,14,13,13,12,15,15,14,14,14,18,18,17,17,18,18,19,21,21,20,19,19,18,21,21,20,20,20,19,20,20,20,20,20,20,17,17,17,17,17,18,21,22,22,20,19,19,20,20,18,16,19,19,18,17,16,15,20,20,19,18,18,20,20,20,20,18,18,17,17,18,18,17,17,12,12,11,10,11,12,12,10,10,10,10,10,19,19,18,17,17,17,16,16,15,15,15,15,15,15,13,13,12,12,11,11,8,8,12,12,15,16,17,18,18,15,15,13,12,10,11,11,10,8,8,9,11,13,13,12,12,12,11,13,13,13,13,11,10,9,7,8,11,11,11,11,13,13,12,11,11,11,10,10,9, [...]
+"178",17,17,17,17,15,15,15,13,13,14,15,15,14,14,13,16,16,15,15,15,19,19,18,18,19,19,20,22,22,21,20,20,19,22,22,21,21,21,20,21,21,21,21,21,21,18,18,18,18,18,19,22,23,23,21,20,20,21,21,19,17,20,20,19,18,17,16,21,21,20,19,19,21,21,21,21,19,19,18,18,19,19,18,18,13,13,12,11,12,13,13,11,11,11,11,11,20,20,19,18,18,18,17,17,16,16,16,16,16,16,14,14,13,13,12,12,9,9,13,13,16,17,18,19,19,16,16,14,13,11,12,12,11,9,9,10,12,14,14,13,13,13,12,14,14,14,14,12,11,10,8,11,14,14,14,14,16,16,15,14,14,14,13,13 [...]
+"179",18,18,18,18,16,16,16,14,14,15,16,16,15,15,14,17,17,16,16,16,20,20,19,19,20,20,21,23,23,22,21,21,20,23,23,22,22,22,21,22,22,22,22,22,22,19,19,19,19,19,20,23,24,24,22,21,21,22,22,20,18,21,21,20,19,18,17,22,22,21,20,20,22,22,22,22,20,20,19,19,20,20,19,19,14,14,13,12,13,14,14,12,12,12,12,12,21,21,20,19,19,19,18,18,17,17,17,17,17,17,15,15,14,14,13,13,10,10,14,14,17,18,19,20,20,17,17,15,14,12,13,13,12,10,10,11,13,15,15,14,14,14,13,15,15,15,15,13,12,11,9,12,15,15,15,15,17,17,16,15,15,15,1 [...]
+"180",21,21,21,21,19,19,19,17,17,18,19,19,18,18,17,20,20,19,19,19,23,23,22,22,23,23,24,26,26,25,24,24,23,26,26,25,25,25,24,25,25,25,25,25,25,22,22,22,22,22,23,26,27,27,25,24,24,25,25,23,21,24,24,23,22,21,20,25,25,24,23,23,25,25,25,25,23,23,22,22,23,23,22,22,17,17,16,15,16,17,17,15,15,15,15,15,24,24,23,22,22,22,21,21,20,20,20,20,20,20,18,18,17,17,16,16,13,13,17,17,20,21,22,23,23,20,20,18,17,15,16,16,15,13,13,14,16,18,18,17,17,17,16,18,18,18,18,16,15,14,12,15,18,18,18,18,20,20,19,18,18,18, [...]
+"181",21,21,21,21,19,19,19,17,17,18,19,19,18,18,17,20,20,19,19,19,23,23,22,22,23,23,24,26,26,25,24,24,23,26,26,25,25,25,24,25,25,25,25,25,25,22,22,22,22,22,23,26,27,27,25,24,24,25,25,23,21,24,24,23,22,21,20,25,25,24,23,23,25,25,25,25,23,23,22,22,23,23,22,22,17,17,16,15,16,17,17,15,15,15,15,15,24,24,23,22,22,22,21,21,20,20,20,20,20,20,18,18,17,17,16,16,13,13,17,17,20,21,22,23,23,20,20,18,17,15,16,16,15,13,13,14,16,18,18,17,17,17,16,18,18,18,18,16,15,14,12,15,18,18,18,18,20,20,19,18,18,18, [...]
+"182",20,20,20,20,18,18,18,16,16,17,18,18,17,17,16,19,19,18,18,18,22,22,21,21,22,22,23,25,25,24,23,23,22,25,25,24,24,24,23,24,24,24,24,24,24,21,21,21,21,21,22,25,26,26,24,23,23,24,24,22,20,23,23,22,21,20,19,24,24,23,22,22,24,24,24,24,22,22,21,21,22,22,21,21,16,16,15,14,15,16,16,14,14,14,14,14,23,23,22,21,21,21,20,20,19,19,19,19,19,19,17,17,16,16,15,15,12,12,16,16,19,20,21,22,22,19,19,17,16,14,15,15,14,12,12,13,15,17,17,16,16,16,15,17,17,17,17,15,14,13,11,14,17,17,17,17,19,19,18,17,17,17, [...]
+"183",20,20,20,20,18,18,18,16,16,17,18,18,17,17,16,19,19,18,18,18,22,22,21,21,22,22,23,25,25,24,23,23,22,25,25,24,24,24,23,24,24,24,24,24,24,21,21,21,21,21,22,25,26,26,24,23,23,24,24,22,20,23,23,22,21,20,19,24,24,23,22,22,24,24,24,24,22,22,21,21,22,22,21,21,16,16,15,14,15,16,16,14,14,14,14,14,23,23,22,21,21,21,20,20,19,19,19,19,19,19,17,17,16,16,15,15,12,12,16,16,19,20,21,22,22,19,19,17,16,14,15,15,14,12,12,13,15,17,17,16,16,16,15,17,17,17,17,15,14,13,11,14,17,17,17,17,19,19,18,17,17,17, [...]
+"184",20,20,20,20,18,18,18,16,16,17,18,18,17,17,16,19,19,18,18,18,22,22,21,21,22,22,23,25,25,24,23,23,22,25,25,24,24,24,23,24,24,24,24,24,24,21,21,21,21,21,22,25,26,26,24,23,23,24,24,22,20,23,23,22,21,20,19,24,24,23,22,22,24,24,24,24,22,22,21,21,22,22,21,21,16,16,15,14,15,16,16,14,14,14,14,14,23,23,22,21,21,21,20,20,19,19,19,19,19,19,17,17,16,16,15,15,12,12,16,16,19,20,21,22,22,19,19,17,16,14,15,15,14,12,12,13,15,17,17,16,16,16,15,17,17,17,17,15,14,13,11,14,17,17,17,17,19,19,18,17,17,17, [...]
+"185",16,16,16,16,14,14,14,12,12,13,14,14,13,13,12,15,15,14,14,14,18,18,17,17,18,18,19,21,21,20,19,19,18,21,21,20,20,20,19,20,20,20,20,20,20,17,17,17,17,17,18,21,22,22,20,19,19,20,20,18,16,19,19,18,17,16,15,20,20,19,18,18,20,20,20,20,18,18,17,17,18,18,17,17,12,12,11,10,11,12,12,10,10,10,10,10,19,19,18,17,17,17,16,16,15,15,15,15,15,15,13,13,12,12,11,11,8,8,12,12,15,16,17,18,18,15,15,13,12,10,11,11,10,8,8,9,11,13,13,12,12,12,11,13,13,13,13,11,10,9,7,10,13,13,13,13,15,15,14,13,13,13,12,12,1 [...]
+"186",18,18,18,18,16,16,16,14,14,15,16,16,15,15,14,17,17,16,16,16,20,20,19,19,20,20,21,23,23,22,21,21,20,23,23,22,22,22,21,22,22,22,22,22,22,19,19,19,19,19,20,23,24,24,22,21,21,22,22,20,18,21,21,20,19,18,17,22,22,21,20,20,22,22,22,22,20,20,19,19,20,20,19,19,14,14,13,12,13,14,14,12,12,12,12,12,21,21,20,19,19,19,18,18,17,17,17,17,17,17,15,15,14,14,13,13,10,10,14,14,17,18,19,20,20,17,17,15,14,12,13,13,12,10,10,11,13,15,15,14,14,14,13,15,15,15,15,13,12,11,9,12,15,15,15,15,17,17,16,15,15,15,1 [...]
+"187",19,19,19,19,17,17,17,15,15,16,17,17,16,16,15,18,18,17,17,17,21,21,20,20,21,21,22,24,24,23,22,22,21,24,24,23,23,23,22,23,23,23,23,23,23,20,20,20,20,20,21,24,25,25,23,22,22,23,23,21,19,22,22,21,20,19,18,23,23,22,21,21,23,23,23,23,21,21,20,20,21,21,20,20,15,15,14,13,14,15,15,13,13,13,13,13,22,22,21,20,20,20,19,19,18,18,18,18,18,18,16,16,15,15,14,14,11,11,15,15,18,19,20,21,21,18,18,16,15,13,14,14,13,11,11,12,14,16,16,15,15,15,14,16,16,16,16,14,13,12,10,13,16,16,16,16,18,18,17,16,16,16, [...]
+"188",20,20,20,20,18,18,18,16,16,17,18,18,17,17,16,19,19,18,18,18,22,22,21,21,22,22,23,25,25,24,23,23,22,25,25,24,24,24,23,24,24,24,24,24,24,21,21,21,21,21,22,25,26,26,24,23,23,24,24,22,20,23,23,22,21,20,19,24,24,23,22,22,24,24,24,24,22,22,21,21,22,22,21,21,16,16,15,14,15,16,16,14,14,14,14,14,23,23,22,21,21,21,20,20,19,19,19,19,19,19,17,17,16,16,15,15,12,12,16,16,19,20,21,22,22,19,19,17,16,14,15,15,14,12,12,13,15,17,17,16,16,16,15,17,17,17,17,15,14,13,11,14,17,17,17,17,19,19,18,17,17,17, [...]
+"189",20,20,20,20,18,18,18,16,16,17,18,18,17,17,16,19,19,18,18,18,22,22,21,21,22,22,23,25,25,24,23,23,22,25,25,24,24,24,23,24,24,24,24,24,24,21,21,21,21,21,22,25,26,26,24,23,23,24,24,22,20,23,23,22,21,20,19,24,24,23,22,22,24,24,24,24,22,22,21,21,22,22,21,21,16,16,15,14,15,16,16,14,14,14,14,14,23,23,22,21,21,21,20,20,19,19,19,19,19,19,17,17,16,16,15,15,12,12,16,16,19,20,21,22,22,19,19,17,16,14,15,15,14,12,12,13,15,17,17,16,16,16,15,17,17,17,17,15,14,13,11,14,17,17,17,17,19,19,18,17,17,17, [...]
+"190",17,17,17,17,15,15,15,13,13,14,15,15,14,14,13,16,16,15,15,15,19,19,18,18,19,19,20,22,22,21,20,20,19,22,22,21,21,21,20,21,21,21,21,21,21,18,18,18,18,18,19,22,23,23,21,20,20,21,21,19,17,20,20,19,18,17,16,21,21,20,19,19,21,21,21,21,19,19,18,18,19,19,18,18,13,13,12,11,12,13,13,11,11,11,11,11,20,20,19,18,18,18,17,17,16,16,16,16,16,16,14,14,13,13,12,12,9,9,13,13,16,17,18,19,19,16,16,14,13,11,12,12,11,9,9,10,12,14,14,13,13,13,12,14,14,14,14,12,11,10,8,11,14,14,14,14,16,16,15,14,14,14,13,13 [...]
+"191",18,18,18,18,16,16,16,14,14,15,16,16,15,15,14,17,17,16,16,16,20,20,19,19,20,20,21,23,23,22,21,21,20,23,23,22,22,22,21,22,22,22,22,22,22,19,19,19,19,19,20,23,24,24,22,21,21,22,22,20,18,21,21,20,19,18,17,22,22,21,20,20,22,22,22,22,20,20,19,19,20,20,19,19,14,14,13,12,13,14,14,12,12,12,12,12,21,21,20,19,19,19,18,18,17,17,17,17,17,17,15,15,14,14,13,13,10,10,14,14,17,18,19,20,20,17,17,15,14,12,13,13,12,10,10,11,13,15,15,14,14,14,13,15,15,15,15,13,12,11,9,12,15,15,15,15,17,17,16,15,15,15,1 [...]
+"192",18,18,18,18,16,16,16,14,14,15,16,16,15,15,14,17,17,16,16,16,20,20,19,19,20,20,21,23,23,22,21,21,20,23,23,22,22,22,21,22,22,22,22,22,22,19,19,19,19,19,20,23,24,24,22,21,21,22,22,20,18,21,21,20,19,18,17,22,22,21,20,20,22,22,22,22,20,20,19,19,20,20,19,19,14,14,13,12,13,14,14,12,12,12,12,12,21,21,20,19,19,19,18,18,17,17,17,17,17,17,15,15,14,14,13,13,10,10,14,14,17,18,19,20,20,17,17,15,14,12,13,13,12,10,10,11,13,15,15,14,14,14,13,15,15,15,15,13,12,11,9,12,15,15,15,15,17,17,16,15,15,15,1 [...]
+"193",17,17,17,17,15,15,15,13,13,14,15,15,14,14,13,16,16,15,15,15,19,19,18,18,19,19,20,22,22,21,20,20,19,22,22,21,21,21,20,21,21,21,21,21,21,18,18,18,18,18,19,22,23,23,21,20,20,21,21,19,17,20,20,19,18,17,16,21,21,20,19,19,21,21,21,21,19,19,18,18,19,19,18,18,13,13,12,11,12,13,13,11,11,11,11,11,20,20,19,18,18,18,17,17,16,16,16,16,16,16,14,14,13,13,12,12,9,9,13,13,16,17,18,19,19,16,16,14,13,11,12,12,11,9,9,10,12,14,14,13,13,13,12,14,14,14,14,12,11,10,8,11,14,14,14,14,16,16,15,14,14,14,13,13 [...]
+"194",11,11,11,11,9,9,9,7,7,8,9,9,8,8,7,10,10,9,9,9,13,13,12,12,13,13,14,16,16,15,14,14,13,16,16,15,15,15,14,15,15,15,15,15,15,12,12,12,12,12,13,16,17,17,15,14,14,15,15,13,11,14,14,13,12,11,10,15,15,14,13,13,15,15,15,15,13,13,12,12,13,13,12,12,7,7,6,5,6,7,7,5,5,5,5,5,14,14,13,12,12,12,11,11,10,10,10,10,10,10,8,8,7,7,6,6,3,5,9,9,12,13,14,15,15,12,12,10,9,7,8,8,7,5,5,6,8,10,10,9,9,9,8,10,10,10,10,8,7,6,4,9,12,12,12,12,14,14,13,12,12,12,11,11,10,9,7,6,5,8,8,10,10,9,8,6,5,6,7,10,10,9,9,9,5,7 [...]
+"195",10,10,10,10,8,8,8,6,6,7,8,8,7,7,6,9,9,8,8,8,12,12,11,11,12,12,13,15,15,14,13,13,12,15,15,14,14,14,13,14,14,14,14,14,14,11,11,11,11,11,12,15,16,16,14,13,13,14,14,12,10,13,13,12,11,10,9,14,14,13,12,12,14,14,14,14,12,12,11,11,12,12,11,11,6,6,5,4,5,6,6,4,4,4,4,4,13,13,12,11,11,11,10,10,9,9,9,9,9,9,7,7,6,6,5,5,2,6,10,10,13,14,15,16,16,13,13,11,10,8,9,9,8,6,6,7,9,11,11,10,10,10,9,11,11,11,11,9,8,7,5,10,13,13,13,13,15,15,14,13,13,13,12,12,11,10,8,7,6,9,9,11,11,10,9,7,6,7,8,11,11,10,10,10, [...]
+"196",9,9,9,9,7,7,7,5,5,6,7,7,6,6,5,8,8,7,7,7,11,11,10,10,11,11,12,14,14,13,12,12,11,14,14,13,13,13,12,13,13,13,13,13,13,10,10,10,10,10,11,14,15,15,13,12,12,13,13,11,9,12,12,11,10,9,8,13,13,12,11,11,13,13,13,13,11,11,10,10,11,11,10,10,5,5,4,3,4,5,5,3,3,3,5,5,14,14,13,12,12,12,11,11,10,10,10,10,10,10,8,8,7,7,6,6,3,7,11,11,14,15,16,17,17,14,14,12,11,9,10,10,9,7,7,8,10,12,12,11,11,11,10,12,12,12,12,10,9,8,6,11,14,14,14,14,16,16,15,14,14,14,13,13,12,11,9,8,7,10,10,12,12,11,10,8,7,8,9,12,12,1 [...]
+"197",8,8,8,8,6,6,6,4,4,5,6,6,5,5,4,7,7,6,6,6,10,10,9,9,10,10,11,13,13,12,11,11,10,13,13,12,12,12,11,12,12,12,12,12,12,9,9,9,9,9,10,13,14,14,12,11,11,12,12,10,8,11,11,10,9,8,7,12,12,11,10,10,12,12,12,12,10,10,9,9,10,10,9,9,4,4,3,2,5,6,6,4,4,4,6,6,15,15,14,13,13,13,12,12,11,11,11,11,11,11,9,9,8,8,7,7,4,8,12,12,15,16,17,18,18,15,15,13,12,10,11,11,10,8,8,9,11,13,13,12,12,12,11,13,13,13,13,11,10,9,7,12,15,15,15,15,17,17,16,15,15,15,14,14,13,12,10,9,8,11,11,13,13,12,11,9,8,9,10,13,13,12,12,12 [...]
+"198",7,7,7,7,5,5,5,3,3,4,5,5,4,4,3,6,6,5,5,5,9,9,8,8,9,9,10,12,12,11,10,10,9,12,12,11,11,11,10,11,11,11,11,11,11,8,8,8,8,8,9,12,13,13,11,10,10,11,11,9,7,10,10,9,8,7,6,11,11,10,9,9,11,11,11,11,9,9,8,8,9,9,8,8,5,5,4,3,6,7,7,5,5,5,7,7,16,16,15,14,14,14,13,13,12,12,12,12,12,12,10,10,9,9,8,8,5,9,13,13,16,17,18,19,19,16,16,14,13,11,12,12,11,9,9,10,12,14,14,13,13,13,12,14,14,14,14,12,11,10,8,13,16,16,16,16,18,18,17,16,16,16,15,15,14,13,11,10,9,12,12,14,14,13,12,10,9,10,11,14,14,13,13,13,9,11,1 [...]
+"199",6,6,6,6,4,4,4,2,2,3,4,4,5,5,4,7,7,6,6,6,10,10,9,9,10,10,11,13,13,12,11,11,10,13,13,12,12,12,11,12,12,12,12,12,12,9,9,9,9,9,10,13,14,14,12,11,11,12,12,10,8,11,11,10,9,8,7,12,12,11,10,10,12,12,12,12,10,10,9,9,10,10,9,9,6,6,5,4,7,8,8,6,6,6,8,8,17,17,16,15,15,15,14,14,13,13,13,13,13,13,11,11,10,10,9,9,6,10,14,14,17,18,19,20,20,17,17,15,14,12,13,13,12,10,10,11,13,15,15,14,14,14,13,15,15,15,15,13,12,11,9,14,17,17,17,17,19,19,18,17,17,17,16,16,15,14,12,11,10,13,13,15,15,14,13,11,10,11,12, [...]
+"200",5,5,5,5,3,3,3,1,3,4,5,5,6,6,5,8,8,7,7,7,11,11,10,10,11,11,12,14,14,13,12,12,11,14,14,13,13,13,12,13,13,13,13,13,13,10,10,10,10,10,11,14,15,15,13,12,12,13,13,11,9,12,12,11,10,9,8,13,13,12,11,11,13,13,13,13,11,11,10,10,11,11,10,10,7,7,6,5,8,9,9,7,7,7,9,9,18,18,17,16,16,16,15,15,14,14,14,14,14,14,12,12,11,11,10,10,7,11,15,15,18,19,20,21,21,18,18,16,15,13,14,14,13,11,11,12,14,16,16,15,15,15,14,16,16,16,16,14,13,12,10,15,18,18,18,18,20,20,19,18,18,18,17,17,16,15,13,12,11,14,14,16,16,15, [...]
+"201",4,4,4,4,2,2,2,2,4,5,6,6,7,7,6,9,9,8,8,8,12,12,11,11,12,12,13,15,15,14,13,13,12,15,15,14,14,14,13,14,14,14,14,14,14,11,11,11,11,11,12,15,16,16,14,13,13,14,14,12,10,13,13,12,11,10,9,14,14,13,12,12,14,14,14,14,12,12,11,11,12,12,11,11,8,8,7,6,9,10,10,8,8,8,10,10,19,19,18,17,17,17,16,16,15,15,15,15,15,15,13,13,12,12,11,11,8,12,16,16,19,20,21,22,22,19,19,17,16,14,15,15,14,12,12,13,15,17,17,16,16,16,15,17,17,17,17,15,14,13,11,16,19,19,19,19,21,21,20,19,19,19,18,18,17,16,14,13,12,15,15,17, [...]
+"202",3,3,3,3,1,3,3,3,5,6,7,7,8,8,7,10,10,9,9,9,13,13,12,12,13,13,14,16,16,15,14,14,13,16,16,15,15,15,14,15,15,15,15,15,15,12,12,12,12,12,13,16,17,17,15,14,14,15,15,13,11,14,14,13,12,11,10,15,15,14,13,13,15,15,15,15,13,13,12,12,13,13,12,12,9,9,8,7,10,11,11,9,9,9,11,11,20,20,19,18,18,18,17,17,16,16,16,16,16,16,14,14,13,13,12,12,9,13,17,17,20,21,22,23,23,20,20,18,17,15,16,16,15,13,13,14,16,18,18,17,17,17,16,18,18,18,18,16,15,14,12,17,20,20,20,20,22,22,21,20,20,20,19,19,18,17,15,14,13,16,16 [...]
+"203",2,2,2,2,2,4,4,4,6,7,8,8,9,9,8,11,11,10,10,10,14,14,13,13,14,14,15,17,17,16,15,15,14,17,17,16,16,16,15,16,16,16,16,16,16,13,13,13,13,13,14,17,18,18,16,15,15,16,16,14,12,15,15,14,13,12,11,16,16,15,14,14,16,16,16,16,14,14,13,13,14,14,13,13,10,10,9,8,11,12,12,10,10,10,12,12,21,21,20,19,19,19,18,18,17,17,17,17,17,17,15,15,14,14,13,13,10,14,18,18,21,22,23,24,24,21,21,19,18,16,17,17,16,14,14,15,17,19,19,18,18,18,17,19,19,19,19,17,16,15,13,18,21,21,21,21,23,23,22,21,21,21,20,20,19,18,16,15 [...]
+"204",1,1,3,3,3,5,5,5,7,8,9,9,10,10,9,12,12,11,11,11,15,15,14,14,15,15,16,18,18,17,16,16,15,18,18,17,17,17,16,17,17,17,17,17,17,14,14,14,14,14,15,18,19,19,17,16,16,17,17,15,13,16,16,15,14,13,12,17,17,16,15,15,17,17,17,17,15,15,14,14,15,15,14,14,11,11,10,9,12,13,13,11,11,11,13,13,22,22,21,20,20,20,19,19,18,18,18,18,18,18,16,16,15,15,14,14,11,15,19,19,22,23,24,25,25,22,22,20,19,17,18,18,17,15,15,16,18,20,20,19,19,19,18,20,20,20,20,18,17,16,14,19,22,22,22,22,24,24,23,22,22,22,21,21,20,19,17 [...]
+"205",3,3,1,1,3,5,5,5,7,8,9,9,10,10,9,12,12,11,11,11,15,15,14,14,15,15,16,18,18,17,16,16,15,18,18,17,17,17,16,17,17,17,17,17,17,14,14,14,14,14,15,18,19,19,17,16,16,17,17,15,13,16,16,15,14,13,12,17,17,16,15,15,17,17,17,17,15,15,14,14,15,15,14,14,11,11,10,9,12,13,13,11,11,11,13,13,22,22,21,20,20,20,19,19,18,18,18,18,18,18,16,16,15,15,14,14,11,15,19,19,22,23,24,25,25,22,22,20,19,17,18,18,17,15,15,16,18,20,20,19,19,19,18,20,20,20,20,18,17,16,14,19,22,22,22,22,24,24,23,22,22,22,21,21,20,19,17 [...]
+"206",5,5,5,5,3,1,1,3,5,6,7,7,8,8,7,10,10,9,9,9,13,13,12,12,13,13,14,16,16,15,14,14,13,16,16,15,15,15,14,15,15,15,15,15,15,12,12,12,12,12,13,16,17,17,15,14,14,15,15,13,11,14,14,13,12,11,10,15,15,14,13,13,15,15,15,15,13,13,12,12,13,13,12,12,9,9,8,7,10,11,11,9,9,9,11,11,20,20,19,18,18,18,17,17,16,16,16,16,16,16,14,14,13,13,12,12,9,13,17,17,20,21,22,23,23,20,20,18,17,15,16,16,15,13,13,14,16,18,18,17,17,17,16,18,18,18,18,16,15,14,12,17,20,20,20,20,22,22,21,20,20,20,19,19,18,17,15,14,13,16,16 [...]
+"207",7,7,7,7,5,5,5,3,1,2,3,3,6,6,5,8,8,7,7,7,11,11,10,10,11,11,12,14,14,13,12,12,11,14,14,13,13,13,12,13,13,13,13,13,13,10,10,10,10,10,11,14,15,15,13,12,12,13,13,11,9,12,12,11,10,9,8,13,13,12,11,11,13,13,13,13,11,11,10,10,11,11,10,10,7,7,6,5,8,9,9,7,7,7,9,9,18,18,17,16,16,16,15,15,14,14,14,14,14,14,12,12,11,11,10,10,7,11,15,15,18,19,20,21,21,18,18,16,15,13,14,14,13,11,11,12,14,16,16,15,15,15,14,16,16,16,16,14,13,12,10,15,18,18,18,18,20,20,19,18,18,18,17,17,16,15,13,12,11,14,14,16,16,15, [...]
+"208",8,8,8,8,6,6,6,4,2,1,2,2,7,7,6,9,9,8,8,8,12,12,11,11,12,12,13,15,15,14,13,13,12,15,15,14,14,14,13,14,14,14,14,14,14,11,11,11,11,11,12,15,16,16,14,13,13,14,14,12,10,13,13,12,11,10,9,14,14,13,12,12,14,14,14,14,12,12,11,11,12,12,11,11,8,8,7,6,9,10,10,8,8,8,10,10,19,19,18,17,17,17,16,16,15,15,15,15,15,15,13,13,12,12,11,11,8,12,16,16,19,20,21,22,22,19,19,17,16,14,15,15,14,12,12,13,15,17,17,16,16,16,15,17,17,17,17,15,14,13,11,16,19,19,19,19,21,21,20,19,19,19,18,18,17,16,14,13,12,15,15,17, [...]
+"209",9,9,9,9,7,7,7,5,3,2,1,1,8,8,7,10,10,9,9,9,13,13,12,12,13,13,14,16,16,15,14,14,13,16,16,15,15,15,14,15,15,15,15,15,15,12,12,12,12,12,13,16,17,17,15,14,14,15,15,13,11,14,14,13,12,11,10,15,15,14,13,13,15,15,15,15,13,13,12,12,13,13,12,12,9,9,8,7,10,11,11,9,9,9,11,11,20,20,19,18,18,18,17,17,16,16,16,16,16,16,14,14,13,13,12,12,9,13,17,17,20,21,22,23,23,20,20,18,17,15,16,16,15,13,13,14,16,18,18,17,17,17,16,18,18,18,18,16,15,14,12,17,20,20,20,20,22,22,21,20,20,20,19,19,18,17,15,14,13,16,16 [...]
+"210",8,8,8,8,6,6,6,4,4,5,6,6,3,3,2,5,5,4,4,4,8,8,7,7,8,8,9,11,11,10,9,9,8,11,11,10,10,10,9,10,10,10,10,10,10,7,7,7,7,7,8,11,12,12,10,9,9,10,10,8,6,9,9,8,7,6,5,10,10,9,8,8,10,10,10,10,8,8,7,7,8,8,7,7,6,6,5,4,7,8,8,6,6,6,8,8,17,17,16,15,15,15,14,14,13,13,13,13,13,13,11,11,10,10,9,9,6,10,14,14,17,18,19,20,20,17,17,15,14,12,13,13,12,10,10,11,13,15,15,14,14,14,13,15,15,15,15,13,12,11,9,14,17,17,17,17,19,19,18,17,17,17,16,16,15,14,12,11,10,13,13,15,15,14,13,11,10,11,12,15,15,14,14,14,10,12,13 [...]
+"211",9,9,9,9,7,7,7,5,5,6,7,7,2,2,1,6,6,5,5,5,9,9,8,8,9,9,10,12,12,11,10,10,9,12,12,11,11,11,10,11,11,11,11,11,11,8,8,8,8,8,9,12,13,13,11,10,10,11,11,9,7,10,10,9,8,7,6,11,11,10,9,9,11,11,11,11,9,9,8,8,9,9,8,8,7,7,6,5,8,9,9,7,7,7,9,9,18,18,17,16,16,16,15,15,14,14,14,14,14,14,12,12,11,11,10,10,7,11,15,15,18,19,20,21,21,18,18,16,15,13,14,14,13,11,11,12,14,16,16,15,15,15,14,16,16,16,16,14,13,12,10,15,18,18,18,18,20,20,19,18,18,18,17,17,16,15,13,12,11,14,14,16,16,15,14,12,11,12,13,16,16,15,15 [...]
+"212",10,10,10,10,8,8,8,6,6,7,8,8,1,1,2,7,7,6,6,6,10,10,9,9,10,10,11,13,13,12,11,11,10,13,13,12,12,12,11,12,12,12,12,12,12,9,9,9,9,9,10,13,14,14,12,11,11,12,12,10,8,11,11,10,9,8,7,12,12,11,10,10,12,12,12,12,10,10,9,9,10,10,9,9,8,8,7,6,9,10,10,8,8,8,10,10,19,19,18,17,17,17,16,16,15,15,15,15,15,15,13,13,12,12,11,11,8,12,16,16,19,20,21,22,22,19,19,17,16,14,15,15,14,12,12,13,15,17,17,16,16,16,15,17,17,17,17,15,14,13,11,16,19,19,19,19,21,21,20,19,19,19,18,18,17,16,14,13,12,15,15,17,17,16,15,1 [...]
+"213",9,9,9,9,7,7,7,5,5,6,7,7,4,4,3,4,4,3,3,3,7,7,6,6,7,7,8,10,10,9,8,8,7,10,10,9,9,9,8,9,9,9,9,9,9,6,6,6,6,6,7,10,11,11,9,8,8,9,9,7,5,8,8,7,6,5,4,9,9,8,7,7,9,9,9,9,7,7,6,6,7,7,6,6,7,7,6,5,8,9,9,7,7,7,9,9,18,18,17,16,16,16,15,15,14,14,14,14,14,14,12,12,11,11,10,10,7,11,15,15,18,19,20,21,21,18,18,16,15,13,14,14,13,11,11,12,14,16,16,15,15,15,14,16,16,16,16,14,13,12,10,15,18,18,18,18,20,20,19,18,18,18,17,17,16,15,13,12,11,14,14,16,16,15,14,12,11,12,13,16,16,15,15,15,11,13,14,15,15,12,13,13, [...]
+"214",10,10,10,10,8,8,8,6,6,7,8,8,5,5,4,3,3,2,2,2,8,8,7,7,8,8,9,11,11,10,9,9,8,11,11,10,10,10,9,10,10,10,10,10,10,7,7,7,7,7,8,11,12,12,10,9,9,10,10,8,6,9,9,8,7,6,5,10,10,9,8,8,10,10,10,10,8,8,7,7,8,8,7,7,8,8,7,6,9,10,10,8,8,8,10,10,19,19,18,17,17,17,16,16,15,15,15,15,15,15,13,13,12,12,11,11,8,12,16,16,19,20,21,22,22,19,19,17,16,14,15,15,14,12,12,13,15,17,17,16,16,16,15,17,17,17,17,15,14,13,11,16,19,19,19,19,21,21,20,19,19,19,18,18,17,16,14,13,12,15,15,17,17,16,15,13,12,13,14,17,17,16,16, [...]
+"215",11,11,11,11,9,9,9,7,7,8,9,9,6,6,5,2,2,1,3,3,9,9,8,8,9,9,10,12,12,11,10,10,9,12,12,11,11,11,10,11,11,11,11,11,11,8,8,8,8,8,9,12,13,13,11,10,10,11,11,9,7,10,10,9,8,7,6,11,11,10,9,9,11,11,11,11,9,9,8,8,9,9,8,8,9,9,8,7,10,11,11,9,9,9,11,11,20,20,19,18,18,18,17,17,16,16,16,16,16,16,14,14,13,13,12,12,9,13,17,17,20,21,22,23,23,20,20,18,17,15,16,16,15,13,13,14,16,18,18,17,17,17,16,18,18,18,18,16,15,14,12,17,20,20,20,20,22,22,21,20,20,20,19,19,18,17,15,14,13,16,16,18,18,17,16,14,13,14,15,18 [...]
+"216",12,12,12,12,10,10,10,8,8,9,10,10,7,7,6,1,1,2,4,4,10,10,9,9,10,10,11,13,13,12,11,11,10,13,13,12,12,12,11,12,12,12,12,12,12,9,9,9,9,9,10,13,14,14,12,11,11,12,12,10,8,11,11,10,9,8,7,12,12,11,10,10,12,12,12,12,10,10,9,9,10,10,9,9,10,10,9,8,11,12,12,10,10,10,12,12,21,21,20,19,19,19,18,18,17,17,17,17,17,17,15,15,14,14,13,13,10,14,18,18,21,22,23,24,24,21,21,19,18,16,17,17,16,14,14,15,17,19,19,18,18,18,17,19,19,19,19,17,16,15,13,18,21,21,21,21,23,23,22,21,21,21,20,20,19,18,16,15,14,17,17,1 [...]
+"217",11,11,11,11,9,9,9,7,7,8,9,9,6,6,5,4,4,3,1,1,9,9,8,8,9,9,10,12,12,11,10,10,9,12,12,11,11,11,10,11,11,11,11,11,11,8,8,8,8,8,9,12,13,13,11,10,10,11,11,9,7,10,10,9,8,7,6,11,11,10,9,9,11,11,11,11,9,9,8,8,9,9,8,8,9,9,8,7,10,11,11,9,9,9,11,11,20,20,19,18,18,18,17,17,16,16,16,16,16,16,14,14,13,13,12,12,9,13,17,17,20,21,22,23,23,20,20,18,17,15,16,16,15,13,13,14,16,18,18,17,17,17,16,18,18,18,18,16,15,14,12,17,20,20,20,20,22,22,21,20,20,20,19,19,18,17,15,14,13,16,16,18,18,17,16,14,13,14,15,18 [...]
+"218",10,10,10,10,8,8,8,6,6,7,8,8,5,5,4,5,5,4,4,4,6,6,5,5,6,6,7,9,9,8,7,7,6,9,9,8,8,8,7,8,8,8,8,8,8,5,5,5,5,5,6,9,10,10,8,7,7,8,8,6,4,7,7,6,5,4,3,8,8,7,6,6,8,8,8,8,6,6,5,5,6,6,5,5,8,8,7,6,9,10,10,8,8,8,10,10,19,19,18,17,17,17,16,16,15,15,15,15,15,15,13,13,12,12,11,11,8,12,16,16,19,20,21,22,22,19,19,17,16,14,15,15,14,12,12,13,15,17,17,16,16,16,15,17,17,17,17,15,14,13,11,16,19,19,19,19,21,21,20,19,19,19,18,18,17,16,14,13,12,15,15,17,17,16,15,13,12,13,14,17,17,16,16,16,12,14,15,16,16,13,14, [...]
+"219",11,11,11,11,9,9,9,7,7,8,9,9,6,6,5,6,6,5,5,5,5,5,4,4,5,5,6,8,8,7,6,6,5,8,8,7,7,7,6,7,7,7,7,7,7,4,4,4,4,4,5,8,9,9,7,6,6,7,7,5,3,8,8,7,6,5,4,9,9,8,7,7,9,9,9,9,7,7,6,6,7,7,6,6,9,9,8,7,10,11,11,9,9,9,11,11,20,20,19,18,18,18,17,17,16,16,16,16,16,16,14,14,13,13,12,12,9,13,17,17,20,21,22,23,23,20,20,18,17,15,16,16,15,13,13,14,16,18,18,17,17,17,16,18,18,18,18,16,15,14,12,17,20,20,20,20,22,22,21,20,20,20,19,19,18,17,15,14,13,16,16,18,18,17,16,14,13,14,15,18,18,17,17,17,13,15,16,17,17,14,15,1 [...]
+"220",12,12,12,12,10,10,10,8,8,9,10,10,7,7,6,7,7,6,6,6,4,4,3,3,4,4,5,7,7,6,5,5,4,7,7,6,6,6,5,6,6,6,6,6,6,3,5,5,5,5,6,9,10,10,8,7,7,8,8,6,4,9,9,8,7,6,5,10,10,9,8,8,10,10,10,10,8,8,7,7,8,8,7,7,10,10,9,8,11,12,12,10,10,10,12,12,21,21,20,19,19,19,18,18,17,17,17,17,17,17,15,15,14,14,13,13,10,14,18,18,21,22,23,24,24,21,21,19,18,16,17,17,16,14,14,15,17,19,19,18,18,18,17,19,19,19,19,17,16,15,13,18,21,21,21,21,23,23,22,21,21,21,20,20,19,18,16,15,14,17,17,19,19,18,17,15,14,15,16,19,19,18,18,18,14, [...]
+"221",13,13,13,13,11,11,11,9,9,10,11,11,8,8,7,8,8,7,7,7,3,3,2,2,3,3,6,8,8,7,6,6,5,8,8,7,7,7,6,7,7,7,7,7,7,4,6,6,6,6,7,10,11,11,9,8,8,9,9,7,5,10,10,9,8,7,6,11,11,10,9,9,11,11,11,11,9,9,8,8,9,9,8,8,11,11,10,9,12,13,13,11,11,11,13,13,22,22,21,20,20,20,19,19,18,18,18,18,18,18,16,16,15,15,14,14,11,15,19,19,22,23,24,25,25,22,22,20,19,17,18,18,17,15,15,16,18,20,20,19,19,19,18,20,20,20,20,18,17,16,14,19,22,22,22,22,24,24,23,22,22,22,21,21,20,19,17,16,15,18,18,20,20,19,18,16,15,16,17,20,20,19,19, [...]
+"222",14,14,14,14,12,12,12,10,10,11,12,12,9,9,8,9,9,8,8,8,2,2,1,3,4,4,7,9,9,8,7,7,6,9,9,8,8,8,7,8,8,8,8,8,8,5,7,7,7,7,8,11,12,12,10,9,9,10,10,8,6,11,11,10,9,8,7,12,12,11,10,10,12,12,12,12,10,10,9,9,10,10,9,9,12,12,11,10,13,14,14,12,12,12,14,14,23,23,22,21,21,21,20,20,19,19,19,19,19,19,17,17,16,16,15,15,12,16,20,20,23,24,25,26,26,23,23,21,20,18,19,19,18,16,16,17,19,21,21,20,20,20,19,21,21,21,21,19,18,17,15,20,23,23,23,23,25,25,24,23,23,23,22,22,21,20,18,17,16,19,19,21,21,20,19,17,16,17,18 [...]
+"223",15,15,15,15,13,13,13,11,11,12,13,13,10,10,9,10,10,9,9,9,1,1,2,4,5,5,8,10,10,9,8,8,7,10,10,9,9,9,8,9,9,9,9,9,9,6,8,8,8,8,9,12,13,13,11,10,10,11,11,9,7,12,12,11,10,9,8,13,13,12,11,11,13,13,13,13,11,11,10,10,11,11,10,10,13,13,12,11,14,15,15,13,13,13,15,15,24,24,23,22,22,22,21,21,20,20,20,20,20,20,18,18,17,17,16,16,13,17,21,21,24,25,26,27,27,24,24,22,21,19,20,20,19,17,17,18,20,22,22,21,21,21,20,22,22,22,22,20,19,18,16,21,24,24,24,24,26,26,25,24,24,24,23,23,22,21,19,18,17,20,20,22,22,21 [...]
+"224",14,14,14,14,12,12,12,10,10,11,12,12,9,9,8,9,9,8,8,8,4,4,3,1,2,2,7,9,9,8,7,7,6,9,9,8,8,8,7,8,8,8,8,8,8,5,7,7,7,7,8,11,12,12,10,9,9,10,10,8,6,11,11,10,9,8,7,12,12,11,10,10,12,12,12,12,10,10,9,9,10,10,9,9,12,12,11,10,13,14,14,12,12,12,14,14,23,23,22,21,21,21,20,20,19,19,19,19,19,19,17,17,16,16,15,15,12,16,20,20,23,24,25,26,26,23,23,21,20,18,19,19,18,16,16,17,19,21,21,20,20,20,19,21,21,21,21,19,18,17,15,20,23,23,23,23,25,25,24,23,23,23,22,22,21,20,18,17,16,19,19,21,21,20,19,17,16,17,18 [...]
+"225",15,15,15,15,13,13,13,11,11,12,13,13,10,10,9,10,10,9,9,9,5,5,4,2,1,1,8,10,10,9,8,8,7,10,10,9,9,9,8,9,9,9,9,9,9,6,8,8,8,8,9,12,13,13,11,10,10,11,11,9,7,12,12,11,10,9,8,13,13,12,11,11,13,13,13,13,11,11,10,10,11,11,10,10,13,13,12,11,14,15,15,13,13,13,15,15,24,24,23,22,22,22,21,21,20,20,20,20,20,20,18,18,17,17,16,16,13,17,21,21,24,25,26,27,27,24,24,22,21,19,20,20,19,17,17,18,20,22,22,21,21,21,20,22,22,22,22,20,19,18,16,21,24,24,24,24,26,26,25,24,24,24,23,23,22,21,19,18,17,20,20,22,22,21 [...]
+"226",13,13,13,13,11,11,11,9,9,10,11,11,8,8,7,8,8,7,7,7,5,5,4,4,5,5,4,6,6,5,4,4,3,6,6,5,5,5,4,5,5,5,5,5,5,2,6,6,6,6,7,10,11,11,9,8,8,9,9,7,5,10,10,9,8,7,6,11,11,10,9,9,11,11,11,11,9,9,8,8,9,9,8,8,11,11,10,9,12,13,13,11,11,11,13,13,22,22,21,20,20,20,19,19,18,18,18,18,18,18,16,16,15,15,14,14,11,15,19,19,22,23,24,25,25,22,22,20,19,17,18,18,17,15,15,16,18,20,20,19,19,19,18,20,20,20,20,18,17,16,14,19,22,22,22,22,24,24,23,22,22,22,21,21,20,19,17,16,15,18,18,20,20,19,18,16,15,16,17,20,20,19,19, [...]
+"227",14,14,14,14,12,12,12,10,10,11,12,12,9,9,8,9,9,8,8,8,6,6,5,5,6,6,3,5,5,4,3,3,2,5,5,4,4,4,5,6,6,6,6,6,6,3,7,7,7,7,8,11,12,12,10,9,9,10,10,8,6,11,11,10,9,8,7,12,12,11,10,10,12,12,12,12,10,10,9,9,10,10,9,9,12,12,11,10,13,14,14,12,12,12,14,14,23,23,22,21,21,21,20,20,19,19,19,19,19,19,17,17,16,16,15,15,12,16,20,20,23,24,25,26,26,23,23,21,20,18,19,19,18,16,16,17,19,21,21,20,20,20,19,21,21,21,21,19,18,17,15,20,23,23,23,23,25,25,24,23,23,23,22,22,21,20,18,17,16,19,19,21,21,20,19,17,16,17,18 [...]
+"228",15,15,15,15,13,13,13,11,11,12,13,13,10,10,9,10,10,9,9,9,7,7,6,6,7,7,2,4,4,3,2,2,3,6,6,5,5,5,6,7,7,7,7,7,7,4,8,8,8,8,9,12,13,13,11,10,10,11,11,9,7,12,12,11,10,9,8,13,13,12,11,11,13,13,13,13,11,11,10,10,11,11,10,10,13,13,12,11,14,15,15,13,13,13,15,15,24,24,23,22,22,22,21,21,20,20,20,20,20,20,18,18,17,17,16,16,13,17,21,21,24,25,26,27,27,24,24,22,21,19,20,20,19,17,17,18,20,22,22,21,21,21,20,22,22,22,22,20,19,18,16,21,24,24,24,24,26,26,25,24,24,24,23,23,22,21,19,18,17,20,20,22,22,21,20, [...]
+"229",16,16,16,16,14,14,14,12,12,13,14,14,11,11,10,11,11,10,10,10,8,8,7,7,8,8,1,3,3,2,3,3,4,7,7,6,6,6,7,8,8,8,8,8,8,5,9,9,9,9,10,13,14,14,12,11,11,12,12,10,8,13,13,12,11,10,9,14,14,13,12,12,14,14,14,14,12,12,11,11,12,12,11,11,14,14,13,12,15,16,16,14,14,14,16,16,25,25,24,23,23,23,22,22,21,21,21,21,21,21,19,19,18,18,17,17,14,18,22,22,25,26,27,28,28,25,25,23,22,20,21,21,20,18,18,19,21,23,23,22,22,22,21,23,23,23,23,21,20,19,17,22,25,25,25,25,27,27,26,25,25,25,24,24,23,22,20,19,18,21,21,23,23 [...]
+"230",17,17,17,17,15,15,15,13,13,14,15,15,12,12,11,12,12,11,11,11,9,9,8,8,9,9,2,2,2,1,4,4,5,8,8,7,7,7,8,9,9,9,9,9,9,6,10,10,10,10,11,14,15,15,13,12,12,13,13,11,9,14,14,13,12,11,10,15,15,14,13,13,15,15,15,15,13,13,12,12,13,13,12,12,15,15,14,13,16,17,17,15,15,15,17,17,26,26,25,24,24,24,23,23,22,22,22,22,22,22,20,20,19,19,18,18,15,19,23,23,26,27,28,29,29,26,26,24,23,21,22,22,21,19,19,20,22,24,24,23,23,23,22,24,24,24,24,22,21,20,18,23,26,26,26,26,28,28,27,26,26,26,25,25,24,23,21,20,19,22,22, [...]
+"231",18,18,18,18,16,16,16,14,14,15,16,16,13,13,12,13,13,12,12,12,10,10,9,9,10,10,3,1,1,2,5,5,6,9,9,8,8,8,9,10,10,10,10,10,10,7,11,11,11,11,12,15,16,16,14,13,13,14,14,12,10,15,15,14,13,12,11,16,16,15,14,14,16,16,16,16,14,14,13,13,14,14,13,13,16,16,15,14,17,18,18,16,16,16,18,18,27,27,26,25,25,25,24,24,23,23,23,23,23,23,21,21,20,20,19,19,16,20,24,24,27,28,29,30,30,27,27,25,24,22,23,23,22,20,20,21,23,25,25,24,24,24,23,25,25,25,25,23,22,21,19,24,27,27,27,27,29,29,28,27,27,27,26,26,25,24,22,2 [...]
+"232",16,16,16,16,14,14,14,12,12,13,14,14,11,11,10,11,11,10,10,10,8,8,7,7,8,8,3,5,5,4,1,1,4,7,7,6,6,6,7,8,8,8,8,8,8,5,9,9,9,9,10,13,14,14,12,11,11,12,12,10,8,13,13,12,11,10,9,14,14,13,12,12,14,14,14,14,12,12,11,11,12,12,11,11,14,14,13,12,15,16,16,14,14,14,16,16,25,25,24,23,23,23,22,22,21,21,21,21,21,21,19,19,18,18,17,17,14,18,22,22,25,26,27,28,28,25,25,23,22,20,21,21,20,18,18,19,21,23,23,22,22,22,21,23,23,23,23,21,20,19,17,22,25,25,25,25,27,27,26,25,25,25,24,24,23,22,20,19,18,21,21,23,23 [...]
+"233",15,15,15,15,13,13,13,11,11,12,13,13,10,10,9,10,10,9,9,9,7,7,6,6,7,7,4,6,6,5,4,4,1,4,4,3,3,3,6,7,7,7,7,7,7,4,8,8,8,8,9,12,13,13,11,10,10,11,11,9,7,12,12,11,10,9,8,13,13,12,11,11,13,13,13,13,11,11,10,10,11,11,10,10,13,13,12,11,14,15,15,13,13,13,15,15,24,24,23,22,22,22,21,21,20,20,20,20,20,20,18,18,17,17,16,16,13,17,21,21,24,25,26,27,27,24,24,22,21,19,20,20,19,17,17,18,20,22,22,21,21,21,20,22,22,22,22,20,19,18,16,21,24,24,24,24,26,26,25,24,24,24,23,23,22,21,19,18,17,20,20,22,22,21,20, [...]
+"234",16,16,16,16,14,14,14,12,12,13,14,14,11,11,10,11,11,10,10,10,8,8,7,7,8,8,5,7,7,6,5,5,2,3,3,2,2,2,7,8,8,8,8,8,8,5,9,9,9,9,10,13,14,14,12,11,11,12,12,10,8,13,13,12,11,10,9,14,14,13,12,12,14,14,14,14,12,12,11,11,12,12,11,11,14,14,13,12,15,16,16,14,14,14,16,16,25,25,24,23,23,23,22,22,21,21,21,21,21,21,19,19,18,18,17,17,14,18,22,22,25,26,27,28,28,25,25,23,22,20,21,21,20,18,18,19,21,23,23,22,22,22,21,23,23,23,23,21,20,19,17,22,25,25,25,25,27,27,26,25,25,25,24,24,23,22,20,19,18,21,21,23,23 [...]
+"235",17,17,17,17,15,15,15,13,13,14,15,15,12,12,11,12,12,11,11,11,9,9,8,8,9,9,6,8,8,7,6,6,3,2,2,1,3,3,8,9,9,9,9,9,9,6,10,10,10,10,11,14,15,15,13,12,12,13,13,11,9,14,14,13,12,11,10,15,15,14,13,13,15,15,15,15,13,13,12,12,13,13,12,12,15,15,14,13,16,17,17,15,15,15,17,17,26,26,25,24,24,24,23,23,22,22,22,22,22,22,20,20,19,19,18,18,15,19,23,23,26,27,28,29,29,26,26,24,23,21,22,22,21,19,19,20,22,24,24,23,23,23,22,24,24,24,24,22,21,20,18,23,26,26,26,26,28,28,27,26,26,26,25,25,24,23,21,20,19,22,22, [...]
+"236",18,18,18,18,16,16,16,14,14,15,16,16,13,13,12,13,13,12,12,12,10,10,9,9,10,10,7,9,9,8,7,7,4,1,1,2,4,4,9,10,10,10,10,10,10,7,11,11,11,11,12,15,16,16,14,13,13,14,14,12,10,15,15,14,13,12,11,16,16,15,14,14,16,16,16,16,14,14,13,13,14,14,13,13,16,16,15,14,17,18,18,16,16,16,18,18,27,27,26,25,25,25,24,24,23,23,23,23,23,23,21,21,20,20,19,19,16,20,24,24,27,28,29,30,30,27,27,25,24,22,23,23,22,20,20,21,23,25,25,24,24,24,23,25,25,25,25,23,22,21,19,24,27,27,27,27,29,29,28,27,27,27,26,26,25,24,22,2 [...]
+"237",17,17,17,17,15,15,15,13,13,14,15,15,12,12,11,12,12,11,11,11,9,9,8,8,9,9,6,8,8,7,6,6,3,4,4,3,1,1,8,9,9,9,9,9,9,6,10,10,10,10,11,14,15,15,13,12,12,13,13,11,9,14,14,13,12,11,10,15,15,14,13,13,15,15,15,15,13,13,12,12,13,13,12,12,15,15,14,13,16,17,17,15,15,15,17,17,26,26,25,24,24,24,23,23,22,22,22,22,22,22,20,20,19,19,18,18,15,19,23,23,26,27,28,29,29,26,26,24,23,21,22,22,21,19,19,20,22,24,24,23,23,23,22,24,24,24,24,22,21,20,18,23,26,26,26,26,28,28,27,26,26,26,25,25,24,23,21,20,19,22,22, [...]
+"238",14,14,14,14,12,12,12,10,10,11,12,12,9,9,8,9,9,8,8,8,6,6,5,5,6,6,5,7,7,6,5,5,4,7,7,6,6,6,3,4,4,4,4,4,4,1,7,7,7,7,8,11,12,12,10,9,9,10,10,8,6,11,11,10,9,8,7,12,12,11,10,10,12,12,12,12,10,10,9,9,10,10,9,9,12,12,11,10,13,14,14,12,12,12,14,14,23,23,22,21,21,21,20,20,19,19,19,19,19,19,17,17,16,16,15,15,12,16,20,20,23,24,25,26,26,23,23,21,20,18,19,19,18,16,16,17,19,21,21,20,20,20,19,21,21,21,21,19,18,17,15,20,23,23,23,23,25,25,24,23,23,23,22,22,21,20,18,17,16,19,19,21,21,20,19,17,16,17,18 [...]
+"239",15,15,15,15,13,13,13,11,11,12,13,13,10,10,9,10,10,9,9,9,7,7,6,6,7,7,6,8,8,7,6,6,5,8,8,7,7,7,2,3,3,3,3,3,3,2,8,8,8,8,9,12,13,13,11,10,10,11,11,9,7,12,12,11,10,9,8,13,13,12,11,11,13,13,13,13,11,11,10,10,11,11,10,10,13,13,12,11,14,15,15,13,13,13,15,15,24,24,23,22,22,22,21,21,20,20,20,20,20,20,18,18,17,17,16,16,13,17,21,21,24,25,26,27,27,24,24,22,21,19,20,20,19,17,17,18,20,22,22,21,21,21,20,22,22,22,22,20,19,18,16,21,24,24,24,24,26,26,25,24,24,24,23,23,22,21,19,18,17,20,20,22,22,21,20, [...]
+"240",16,16,16,16,14,14,14,12,12,13,14,14,11,11,10,11,11,10,10,10,8,8,7,7,8,8,7,9,9,8,7,7,6,9,9,8,8,8,1,2,2,4,4,4,4,3,9,9,9,9,10,13,14,14,12,11,11,12,12,10,8,13,13,12,11,10,9,14,14,13,12,12,14,14,14,14,12,12,11,11,12,12,11,11,14,14,13,12,15,16,16,14,14,14,16,16,25,25,24,23,23,23,22,22,21,21,21,21,21,21,19,19,18,18,17,17,14,18,22,22,25,26,27,28,28,25,25,23,22,20,21,21,20,18,18,19,21,23,23,22,22,22,21,23,23,23,23,21,20,19,17,22,25,25,25,25,27,27,26,25,25,25,24,24,23,22,20,19,18,21,21,23,23 [...]
+"241",17,17,17,17,15,15,15,13,13,14,15,15,12,12,11,12,12,11,11,11,9,9,8,8,9,9,8,10,10,9,8,8,7,10,10,9,9,9,2,1,1,5,5,5,5,4,10,10,10,10,11,14,15,15,13,12,12,13,13,11,9,14,14,13,12,11,10,15,15,14,13,13,15,15,15,15,13,13,12,12,13,13,12,12,15,15,14,13,16,17,17,15,15,15,17,17,26,26,25,24,24,24,23,23,22,22,22,22,22,22,20,20,19,19,18,18,15,19,23,23,26,27,28,29,29,26,26,24,23,21,22,22,21,19,19,20,22,24,24,23,23,23,22,24,24,24,24,22,21,20,18,23,26,26,26,26,28,28,27,26,26,26,25,25,24,23,21,20,19,22 [...]
+"242",16,16,16,16,14,14,14,12,12,13,14,14,11,11,10,11,11,10,10,10,8,8,7,7,8,8,7,9,9,8,7,7,6,9,9,8,8,8,3,4,4,2,2,2,2,3,9,9,9,9,10,13,14,14,12,11,11,12,12,10,8,13,13,12,11,10,9,14,14,13,12,12,14,14,14,14,12,12,11,11,12,12,11,11,14,14,13,12,15,16,16,14,14,14,16,16,25,25,24,23,23,23,22,22,21,21,21,21,21,21,19,19,18,18,17,17,14,18,22,22,25,26,27,28,28,25,25,23,22,20,21,21,20,18,18,19,21,23,23,22,22,22,21,23,23,23,23,21,20,19,17,22,25,25,25,25,27,27,26,25,25,25,24,24,23,22,20,19,18,21,21,23,23 [...]
+"243",17,17,17,17,15,15,15,13,13,14,15,15,12,12,11,12,12,11,11,11,9,9,8,8,9,9,8,10,10,9,8,8,7,10,10,9,9,9,4,5,5,1,1,3,3,4,10,10,10,10,11,14,15,15,13,12,12,13,13,11,9,14,14,13,12,11,10,15,15,14,13,13,15,15,15,15,13,13,12,12,13,13,12,12,15,15,14,13,16,17,17,15,15,15,17,17,26,26,25,24,24,24,23,23,22,22,22,22,22,22,20,20,19,19,18,18,15,19,23,23,26,27,28,29,29,26,26,24,23,21,22,22,21,19,19,20,22,24,24,23,23,23,22,24,24,24,24,22,21,20,18,23,26,26,26,26,28,28,27,26,26,26,25,25,24,23,21,20,19,22 [...]
+"244",17,17,17,17,15,15,15,13,13,14,15,15,12,12,11,12,12,11,11,11,9,9,8,8,9,9,8,10,10,9,8,8,7,10,10,9,9,9,4,5,5,3,3,1,1,4,10,10,10,10,11,14,15,15,13,12,12,13,13,11,9,14,14,13,12,11,10,15,15,14,13,13,15,15,15,15,13,13,12,12,13,13,12,12,15,15,14,13,16,17,17,15,15,15,17,17,26,26,25,24,24,24,23,23,22,22,22,22,22,22,20,20,19,19,18,18,15,19,23,23,26,27,28,29,29,26,26,24,23,21,22,22,21,19,19,20,22,24,24,23,23,23,22,24,24,24,24,22,21,20,18,23,26,26,26,26,28,28,27,26,26,26,25,25,24,23,21,20,19,22 [...]
+"245",12,12,12,12,10,10,10,8,8,9,10,10,7,7,6,7,7,6,6,6,6,6,5,5,6,6,7,9,9,8,7,7,6,9,9,8,8,8,7,8,8,8,8,8,8,5,3,3,3,3,4,7,8,8,6,5,5,6,6,4,2,9,9,8,7,6,5,10,10,9,8,8,10,10,10,10,8,8,7,7,8,8,7,7,10,10,9,8,11,12,12,10,10,10,12,12,21,21,20,19,19,19,18,18,17,17,17,17,17,17,15,15,14,14,13,13,10,14,18,18,21,22,23,24,24,21,21,19,18,16,17,17,16,14,14,15,17,19,19,18,18,18,17,19,19,19,19,17,16,15,13,18,21,21,21,21,23,23,22,21,21,21,20,20,19,18,16,15,14,17,17,19,19,18,17,15,14,15,16,19,19,18,18,18,14,16 [...]
+"246",13,13,13,13,11,11,11,9,9,10,11,11,8,8,7,8,8,7,7,7,7,7,6,6,7,7,8,10,10,9,8,8,7,10,10,9,9,9,8,9,9,9,9,9,9,6,2,2,2,2,5,8,9,9,7,6,6,7,7,5,3,10,10,9,8,7,6,11,11,10,9,9,11,11,11,11,9,9,8,8,9,9,8,8,11,11,10,9,12,13,13,11,11,11,13,13,22,22,21,20,20,20,19,19,18,18,18,18,18,18,16,16,15,15,14,14,11,15,19,19,22,23,24,25,25,22,22,20,19,17,18,18,17,15,15,16,18,20,20,19,19,19,18,20,20,20,20,18,17,16,14,19,22,22,22,22,24,24,23,22,22,22,21,21,20,19,17,16,15,18,18,20,20,19,18,16,15,16,17,20,20,19,19 [...]
+"247",14,14,14,14,12,12,12,10,10,11,12,12,9,9,8,9,9,8,8,8,8,8,7,7,8,8,9,11,11,10,9,9,8,11,11,10,10,10,9,10,10,10,10,10,10,7,1,1,3,3,6,9,10,10,8,7,7,8,8,6,4,11,11,10,9,8,7,12,12,11,10,10,12,12,12,12,10,10,9,9,10,10,9,9,12,12,11,10,13,14,14,12,12,12,14,14,23,23,22,21,21,21,20,20,19,19,19,19,19,19,17,17,16,16,15,15,12,16,20,20,23,24,25,26,26,23,23,21,20,18,19,19,18,16,16,17,19,21,21,20,20,20,19,21,21,21,21,19,18,17,15,20,23,23,23,23,25,25,24,23,23,23,22,22,21,20,18,17,16,19,19,21,21,20,19,1 [...]
+"248",14,14,14,14,12,12,12,10,10,11,12,12,9,9,8,9,9,8,8,8,8,8,7,7,8,8,9,11,11,10,9,9,8,11,11,10,10,10,9,10,10,10,10,10,10,7,3,3,1,1,6,9,10,10,8,7,7,8,8,6,4,11,11,10,9,8,7,12,12,11,10,10,12,12,12,12,10,10,9,9,10,10,9,9,12,12,11,10,13,14,14,12,12,12,14,14,23,23,22,21,21,21,20,20,19,19,19,19,19,19,17,17,16,16,15,15,12,16,20,20,23,24,25,26,26,23,23,21,20,18,19,19,18,16,16,17,19,21,21,20,20,20,19,21,21,21,21,19,18,17,15,20,23,23,23,23,25,25,24,23,23,23,22,22,21,20,18,17,16,19,19,21,21,20,19,1 [...]
+"249",13,13,13,13,11,11,11,9,9,10,11,11,8,8,7,8,8,7,7,7,7,7,6,6,7,7,8,10,10,9,8,8,7,10,10,9,9,9,8,9,9,9,9,9,9,6,4,4,4,4,3,6,7,7,5,4,4,5,5,3,1,10,10,9,8,7,6,11,11,10,9,9,11,11,11,11,9,9,8,8,9,9,8,8,11,11,10,9,12,13,13,11,11,11,13,13,22,22,21,20,20,20,19,19,18,18,18,18,18,18,16,16,15,15,14,14,11,15,19,19,22,23,24,25,25,22,22,20,19,17,18,18,17,15,15,16,18,20,20,19,19,19,18,20,20,20,20,18,17,16,14,19,22,22,22,22,24,24,23,22,22,22,21,21,20,19,17,16,15,18,18,20,20,19,18,16,15,16,17,20,20,19,19 [...]
+"250",14,14,14,14,12,12,12,10,10,11,12,12,9,9,8,9,9,8,8,8,8,8,7,7,8,8,9,11,11,10,9,9,8,11,11,10,10,10,9,10,10,10,10,10,10,7,5,5,5,5,2,5,6,6,4,3,3,4,4,2,2,11,11,10,9,8,7,12,12,11,10,10,12,12,12,12,10,10,9,9,10,10,9,9,12,12,11,10,13,14,14,12,12,12,14,14,23,23,22,21,21,21,20,20,19,19,19,19,19,19,17,17,16,16,15,15,12,16,20,20,23,24,25,26,26,23,23,21,20,18,19,19,18,16,16,17,19,21,21,20,20,20,19,21,21,21,21,19,18,17,15,20,23,23,23,23,25,25,24,23,23,23,22,22,21,20,18,17,16,19,19,21,21,20,19,17, [...]
+"251",15,15,15,15,13,13,13,11,11,12,13,13,10,10,9,10,10,9,9,9,9,9,8,8,9,9,10,12,12,11,10,10,9,12,12,11,11,11,10,11,11,11,11,11,11,8,6,6,6,6,1,4,5,5,3,2,4,5,5,3,3,12,12,11,10,9,8,13,13,12,11,11,13,13,13,13,11,11,10,10,11,11,10,10,13,13,12,11,14,15,15,13,13,13,15,15,24,24,23,22,22,22,21,21,20,20,20,20,20,20,18,18,17,17,16,16,13,17,21,21,24,25,26,27,27,24,24,22,21,19,20,20,19,17,17,18,20,22,22,21,21,21,20,22,22,22,22,20,19,18,16,21,24,24,24,24,26,26,25,24,24,24,23,23,22,21,19,18,17,20,20,22 [...]
+"252",16,16,16,16,14,14,14,12,12,13,14,14,11,11,10,11,11,10,10,10,10,10,9,9,10,10,11,13,13,12,11,11,10,13,13,12,12,12,11,12,12,12,12,12,12,9,7,7,7,7,2,3,4,4,2,1,5,6,6,4,4,13,13,12,11,10,9,14,14,13,12,12,14,14,14,14,12,12,11,11,12,12,11,11,14,14,13,12,15,16,16,14,14,14,16,16,25,25,24,23,23,23,22,22,21,21,21,21,21,21,19,19,18,18,17,17,14,18,22,22,25,26,27,28,28,25,25,23,22,20,21,21,20,18,18,19,21,23,23,22,22,22,21,23,23,23,23,21,20,19,17,22,25,25,25,25,27,27,26,25,25,25,24,24,23,22,20,19,1 [...]
+"253",17,17,17,17,15,15,15,13,13,14,15,15,12,12,11,12,12,11,11,11,11,11,10,10,11,11,12,14,14,13,12,12,11,14,14,13,13,13,12,13,13,13,13,13,13,10,8,8,8,8,3,2,3,3,1,2,6,7,7,5,5,14,14,13,12,11,10,15,15,14,13,13,15,15,15,15,13,13,12,12,13,13,12,12,15,15,14,13,16,17,17,15,15,15,17,17,26,26,25,24,24,24,23,23,22,22,22,22,22,22,20,20,19,19,18,18,15,19,23,23,26,27,28,29,29,26,26,24,23,21,22,22,21,19,19,20,22,24,24,23,23,23,22,24,24,24,24,22,21,20,18,23,26,26,26,26,28,28,27,26,26,26,25,25,24,23,21, [...]
+"254",18,18,18,18,16,16,16,14,14,15,16,16,13,13,12,13,13,12,12,12,12,12,11,11,12,12,13,15,15,14,13,13,12,15,15,14,14,14,13,14,14,14,14,14,14,11,9,9,9,9,4,1,2,2,2,3,7,8,8,6,6,15,15,14,13,12,11,16,16,15,14,14,16,16,16,16,14,14,13,13,14,14,13,13,16,16,15,14,17,18,18,16,16,16,18,18,27,27,26,25,25,25,24,24,23,23,23,23,23,23,21,21,20,20,19,19,16,20,24,24,27,28,29,30,30,27,27,25,24,22,23,23,22,20,20,21,23,25,25,24,24,24,23,25,25,25,25,23,22,21,19,24,27,27,27,27,29,29,28,27,27,27,26,26,25,24,22, [...]
+"255",19,19,19,19,17,17,17,15,15,16,17,17,14,14,13,14,14,13,13,13,13,13,12,12,13,13,14,16,16,15,14,14,13,16,16,15,15,15,14,15,15,15,15,15,15,12,10,10,10,10,5,2,1,1,3,4,8,9,9,7,7,16,16,15,14,13,12,17,17,16,15,15,17,17,17,17,15,15,14,14,15,15,14,14,17,17,16,15,18,19,19,17,17,17,19,19,28,28,27,26,26,26,25,25,24,24,24,24,24,24,22,22,21,21,20,20,17,21,25,25,28,29,30,31,31,28,28,26,25,23,24,24,23,21,21,22,24,26,26,25,25,25,24,26,26,26,26,24,23,22,20,25,28,28,28,28,30,30,29,28,28,28,27,27,26,25 [...]
+"256",15,15,15,15,13,13,13,11,11,12,13,13,10,10,9,10,10,9,9,9,9,9,8,8,9,9,10,12,12,11,10,10,9,12,12,11,11,11,10,11,11,11,11,11,11,8,6,6,6,6,3,6,7,7,5,4,2,3,3,1,3,12,12,11,10,9,8,13,13,12,11,11,13,13,13,13,11,11,10,10,11,11,10,10,13,13,12,11,14,15,15,13,13,13,15,15,24,24,23,22,22,22,21,21,20,20,20,20,20,20,18,18,17,17,16,16,13,17,21,21,24,25,26,27,27,24,24,22,21,19,20,20,19,17,17,18,20,22,22,21,21,21,20,22,22,22,22,20,19,18,16,21,24,24,24,24,26,26,25,24,24,24,23,23,22,21,19,18,17,20,20,22 [...]
+"257",16,16,16,16,14,14,14,12,12,13,14,14,11,11,10,11,11,10,10,10,10,10,9,9,10,10,11,13,13,12,11,11,10,13,13,12,12,12,11,12,12,12,12,12,12,9,7,7,7,7,4,7,8,8,6,5,1,2,2,2,4,13,13,12,11,10,9,14,14,13,12,12,14,14,14,14,12,12,11,11,12,12,11,11,14,14,13,12,15,16,16,14,14,14,16,16,25,25,24,23,23,23,22,22,21,21,21,21,21,21,19,19,18,18,17,17,14,18,22,22,25,26,27,28,28,25,25,23,22,20,21,21,20,18,18,19,21,23,23,22,22,22,21,23,23,23,23,21,20,19,17,22,25,25,25,25,27,27,26,25,25,25,24,24,23,22,20,19,1 [...]
+"258",17,17,17,17,15,15,15,13,13,14,15,15,12,12,11,12,12,11,11,11,11,11,10,10,11,11,12,14,14,13,12,12,11,14,14,13,13,13,12,13,13,13,13,13,13,10,8,8,8,8,5,8,9,9,7,6,2,1,1,3,5,14,14,13,12,11,10,15,15,14,13,13,15,15,15,15,13,13,12,12,13,13,12,12,15,15,14,13,16,17,17,15,15,15,17,17,26,26,25,24,24,24,23,23,22,22,22,22,22,22,20,20,19,19,18,18,15,19,23,23,26,27,28,29,29,26,26,24,23,21,22,22,21,19,19,20,22,24,24,23,23,23,22,24,24,24,24,22,21,20,18,23,26,26,26,26,28,28,27,26,26,26,25,25,24,23,21, [...]
+"259",11,11,11,11,9,9,9,7,7,8,9,9,6,6,5,6,6,5,5,5,7,7,6,6,7,7,8,10,10,9,8,8,7,10,10,9,9,9,8,9,9,9,9,9,9,6,6,6,6,6,7,10,11,11,9,8,8,9,9,7,5,6,6,5,4,3,2,7,7,6,5,5,7,7,7,7,5,5,4,4,5,5,4,4,9,9,8,7,10,11,11,9,9,9,11,11,20,20,19,18,18,18,17,17,16,16,16,16,16,16,14,14,13,13,12,12,9,13,17,17,20,21,22,23,23,20,20,18,17,15,16,16,15,13,13,14,16,18,18,17,17,17,16,18,18,18,18,16,15,14,12,17,20,20,20,20,22,22,21,20,20,20,19,19,18,17,15,14,13,16,16,18,18,17,16,14,13,14,15,18,18,17,17,17,13,15,16,17,17, [...]
+"260",12,12,12,12,10,10,10,8,8,9,10,10,7,7,6,7,7,6,6,6,8,8,7,7,8,8,9,11,11,10,9,9,8,11,11,10,10,10,9,10,10,10,10,10,10,7,7,7,7,7,8,11,12,12,10,9,9,10,10,8,6,5,5,4,3,2,1,8,8,7,6,6,8,8,8,8,6,6,5,5,6,6,5,5,10,10,9,8,11,12,12,10,10,10,12,12,21,21,20,19,19,19,18,18,17,17,17,17,17,17,15,15,14,14,13,13,10,14,18,18,21,22,23,24,24,21,21,19,18,16,17,17,16,14,14,15,17,19,19,18,18,18,17,19,19,19,19,17,16,15,13,18,21,21,21,21,23,23,22,21,21,21,20,20,19,18,16,15,14,17,17,19,19,18,17,15,14,15,16,19,19, [...]
+"261",13,13,13,13,11,11,11,9,9,10,11,11,8,8,7,8,8,7,7,7,9,9,8,8,9,9,10,12,12,11,10,10,9,12,12,11,11,11,10,11,11,11,11,11,11,8,8,8,8,8,9,12,13,13,11,10,10,11,11,9,7,4,4,3,2,1,2,9,9,8,7,7,9,9,9,9,7,7,6,6,7,7,6,6,11,11,10,9,12,13,13,11,11,11,13,13,22,22,21,20,20,20,19,19,18,18,18,18,18,18,16,16,15,15,14,14,11,15,19,19,22,23,24,25,25,22,22,20,19,17,18,18,17,15,15,16,18,20,20,19,19,19,18,20,20,20,20,18,17,16,14,19,22,22,22,22,24,24,23,22,22,22,21,21,20,19,17,16,15,18,18,20,20,19,18,16,15,16,1 [...]
+"262",14,14,14,14,12,12,12,10,10,11,12,12,9,9,8,9,9,8,8,8,10,10,9,9,10,10,11,13,13,12,11,11,10,13,13,12,12,12,11,12,12,12,12,12,12,9,9,9,9,9,10,13,14,14,12,11,11,12,12,10,8,3,3,2,1,2,3,10,10,9,8,8,10,10,10,10,8,8,7,7,8,8,7,7,12,12,11,10,13,14,14,12,12,12,14,14,23,23,22,21,21,21,20,20,19,19,19,19,19,19,17,17,16,16,15,15,12,16,20,20,23,24,25,26,26,23,23,21,20,18,19,19,18,16,16,17,19,21,21,20,20,20,19,21,21,21,21,19,18,17,15,20,23,23,23,23,25,25,24,23,23,23,22,22,21,20,18,17,16,19,19,21,21, [...]
+"263",15,15,15,15,13,13,13,11,11,12,13,13,10,10,9,10,10,9,9,9,11,11,10,10,11,11,12,14,14,13,12,12,11,14,14,13,13,13,12,13,13,13,13,13,13,10,10,10,10,10,11,14,15,15,13,12,12,13,13,11,9,2,2,1,2,3,4,11,11,10,9,9,11,11,11,11,9,9,8,8,9,9,8,8,13,13,12,11,14,15,15,13,13,13,15,15,24,24,23,22,22,22,21,21,20,20,20,20,20,20,18,18,17,17,16,16,13,17,21,21,24,25,26,27,27,24,24,22,21,19,20,20,19,17,17,18,20,22,22,21,21,21,20,22,22,22,22,20,19,18,16,21,24,24,24,24,26,26,25,24,24,24,23,23,22,21,19,18,17, [...]
+"264",16,16,16,16,14,14,14,12,12,13,14,14,11,11,10,11,11,10,10,10,12,12,11,11,12,12,13,15,15,14,13,13,12,15,15,14,14,14,13,14,14,14,14,14,14,11,11,11,11,11,12,15,16,16,14,13,13,14,14,12,10,1,1,2,3,4,5,12,12,11,10,10,12,12,12,12,10,10,9,9,10,10,9,9,14,14,13,12,15,16,16,14,14,14,16,16,25,25,24,23,23,23,22,22,21,21,21,21,21,21,19,19,18,18,17,17,14,18,22,22,25,26,27,28,28,25,25,23,22,20,21,21,20,18,18,19,21,23,23,22,22,22,21,23,23,23,23,21,20,19,17,22,25,25,25,25,27,27,26,25,25,25,24,24,23,2 [...]
+"265",12,12,12,12,10,10,10,8,8,9,10,10,7,7,6,7,7,6,6,6,8,8,7,7,8,8,9,11,11,10,9,9,8,11,11,10,10,10,9,10,10,10,10,10,10,7,7,7,7,7,8,11,12,12,10,9,9,10,10,8,6,7,7,6,5,4,3,6,6,5,4,4,6,6,6,6,4,4,3,3,4,4,3,3,10,10,9,8,11,12,12,10,10,10,12,12,21,21,20,19,19,19,18,18,17,17,17,17,17,17,15,15,14,14,13,13,10,14,18,18,21,22,23,24,24,21,21,19,18,16,17,17,16,14,14,15,17,19,19,18,18,18,17,19,19,19,19,17,16,15,13,18,21,21,21,21,23,23,22,21,21,21,20,20,19,18,16,15,14,17,17,19,19,18,17,15,14,15,16,19,19, [...]
+"266",13,13,13,13,11,11,11,9,9,10,11,11,8,8,7,8,8,7,7,7,9,9,8,8,9,9,10,12,12,11,10,10,9,12,12,11,11,11,10,11,11,11,11,11,11,8,8,8,8,8,9,12,13,13,11,10,10,11,11,9,7,8,8,7,6,5,4,5,5,4,3,3,5,5,5,5,3,3,2,4,5,5,4,4,11,11,10,9,12,13,13,11,11,11,13,13,22,22,21,20,20,20,19,19,18,18,18,18,18,18,16,16,15,15,14,14,11,15,19,19,22,23,24,25,25,22,22,20,19,17,18,18,17,15,15,16,18,20,20,19,19,19,18,20,20,20,20,18,17,16,14,19,22,22,22,22,24,24,23,22,22,22,21,21,20,19,17,16,15,18,18,20,20,19,18,16,15,16,1 [...]
+"267",14,14,14,14,12,12,12,10,10,11,12,12,9,9,8,9,9,8,8,8,10,10,9,9,10,10,11,13,13,12,11,11,10,13,13,12,12,12,11,12,12,12,12,12,12,9,9,9,9,9,10,13,14,14,12,11,11,12,12,10,8,9,9,8,7,6,5,4,4,3,2,2,4,4,4,4,4,4,3,5,6,6,5,5,12,12,11,10,13,14,14,12,12,12,14,14,23,23,22,21,21,21,20,20,19,19,19,19,19,19,17,17,16,16,15,15,12,16,20,20,23,24,25,26,26,23,23,21,20,18,19,19,18,16,16,17,19,21,21,20,20,20,19,21,21,21,21,19,18,17,15,20,23,23,23,23,25,25,24,23,23,23,22,22,21,20,18,17,16,19,19,21,21,20,19, [...]
+"268",15,15,15,15,13,13,13,11,11,12,13,13,10,10,9,10,10,9,9,9,11,11,10,10,11,11,12,14,14,13,12,12,11,14,14,13,13,13,12,13,13,13,13,13,13,10,10,10,10,10,11,14,15,15,13,12,12,13,13,11,9,10,10,9,8,7,6,3,3,2,1,3,5,5,5,5,5,5,4,6,7,7,6,6,13,13,12,11,14,15,15,13,13,13,15,15,24,24,23,22,22,22,21,21,20,20,20,20,20,20,18,18,17,17,16,16,13,17,21,21,24,25,26,27,27,24,24,22,21,19,20,20,19,17,17,18,20,22,22,21,21,21,20,22,22,22,22,20,19,18,16,21,24,24,24,24,26,26,25,24,24,24,23,23,22,21,19,18,17,20,20 [...]
+"269",16,16,16,16,14,14,14,12,12,13,14,14,11,11,10,11,11,10,10,10,12,12,11,11,12,12,13,15,15,14,13,13,12,15,15,14,14,14,13,14,14,14,14,14,14,11,11,11,11,11,12,15,16,16,14,13,13,14,14,12,10,11,11,10,9,8,7,2,2,1,2,4,6,6,6,6,6,6,5,7,8,8,7,7,14,14,13,12,15,16,16,14,14,14,16,16,25,25,24,23,23,23,22,22,21,21,21,21,21,21,19,19,18,18,17,17,14,18,22,22,25,26,27,28,28,25,25,23,22,20,21,21,20,18,18,19,21,23,23,22,22,22,21,23,23,23,23,21,20,19,17,22,25,25,25,25,27,27,26,25,25,25,24,24,23,22,20,19,18 [...]
+"270",17,17,17,17,15,15,15,13,13,14,15,15,12,12,11,12,12,11,11,11,13,13,12,12,13,13,14,16,16,15,14,14,13,16,16,15,15,15,14,15,15,15,15,15,15,12,12,12,12,12,13,16,17,17,15,14,14,15,15,13,11,12,12,11,10,9,8,1,1,2,3,5,7,7,7,7,7,7,6,8,9,9,8,8,15,15,14,13,16,17,17,15,15,15,17,17,26,26,25,24,24,24,23,23,22,22,22,22,22,22,20,20,19,19,18,18,15,19,23,23,26,27,28,29,29,26,26,24,23,21,22,22,21,19,19,20,22,24,24,23,23,23,22,24,24,24,24,22,21,20,18,23,26,26,26,26,28,28,27,26,26,26,25,25,24,23,21,20,1 [...]
+"271",15,15,15,15,13,13,13,11,11,12,13,13,10,10,9,10,10,9,9,9,11,11,10,10,11,11,12,14,14,13,12,12,11,14,14,13,13,13,12,13,13,13,13,13,13,10,10,10,10,10,11,14,15,15,13,12,12,13,13,11,9,10,10,9,8,7,6,5,5,4,3,1,3,3,3,3,5,5,4,6,7,7,6,6,13,13,12,11,14,15,15,13,13,13,15,15,24,24,23,22,22,22,21,21,20,20,20,20,20,20,18,18,17,17,16,16,13,17,21,21,24,25,26,27,27,24,24,22,21,19,20,20,19,17,17,18,20,22,22,21,21,21,20,22,22,22,22,20,19,18,16,21,24,24,24,24,26,26,25,24,24,24,23,23,22,21,19,18,17,20,20 [...]
+"272",16,16,16,16,14,14,14,12,12,13,14,14,11,11,10,11,11,10,10,10,12,12,11,11,12,12,13,15,15,14,13,13,12,15,15,14,14,14,13,14,14,14,14,14,14,11,11,11,11,11,12,15,16,16,14,13,13,14,14,12,10,11,11,10,9,8,7,6,6,5,4,2,2,2,2,2,6,6,5,7,8,8,7,7,14,14,13,12,15,16,16,14,14,14,16,16,25,25,24,23,23,23,22,22,21,21,21,21,21,21,19,19,18,18,17,17,14,18,22,22,25,26,27,28,28,25,25,23,22,20,21,21,20,18,18,19,21,23,23,22,22,22,21,23,23,23,23,21,20,19,17,22,25,25,25,25,27,27,26,25,25,25,24,24,23,22,20,19,18 [...]
+"273",17,17,17,17,15,15,15,13,13,14,15,15,12,12,11,12,12,11,11,11,13,13,12,12,13,13,14,16,16,15,14,14,13,16,16,15,15,15,14,15,15,15,15,15,15,12,12,12,12,12,13,16,17,17,15,14,14,15,15,13,11,12,12,11,10,9,8,7,7,6,5,3,1,1,3,3,7,7,6,8,9,9,8,8,15,15,14,13,16,17,17,15,15,15,17,17,26,26,25,24,24,24,23,23,22,22,22,22,22,22,20,20,19,19,18,18,15,19,23,23,26,27,28,29,29,26,26,24,23,21,22,22,21,19,19,20,22,24,24,23,23,23,22,24,24,24,24,22,21,20,18,23,26,26,26,26,28,28,27,26,26,26,25,25,24,23,21,20,1 [...]
+"274",17,17,17,17,15,15,15,13,13,14,15,15,12,12,11,12,12,11,11,11,13,13,12,12,13,13,14,16,16,15,14,14,13,16,16,15,15,15,14,15,15,15,15,15,15,12,12,12,12,12,13,16,17,17,15,14,14,15,15,13,11,12,12,11,10,9,8,7,7,6,5,3,3,3,1,1,7,7,6,8,9,9,8,8,15,15,14,13,16,17,17,15,15,15,17,17,26,26,25,24,24,24,23,23,22,22,22,22,22,22,20,20,19,19,18,18,15,19,23,23,26,27,28,29,29,26,26,24,23,21,22,22,21,19,19,20,22,24,24,23,23,23,22,24,24,24,24,22,21,20,18,23,26,26,26,26,28,28,27,26,26,26,25,25,24,23,21,20,1 [...]
+"275",14,14,14,14,12,12,12,10,10,11,12,12,9,9,8,9,9,8,8,8,10,10,9,9,10,10,11,13,13,12,11,11,10,13,13,12,12,12,11,12,12,12,12,12,12,9,9,9,9,9,10,13,14,14,12,11,11,12,12,10,8,9,9,8,7,6,5,6,6,5,4,4,6,6,6,6,2,2,1,5,6,6,5,5,12,12,11,10,13,14,14,12,12,12,14,14,23,23,22,21,21,21,20,20,19,19,19,19,19,19,17,17,16,16,15,15,12,16,20,20,23,24,25,26,26,23,23,21,20,18,19,19,18,16,16,17,19,21,21,20,20,20,19,21,21,21,21,19,18,17,15,20,23,23,23,23,25,25,24,23,23,23,22,22,21,20,18,17,16,19,19,21,21,20,19, [...]
+"276",15,15,15,15,13,13,13,11,11,12,13,13,10,10,9,10,10,9,9,9,11,11,10,10,11,11,12,14,14,13,12,12,11,14,14,13,13,13,12,13,13,13,13,13,13,10,10,10,10,10,11,14,15,15,13,12,12,13,13,11,9,10,10,9,8,7,6,7,7,6,5,5,7,7,7,7,1,1,2,6,7,7,6,6,13,13,12,11,14,15,15,13,13,13,15,15,24,24,23,22,22,22,21,21,20,20,20,20,20,20,18,18,17,17,16,16,13,17,21,21,24,25,26,27,27,24,24,22,21,19,20,20,19,17,17,18,20,22,22,21,21,21,20,22,22,22,22,20,19,18,16,21,24,24,24,24,26,26,25,24,24,24,23,23,22,21,19,18,17,20,20 [...]
+"277",13,13,13,13,11,11,11,9,9,10,11,11,8,8,7,8,8,7,7,7,9,9,8,8,9,9,10,12,12,11,10,10,9,12,12,11,11,11,10,11,11,11,11,11,11,8,8,8,8,8,9,12,13,13,11,10,10,11,11,9,7,8,8,7,6,5,4,7,7,6,5,5,7,7,7,7,5,5,4,2,3,3,2,2,11,11,10,9,12,13,13,11,11,11,13,13,22,22,21,20,20,20,19,19,18,18,18,18,18,18,16,16,15,15,14,14,11,15,19,19,22,23,24,25,25,22,22,20,19,17,18,18,17,15,15,16,18,20,20,19,19,19,18,20,20,20,20,18,17,16,14,19,22,22,22,22,24,24,23,22,22,22,21,21,20,19,17,16,15,18,18,20,20,19,18,16,15,16,1 [...]
+"278",14,14,14,14,12,12,12,10,10,11,12,12,9,9,8,9,9,8,8,8,10,10,9,9,10,10,11,13,13,12,11,11,10,13,13,12,12,12,11,12,12,12,12,12,12,9,9,9,9,9,10,13,14,14,12,11,11,12,12,10,8,9,9,8,7,6,5,8,8,7,6,6,8,8,8,8,6,6,5,1,2,2,3,3,12,12,11,10,13,14,14,12,12,12,14,14,23,23,22,21,21,21,20,20,19,19,19,19,19,19,17,17,16,16,15,15,12,16,20,20,23,24,25,26,26,23,23,21,20,18,19,19,18,16,16,17,19,21,21,20,20,20,19,21,21,21,21,19,18,17,15,20,23,23,23,23,25,25,24,23,23,23,22,22,21,20,18,17,16,19,19,21,21,20,19, [...]
+"279",15,15,15,15,13,13,13,11,11,12,13,13,10,10,9,10,10,9,9,9,11,11,10,10,11,11,12,14,14,13,12,12,11,14,14,13,13,13,12,13,13,13,13,13,13,10,10,10,10,10,11,14,15,15,13,12,12,13,13,11,9,10,10,9,8,7,6,9,9,8,7,7,9,9,9,9,7,7,6,2,1,1,4,4,13,13,12,11,14,15,15,13,13,13,15,15,24,24,23,22,22,22,21,21,20,20,20,20,20,20,18,18,17,17,16,16,13,17,21,21,24,25,26,27,27,24,24,22,21,19,20,20,19,17,17,18,20,22,22,21,21,21,20,22,22,22,22,20,19,18,16,21,24,24,24,24,26,26,25,24,24,24,23,23,22,21,19,18,17,20,20 [...]
+"280",14,14,14,14,12,12,12,10,10,11,12,12,9,9,8,9,9,8,8,8,10,10,9,9,10,10,11,13,13,12,11,11,10,13,13,12,12,12,11,12,12,12,12,12,12,9,9,9,9,9,10,13,14,14,12,11,11,12,12,10,8,9,9,8,7,6,5,8,8,7,6,6,8,8,8,8,6,6,5,3,4,4,1,1,12,12,11,10,13,14,14,12,12,12,14,14,23,23,22,21,21,21,20,20,19,19,19,19,19,19,17,17,16,16,15,15,12,16,20,20,23,24,25,26,26,23,23,21,20,18,19,19,18,16,16,17,19,21,21,20,20,20,19,21,21,21,21,19,18,17,15,20,23,23,23,23,25,25,24,23,23,23,22,22,21,20,18,17,16,19,19,21,21,20,19, [...]
+"281",9,9,9,9,7,7,7,5,5,6,7,7,6,6,5,8,8,7,7,7,11,11,10,10,11,11,12,14,14,13,12,12,11,14,14,13,13,13,12,13,13,13,13,13,13,10,10,10,10,10,11,14,15,15,13,12,12,13,13,11,9,12,12,11,10,9,8,13,13,12,11,11,13,13,13,13,11,11,10,10,11,11,10,10,3,3,2,1,6,7,7,5,5,5,7,7,16,16,15,14,14,14,13,13,12,12,12,12,12,12,10,10,9,9,8,8,5,9,13,13,16,17,18,19,19,16,16,14,13,11,12,12,11,9,9,10,12,14,14,13,13,13,12,14,14,14,14,12,11,10,8,13,16,16,16,16,18,18,17,16,16,16,15,15,14,13,11,10,9,12,12,14,14,13,12,10,9,1 [...]
+"282",10,10,10,10,8,8,8,6,6,7,8,8,7,7,6,9,9,8,8,8,12,12,11,11,12,12,13,15,15,14,13,13,12,15,15,14,14,14,13,14,14,14,14,14,14,11,11,11,11,11,12,15,16,16,14,13,13,14,14,12,10,13,13,12,11,10,9,14,14,13,12,12,14,14,14,14,12,12,11,11,12,12,11,11,2,2,1,2,7,8,8,6,6,6,8,8,17,17,16,15,15,15,14,14,13,13,13,13,13,13,11,11,10,10,9,9,6,10,14,14,17,18,19,20,20,17,17,15,14,12,13,13,12,10,10,11,13,15,15,14,14,14,13,15,15,15,15,13,12,11,9,14,17,17,17,17,19,19,18,17,17,17,16,16,15,14,12,11,10,13,13,15,15, [...]
+"283",11,11,11,11,9,9,9,7,7,8,9,9,8,8,7,10,10,9,9,9,13,13,12,12,13,13,14,16,16,15,14,14,13,16,16,15,15,15,14,15,15,15,15,15,15,12,12,12,12,12,13,16,17,17,15,14,14,15,15,13,11,14,14,13,12,11,10,15,15,14,13,13,15,15,15,15,13,13,12,12,13,13,12,12,1,1,2,3,8,9,9,7,7,7,9,9,18,18,17,16,16,16,15,15,14,14,14,14,14,14,12,12,11,11,10,10,7,11,15,15,18,19,20,21,21,18,18,16,15,13,14,14,13,11,11,12,14,16,16,15,15,15,14,16,16,16,16,14,13,12,10,15,18,18,18,18,20,20,19,18,18,18,17,17,16,15,13,12,11,14,14, [...]
+"284",10,10,10,10,8,8,8,6,6,7,8,8,7,7,6,9,9,8,8,8,12,12,11,11,12,12,13,15,15,14,13,13,12,15,15,14,14,14,13,14,14,14,14,14,14,11,11,11,11,11,12,15,16,16,14,13,13,14,14,12,10,13,13,12,11,10,9,14,14,13,12,12,14,14,14,14,12,12,11,11,12,12,11,11,6,6,5,4,3,4,4,2,2,2,6,6,15,15,14,13,13,13,12,12,11,11,11,11,11,11,9,9,8,8,7,7,4,8,12,12,15,16,17,18,18,15,15,13,12,10,11,11,10,8,8,9,11,13,13,12,12,12,11,13,13,13,13,11,10,9,7,12,15,15,15,15,17,17,16,15,15,15,14,14,13,12,10,9,8,11,11,13,13,12,11,9,8,9 [...]
+"285",11,11,11,11,9,9,9,7,7,8,9,9,8,8,7,10,10,9,9,9,13,13,12,12,13,13,14,16,16,15,14,14,13,16,16,15,15,15,14,15,15,15,15,15,15,12,12,12,12,12,13,16,17,17,15,14,14,15,15,13,11,14,14,13,12,11,10,15,15,14,13,13,15,15,15,15,13,13,12,12,13,13,12,12,7,7,6,5,2,3,3,1,3,3,7,7,16,16,15,14,14,14,13,13,12,12,12,12,12,12,10,10,9,9,8,8,5,9,13,13,16,17,18,19,19,16,16,14,13,11,12,12,11,9,9,10,12,14,14,13,13,13,12,14,14,14,14,12,11,10,8,13,16,16,16,16,18,18,17,16,16,16,15,15,14,13,11,10,9,12,12,14,14,13, [...]
+"286",12,12,12,12,10,10,10,8,8,9,10,10,9,9,8,11,11,10,10,10,14,14,13,13,14,14,15,17,17,16,15,15,14,17,17,16,16,16,15,16,16,16,16,16,16,13,13,13,13,13,14,17,18,18,16,15,15,16,16,14,12,15,15,14,13,12,11,16,16,15,14,14,16,16,16,16,14,14,13,13,14,14,13,13,8,8,7,6,1,2,2,2,4,4,8,8,17,17,16,15,15,15,14,14,13,13,13,13,13,13,11,11,10,10,9,9,6,10,14,14,17,18,19,20,20,17,17,15,14,12,13,13,12,10,10,11,13,15,15,14,14,14,13,15,15,15,15,13,12,11,9,14,17,17,17,17,19,19,18,17,17,17,16,16,15,14,12,11,10,1 [...]
+"287",13,13,13,13,11,11,11,9,9,10,11,11,10,10,9,12,12,11,11,11,15,15,14,14,15,15,16,18,18,17,16,16,15,18,18,17,17,17,16,17,17,17,17,17,17,14,14,14,14,14,15,18,19,19,17,16,16,17,17,15,13,16,16,15,14,13,12,17,17,16,15,15,17,17,17,17,15,15,14,14,15,15,14,14,9,9,8,7,2,1,1,3,5,5,9,9,18,18,17,16,16,16,15,15,14,14,14,14,14,14,12,12,11,11,10,10,7,11,15,15,18,19,20,21,21,18,18,16,15,13,14,14,13,11,11,12,14,16,16,15,15,15,14,16,16,16,16,14,13,12,10,15,18,18,18,18,20,20,19,18,18,18,17,17,16,15,13,1 [...]
+"288",11,11,11,11,9,9,9,7,7,8,9,9,8,8,7,10,10,9,9,9,13,13,12,12,13,13,14,16,16,15,14,14,13,16,16,15,15,15,14,15,15,15,15,15,15,12,12,12,12,12,13,16,17,17,15,14,14,15,15,13,11,14,14,13,12,11,10,15,15,14,13,13,15,15,15,15,13,13,12,12,13,13,12,12,7,7,6,5,4,5,5,3,1,1,7,7,16,16,15,14,14,14,13,13,12,12,12,12,12,12,10,10,9,9,8,8,5,9,13,13,16,17,18,19,19,16,16,14,13,11,12,12,11,9,9,10,12,14,14,13,13,13,12,14,14,14,14,12,11,10,8,13,16,16,16,16,18,18,17,16,16,16,15,15,14,13,11,10,9,12,12,14,14,13, [...]
+"289",11,11,11,11,9,9,9,7,7,8,9,9,8,8,7,10,10,9,9,9,13,13,12,12,13,13,14,16,16,15,14,14,13,16,16,15,15,15,14,15,15,15,15,15,15,12,12,12,12,12,13,16,17,17,15,14,14,15,15,13,11,14,14,13,12,11,10,15,15,14,13,13,15,15,15,15,13,13,12,12,13,13,12,12,7,7,6,5,6,7,7,5,5,5,3,3,12,12,11,10,10,10,9,9,8,8,8,8,8,8,6,6,5,5,4,4,1,7,11,11,14,15,16,17,17,14,14,12,11,9,10,10,9,7,7,8,10,12,12,11,11,11,10,12,12,12,12,10,9,8,6,11,14,14,14,14,16,16,15,14,14,14,13,13,12,11,9,8,7,10,10,12,12,11,10,8,7,8,9,12,12, [...]
+"290",12,12,12,12,10,10,10,8,8,9,10,10,9,9,8,11,11,10,10,10,14,14,13,13,14,14,15,17,17,16,15,15,14,17,17,16,16,16,15,16,16,16,16,16,16,13,13,13,13,13,14,17,18,18,16,15,15,16,16,14,12,15,15,14,13,12,11,16,16,15,14,14,16,16,16,16,14,14,13,13,14,14,13,13,8,8,7,6,7,8,8,6,6,6,2,2,11,11,10,9,9,9,8,8,7,7,7,7,7,7,5,5,4,4,3,3,2,8,12,12,15,16,17,18,18,15,15,13,12,10,11,11,10,8,8,9,11,13,13,12,12,12,11,13,13,13,13,11,10,9,7,12,15,15,15,15,17,17,16,15,15,15,14,14,13,12,10,9,8,11,11,13,13,12,11,9,8,9 [...]
+"291",13,13,13,13,11,11,11,9,9,10,11,11,10,10,9,12,12,11,11,11,15,15,14,14,15,15,16,18,18,17,16,16,15,18,18,17,17,17,16,17,17,17,17,17,17,14,14,14,14,14,15,18,19,19,17,16,16,17,17,15,13,16,16,15,14,13,12,17,17,16,15,15,17,17,17,17,15,15,14,14,15,15,14,14,9,9,8,7,8,9,9,7,7,7,1,1,12,12,11,10,10,10,9,9,8,8,8,8,8,8,6,6,5,5,4,4,3,9,13,13,16,17,18,19,19,16,16,14,13,11,12,12,11,9,9,10,12,14,14,13,13,13,12,14,14,14,14,12,11,10,8,13,16,16,16,16,18,18,17,16,16,16,15,15,14,13,11,10,9,12,12,14,14,13 [...]
+"292",13,13,13,13,11,11,11,9,9,10,11,11,10,10,9,12,12,11,11,11,15,15,14,14,15,15,16,18,18,17,16,16,15,18,18,17,17,17,16,17,17,17,17,17,17,14,14,14,14,14,15,18,19,19,17,16,16,17,17,15,13,16,16,15,14,13,12,17,17,16,15,15,17,17,17,17,15,15,14,14,15,15,14,14,9,9,8,7,8,9,9,7,7,7,3,3,10,10,9,8,8,8,7,7,6,6,6,6,6,6,4,4,3,3,2,2,3,9,13,13,16,17,18,19,19,16,16,14,13,11,12,12,11,9,9,10,12,14,14,13,13,13,12,14,14,14,14,12,11,10,8,13,16,16,16,16,18,18,17,16,16,16,15,15,14,13,11,10,9,12,12,14,14,13,12, [...]
+"293",14,14,14,14,12,12,12,10,10,11,12,12,11,11,10,13,13,12,12,12,16,16,15,15,16,16,17,19,19,18,17,17,16,19,19,18,18,18,17,18,18,18,18,18,18,15,15,15,15,15,16,19,20,20,18,17,17,18,18,16,14,17,17,16,15,14,13,18,18,17,16,16,18,18,18,18,16,16,15,15,16,16,15,15,10,10,9,8,9,10,10,8,8,8,4,4,9,9,8,7,7,7,6,6,5,5,5,5,5,5,3,3,2,2,3,3,4,10,14,14,17,18,19,20,20,17,17,15,14,12,13,13,12,10,10,11,13,15,15,14,14,14,13,15,15,15,15,13,12,11,9,14,17,17,17,17,19,19,18,17,17,17,16,16,15,14,12,11,10,13,13,15, [...]
+"294",15,15,15,15,13,13,13,11,11,12,13,13,12,12,11,14,14,13,13,13,17,17,16,16,17,17,18,20,20,19,18,18,17,20,20,19,19,19,18,19,19,19,19,19,19,16,16,16,16,16,17,20,21,21,19,18,18,19,19,17,15,18,18,17,16,15,14,19,19,18,17,17,19,19,19,19,17,17,16,16,17,17,16,16,11,11,10,9,10,11,11,9,9,9,5,5,8,8,7,6,6,6,5,5,4,4,4,4,4,4,2,2,3,3,4,4,5,11,15,15,18,19,20,21,21,18,18,16,15,13,14,14,13,11,11,12,14,16,16,15,15,15,14,16,16,16,16,14,13,12,10,15,18,18,18,18,20,20,19,18,18,18,17,17,16,15,13,12,11,14,14, [...]
+"295",16,16,16,16,14,14,14,12,12,13,14,14,13,13,12,15,15,14,14,14,18,18,17,17,18,18,19,21,21,20,19,19,18,21,21,20,20,20,19,20,20,20,20,20,20,17,17,17,17,17,18,21,22,22,20,19,19,20,20,18,16,19,19,18,17,16,15,20,20,19,18,18,20,20,20,20,18,18,17,17,18,18,17,17,12,12,11,10,11,12,12,10,10,10,6,6,7,7,6,5,5,5,4,4,3,3,3,3,3,3,3,3,4,4,5,5,6,12,16,16,19,20,21,22,22,19,19,17,16,14,15,15,14,12,12,13,15,17,17,16,16,16,15,17,17,17,17,15,14,13,11,16,19,19,19,19,21,21,20,19,19,19,18,18,17,16,14,13,12,15 [...]
+"296",17,17,17,17,15,15,15,13,13,14,15,15,14,14,13,16,16,15,15,15,19,19,18,18,19,19,20,22,22,21,20,20,19,22,22,21,21,21,20,21,21,21,21,21,21,18,18,18,18,18,19,22,23,23,21,20,20,21,21,19,17,20,20,19,18,17,16,21,21,20,19,19,21,21,21,21,19,19,18,18,19,19,18,18,13,13,12,11,12,13,13,11,11,11,7,7,6,6,5,4,4,4,3,3,2,2,4,4,4,4,4,4,5,5,6,6,7,13,17,17,20,21,22,23,23,20,20,18,17,15,16,16,15,13,13,14,16,18,18,17,17,17,16,18,18,18,18,16,15,14,12,17,20,20,20,20,22,22,21,20,20,20,19,19,18,17,15,14,13,16 [...]
+"297",18,18,18,18,16,16,16,14,14,15,16,16,15,15,14,17,17,16,16,16,20,20,19,19,20,20,21,23,23,22,21,21,20,23,23,22,22,22,21,22,22,22,22,22,22,19,19,19,19,19,20,23,24,24,22,21,21,22,22,20,18,21,21,20,19,18,17,22,22,21,20,20,22,22,22,22,20,20,19,19,20,20,19,19,14,14,13,12,13,14,14,12,12,12,8,8,5,5,4,3,3,3,2,2,3,3,5,5,5,5,5,5,6,6,7,7,8,14,18,18,21,22,23,24,24,21,21,19,18,16,17,17,16,14,14,15,17,19,19,18,18,18,17,19,19,19,19,17,16,15,13,18,21,21,21,21,23,23,22,21,21,21,20,20,19,18,16,15,14,17 [...]
+"298",19,19,19,19,17,17,17,15,15,16,17,17,16,16,15,18,18,17,17,17,21,21,20,20,21,21,22,24,24,23,22,22,21,24,24,23,23,23,22,23,23,23,23,23,23,20,20,20,20,20,21,24,25,25,23,22,22,23,23,21,19,22,22,21,20,19,18,23,23,22,21,21,23,23,23,23,21,21,20,20,21,21,20,20,15,15,14,13,14,15,15,13,13,13,9,9,4,4,3,2,2,2,3,3,4,4,6,6,6,6,6,6,7,7,8,8,9,15,19,19,22,23,24,25,25,22,22,20,19,17,18,18,17,15,15,16,18,20,20,19,19,19,18,20,20,20,20,18,17,16,14,19,22,22,22,22,24,24,23,22,22,22,21,21,20,19,17,16,15,18 [...]
+"299",20,20,20,20,18,18,18,16,16,17,18,18,17,17,16,19,19,18,18,18,22,22,21,21,22,22,23,25,25,24,23,23,22,25,25,24,24,24,23,24,24,24,24,24,24,21,21,21,21,21,22,25,26,26,24,23,23,24,24,22,20,23,23,22,21,20,19,24,24,23,22,22,24,24,24,24,22,22,21,21,22,22,21,21,16,16,15,14,15,16,16,14,14,14,10,10,3,3,2,1,3,3,4,4,5,5,7,7,7,7,7,7,8,8,9,9,10,16,20,20,23,24,25,26,26,23,23,21,20,18,19,19,18,16,16,17,19,21,21,20,20,20,19,21,21,21,21,19,18,17,15,20,23,23,23,23,25,25,24,23,23,23,22,22,21,20,18,17,16 [...]
+"300",21,21,21,21,19,19,19,17,17,18,19,19,18,18,17,20,20,19,19,19,23,23,22,22,23,23,24,26,26,25,24,24,23,26,26,25,25,25,24,25,25,25,25,25,25,22,22,22,22,22,23,26,27,27,25,24,24,25,25,23,21,24,24,23,22,21,20,25,25,24,23,23,25,25,25,25,23,23,22,22,23,23,22,22,17,17,16,15,16,17,17,15,15,15,11,11,2,2,1,2,4,4,5,5,6,6,8,8,8,8,8,8,9,9,10,10,11,17,21,21,24,25,26,27,27,24,24,22,21,19,20,20,19,17,17,18,20,22,22,21,21,21,20,22,22,22,22,20,19,18,16,21,24,24,24,24,26,26,25,24,24,24,23,23,22,21,19,18, [...]
+"301",22,22,22,22,20,20,20,18,18,19,20,20,19,19,18,21,21,20,20,20,24,24,23,23,24,24,25,27,27,26,25,25,24,27,27,26,26,26,25,26,26,26,26,26,26,23,23,23,23,23,24,27,28,28,26,25,25,26,26,24,22,25,25,24,23,22,21,26,26,25,24,24,26,26,26,26,24,24,23,23,24,24,23,23,18,18,17,16,17,18,18,16,16,16,12,12,1,1,2,3,5,5,6,6,7,7,9,9,9,9,9,9,10,10,11,11,12,18,22,22,25,26,27,28,28,25,25,23,22,20,21,21,20,18,18,19,21,23,23,22,22,22,21,23,23,23,23,21,20,19,17,22,25,25,25,25,27,27,26,25,25,25,24,24,23,22,20,1 [...]
+"302",20,20,20,20,18,18,18,16,16,17,18,18,17,17,16,19,19,18,18,18,22,22,21,21,22,22,23,25,25,24,23,23,22,25,25,24,24,24,23,24,24,24,24,24,24,21,21,21,21,21,22,25,26,26,24,23,23,24,24,22,20,23,23,22,21,20,19,24,24,23,22,22,24,24,24,24,22,22,21,21,22,22,21,21,16,16,15,14,15,16,16,14,14,14,10,10,5,5,4,3,1,1,4,4,5,5,7,7,7,7,7,7,8,8,9,9,10,16,20,20,23,24,25,26,26,23,23,21,20,18,19,19,18,16,16,17,19,21,21,20,20,20,19,21,21,21,21,19,18,17,15,20,23,23,23,23,25,25,24,23,23,23,22,22,21,20,18,17,16 [...]
+"303",19,19,19,19,17,17,17,15,15,16,17,17,16,16,15,18,18,17,17,17,21,21,20,20,21,21,22,24,24,23,22,22,21,24,24,23,23,23,22,23,23,23,23,23,23,20,20,20,20,20,21,24,25,25,23,22,22,23,23,21,19,22,22,21,20,19,18,23,23,22,21,21,23,23,23,23,21,21,20,20,21,21,20,20,15,15,14,13,14,15,15,13,13,13,9,9,6,6,5,4,4,4,1,1,4,4,6,6,6,6,6,6,7,7,8,8,9,15,19,19,22,23,24,25,25,22,22,20,19,17,18,18,17,15,15,16,18,20,20,19,19,19,18,20,20,20,20,18,17,16,14,19,22,22,22,22,24,24,23,22,22,22,21,21,20,19,17,16,15,18 [...]
+"304",18,18,18,18,16,16,16,14,14,15,16,16,15,15,14,17,17,16,16,16,20,20,19,19,20,20,21,23,23,22,21,21,20,23,23,22,22,22,21,22,22,22,22,22,22,19,19,19,19,19,20,23,24,24,22,21,21,22,22,20,18,21,21,20,19,18,17,22,22,21,20,20,22,22,22,22,20,20,19,19,20,20,19,19,14,14,13,12,13,14,14,12,12,12,8,8,7,7,6,5,5,5,4,4,1,1,5,5,5,5,5,5,6,6,7,7,8,14,18,18,21,22,23,24,24,21,21,19,18,16,17,17,16,14,14,15,17,19,19,18,18,18,17,19,19,19,19,17,16,15,13,18,21,21,21,21,23,23,22,21,21,21,20,20,19,18,16,15,14,17 [...]
+"305",17,17,17,17,15,15,15,13,13,14,15,15,14,14,13,16,16,15,15,15,19,19,18,18,19,19,20,22,22,21,20,20,19,22,22,21,21,21,20,21,21,21,21,21,21,18,18,18,18,18,19,22,23,23,21,20,20,21,21,19,17,20,20,19,18,17,16,21,21,20,19,19,21,21,21,21,19,19,18,18,19,19,18,18,13,13,12,11,12,13,13,11,11,11,7,7,8,8,7,6,6,6,5,5,4,4,2,2,2,2,4,4,5,5,6,6,7,13,17,17,20,21,22,23,23,20,20,18,17,15,16,16,15,13,13,14,16,18,18,17,17,17,16,18,18,18,18,16,15,14,12,17,20,20,20,20,22,22,21,20,20,20,19,19,18,17,15,14,13,16 [...]
+"306",18,18,18,18,16,16,16,14,14,15,16,16,15,15,14,17,17,16,16,16,20,20,19,19,20,20,21,23,23,22,21,21,20,23,23,22,22,22,21,22,22,22,22,22,22,19,19,19,19,19,20,23,24,24,22,21,21,22,22,20,18,21,21,20,19,18,17,22,22,21,20,20,22,22,22,22,20,20,19,19,20,20,19,19,14,14,13,12,13,14,14,12,12,12,8,8,9,9,8,7,7,7,6,6,5,5,1,1,3,3,5,5,6,6,7,7,8,14,18,18,21,22,23,24,24,21,21,19,18,16,17,17,16,14,14,15,17,19,19,18,18,18,17,19,19,19,19,17,16,15,13,18,21,21,21,21,23,23,22,21,21,21,20,20,19,18,16,15,14,17 [...]
+"307",18,18,18,18,16,16,16,14,14,15,16,16,15,15,14,17,17,16,16,16,20,20,19,19,20,20,21,23,23,22,21,21,20,23,23,22,22,22,21,22,22,22,22,22,22,19,19,19,19,19,20,23,24,24,22,21,21,22,22,20,18,21,21,20,19,18,17,22,22,21,20,20,22,22,22,22,20,20,19,19,20,20,19,19,14,14,13,12,13,14,14,12,12,12,8,8,9,9,8,7,7,7,6,6,5,5,3,3,1,1,5,5,6,6,7,7,8,14,18,18,21,22,23,24,24,21,21,19,18,16,17,17,16,14,14,15,17,19,19,18,18,18,17,19,19,19,19,17,16,15,13,18,21,21,21,21,23,23,22,21,21,21,20,20,19,18,16,15,14,17 [...]
+"308",16,16,16,16,14,14,14,12,12,13,14,14,13,13,12,15,15,14,14,14,18,18,17,17,18,18,19,21,21,20,19,19,18,21,21,20,20,20,19,20,20,20,20,20,20,17,17,17,17,17,18,21,22,22,20,19,19,20,20,18,16,19,19,18,17,16,15,20,20,19,18,18,20,20,20,20,18,18,17,17,18,18,17,17,12,12,11,10,11,12,12,10,10,10,6,6,9,9,8,7,7,7,6,6,5,5,5,5,5,5,1,1,4,4,5,5,6,12,16,16,19,20,21,22,22,19,19,17,16,14,15,15,14,12,12,13,15,17,17,16,16,16,15,17,17,17,17,15,14,13,11,16,19,19,19,19,21,21,20,19,19,19,18,18,17,16,14,13,12,15 [...]
+"309",15,15,15,15,13,13,13,11,11,12,13,13,12,12,11,14,14,13,13,13,17,17,16,16,17,17,18,20,20,19,18,18,17,20,20,19,19,19,18,19,19,19,19,19,19,16,16,16,16,16,17,20,21,21,19,18,18,19,19,17,15,18,18,17,16,15,14,19,19,18,17,17,19,19,19,19,17,17,16,16,17,17,16,16,11,11,10,9,10,11,11,9,9,9,5,5,10,10,9,8,8,8,7,7,6,6,6,6,6,6,4,4,1,1,4,4,5,11,15,15,18,19,20,21,21,18,18,16,15,13,14,14,13,11,11,12,14,16,16,15,15,15,14,16,16,16,16,14,13,12,10,15,18,18,18,18,20,20,19,18,18,18,17,17,16,15,13,12,11,14,1 [...]
+"310",14,14,14,14,12,12,12,10,10,11,12,12,11,11,10,13,13,12,12,12,16,16,15,15,16,16,17,19,19,18,17,17,16,19,19,18,18,18,17,18,18,18,18,18,18,15,15,15,15,15,16,19,20,20,18,17,17,18,18,16,14,17,17,16,15,14,13,18,18,17,16,16,18,18,18,18,16,16,15,15,16,16,15,15,10,10,9,8,9,10,10,8,8,8,4,4,11,11,10,9,9,9,8,8,7,7,7,7,7,7,5,5,4,4,1,1,4,10,14,14,17,18,19,20,20,17,17,15,14,12,13,13,12,10,10,11,13,15,15,14,14,14,13,15,15,15,15,13,12,11,9,14,17,17,17,17,19,19,18,17,17,17,16,16,15,14,12,11,10,13,13, [...]
+"311",12,12,12,12,10,10,10,8,8,9,10,10,9,9,8,11,11,10,10,10,14,14,13,13,14,14,15,17,17,16,15,15,14,17,17,16,16,16,15,16,16,16,16,16,16,13,13,13,13,13,14,17,18,18,16,15,15,16,16,14,12,15,15,14,13,12,11,16,16,15,14,14,16,16,16,16,14,14,13,13,14,14,13,13,8,8,7,6,7,8,8,6,6,6,6,6,15,15,14,13,13,13,12,12,11,11,11,11,11,11,9,9,8,8,7,7,4,4,8,8,11,12,13,14,14,11,11,9,8,6,7,7,6,4,4,5,7,9,9,8,8,8,7,9,9,9,9,7,6,5,3,8,11,11,11,11,13,13,12,11,11,11,10,10,9,8,6,5,4,7,7,9,9,8,7,5,4,5,6,9,9,8,8,8,4,6,7,8 [...]
+"312",13,13,13,13,11,11,11,9,9,10,11,11,10,10,9,12,12,11,11,11,15,15,14,14,15,15,16,18,18,17,16,16,15,18,18,17,17,17,16,17,17,17,17,17,17,14,14,14,14,14,15,18,19,19,17,16,16,17,17,15,13,16,16,15,14,13,12,17,17,16,15,15,17,17,17,17,15,15,14,14,15,15,14,14,9,9,8,7,8,9,9,7,7,7,7,7,16,16,15,14,14,14,13,13,12,12,12,12,12,12,10,10,9,9,8,8,5,3,7,7,10,11,12,13,13,10,10,8,7,5,6,6,5,3,3,4,6,8,8,7,7,7,6,8,8,8,8,6,5,4,2,9,12,12,12,12,14,14,13,12,12,12,11,11,10,9,7,6,5,8,8,10,10,9,8,6,5,6,7,10,10,9,9 [...]
+"313",14,14,14,14,12,12,12,10,10,11,12,12,11,11,10,13,13,12,12,12,16,16,15,15,16,16,17,19,19,18,17,17,16,19,19,18,18,18,17,18,18,18,18,18,18,15,15,15,15,15,16,19,20,20,18,17,17,18,18,16,14,17,17,16,15,14,13,18,18,17,16,16,18,18,18,18,16,16,15,15,16,16,15,15,10,10,9,8,9,10,10,8,8,8,8,8,17,17,16,15,15,15,14,14,13,13,13,13,13,13,11,11,10,10,9,9,6,2,6,6,9,10,11,12,12,9,9,7,6,4,5,5,4,2,2,5,7,9,9,8,8,8,7,9,9,9,9,7,6,5,3,10,13,13,13,13,15,15,14,13,13,13,12,12,11,10,8,7,6,9,9,11,11,10,9,7,6,7,8, [...]
+"314",15,15,15,15,13,13,13,11,11,12,13,13,12,12,11,14,14,13,13,13,17,17,16,16,17,17,18,20,20,19,18,18,17,20,20,19,19,19,18,19,19,19,19,19,19,16,16,16,16,16,17,20,21,21,19,18,18,19,19,17,15,18,18,17,16,15,14,19,19,18,17,17,19,19,19,19,17,17,16,16,17,17,16,16,11,11,10,9,10,11,11,9,9,9,9,9,18,18,17,16,16,16,15,15,14,14,14,14,14,14,12,12,11,11,10,10,7,1,5,5,8,9,10,11,11,8,8,6,5,3,4,4,3,3,3,6,8,10,10,9,9,9,8,10,10,10,10,8,7,6,4,11,14,14,14,14,16,16,15,14,14,14,13,13,12,11,9,8,7,10,10,12,12,11 [...]
+"315",16,16,16,16,14,14,14,12,12,13,14,14,13,13,12,15,15,14,14,14,18,18,17,17,18,18,19,21,21,20,19,19,18,21,21,20,20,20,19,20,20,20,20,20,20,17,17,17,17,17,18,21,22,22,20,19,19,20,20,18,16,19,19,18,17,16,15,20,20,19,18,18,20,20,20,20,18,18,17,17,18,18,17,17,12,12,11,10,11,12,12,10,10,10,10,10,19,19,18,17,17,17,16,16,15,15,15,15,15,15,13,13,12,12,11,11,8,2,4,4,7,8,9,10,10,7,7,5,4,2,3,3,2,4,4,7,9,11,11,10,10,10,9,11,11,11,11,9,8,7,5,12,15,15,15,15,17,17,16,15,15,15,14,14,13,12,10,9,8,11,11 [...]
+"316",17,17,17,17,15,15,15,13,13,14,15,15,14,14,13,16,16,15,15,15,19,19,18,18,19,19,20,22,22,21,20,20,19,22,22,21,21,21,20,21,21,21,21,21,21,18,18,18,18,18,19,22,23,23,21,20,20,21,21,19,17,20,20,19,18,17,16,21,21,20,19,19,21,21,21,21,19,19,18,18,19,19,18,18,13,13,12,11,12,13,13,11,11,11,11,11,20,20,19,18,18,18,17,17,16,16,16,16,16,16,14,14,13,13,12,12,9,3,3,3,6,7,8,9,9,6,6,4,3,1,4,4,3,5,5,8,10,12,12,11,11,11,10,12,12,12,12,10,9,8,6,13,16,16,16,16,18,18,17,16,16,16,15,15,14,13,11,10,9,12, [...]
+"317",18,18,18,18,16,16,16,14,14,15,16,16,15,15,14,17,17,16,16,16,20,20,19,19,20,20,21,23,23,22,21,21,20,23,23,22,22,22,21,22,22,22,22,22,22,19,19,19,19,19,20,23,24,24,22,21,21,22,22,20,18,21,21,20,19,18,17,22,22,21,20,20,22,22,22,22,20,20,19,19,20,20,19,19,14,14,13,12,13,14,14,12,12,12,12,12,21,21,20,19,19,19,18,18,17,17,17,17,17,17,15,15,14,14,13,13,10,4,2,2,5,6,7,8,8,5,5,3,2,2,5,5,4,6,6,9,11,13,13,12,12,12,11,13,13,13,13,11,10,9,7,14,17,17,17,17,19,19,18,17,17,17,16,16,15,14,12,11,10, [...]
+"318",19,19,19,19,17,17,17,15,15,16,17,17,16,16,15,18,18,17,17,17,21,21,20,20,21,21,22,24,24,23,22,22,21,24,24,23,23,23,22,23,23,23,23,23,23,20,20,20,20,20,21,24,25,25,23,22,22,23,23,21,19,22,22,21,20,19,18,23,23,22,21,21,23,23,23,23,21,21,20,20,21,21,20,20,15,15,14,13,14,15,15,13,13,13,13,13,22,22,21,20,20,20,19,19,18,18,18,18,18,18,16,16,15,15,14,14,11,5,1,1,6,7,8,9,9,6,6,4,3,3,6,6,5,7,7,10,12,14,14,13,13,13,12,14,14,14,14,12,11,10,8,15,18,18,18,18,20,20,19,18,18,18,17,17,16,15,13,12,1 [...]
+"319",19,19,19,19,17,17,17,15,15,16,17,17,16,16,15,18,18,17,17,17,21,21,20,20,21,21,22,24,24,23,22,22,21,24,24,23,23,23,22,23,23,23,23,23,23,20,20,20,20,20,21,24,25,25,23,22,22,23,23,21,19,22,22,21,20,19,18,23,23,22,21,21,23,23,23,23,21,21,20,20,21,21,20,20,15,15,14,13,14,15,15,13,13,13,13,13,22,22,21,20,20,20,19,19,18,18,18,18,18,18,16,16,15,15,14,14,11,5,3,3,4,5,6,7,7,4,4,2,1,3,6,6,5,7,7,10,12,14,14,13,13,13,12,14,14,14,14,12,11,10,8,15,18,18,18,18,20,20,19,18,18,18,17,17,16,15,13,12,1 [...]
+"320",20,20,20,20,18,18,18,16,16,17,18,18,17,17,16,19,19,18,18,18,22,22,21,21,22,22,23,25,25,24,23,23,22,25,25,24,24,24,23,24,24,24,24,24,24,21,21,21,21,21,22,25,26,26,24,23,23,24,24,22,20,23,23,22,21,20,19,24,24,23,22,22,24,24,24,24,22,22,21,21,22,22,21,21,16,16,15,14,15,16,16,14,14,14,14,14,23,23,22,21,21,21,20,20,19,19,19,19,19,19,17,17,16,16,15,15,12,6,4,4,3,4,5,6,6,3,3,1,2,4,7,7,6,8,8,11,13,15,15,14,14,14,13,15,15,15,15,13,12,11,9,16,19,19,19,19,21,21,20,19,19,19,18,18,17,16,14,13,1 [...]
+"321",21,21,21,21,19,19,19,17,17,18,19,19,18,18,17,20,20,19,19,19,23,23,22,22,23,23,24,26,26,25,24,24,23,26,26,25,25,25,24,25,25,25,25,25,25,22,22,22,22,22,23,26,27,27,25,24,24,25,25,23,21,24,24,23,22,21,20,25,25,24,23,23,25,25,25,25,23,23,22,22,23,23,22,22,17,17,16,15,16,17,17,15,15,15,15,15,24,24,23,22,22,22,21,21,20,20,20,20,20,20,18,18,17,17,16,16,13,7,5,5,2,3,4,5,5,2,2,2,3,5,8,8,7,9,9,12,14,16,16,15,15,15,14,16,16,16,16,14,13,12,10,17,20,20,20,20,22,22,21,20,20,20,19,19,18,17,15,14, [...]
+"322",22,22,22,22,20,20,20,18,18,19,20,20,19,19,18,21,21,20,20,20,24,24,23,23,24,24,25,27,27,26,25,25,24,27,27,26,26,26,25,26,26,26,26,26,26,23,23,23,23,23,24,27,28,28,26,25,25,26,26,24,22,25,25,24,23,22,21,26,26,25,24,24,26,26,26,26,24,24,23,23,24,24,23,23,18,18,17,16,17,18,18,16,16,16,16,16,25,25,24,23,23,23,22,22,21,21,21,21,21,21,19,19,18,18,17,17,14,8,6,6,1,2,3,4,4,3,3,3,4,6,9,9,8,10,10,13,15,17,17,16,16,16,15,17,17,17,17,15,14,13,11,18,21,21,21,21,23,23,22,21,21,21,20,20,19,18,16,1 [...]
+"323",23,23,23,23,21,21,21,19,19,20,21,21,20,20,19,22,22,21,21,21,25,25,24,24,25,25,26,28,28,27,26,26,25,28,28,27,27,27,26,27,27,27,27,27,27,24,24,24,24,24,25,28,29,29,27,26,26,27,27,25,23,26,26,25,24,23,22,27,27,26,25,25,27,27,27,27,25,25,24,24,25,25,24,24,19,19,18,17,18,19,19,17,17,17,17,17,26,26,25,24,24,24,23,23,22,22,22,22,22,22,20,20,19,19,18,18,15,9,7,7,2,1,2,3,3,4,4,4,5,7,10,10,9,11,11,14,16,18,18,17,17,17,16,18,18,18,18,16,15,14,12,19,22,22,22,22,24,24,23,22,22,22,21,21,20,19,17 [...]
+"324",24,24,24,24,22,22,22,20,20,21,22,22,21,21,20,23,23,22,22,22,26,26,25,25,26,26,27,29,29,28,27,27,26,29,29,28,28,28,27,28,28,28,28,28,28,25,25,25,25,25,26,29,30,30,28,27,27,28,28,26,24,27,27,26,25,24,23,28,28,27,26,26,28,28,28,28,26,26,25,25,26,26,25,25,20,20,19,18,19,20,20,18,18,18,18,18,27,27,26,25,25,25,24,24,23,23,23,23,23,23,21,21,20,20,19,19,16,10,8,8,3,2,1,2,2,5,5,5,6,8,11,11,10,12,12,15,17,19,19,18,18,18,17,19,19,19,19,17,16,15,13,20,23,23,23,23,25,25,24,23,23,23,22,22,21,20, [...]
+"325",25,25,25,25,23,23,23,21,21,22,23,23,22,22,21,24,24,23,23,23,27,27,26,26,27,27,28,30,30,29,28,28,27,30,30,29,29,29,28,29,29,29,29,29,29,26,26,26,26,26,27,30,31,31,29,28,28,29,29,27,25,28,28,27,26,25,24,29,29,28,27,27,29,29,29,29,27,27,26,26,27,27,26,26,21,21,20,19,20,21,21,19,19,19,19,19,28,28,27,26,26,26,25,25,24,24,24,24,24,24,22,22,21,21,20,20,17,11,9,9,4,3,2,1,1,6,6,6,7,9,12,12,11,13,13,16,18,20,20,19,19,19,18,20,20,20,20,18,17,16,14,21,24,24,24,24,26,26,25,24,24,24,23,23,22,21, [...]
+"326",22,22,22,22,20,20,20,18,18,19,20,20,19,19,18,21,21,20,20,20,24,24,23,23,24,24,25,27,27,26,25,25,24,27,27,26,26,26,25,26,26,26,26,26,26,23,23,23,23,23,24,27,28,28,26,25,25,26,26,24,22,25,25,24,23,22,21,26,26,25,24,24,26,26,26,26,24,24,23,23,24,24,23,23,18,18,17,16,17,18,18,16,16,16,16,16,25,25,24,23,23,23,22,22,21,21,21,21,21,21,19,19,18,18,17,17,14,8,6,6,3,4,5,6,6,1,1,3,4,6,9,9,8,10,10,13,15,17,17,16,16,16,15,17,17,17,17,15,14,13,11,18,21,21,21,21,23,23,22,21,21,21,20,20,19,18,16,1 [...]
+"327",17,17,17,17,15,15,15,13,13,14,15,15,14,14,13,16,16,15,15,15,19,19,18,18,19,19,20,22,22,21,20,20,19,22,22,21,21,21,20,21,21,21,21,21,21,18,18,18,18,18,19,22,23,23,21,20,20,21,21,19,17,20,20,19,18,17,16,21,21,20,19,19,21,21,21,21,19,19,18,18,19,19,18,18,13,13,12,11,12,13,13,11,11,11,11,11,20,20,19,18,18,18,17,17,16,16,16,16,16,16,14,14,13,13,12,12,9,3,5,5,8,9,10,11,11,8,8,6,5,3,2,2,1,5,5,8,10,12,12,11,11,11,10,12,12,12,12,10,9,8,6,13,16,16,16,16,18,18,17,16,16,16,15,15,14,13,11,10,9, [...]
+"328",18,18,18,18,16,16,16,14,14,15,16,16,15,15,14,17,17,16,16,16,20,20,19,19,20,20,21,23,23,22,21,21,20,23,23,22,22,22,21,22,22,22,22,22,22,19,19,19,19,19,20,23,24,24,22,21,21,22,22,20,18,21,21,20,19,18,17,22,22,21,20,20,22,22,22,22,20,20,19,19,20,20,19,19,14,14,13,12,13,14,14,12,12,12,12,12,21,21,20,19,19,19,18,18,17,17,17,17,17,17,15,15,14,14,13,13,10,4,6,6,9,10,11,12,12,9,9,7,6,4,1,1,2,6,6,9,11,13,13,12,12,12,11,13,13,13,13,11,10,9,7,14,17,17,17,17,19,19,18,17,17,17,16,16,15,14,12,11 [...]
+"329",15,15,15,15,13,13,13,11,11,12,13,13,12,12,11,14,14,13,13,13,17,17,16,16,17,17,18,20,20,19,18,18,17,20,20,19,19,19,18,19,19,19,19,19,19,16,16,16,16,16,17,20,21,21,19,18,18,19,19,17,15,18,18,17,16,15,14,19,19,18,17,17,19,19,19,19,17,17,16,16,17,17,16,16,11,11,10,9,10,11,11,9,9,9,9,9,18,18,17,16,16,16,15,15,14,14,14,14,14,14,12,12,11,11,10,10,7,3,7,7,10,11,12,13,13,10,10,8,7,5,6,6,5,1,1,6,8,10,10,9,9,9,8,10,10,10,10,8,7,6,4,11,14,14,14,14,16,16,15,14,14,14,13,13,12,11,9,8,7,10,10,12,1 [...]
+"330",14,14,14,14,12,12,12,10,10,11,12,12,11,11,10,13,13,12,12,12,16,16,15,15,16,16,17,19,19,18,17,17,16,19,19,18,18,18,17,18,18,18,18,18,18,15,15,15,15,15,16,19,20,20,18,17,17,18,18,16,14,17,17,16,15,14,13,18,18,17,16,16,18,18,18,18,16,16,15,15,16,16,15,15,10,10,9,8,9,10,10,8,8,8,8,8,17,17,16,15,15,15,14,14,13,13,13,13,13,13,11,11,10,10,9,9,6,4,8,8,11,12,13,14,14,11,11,9,8,6,7,7,6,4,4,3,5,7,7,6,6,6,5,7,7,7,7,5,4,3,1,10,13,13,13,13,15,15,14,13,13,13,12,12,11,10,8,7,6,9,9,11,11,10,9,7,6,7 [...]
+"331",15,15,15,15,13,13,13,11,11,12,13,13,12,12,11,14,14,13,13,13,17,17,16,16,17,17,18,20,20,19,18,18,17,20,20,19,19,19,18,19,19,19,19,19,19,16,16,16,16,16,17,20,21,21,19,18,18,19,19,17,15,18,18,17,16,15,14,19,19,18,17,17,19,19,19,19,17,17,16,16,17,17,16,16,11,11,10,9,10,11,11,9,9,9,9,9,18,18,17,16,16,16,15,15,14,14,14,14,14,14,12,12,11,11,10,10,7,5,9,9,12,13,14,15,15,12,12,10,9,7,8,8,7,5,5,2,4,6,6,5,5,5,4,6,6,6,6,4,3,2,2,11,14,14,14,14,16,16,15,14,14,14,13,13,12,11,9,8,7,10,10,12,12,11, [...]
+"332",16,16,16,16,14,14,14,12,12,13,14,14,13,13,12,15,15,14,14,14,18,18,17,17,18,18,19,21,21,20,19,19,18,21,21,20,20,20,19,20,20,20,20,20,20,17,17,17,17,17,18,21,22,22,20,19,19,20,20,18,16,19,19,18,17,16,15,20,20,19,18,18,20,20,20,20,18,18,17,17,18,18,17,17,12,12,11,10,11,12,12,10,10,10,10,10,19,19,18,17,17,17,16,16,15,15,15,15,15,15,13,13,12,12,11,11,8,6,10,10,13,14,15,16,16,13,13,11,10,8,9,9,8,6,6,1,3,5,5,4,4,4,3,7,7,7,7,5,4,3,3,12,15,15,15,15,17,17,16,15,15,15,14,14,13,12,10,9,8,11,11 [...]
+"333",17,17,17,17,15,15,15,13,13,14,15,15,14,14,13,16,16,15,15,15,19,19,18,18,19,19,20,22,22,21,20,20,19,22,22,21,21,21,20,21,21,21,21,21,21,18,18,18,18,18,19,22,23,23,21,20,20,21,21,19,17,20,20,19,18,17,16,21,21,20,19,19,21,21,21,21,19,19,18,18,19,19,18,18,13,13,12,11,12,13,13,11,11,11,11,11,20,20,19,18,18,18,17,17,16,16,16,16,16,16,14,14,13,13,12,12,9,7,11,11,14,15,16,17,17,14,14,12,11,9,10,10,9,7,7,2,2,4,4,3,3,3,2,8,8,8,8,6,5,4,4,13,16,16,16,16,18,18,17,16,16,16,15,15,14,13,11,10,9,12 [...]
+"334",18,18,18,18,16,16,16,14,14,15,16,16,15,15,14,17,17,16,16,16,20,20,19,19,20,20,21,23,23,22,21,21,20,23,23,22,22,22,21,22,22,22,22,22,22,19,19,19,19,19,20,23,24,24,22,21,21,22,22,20,18,21,21,20,19,18,17,22,22,21,20,20,22,22,22,22,20,20,19,19,20,20,19,19,14,14,13,12,13,14,14,12,12,12,12,12,21,21,20,19,19,19,18,18,17,17,17,17,17,17,15,15,14,14,13,13,10,8,12,12,15,16,17,18,18,15,15,13,12,10,11,11,10,8,8,3,1,3,3,2,4,4,3,9,9,9,9,7,6,5,5,14,17,17,17,17,19,19,18,17,17,17,16,16,15,14,12,11,1 [...]
+"335",19,19,19,19,17,17,17,15,15,16,17,17,16,16,15,18,18,17,17,17,21,21,20,20,21,21,22,24,24,23,22,22,21,24,24,23,23,23,22,23,23,23,23,23,23,20,20,20,20,20,21,24,25,25,23,22,22,23,23,21,19,22,22,21,20,19,18,23,23,22,21,21,23,23,23,23,21,21,20,20,21,21,20,20,15,15,14,13,14,15,15,13,13,13,13,13,22,22,21,20,20,20,19,19,18,18,18,18,18,18,16,16,15,15,14,14,11,9,13,13,16,17,18,19,19,16,16,14,13,11,12,12,11,9,9,4,2,2,2,1,5,5,4,10,10,10,10,8,7,6,6,15,18,18,18,18,20,20,19,18,18,18,17,17,16,15,13, [...]
+"336",20,20,20,20,18,18,18,16,16,17,18,18,17,17,16,19,19,18,18,18,22,22,21,21,22,22,23,25,25,24,23,23,22,25,25,24,24,24,23,24,24,24,24,24,24,21,21,21,21,21,22,25,26,26,24,23,23,24,24,22,20,23,23,22,21,20,19,24,24,23,22,22,24,24,24,24,22,22,21,21,22,22,21,21,16,16,15,14,15,16,16,14,14,14,14,14,23,23,22,21,21,21,20,20,19,19,19,19,19,19,17,17,16,16,15,15,12,10,14,14,17,18,19,20,20,17,17,15,14,12,13,13,12,10,10,5,3,1,1,2,6,6,5,11,11,11,11,9,8,7,7,16,19,19,19,19,21,21,20,19,19,19,18,18,17,16, [...]
+"337",18,18,18,18,16,16,16,14,14,15,16,16,15,15,14,17,17,16,16,16,20,20,19,19,20,20,21,23,23,22,21,21,20,23,23,22,22,22,21,22,22,22,22,22,22,19,19,19,19,19,20,23,24,24,22,21,21,22,22,20,18,21,21,20,19,18,17,22,22,21,20,20,22,22,22,22,20,20,19,19,20,20,19,19,14,14,13,12,13,14,14,12,12,12,12,12,21,21,20,19,19,19,18,18,17,17,17,17,17,17,15,15,14,14,13,13,10,8,12,12,15,16,17,18,18,15,15,13,12,10,11,11,10,8,8,3,3,5,5,4,2,2,1,9,9,9,9,7,6,5,5,14,17,17,17,17,19,19,18,17,17,17,16,16,15,14,12,11,1 [...]
+"338",19,19,19,19,17,17,17,15,15,16,17,17,16,16,15,18,18,17,17,17,21,21,20,20,21,21,22,24,24,23,22,22,21,24,24,23,23,23,22,23,23,23,23,23,23,20,20,20,20,20,21,24,25,25,23,22,22,23,23,21,19,22,22,21,20,19,18,23,23,22,21,21,23,23,23,23,21,21,20,20,21,21,20,20,15,15,14,13,14,15,15,13,13,13,13,13,22,22,21,20,20,20,19,19,18,18,18,18,18,18,16,16,15,15,14,14,11,9,13,13,16,17,18,19,19,16,16,14,13,11,12,12,11,9,9,4,4,6,6,5,1,1,2,10,10,10,10,8,7,6,6,15,18,18,18,18,20,20,19,18,18,18,17,17,16,15,13, [...]
+"339",16,16,16,16,14,14,14,12,12,13,14,14,13,13,12,15,15,14,14,14,18,18,17,17,18,18,19,21,21,20,19,19,18,21,21,20,20,20,19,20,20,20,20,20,20,17,17,17,17,17,18,21,22,22,20,19,19,20,20,18,16,19,19,18,17,16,15,20,20,19,18,18,20,20,20,20,18,18,17,17,18,18,17,17,12,12,11,10,11,12,12,10,10,10,10,10,19,19,18,17,17,17,16,16,15,15,15,15,15,15,13,13,12,12,11,11,8,6,10,10,13,14,15,16,16,13,13,11,10,8,9,9,8,6,6,3,5,7,7,6,6,6,5,5,5,5,5,3,2,1,3,12,15,15,15,15,17,17,16,15,15,15,14,14,13,12,10,9,8,11,11 [...]
+"340",17,17,17,17,15,15,15,13,13,14,15,15,14,14,13,16,16,15,15,15,19,19,18,18,19,19,20,22,22,21,20,20,19,22,22,21,21,21,20,21,21,21,21,21,21,18,18,18,18,18,19,22,23,23,21,20,20,21,21,19,17,20,20,19,18,17,16,21,21,20,19,19,21,21,21,21,19,19,18,18,19,19,18,18,13,13,12,11,12,13,13,11,11,11,11,11,20,20,19,18,18,18,17,17,16,16,16,16,16,16,14,14,13,13,12,12,9,7,11,11,14,15,16,17,17,14,14,12,11,9,10,10,9,7,7,4,6,8,8,7,7,7,6,4,4,4,4,2,1,2,4,13,16,16,16,16,18,18,17,16,16,16,15,15,14,13,11,10,9,12 [...]
+"341",18,18,18,18,16,16,16,14,14,15,16,16,15,15,14,17,17,16,16,16,20,20,19,19,20,20,21,23,23,22,21,21,20,23,23,22,22,22,21,22,22,22,22,22,22,19,19,19,19,19,20,23,24,24,22,21,21,22,22,20,18,21,21,20,19,18,17,22,22,21,20,20,22,22,22,22,20,20,19,19,20,20,19,19,14,14,13,12,13,14,14,12,12,12,12,12,21,21,20,19,19,19,18,18,17,17,17,17,17,17,15,15,14,14,13,13,10,8,12,12,15,16,17,18,18,15,15,13,12,10,11,11,10,8,8,5,7,9,9,8,8,8,7,3,3,3,3,1,2,3,5,14,17,17,17,17,19,19,18,17,17,17,16,16,15,14,12,11,1 [...]
+"342",19,19,19,19,17,17,17,15,15,16,17,17,16,16,15,18,18,17,17,17,21,21,20,20,21,21,22,24,24,23,22,22,21,24,24,23,23,23,22,23,23,23,23,23,23,20,20,20,20,20,21,24,25,25,23,22,22,23,23,21,19,22,22,21,20,19,18,23,23,22,21,21,23,23,23,23,21,21,20,20,21,21,20,20,15,15,14,13,14,15,15,13,13,13,13,13,22,22,21,20,20,20,19,19,18,18,18,18,18,18,16,16,15,15,14,14,11,9,13,13,16,17,18,19,19,16,16,14,13,11,12,12,11,9,9,6,8,10,10,9,9,9,8,2,2,2,2,2,3,4,6,15,18,18,18,18,20,20,19,18,18,18,17,17,16,15,13,12 [...]
+"343",20,20,20,20,18,18,18,16,16,17,18,18,17,17,16,19,19,18,18,18,22,22,21,21,22,22,23,25,25,24,23,23,22,25,25,24,24,24,23,24,24,24,24,24,24,21,21,21,21,21,22,25,26,26,24,23,23,24,24,22,20,23,23,22,21,20,19,24,24,23,22,22,24,24,24,24,22,22,21,21,22,22,21,21,16,16,15,14,15,16,16,14,14,14,14,14,23,23,22,21,21,21,20,20,19,19,19,19,19,19,17,17,16,16,15,15,12,10,14,14,17,18,19,20,20,17,17,15,14,12,13,13,12,10,10,7,9,11,11,10,10,10,9,1,1,3,3,3,4,5,7,16,19,19,19,19,21,21,20,19,19,19,18,18,17,16 [...]
+"344",20,20,20,20,18,18,18,16,16,17,18,18,17,17,16,19,19,18,18,18,22,22,21,21,22,22,23,25,25,24,23,23,22,25,25,24,24,24,23,24,24,24,24,24,24,21,21,21,21,21,22,25,26,26,24,23,23,24,24,22,20,23,23,22,21,20,19,24,24,23,22,22,24,24,24,24,22,22,21,21,22,22,21,21,16,16,15,14,15,16,16,14,14,14,14,14,23,23,22,21,21,21,20,20,19,19,19,19,19,19,17,17,16,16,15,15,12,10,14,14,17,18,19,20,20,17,17,15,14,12,13,13,12,10,10,7,9,11,11,10,10,10,9,3,3,1,1,3,4,5,7,16,19,19,19,19,21,21,20,19,19,19,18,18,17,16 [...]
+"345",13,13,13,13,11,11,11,9,9,10,11,11,10,10,9,12,12,11,11,11,15,15,14,14,15,15,16,18,18,17,16,16,15,18,18,17,17,17,16,17,17,17,17,17,17,14,14,14,14,14,15,18,19,19,17,16,16,17,17,15,13,16,16,15,14,13,12,17,17,16,15,15,17,17,17,17,15,15,14,14,15,15,14,14,9,9,8,7,8,9,9,7,7,7,7,7,16,16,15,14,14,14,13,13,12,12,12,12,12,12,10,10,9,9,8,8,5,5,9,9,12,13,14,15,15,12,12,10,9,7,8,8,7,5,5,6,8,10,10,9,9,9,8,10,10,10,10,8,7,6,4,7,10,10,10,10,12,12,11,10,10,10,9,9,8,7,5,4,3,6,6,8,8,7,6,4,3,4,5,8,8,7,7 [...]
+"346",14,14,14,14,12,12,12,10,10,11,12,12,11,11,10,13,13,12,12,12,16,16,15,15,16,16,17,19,19,18,17,17,16,19,19,18,18,18,17,18,18,18,18,18,18,15,15,15,15,15,16,19,20,20,18,17,17,18,18,16,14,17,17,16,15,14,13,18,18,17,16,16,18,18,18,18,16,16,15,15,16,16,15,15,10,10,9,8,9,10,10,8,8,8,8,8,17,17,16,15,15,15,14,14,13,13,13,13,13,13,11,11,10,10,9,9,6,6,10,10,13,14,15,16,16,13,13,11,10,8,9,9,8,6,6,7,9,11,11,10,10,10,9,11,11,11,11,9,8,7,5,6,9,9,9,9,11,11,10,9,9,9,8,8,7,6,4,3,2,5,5,7,7,6,5,3,2,5,6 [...]
+"347",15,15,15,15,13,13,13,11,11,12,13,13,12,12,11,14,14,13,13,13,17,17,16,16,17,17,18,20,20,19,18,18,17,20,20,19,19,19,18,19,19,19,19,19,19,16,16,16,16,16,17,20,21,21,19,18,18,19,19,17,15,18,18,17,16,15,14,19,19,18,17,17,19,19,19,19,17,17,16,16,17,17,16,16,11,11,10,9,10,11,11,9,9,9,9,9,18,18,17,16,16,16,15,15,14,14,14,14,14,14,12,12,11,11,10,10,7,7,11,11,14,15,16,17,17,14,14,12,11,9,10,10,9,7,7,8,10,12,12,11,11,11,10,12,12,12,12,10,9,8,6,5,8,8,8,8,10,10,9,8,8,8,7,7,6,5,3,2,1,6,6,8,8,7,6 [...]
+"348",16,16,16,16,14,14,14,12,12,13,14,14,13,13,12,15,15,14,14,14,18,18,17,17,18,18,19,21,21,20,19,19,18,21,21,20,20,20,19,20,20,20,20,20,20,17,17,17,17,17,18,21,22,22,20,19,19,20,20,18,16,19,19,18,17,16,15,20,20,19,18,18,20,20,20,20,18,18,17,17,18,18,17,17,12,12,11,10,11,12,12,10,10,10,10,10,19,19,18,17,17,17,16,16,15,15,15,15,15,15,13,13,12,12,11,11,8,8,12,12,15,16,17,18,18,15,15,13,12,10,11,11,10,8,8,9,11,13,13,12,12,12,11,13,13,13,13,11,10,9,7,4,7,7,7,7,9,9,8,7,7,7,6,6,5,4,2,1,2,7,7, [...]
+"349",17,17,17,17,15,15,15,13,13,14,15,15,14,14,13,16,16,15,15,15,19,19,18,18,19,19,20,22,22,21,20,20,19,22,22,21,21,21,20,21,21,21,21,21,21,18,18,18,18,18,19,22,23,23,21,20,20,21,21,19,17,20,20,19,18,17,16,21,21,20,19,19,21,21,21,21,19,19,18,18,19,19,18,18,13,13,12,11,12,13,13,11,11,11,11,11,20,20,19,18,18,18,17,17,16,16,16,16,16,16,14,14,13,13,12,12,9,9,13,13,16,17,18,19,19,16,16,14,13,11,12,12,11,9,9,10,12,14,14,13,13,13,12,14,14,14,14,12,11,10,8,3,6,6,6,6,8,8,7,6,6,6,5,5,4,3,1,2,3,8, [...]
+"350",18,18,18,18,16,16,16,14,14,15,16,16,15,15,14,17,17,16,16,16,20,20,19,19,20,20,21,23,23,22,21,21,20,23,23,22,22,22,21,22,22,22,22,22,22,19,19,19,19,19,20,23,24,24,22,21,21,22,22,20,18,21,21,20,19,18,17,22,22,21,20,20,22,22,22,22,20,20,19,19,20,20,19,19,14,14,13,12,13,14,14,12,12,12,12,12,21,21,20,19,19,19,18,18,17,17,17,17,17,17,15,15,14,14,13,13,10,10,14,14,17,18,19,20,20,17,17,15,14,12,13,13,12,10,10,11,13,15,15,14,14,14,13,15,15,15,15,13,12,11,9,2,5,5,5,5,7,7,6,5,5,5,4,4,3,2,2,3, [...]
+"351",19,19,19,19,17,17,17,15,15,16,17,17,16,16,15,18,18,17,17,17,21,21,20,20,21,21,22,24,24,23,22,22,21,24,24,23,23,23,22,23,23,23,23,23,23,20,20,20,20,20,21,24,25,25,23,22,22,23,23,21,19,22,22,21,20,19,18,23,23,22,21,21,23,23,23,23,21,21,20,20,21,21,20,20,15,15,14,13,14,15,15,13,13,13,13,13,22,22,21,20,20,20,19,19,18,18,18,18,18,18,16,16,15,15,14,14,11,11,15,15,18,19,20,21,21,18,18,16,15,13,14,14,13,11,11,12,14,16,16,15,15,15,14,16,16,16,16,14,13,12,10,1,4,4,4,4,6,6,5,4,4,4,5,5,4,3,3,4 [...]
+"352",20,20,20,20,18,18,18,16,16,17,18,18,17,17,16,19,19,18,18,18,22,22,21,21,22,22,23,25,25,24,23,23,22,25,25,24,24,24,23,24,24,24,24,24,24,21,21,21,21,21,22,25,26,26,24,23,23,24,24,22,20,23,23,22,21,20,19,24,24,23,22,22,24,24,24,24,22,22,21,21,22,22,21,21,16,16,15,14,15,16,16,14,14,14,14,14,23,23,22,21,21,21,20,20,19,19,19,19,19,19,17,17,16,16,15,15,12,12,16,16,19,20,21,22,22,19,19,17,16,14,15,15,14,12,12,13,15,17,17,16,16,16,15,17,17,17,17,15,14,13,11,2,3,3,3,3,5,5,4,3,3,3,6,6,5,4,4,5 [...]
+"353",21,21,21,21,19,19,19,17,17,18,19,19,18,18,17,20,20,19,19,19,23,23,22,22,23,23,24,26,26,25,24,24,23,26,26,25,25,25,24,25,25,25,25,25,25,22,22,22,22,22,23,26,27,27,25,24,24,25,25,23,21,24,24,23,22,21,20,25,25,24,23,23,25,25,25,25,23,23,22,22,23,23,22,22,17,17,16,15,16,17,17,15,15,15,15,15,24,24,23,22,22,22,21,21,20,20,20,20,20,20,18,18,17,17,16,16,13,13,17,17,20,21,22,23,23,20,20,18,17,15,16,16,15,13,13,14,16,18,18,17,17,17,16,18,18,18,18,16,15,14,12,3,2,2,2,2,6,6,5,4,4,4,7,7,6,5,5,6 [...]
+"354",22,22,22,22,20,20,20,18,18,19,20,20,19,19,18,21,21,20,20,20,24,24,23,23,24,24,25,27,27,26,25,25,24,27,27,26,26,26,25,26,26,26,26,26,26,23,23,23,23,23,24,27,28,28,26,25,25,26,26,24,22,25,25,24,23,22,21,26,26,25,24,24,26,26,26,26,24,24,23,23,24,24,23,23,18,18,17,16,17,18,18,16,16,16,16,16,25,25,24,23,23,23,22,22,21,21,21,21,21,21,19,19,18,18,17,17,14,14,18,18,21,22,23,24,24,21,21,19,18,16,17,17,16,14,14,15,17,19,19,18,18,18,17,19,19,19,19,17,16,15,13,4,1,1,3,3,7,7,6,5,5,5,8,8,7,6,6,7 [...]
+"355",22,22,22,22,20,20,20,18,18,19,20,20,19,19,18,21,21,20,20,20,24,24,23,23,24,24,25,27,27,26,25,25,24,27,27,26,26,26,25,26,26,26,26,26,26,23,23,23,23,23,24,27,28,28,26,25,25,26,26,24,22,25,25,24,23,22,21,26,26,25,24,24,26,26,26,26,24,24,23,23,24,24,23,23,18,18,17,16,17,18,18,16,16,16,16,16,25,25,24,23,23,23,22,22,21,21,21,21,21,21,19,19,18,18,17,17,14,14,18,18,21,22,23,24,24,21,21,19,18,16,17,17,16,14,14,15,17,19,19,18,18,18,17,19,19,19,19,17,16,15,13,4,3,3,1,1,7,7,6,5,5,5,8,8,7,6,6,7 [...]
+"356",21,21,21,21,19,19,19,17,17,18,19,19,18,18,17,20,20,19,19,19,23,23,22,22,23,23,24,26,26,25,24,24,23,26,26,25,25,25,24,25,25,25,25,25,25,22,22,22,22,22,23,26,27,27,25,24,24,25,25,23,21,24,24,23,22,21,20,25,25,24,23,23,25,25,25,25,23,23,22,22,23,23,22,22,17,17,16,15,16,17,17,15,15,15,15,15,24,24,23,22,22,22,21,21,20,20,20,20,20,20,18,18,17,17,16,16,13,13,17,17,20,21,22,23,23,20,20,18,17,15,16,16,15,13,13,14,16,18,18,17,17,17,16,18,18,18,18,16,15,14,12,3,4,4,4,4,4,4,3,2,2,2,7,7,6,5,5,6 [...]
+"357",22,22,22,22,20,20,20,18,18,19,20,20,19,19,18,21,21,20,20,20,24,24,23,23,24,24,25,27,27,26,25,25,24,27,27,26,26,26,25,26,26,26,26,26,26,23,23,23,23,23,24,27,28,28,26,25,25,26,26,24,22,25,25,24,23,22,21,26,26,25,24,24,26,26,26,26,24,24,23,23,24,24,23,23,18,18,17,16,17,18,18,16,16,16,16,16,25,25,24,23,23,23,22,22,21,21,21,21,21,21,19,19,18,18,17,17,14,14,18,18,21,22,23,24,24,21,21,19,18,16,17,17,16,14,14,15,17,19,19,18,18,18,17,19,19,19,19,17,16,15,13,4,5,5,5,5,3,3,2,1,3,3,8,8,7,6,6,7 [...]
+"358",23,23,23,23,21,21,21,19,19,20,21,21,20,20,19,22,22,21,21,21,25,25,24,24,25,25,26,28,28,27,26,26,25,28,28,27,27,27,26,27,27,27,27,27,27,24,24,24,24,24,25,28,29,29,27,26,26,27,27,25,23,26,26,25,24,23,22,27,27,26,25,25,27,27,27,27,25,25,24,24,25,25,24,24,19,19,18,17,18,19,19,17,17,17,17,17,26,26,25,24,24,24,23,23,22,22,22,22,22,22,20,20,19,19,18,18,15,15,19,19,22,23,24,25,25,22,22,20,19,17,18,18,17,15,15,16,18,20,20,19,19,19,18,20,20,20,20,18,17,16,14,5,6,6,6,6,2,2,1,2,4,4,9,9,8,7,7,8 [...]
+"359",24,24,24,24,22,22,22,20,20,21,22,22,21,21,20,23,23,22,22,22,26,26,25,25,26,26,27,29,29,28,27,27,26,29,29,28,28,28,27,28,28,28,28,28,28,25,25,25,25,25,26,29,30,30,28,27,27,28,28,26,24,27,27,26,25,24,23,28,28,27,26,26,28,28,28,28,26,26,25,25,26,26,25,25,20,20,19,18,19,20,20,18,18,18,18,18,27,27,26,25,25,25,24,24,23,23,23,23,23,23,21,21,20,20,19,19,16,16,20,20,23,24,25,26,26,23,23,21,20,18,19,19,18,16,16,17,19,21,21,20,20,20,19,21,21,21,21,19,18,17,15,6,7,7,7,7,1,1,2,3,5,5,10,10,9,8,8 [...]
+"360",22,22,22,22,20,20,20,18,18,19,20,20,19,19,18,21,21,20,20,20,24,24,23,23,24,24,25,27,27,26,25,25,24,27,27,26,26,26,25,26,26,26,26,26,26,23,23,23,23,23,24,27,28,28,26,25,25,26,26,24,22,25,25,24,23,22,21,26,26,25,24,24,26,26,26,26,24,24,23,23,24,24,23,23,18,18,17,16,17,18,18,16,16,16,16,16,25,25,24,23,23,23,22,22,21,21,21,21,21,21,19,19,18,18,17,17,14,14,18,18,21,22,23,24,24,21,21,19,18,16,17,17,16,14,14,15,17,19,19,18,18,18,17,19,19,19,19,17,16,15,13,4,5,5,5,5,5,5,4,3,1,1,8,8,7,6,6,7 [...]
+"361",19,19,19,19,17,17,17,15,15,16,17,17,16,16,15,18,18,17,17,17,21,21,20,20,21,21,22,24,24,23,22,22,21,24,24,23,23,23,22,23,23,23,23,23,23,20,20,20,20,20,21,24,25,25,23,22,22,23,23,21,19,22,22,21,20,19,18,23,23,22,21,21,23,23,23,23,21,21,20,20,21,21,20,20,15,15,14,13,14,15,15,13,13,13,13,13,22,22,21,20,20,20,19,19,18,18,18,18,18,18,16,16,15,15,14,14,11,11,15,15,18,19,20,21,21,18,18,16,15,13,14,14,13,11,11,12,14,16,16,15,15,15,14,16,16,16,16,14,13,12,10,3,6,6,6,6,8,8,7,6,6,6,3,3,2,1,3,4 [...]
+"362",20,20,20,20,18,18,18,16,16,17,18,18,17,17,16,19,19,18,18,18,22,22,21,21,22,22,23,25,25,24,23,23,22,25,25,24,24,24,23,24,24,24,24,24,24,21,21,21,21,21,22,25,26,26,24,23,23,24,24,22,20,23,23,22,21,20,19,24,24,23,22,22,24,24,24,24,22,22,21,21,22,22,21,21,16,16,15,14,15,16,16,14,14,14,14,14,23,23,22,21,21,21,20,20,19,19,19,19,19,19,17,17,16,16,15,15,12,12,16,16,19,20,21,22,22,19,19,17,16,14,15,15,14,12,12,13,15,17,17,16,16,16,15,17,17,17,17,15,14,13,11,4,7,7,7,7,9,9,8,7,7,7,2,2,1,2,4,5 [...]
+"363",21,21,21,21,19,19,19,17,17,18,19,19,18,18,17,20,20,19,19,19,23,23,22,22,23,23,24,26,26,25,24,24,23,26,26,25,25,25,24,25,25,25,25,25,25,22,22,22,22,22,23,26,27,27,25,24,24,25,25,23,21,24,24,23,22,21,20,25,25,24,23,23,25,25,25,25,23,23,22,22,23,23,22,22,17,17,16,15,16,17,17,15,15,15,15,15,24,24,23,22,22,22,21,21,20,20,20,20,20,20,18,18,17,17,16,16,13,13,17,17,20,21,22,23,23,20,20,18,17,15,16,16,15,13,13,14,16,18,18,17,17,17,16,18,18,18,18,16,15,14,12,5,8,8,8,8,10,10,9,8,8,8,1,1,2,3,5 [...]
+"364",15,15,15,15,13,13,13,11,11,12,13,13,12,12,11,14,14,13,13,13,17,17,16,16,17,17,18,20,20,19,18,18,17,20,20,19,19,19,18,19,19,19,19,19,19,16,16,16,16,16,17,20,21,21,19,18,18,19,19,17,15,18,18,17,16,15,14,19,19,18,17,17,19,19,19,19,17,17,16,16,17,17,16,16,11,11,10,9,10,11,11,9,9,9,9,9,18,18,17,16,16,16,15,15,14,14,14,14,14,14,12,12,11,11,10,10,7,7,11,11,14,15,16,17,17,14,14,12,11,9,10,10,9,7,7,8,10,12,12,11,11,11,10,12,12,12,12,10,9,8,6,7,10,10,10,10,12,12,11,10,10,10,9,9,8,7,5,4,3,4,4 [...]
+"365",16,16,16,16,14,14,14,12,12,13,14,14,13,13,12,15,15,14,14,14,18,18,17,17,18,18,19,21,21,20,19,19,18,21,21,20,20,20,19,20,20,20,20,20,20,17,17,17,17,17,18,21,22,22,20,19,19,20,20,18,16,19,19,18,17,16,15,20,20,19,18,18,20,20,20,20,18,18,17,17,18,18,17,17,12,12,11,10,11,12,12,10,10,10,10,10,19,19,18,17,17,17,16,16,15,15,15,15,15,15,13,13,12,12,11,11,8,8,12,12,15,16,17,18,18,15,15,13,12,10,11,11,10,8,8,9,11,13,13,12,12,12,11,13,13,13,13,11,10,9,7,8,11,11,11,11,13,13,12,11,11,11,10,10,9, [...]
+"366",17,17,17,17,15,15,15,13,13,14,15,15,14,14,13,16,16,15,15,15,19,19,18,18,19,19,20,22,22,21,20,20,19,22,22,21,21,21,20,21,21,21,21,21,21,18,18,18,18,18,19,22,23,23,21,20,20,21,21,19,17,20,20,19,18,17,16,21,21,20,19,19,21,21,21,21,19,19,18,18,19,19,18,18,13,13,12,11,12,13,13,11,11,11,11,11,20,20,19,18,18,18,17,17,16,16,16,16,16,16,14,14,13,13,12,12,9,9,13,13,16,17,18,19,19,16,16,14,13,11,12,12,11,9,9,10,12,14,14,13,13,13,12,14,14,14,14,12,11,10,8,9,12,12,12,12,14,14,13,12,12,12,11,11, [...]
+"367",18,18,18,18,16,16,16,14,14,15,16,16,15,15,14,17,17,16,16,16,20,20,19,19,20,20,21,23,23,22,21,21,20,23,23,22,22,22,21,22,22,22,22,22,22,19,19,19,19,19,20,23,24,24,22,21,21,22,22,20,18,21,21,20,19,18,17,22,22,21,20,20,22,22,22,22,20,20,19,19,20,20,19,19,14,14,13,12,13,14,14,12,12,12,12,12,21,21,20,19,19,19,18,18,17,17,17,17,17,17,15,15,14,14,13,13,10,10,14,14,17,18,19,20,20,17,17,15,14,12,13,13,12,10,10,11,13,15,15,14,14,14,13,15,15,15,15,13,12,11,9,10,13,13,13,13,15,15,14,13,13,13,1 [...]
+"368",18,18,18,18,16,16,16,14,14,15,16,16,15,15,14,17,17,16,16,16,20,20,19,19,20,20,21,23,23,22,21,21,20,23,23,22,22,22,21,22,22,22,22,22,22,19,19,19,19,19,20,23,24,24,22,21,21,22,22,20,18,21,21,20,19,18,17,22,22,21,20,20,22,22,22,22,20,20,19,19,20,20,19,19,14,14,13,12,13,14,14,12,12,12,12,12,21,21,20,19,19,19,18,18,17,17,17,17,17,17,15,15,14,14,13,13,10,10,14,14,17,18,19,20,20,17,17,15,14,12,13,13,12,10,10,11,13,15,15,14,14,14,13,15,15,15,15,13,12,11,9,10,13,13,13,13,15,15,14,13,13,13,1 [...]
+"369",19,19,19,19,17,17,17,15,15,16,17,17,16,16,15,18,18,17,17,17,21,21,20,20,21,21,22,24,24,23,22,22,21,24,24,23,23,23,22,23,23,23,23,23,23,20,20,20,20,20,21,24,25,25,23,22,22,23,23,21,19,22,22,21,20,19,18,23,23,22,21,21,23,23,23,23,21,21,20,20,21,21,20,20,15,15,14,13,14,15,15,13,13,13,13,13,22,22,21,20,20,20,19,19,18,18,18,18,18,18,16,16,15,15,14,14,11,11,15,15,18,19,20,21,21,18,18,16,15,13,14,14,13,11,11,12,14,16,16,15,15,15,14,16,16,16,16,14,13,12,10,11,14,14,14,14,16,16,15,14,14,14, [...]
+"370",20,20,20,20,18,18,18,16,16,17,18,18,17,17,16,19,19,18,18,18,22,22,21,21,22,22,23,25,25,24,23,23,22,25,25,24,24,24,23,24,24,24,24,24,24,21,21,21,21,21,22,25,26,26,24,23,23,24,24,22,20,23,23,22,21,20,19,24,24,23,22,22,24,24,24,24,22,22,21,21,22,22,21,21,16,16,15,14,15,16,16,14,14,14,14,14,23,23,22,21,21,21,20,20,19,19,19,19,19,19,17,17,16,16,15,15,12,12,16,16,19,20,21,22,22,19,19,17,16,14,15,15,14,12,12,13,15,17,17,16,16,16,15,17,17,17,17,15,14,13,11,12,15,15,15,15,17,17,16,15,15,15, [...]
+"371",14,14,14,14,12,12,12,10,10,11,12,12,11,11,10,13,13,12,12,12,16,16,15,15,16,16,17,19,19,18,17,17,16,19,19,18,18,18,17,18,18,18,18,18,18,15,15,15,15,15,16,19,20,20,18,17,17,18,18,16,14,17,17,16,15,14,13,18,18,17,16,16,18,18,18,18,16,16,15,15,16,16,15,15,10,10,9,8,9,10,10,8,8,8,8,8,17,17,16,15,15,15,14,14,13,13,13,13,13,13,11,11,10,10,9,9,6,6,10,10,13,14,15,16,16,13,13,11,10,8,9,9,8,6,6,7,9,11,11,10,10,10,9,11,11,11,11,9,8,7,5,8,11,11,11,11,13,13,12,11,11,11,10,10,9,8,6,5,4,7,7,9,9,8, [...]
+"372",15,15,15,15,13,13,13,11,11,12,13,13,12,12,11,14,14,13,13,13,17,17,16,16,17,17,18,20,20,19,18,18,17,20,20,19,19,19,18,19,19,19,19,19,19,16,16,16,16,16,17,20,21,21,19,18,18,19,19,17,15,18,18,17,16,15,14,19,19,18,17,17,19,19,19,19,17,17,16,16,17,17,16,16,11,11,10,9,10,11,11,9,9,9,9,9,18,18,17,16,16,16,15,15,14,14,14,14,14,14,12,12,11,11,10,10,7,7,11,11,14,15,16,17,17,14,14,12,11,9,10,10,9,7,7,8,10,12,12,11,11,11,10,12,12,12,12,10,9,8,6,9,12,12,12,12,14,14,13,12,12,12,11,11,10,9,7,6,5, [...]
+"373",16,16,16,16,14,14,14,12,12,13,14,14,13,13,12,15,15,14,14,14,18,18,17,17,18,18,19,21,21,20,19,19,18,21,21,20,20,20,19,20,20,20,20,20,20,17,17,17,17,17,18,21,22,22,20,19,19,20,20,18,16,19,19,18,17,16,15,20,20,19,18,18,20,20,20,20,18,18,17,17,18,18,17,17,12,12,11,10,11,12,12,10,10,10,10,10,19,19,18,17,17,17,16,16,15,15,15,15,15,15,13,13,12,12,11,11,8,8,12,12,15,16,17,18,18,15,15,13,12,10,11,11,10,8,8,9,11,13,13,12,12,12,11,13,13,13,13,11,10,9,7,10,13,13,13,13,15,15,14,13,13,13,12,12,1 [...]
+"374",17,17,17,17,15,15,15,13,13,14,15,15,14,14,13,16,16,15,15,15,19,19,18,18,19,19,20,22,22,21,20,20,19,22,22,21,21,21,20,21,21,21,21,21,21,18,18,18,18,18,19,22,23,23,21,20,20,21,21,19,17,20,20,19,18,17,16,21,21,20,19,19,21,21,21,21,19,19,18,18,19,19,18,18,13,13,12,11,12,13,13,11,11,11,11,11,20,20,19,18,18,18,17,17,16,16,16,16,16,16,14,14,13,13,12,12,9,9,13,13,16,17,18,19,19,16,16,14,13,11,12,12,11,9,9,10,12,14,14,13,13,13,12,14,14,14,14,12,11,10,8,11,14,14,14,14,16,16,15,14,14,14,13,13 [...]
+"375",18,18,18,18,16,16,16,14,14,15,16,16,15,15,14,17,17,16,16,16,20,20,19,19,20,20,21,23,23,22,21,21,20,23,23,22,22,22,21,22,22,22,22,22,22,19,19,19,19,19,20,23,24,24,22,21,21,22,22,20,18,21,21,20,19,18,17,22,22,21,20,20,22,22,22,22,20,20,19,19,20,20,19,19,14,14,13,12,13,14,14,12,12,12,12,12,21,21,20,19,19,19,18,18,17,17,17,17,17,17,15,15,14,14,13,13,10,10,14,14,17,18,19,20,20,17,17,15,14,12,13,13,12,10,10,11,13,15,15,14,14,14,13,15,15,15,15,13,12,11,9,12,15,15,15,15,17,17,16,15,15,15,1 [...]
+"376",19,19,19,19,17,17,17,15,15,16,17,17,16,16,15,18,18,17,17,17,21,21,20,20,21,21,22,24,24,23,22,22,21,24,24,23,23,23,22,23,23,23,23,23,23,20,20,20,20,20,21,24,25,25,23,22,22,23,23,21,19,22,22,21,20,19,18,23,23,22,21,21,23,23,23,23,21,21,20,20,21,21,20,20,15,15,14,13,14,15,15,13,13,13,13,13,22,22,21,20,20,20,19,19,18,18,18,18,18,18,16,16,15,15,14,14,11,11,15,15,18,19,20,21,21,18,18,16,15,13,14,14,13,11,11,12,14,16,16,15,15,15,14,16,16,16,16,14,13,12,10,13,16,16,16,16,18,18,17,16,16,16, [...]
+"377",20,20,20,20,18,18,18,16,16,17,18,18,17,17,16,19,19,18,18,18,22,22,21,21,22,22,23,25,25,24,23,23,22,25,25,24,24,24,23,24,24,24,24,24,24,21,21,21,21,21,22,25,26,26,24,23,23,24,24,22,20,23,23,22,21,20,19,24,24,23,22,22,24,24,24,24,22,22,21,21,22,22,21,21,16,16,15,14,15,16,16,14,14,14,14,14,23,23,22,21,21,21,20,20,19,19,19,19,19,19,17,17,16,16,15,15,12,12,16,16,19,20,21,22,22,19,19,17,16,14,15,15,14,12,12,13,15,17,17,16,16,16,15,17,17,17,17,15,14,13,11,14,17,17,17,17,19,19,18,17,17,17, [...]
+"378",19,19,19,19,17,17,17,15,15,16,17,17,16,16,15,18,18,17,17,17,21,21,20,20,21,21,22,24,24,23,22,22,21,24,24,23,23,23,22,23,23,23,23,23,23,20,20,20,20,20,21,24,25,25,23,22,22,23,23,21,19,22,22,21,20,19,18,23,23,22,21,21,23,23,23,23,21,21,20,20,21,21,20,20,15,15,14,13,14,15,15,13,13,13,13,13,22,22,21,20,20,20,19,19,18,18,18,18,18,18,16,16,15,15,14,14,11,11,15,15,18,19,20,21,21,18,18,16,15,13,14,14,13,11,11,12,14,16,16,15,15,15,14,16,16,16,16,14,13,12,10,13,16,16,16,16,18,18,17,16,16,16, [...]
+"379",15,15,15,15,13,13,13,11,11,12,13,13,12,12,11,14,14,13,13,13,17,17,16,16,17,17,18,20,20,19,18,18,17,20,20,19,19,19,18,19,19,19,19,19,19,16,16,16,16,16,17,20,21,21,19,18,18,19,19,17,15,18,18,17,16,15,14,19,19,18,17,17,19,19,19,19,17,17,16,16,17,17,16,16,11,11,10,9,10,11,11,9,9,9,9,9,18,18,17,16,16,16,15,15,14,14,14,14,14,14,12,12,11,11,10,10,7,7,11,11,14,15,16,17,17,14,14,12,11,9,10,10,9,7,7,8,10,12,12,11,11,11,10,12,12,12,12,10,9,8,6,9,12,12,12,12,14,14,13,12,12,12,11,11,10,9,7,6,5, [...]
+"380",16,16,16,16,14,14,14,12,12,13,14,14,13,13,12,15,15,14,14,14,18,18,17,17,18,18,19,21,21,20,19,19,18,21,21,20,20,20,19,20,20,20,20,20,20,17,17,17,17,17,18,21,22,22,20,19,19,20,20,18,16,19,19,18,17,16,15,20,20,19,18,18,20,20,20,20,18,18,17,17,18,18,17,17,12,12,11,10,11,12,12,10,10,10,10,10,19,19,18,17,17,17,16,16,15,15,15,15,15,15,13,13,12,12,11,11,8,8,12,12,15,16,17,18,18,15,15,13,12,10,11,11,10,8,8,9,11,13,13,12,12,12,11,13,13,13,13,11,10,9,7,10,13,13,13,13,15,15,14,13,13,13,12,12,1 [...]
+"381",17,17,17,17,15,15,15,13,13,14,15,15,14,14,13,16,16,15,15,15,19,19,18,18,19,19,20,22,22,21,20,20,19,22,22,21,21,21,20,21,21,21,21,21,21,18,18,18,18,18,19,22,23,23,21,20,20,21,21,19,17,20,20,19,18,17,16,21,21,20,19,19,21,21,21,21,19,19,18,18,19,19,18,18,13,13,12,11,12,13,13,11,11,11,11,11,20,20,19,18,18,18,17,17,16,16,16,16,16,16,14,14,13,13,12,12,9,9,13,13,16,17,18,19,19,16,16,14,13,11,12,12,11,9,9,10,12,14,14,13,13,13,12,14,14,14,14,12,11,10,8,11,14,14,14,14,16,16,15,14,14,14,13,13 [...]
+"382",18,18,18,18,16,16,16,14,14,15,16,16,15,15,14,17,17,16,16,16,20,20,19,19,20,20,21,23,23,22,21,21,20,23,23,22,22,22,21,22,22,22,22,22,22,19,19,19,19,19,20,23,24,24,22,21,21,22,22,20,18,21,21,20,19,18,17,22,22,21,20,20,22,22,22,22,20,20,19,19,20,20,19,19,14,14,13,12,13,14,14,12,12,12,12,12,21,21,20,19,19,19,18,18,17,17,17,17,17,17,15,15,14,14,13,13,10,10,14,14,17,18,19,20,20,17,17,15,14,12,13,13,12,10,10,11,13,15,15,14,14,14,13,15,15,15,15,13,12,11,9,12,15,15,15,15,17,17,16,15,15,15,1 [...]
+"383",19,19,19,19,17,17,17,15,15,16,17,17,16,16,15,18,18,17,17,17,21,21,20,20,21,21,22,24,24,23,22,22,21,24,24,23,23,23,22,23,23,23,23,23,23,20,20,20,20,20,21,24,25,25,23,22,22,23,23,21,19,22,22,21,20,19,18,23,23,22,21,21,23,23,23,23,21,21,20,20,21,21,20,20,15,15,14,13,14,15,15,13,13,13,13,13,22,22,21,20,20,20,19,19,18,18,18,18,18,18,16,16,15,15,14,14,11,11,15,15,18,19,20,21,21,18,18,16,15,13,14,14,13,11,11,12,14,16,16,15,15,15,14,16,16,16,16,14,13,12,10,13,16,16,16,16,18,18,17,16,16,16, [...]
+"384",16,16,16,16,14,14,14,12,12,13,14,14,13,13,12,15,15,14,14,14,18,18,17,17,18,18,19,21,21,20,19,19,18,21,21,20,20,20,19,20,20,20,20,20,20,17,17,17,17,17,18,21,22,22,20,19,19,20,20,18,16,19,19,18,17,16,15,20,20,19,18,18,20,20,20,20,18,18,17,17,18,18,17,17,12,12,11,10,11,12,12,10,10,10,10,10,19,19,18,17,17,17,16,16,15,15,15,15,15,15,13,13,12,12,11,11,8,8,12,12,15,16,17,18,18,15,15,13,12,10,11,11,10,8,8,9,11,13,13,12,12,12,11,13,13,13,13,11,10,9,7,10,13,13,13,13,15,15,14,13,13,13,12,12,1 [...]
+"385",17,17,17,17,15,15,15,13,13,14,15,15,14,14,13,16,16,15,15,15,19,19,18,18,19,19,20,22,22,21,20,20,19,22,22,21,21,21,20,21,21,21,21,21,21,18,18,18,18,18,19,22,23,23,21,20,20,21,21,19,17,20,20,19,18,17,16,21,21,20,19,19,21,21,21,21,19,19,18,18,19,19,18,18,13,13,12,11,12,13,13,11,11,11,11,11,20,20,19,18,18,18,17,17,16,16,16,16,16,16,14,14,13,13,12,12,9,9,13,13,16,17,18,19,19,16,16,14,13,11,12,12,11,9,9,10,12,14,14,13,13,13,12,14,14,14,14,12,11,10,8,11,14,14,14,14,16,16,15,14,14,14,13,13 [...]
diff --git a/dendropy/test/data/other/laurasiatherian.distances.ml.csv b/dendropy/test/data/other/laurasiatherian.distances.ml.csv
new file mode 100644
index 0000000..26862cd
--- /dev/null
+++ b/dendropy/test/data/other/laurasiatherian.distances.ml.csv
@@ -0,0 +1,48 @@
+,Platypus,Wallaroo,Possum,Bandicoot,Opposum,Armadillo,Elephant,Aardvark,Tenrec,Hedghog,Gymnure,Mole,Shrew,Rbat,FlyingFox,RyFlyFox,FruitBat,LongTBat,Horse,Donkey,WhiteRhino,IndianRhin,Pig,Alpaca,Cow,Sheep,Hippo,FinWhale,BlueWhale,SpermWhale,Rabbit,Pika,Squirrel,Dormouse,GuineaPig,Mouse,Vole,CaneRat,Baboon,Human,Loris,Cebus,Cat,Dog,HarbSeal,FurSeal,GraySeal
+Platypus,0,0.202845210923869,0.205322845661625,0.194237383140155,0.207808692433961,0.247869343494816,0.262456513206709,0.230560050781501,0.228850891802255,0.251819608662095,0.234419959229757,0.222899323090599,0.213641245089358,0.234850066768426,0.235711022523755,0.233131114576337,0.237004312109921,0.248307235785755,0.228850891802255,0.228850891802255,0.231844480951286,0.227997770709272,0.225019465845213,0.236572967741453,0.221630108290447,0.21951951170973,0.231844480951286,0.229277816532 [...]
+Wallaroo,0.202845210923869,0,0.0598944214864539,0.0746901760075418,0.0897837004908082,0.215316053880236,0.237867745792851,0.204083005180896,0.213641245089358,0.21909810419759,0.21405959679453,0.193829940511636,0.194237383140155,0.19546104078753,0.198733922021161,0.197504917239796,0.204909337725581,0.211136023553331,0.197914361770233,0.196277923101098,0.186937068640214,0.193422719108934,0.197504917239796,0.210302805858967,0.189362619871691,0.190172883286084,0.19914403823097,0.209470512806 [...]
+Possum,0.205322845661625,0.0598944214864539,0,0.0757334125267401,0.096550931491202,0.205736581708526,0.232273113624761,0.201609456147525,0.211136023553331,0.215735341102896,0.219098104197591,0.181307769997158,0.188553230881765,0.191389922092698,0.18976764215776,0.192202379856645,0.196277923101098,0.202845210923869,0.190984023016359,0.188148863706584,0.175720408782722,0.178908087907314,0.184519336526338,0.204909337725581,0.181307769997158,0.186130291636238,0.195869370728201,0.199144038230 [...]
+Bandicoot,0.194237383140155,0.0746901760075418,0.0757334125267401,0,0.086952506849177,0.208223802448709,0.236572967741453,0.196277923101098,0.210719298997534,0.216154862859045,0.204909337725581,0.183715154704216,0.174528513418644,0.18976764215776,0.190172883286084,0.190578343493283,0.198733922021161,0.197504917239796,0.19546104078753,0.194645047234986,0.182911834236466,0.180507022556887,0.197504917239796,0.196277923101098,0.187340782820329,0.187744714431009,0.201197989946009,0.2024330663 [...]
+Opposum,0.207808692433961,0.0897837004908082,0.096550931491202,0.086952506849177,0,0.213641245089358,0.241331455225235,0.206150546118097,0.222899323090599,0.22842420995317,0.217835300475655,0.19955437882389,0.199964944045584,0.211552979783667,0.203257582068278,0.203670180070707,0.216154862859045,0.211970167946281,0.19546104078753,0.197095696113834,0.193422719108934,0.193422719108934,0.203257582068278,0.212805241101446,0.191796040960074,0.194237383140155,0.208223802448709,0.20947051280642 [...]
+Armadillo,0.247869343494816,0.215316053880236,0.205736581708526,0.208223802448709,0.213641245089358,0,0.195869370728201,0.16349455636054,0.190984023016359,0.197914361770233,0.197914361770233,0.150310812472035,0.165845348411812,0.160371585029746,0.165060932076743,0.168597284404593,0.171359355131249,0.186533571656709,0.147625044158755,0.149926541937178,0.146476938308834,0.146859445010992,0.148774910232975,0.164277335296568,0.151849866494222,0.158037860859725,0.168597284404593,0.17413163551 [...]
+Elephant,0.262456513206709,0.237867745792851,0.232273113624761,0.236572967741453,0.241331455225235,0.195869370728201,0,0.178508886301082,0.202845210923869,0.227997770709272,0.217835300475655,0.183715154704216,0.187744714431009,0.193015718691946,0.182911834236466,0.184519336526338,0.199144038230971,0.210719298997534,0.174925601449098,0.170569153556768,0.179307502109271,0.179307502109271,0.182510496434247,0.19546104078753,0.184921751022914,0.187744714431009,0.195461040787531,0.197914361770 [...]
+Aardvark,0.230560050781501,0.204083005180896,0.201609456147525,0.196277923101098,0.206150546118097,0.16349455636054,0.178508886301082,0,0.167023513335332,0.192202379856645,0.172150390141956,0.138867488125073,0.141522022560998,0.144948859338867,0.143423887406691,0.145712509653028,0.147625044158755,0.159592869839737,0.139624968305608,0.139624968305608,0.141142227642134,0.143423887406691,0.140003995477289,0.148774910232976,0.148391425627918,0.143423887406691,0.156873716272093,0.154937481816 [...]
+Tenrec,0.228850891802255,0.213641245089358,0.211136023553331,0.210719298997534,0.222899323090599,0.190984023016359,0.202845210923869,0.167023513335332,0,0.215735341102896,0.204083005180896,0.166630586017896,0.168597284404593,0.184117137830548,0.178908087907314,0.185324381551977,0.184117137830548,0.191389922092698,0.176118128532199,0.176516059301581,0.169385410051792,0.172942260348817,0.170964150274259,0.186130291636238,0.175720408782722,0.175322899829465,0.181708464543887,0.1793075021092 [...]
+Hedghog,0.251819608662095,0.21909810419759,0.215735341102896,0.216154862859045,0.22842420995317,0.197914361770233,0.227997770709272,0.192202379856645,0.215735341102896,0,0.170569153556768,0.161931445204662,0.161931445204662,0.166630586017896,0.158037860859724,0.16271259356326,0.173338509202308,0.180106969206957,0.167023513335331,0.170174364759654,0.159592869839737,0.161541175910048,0.163103473050935,0.174925601449098,0.167809986077475,0.172150390141956,0.182911834236466,0.180106969206957 [...]
+Gymnure,0.234419959229757,0.21405959679453,0.219098104197591,0.204909337725581,0.217835300475655,0.197914361770233,0.217835300475655,0.172150390141956,0.204083005180896,0.170569153556768,0,0.140003995477289,0.151464806801513,0.16349455636054,0.161541175910048,0.160371585029746,0.166630586017896,0.186533571656709,0.162321917685172,0.158037860859724,0.159203815233684,0.156873716272093,0.161541175910048,0.172150390141956,0.165060932076743,0.157649611854031,0.172546220735654,0.16820353193459 [...]
+Mole,0.222899323090599,0.193829940511636,0.181307769997158,0.183715154704216,0.19955437882389,0.150310812472035,0.183715154704216,0.138867488125073,0.166630586017896,0.161931445204662,0.140003995477289,0,0.0940506315210736,0.106273790020137,0.0994186611172541,0.0958357091220631,0.12017493178573,0.140383214294621,0.108088233871112,0.10736192949284,0.100496893002975,0.0997778995386835,0.117594759687001,0.121653310975766,0.119436833559102,0.124247507509099,0.133962427250837,0.11980579187425 [...]
+Shrew,0.213641245089358,0.194237383140155,0.188553230881765,0.174528513418644,0.199964944045584,0.165845348411812,0.187744714431009,0.141522022560998,0.168597284404593,0.161931445204662,0.151464806801513,0.0940506315210736,0,0.109907077978247,0.11282643454104,0.111000505459005,0.126850708337525,0.141522022560998,0.104825388845781,0.108088233871112,0.107361929492841,0.105911427408909,0.121653310975766,0.124618840602462,0.112460892922984,0.114656819830257,0.124990357637922,0.12128344288788 [...]
+Rbat,0.234850066768426,0.19546104078753,0.191389922092698,0.18976764215776,0.211552979783667,0.160371585029746,0.193015718691946,0.144948859338867,0.184117137830548,0.166630586017896,0.16349455636054,0.106273790020137,0.109907077978247,0,0.0936941252755017,0.0997778995386835,0.104825388845781,0.129089237545671,0.0958357091220633,0.0961932350494631,0.101216576397529,0.0997778995386834,0.112460892922984,0.12017493178573,0.116859195082252,0.122023361556851,0.127969137773072,0.13245960896466 [...]
+FlyingFox,0.235711022523755,0.198733922021161,0.18976764215776,0.190172883286084,0.203257582068278,0.165060932076743,0.182911834236466,0.143423887406691,0.178908087907314,0.158037860859724,0.161541175910048,0.0994186611172541,0.11282643454104,0.0936941252755017,0,0.0285321295764088,0.11502343354891,0.135845194651033,0.0979834256595283,0.0954783535465113,0.102297398008861,0.09762504553086,0.114290385231543,0.127596142614321,0.11502343354891,0.118331046407075,0.133962427250837,0.1272233328 [...]
+RyFlyFox,0.233131114576337,0.197504917239796,0.192202379856645,0.190578343493283,0.203670180070707,0.168597284404593,0.184519336526338,0.145712509653028,0.185324381551977,0.16271259356326,0.160371585029746,0.0958357091220631,0.111000505459005,0.0997778995386835,0.0285321295764088,0,0.116859195082252,0.13546826286775,0.100137310112233,0.100137310112232,0.105549239788686,0.101936951047701,0.117226887208748,0.121653310975766,0.119068056661691,0.127223332863884,0.134714967135873,0.1261060142 [...]
+FruitBat,0.237004312109921,0.204909337725581,0.196277923101098,0.198733922021161,0.216154862859045,0.171359355131249,0.199144038230971,0.147625044158755,0.184117137830548,0.173338509202308,0.166630586017896,0.12017493178573,0.126850708337525,0.104825388845781,0.11502343354891,0.116859195082252,0,0.135468262867751,0.120544253472376,0.11649168313076,0.119436833559102,0.120544253472376,0.124247507509099,0.131709327546591,0.127969137773072,0.125733944264702,0.146476938308834,0.13095979594142 [...]
+LongTBat,0.248307235785755,0.211136023553331,0.202845210923869,0.197504917239796,0.211970167946281,0.186533571656709,0.210719298997534,0.159592869839737,0.191389922092698,0.180106969206957,0.186533571656709,0.140383214294621,0.141522022560998,0.129089237545671,0.135845194651033,0.13546826286775,0.135468262867751,0,0.1445673255649,0.143423887406691,0.136222315966333,0.13021101265197,0.144948859338866,0.155711375861221,0.147625044158755,0.145712509653028,0.156873716272093,0.148391425627918 [...]
+Horse,0.228850891802255,0.197914361770233,0.190984023016359,0.19546104078753,0.19546104078753,0.147625044158755,0.174925601449098,0.139624968305608,0.176118128532199,0.167023513335331,0.162321917685172,0.108088233871112,0.104825388845781,0.0958357091220633,0.0979834256595283,0.100137310112233,0.120544253472376,0.1445673255649,0,0.0181479723468165,0.0746901760075416,0.0733014474542999,0.098341977118491,0.106999040892559,0.111365335820084,0.109907077978247,0.11282643454104,0.11539022656270 [...]
+Donkey,0.228850891802255,0.196277923101098,0.188148863706584,0.194645047234986,0.197095696113834,0.149926541937178,0.170569153556768,0.139624968305608,0.176516059301581,0.170174364759654,0.158037860859724,0.10736192949284,0.108088233871112,0.0961932350494631,0.0954783535465113,0.100137310112232,0.11649168313076,0.143423887406691,0.0181479723468165,0,0.0802709481823445,0.0767781021907177,0.0969087986100042,0.111000505459005,0.110271376710364,0.111730343735793,0.115757199047086,0.113192154 [...]
+WhiteRhino,0.231844480951286,0.186937068640214,0.175720408782722,0.182911834236466,0.193422719108934,0.146476938308834,0.179307502109271,0.141142227642134,0.169385410051792,0.159592869839737,0.159203815233684,0.100496893002975,0.107361929492841,0.101216576397529,0.102297398008861,0.105549239788686,0.119436833559102,0.136222315966333,0.0746901760075416,0.0802709481823445,0,0.0453849148666674,0.100496893002975,0.113192154406875,0.108451649989671,0.113192154406875,0.113192154406875,0.116859 [...]
+IndianRhin,0.227997770709272,0.193422719108934,0.178908087907314,0.180507022556887,0.193422719108934,0.146859445010992,0.179307502109271,0.143423887406691,0.172942260348817,0.161541175910048,0.156873716272093,0.0997778995386835,0.105911427408909,0.0997778995386834,0.09762504553086,0.101936951047701,0.120544253472376,0.13021101265197,0.0733014474542999,0.0767781021907177,0.0453849148666674,0,0.0961932350494629,0.108815242288635,0.102658018282668,0.105911427408909,0.111730343735793,0.11319 [...]
+Pig,0.225019465845213,0.197504917239796,0.184519336526338,0.197504917239796,0.203257582068278,0.148774910232975,0.182510496434247,0.140003995477289,0.170964150274259,0.163103473050935,0.161541175910048,0.117594759687001,0.121653310975766,0.112460892922984,0.114290385231543,0.117226887208748,0.124247507509099,0.144948859338866,0.098341977118491,0.0969087986100042,0.100496893002975,0.0961932350494629,0,0.115390226562701,0.105187226990539,0.108088233871113,0.116124351177782,0.10374092064863 [...]
+Alpaca,0.236572967741453,0.210302805858967,0.204909337725581,0.196277923101098,0.212805241101446,0.164277335296568,0.19546104078753,0.148774910232976,0.186130291636238,0.174925601449098,0.172150390141956,0.121653310975766,0.124618840602462,0.12017493178573,0.127596142614321,0.121653310975766,0.131709327546591,0.155711375861221,0.106999040892559,0.111000505459005,0.113192154406875,0.108815242288635,0.115390226562701,0,0.111365335820084,0.114290385231542,0.112095529379039,0.117962812694019 [...]
+Cow,0.221630108290447,0.189362619871691,0.181307769997158,0.187340782820329,0.191796040960074,0.151849866494222,0.184921751022914,0.148391425627918,0.175720408782722,0.167809986077475,0.165060932076743,0.119436833559102,0.112460892922984,0.116859195082252,0.11502343354891,0.119068056661691,0.127969137773072,0.147625044158755,0.111365335820084,0.110271376710364,0.108451649989671,0.102658018282668,0.105187226990539,0.111365335820084,0,0.056155884233671,0.111365335820084,0.10917901093891,0. [...]
+Sheep,0.21951951170973,0.190172883286084,0.186130291636238,0.187744714431009,0.194237383140155,0.158037860859725,0.187744714431009,0.143423887406691,0.175322899829465,0.172150390141956,0.157649611854031,0.124247507509099,0.114656819830257,0.122023361556851,0.118331046407075,0.127223332863884,0.125733944264702,0.145712509653028,0.109907077978247,0.111730343735793,0.113192154406875,0.105911427408909,0.108088233871113,0.114290385231542,0.056155884233671,0,0.107724993762305,0.106999040892559 [...]
+Hippo,0.231844480951286,0.19914403823097,0.195869370728201,0.201197989946009,0.208223802448709,0.168597284404593,0.195461040787531,0.156873716272093,0.181708464543887,0.182911834236466,0.172546220735654,0.133962427250837,0.124990357637922,0.127969137773072,0.133962427250837,0.134714967135873,0.146476938308834,0.156873716272093,0.11282643454104,0.115757199047086,0.113192154406875,0.111730343735793,0.116124351177782,0.112095529379039,0.111365335820084,0.107724993762305,0,0.107724993762305, [...]
+FinWhale,0.229277816532724,0.209470512806429,0.19914403823097,0.202433066388151,0.209470512806429,0.174131635515481,0.197914361770233,0.15493748181603,0.179307502109271,0.180106969206957,0.168203531934596,0.119805791874255,0.121283442887885,0.132459608964669,0.127223332863884,0.126106014221483,0.130959795941422,0.148391425627918,0.115390226562701,0.113192154406875,0.116859195082252,0.113192154406875,0.103740920648637,0.117962812694019,0.10917901093891,0.106999040892559,0.107724993762305, [...]
+BlueWhale,0.222052941282619,0.199144038230971,0.193829940511636,0.195052933037017,0.207393812047223,0.170174364759654,0.195461040787531,0.153006233162977,0.174528513418644,0.178109897064382,0.165845348411812,0.1186994610037,0.120913757113302,0.131334468111073,0.125362058797804,0.126106014221483,0.126478268851287,0.150695279992949,0.113924129577823,0.111730343735793,0.110635852479899,0.108815242288635,0.102297398008861,0.116124351177782,0.106636327791547,0.105549239788686,0.10990707797824 [...]
+SpermWhale,0.235280421105295,0.208639142345798,0.196277923101098,0.203670180070708,0.21197016794628,0.174131635515481,0.201609456147525,0.161541175910048,0.182510496434247,0.183313386916384,0.176516059301582,0.123134610062407,0.128342318524645,0.133962427250837,0.128715685053824,0.132835031322653,0.136977127956071,0.16271259356326,0.11502343354891,0.117962812694019,0.116859195082252,0.118331046407075,0.112460892922984,0.11649168313076,0.111000505459004,0.109907077978247,0.11649168313076, [...]
+Rabbit,0.217835300475655,0.187744714431009,0.186130291636238,0.184519336526338,0.202845210923869,0.170964150274259,0.190172883286084,0.143804839795834,0.176118128532199,0.172942260348817,0.169779783664139,0.125733944264702,0.126850708337525,0.136599627004349,0.146476938308834,0.141902009902882,0.138867488125073,0.161151109589983,0.134338602807312,0.133586440277177,0.127223332863884,0.130959795941422,0.136977127956072,0.139246132585974,0.140762624951505,0.137732700366027,0.151079944701984 [...]
+Pika,0.223322872445354,0.206564739142568,0.202021148212205,0.203670180070707,0.218255998845963,0.171359355131249,0.202021148212205,0.159592869839737,0.180907289410951,0.192202379856645,0.188148863706584,0.148391425627918,0.148774910232975,0.144567325564901,0.148774910232976,0.150310812472035,0.158814962340982,0.176118128532199,0.151849866494222,0.154164385497093,0.144185985782946,0.146476938308834,0.151079944701984,0.160371585029746,0.160371585029746,0.159982126368522,0.163103473050935,0 [...]
+Squirrel,0.222476012792921,0.199964944045584,0.193015718691946,0.191796040960074,0.20988654388075,0.173338509202309,0.198733922021161,0.163103473050935,0.177711119971376,0.179307502109271,0.188957816191644,0.149926541937178,0.145330587302318,0.156098622545957,0.161151109589983,0.164669031349341,0.165845348411812,0.174131635515481,0.15223512398311,0.154164385497093,0.151079944701984,0.146094626589074,0.153392085261519,0.163494556360539,0.156098622545957,0.155324329019965,0.169385410051792 [...]
+Dormouse,0.239597600963648,0.211136023553331,0.205736581708526,0.204496057648999,0.218255998845963,0.175322899829465,0.208223802448709,0.163885843704748,0.202021148212205,0.191389922092698,0.188553230881766,0.144185985782946,0.138867488125073,0.148774910232975,0.154164385497093,0.15493748181603,0.164277335296568,0.169779783664139,0.147625044158755,0.146859445010992,0.146859445010992,0.147625044158755,0.159592869839737,0.164277335296569,0.145330587302318,0.151849866494222,0.16702351333533 [...]
+GuineaPig,0.233560483415887,0.202021148212205,0.198733922021161,0.197914361770233,0.20988654388075,0.193015718691946,0.205322845661625,0.168991243704524,0.188957816191644,0.197504917239796,0.191389922092698,0.146094626589074,0.155324329019965,0.164277335296568,0.163494556360539,0.160761246033446,0.168597284404593,0.184117137830548,0.162321917685172,0.161151109589983,0.157649611854031,0.155324329019965,0.17135935513125,0.167416646616512,0.158814962340982,0.16271259356326,0.167809986077475 [...]
+Mouse,0.240897615733746,0.202433066388151,0.199964944045584,0.20037573414212,0.204083005180897,0.191389922092698,0.216994611022351,0.173734967517342,0.202021148212205,0.191389922092699,0.191796040960074,0.160371585029746,0.16271259356326,0.170569153556768,0.168991243704524,0.170964150274259,0.181307769997158,0.186130291636238,0.168991243704524,0.168991243704524,0.163885843704748,0.170174364759654,0.174131635515481,0.180507022556887,0.171754768347209,0.177711119971376,0.18976764215776,0.1 [...]
+Vole,0.237435904698438,0.199964944045584,0.202845210923869,0.205322845661625,0.216154862859045,0.18976764215776,0.225019465845213,0.180907289410951,0.197914361770233,0.20037573414212,0.188553230881765,0.158037860859724,0.156098622545957,0.164277335296568,0.165845348411812,0.169385410051792,0.184921751022913,0.186130291636238,0.168597284404593,0.168203531934596,0.168597284404593,0.168991243704524,0.170569153556768,0.183715154704216,0.178109897064382,0.175322899829465,0.182911834236466,0.1 [...]
+CaneRat,0.249183788113435,0.206564739142568,0.211136023553331,0.197504917239796,0.210719298997534,0.18976764215776,0.199964944045584,0.178508886301082,0.190984023016359,0.193422719108935,0.182510496434247,0.15764961185403,0.159982126368522,0.166237864448509,0.164277335296568,0.166237864448509,0.177711119971376,0.185727228345602,0.158814962340982,0.159982126368522,0.155711375861221,0.156873716272093,0.168597284404593,0.169385410051792,0.163885843704748,0.164669031349341,0.180106969206957, [...]
+Baboon,0.26334976923012,0.230560050781501,0.224594957555969,0.227145618934598,0.241765545817588,0.204083005180897,0.21909810419759,0.192202379856645,0.219941156134048,0.212805241101446,0.205322845661625,0.178109897064382,0.174925601449098,0.178109897064381,0.176516059301581,0.183313386916384,0.185727228345602,0.19955437882389,0.167809986077474,0.168597284404593,0.165453037692784,0.161931445204662,0.17175476834721,0.191389922092698,0.176914201314913,0.181307769997158,0.184519336526338,0.1 [...]
+Human,0.254464725290708,0.215316053880236,0.206979161034588,0.21197016794628,0.234419959229757,0.181708464543887,0.21322312661163,0.179707129133512,0.211136023553331,0.195052933037017,0.199964944045584,0.157261563727407,0.160761246033446,0.167416646616512,0.168203531934596,0.17175476834721,0.170569153556768,0.182911834236467,0.156486069280649,0.158426310952572,0.152620579471486,0.15493748181603,0.168991243704525,0.174925601449098,0.161541175910048,0.168203531934596,0.168991243704525,0.17 [...]
+Loris,0.246994325166016,0.205322845661625,0.201197989946009,0.20037573414212,0.208639142345798,0.174925601449098,0.204909337725581,0.163494556360539,0.191796040960074,0.188148863706584,0.180106969206957,0.137732700366027,0.141522022560998,0.144948859338867,0.14266256263633,0.143043128418947,0.159203815233685,0.177711119971376,0.135091520426072,0.138110772207682,0.140762624951505,0.142282189862867,0.148391425627919,0.159203815233685,0.157261563727407,0.150310812472035,0.159203815233685,0. [...]
+Cebus,0.248745383892272,0.217835300475655,0.209470512806429,0.205736581708526,0.223746661127345,0.196686698148688,0.213641245089358,0.169779783664139,0.21197016794628,0.201197989946009,0.192202379856645,0.157261563727407,0.156873716272093,0.163494556360539,0.156098622545957,0.156873716272093,0.181708464543887,0.180507022556887,0.15455083404358,0.154164385497093,0.148391425627918,0.146859445010992,0.165060932076743,0.167416646616512,0.163103473050935,0.163103473050935,0.167416646616512,0. [...]
+Cat,0.221630108290447,0.193015718691946,0.188148863706584,0.187744714431009,0.196686698148688,0.159592869839737,0.176516059301581,0.13546826286775,0.165453037692784,0.164277335296568,0.15493748181603,0.0994186611172541,0.10736192949284,0.110271376710364,0.103018812035868,0.102658018282668,0.134338602807313,0.140383214294621,0.0894292162587574,0.0915586391963938,0.095835709122063,0.0965509314912019,0.102297398008861,0.118331046407075,0.105549239788687,0.112460892922985,0.124990357637922,0 [...]
+Dog,0.222476012792921,0.192202379856645,0.186130291636238,0.188553230881765,0.195052933037017,0.163103473050935,0.181307769997159,0.133210641697349,0.161541175910048,0.167023513335331,0.166237864448509,0.111000505459004,0.10736192949284,0.117594759687001,0.110635852479899,0.111000505459005,0.130585310850631,0.145712509653028,0.095835709122063,0.0990595946831067,0.105549239788687,0.108451649989671,0.111000505459005,0.124990357637922,0.114290385231543,0.11649168313076,0.126850708337525,0.1 [...]
+HarbSeal,0.21951951170973,0.193829940511636,0.190984023016359,0.193829940511636,0.204909337725581,0.150310812472035,0.174528513418644,0.132835031322653,0.169385410051792,0.16271259356326,0.154164385497094,0.113192154406876,0.11649168313076,0.118331046407075,0.111365335820084,0.117962812694019,0.139624968305608,0.143804839795834,0.104102235842907,0.105911427408909,0.103379779435448,0.106999040892559,0.109542956111646,0.119068056661691,0.11502343354891,0.115390226562701,0.126850708337525,0 [...]
+FurSeal,0.233990098206383,0.205736581708526,0.200375734142119,0.202433066388151,0.219519511709731,0.168991243704524,0.191389922092698,0.1445673255649,0.175720408782722,0.176118128532199,0.161541175910048,0.124990357637922,0.126478268851287,0.120913757113302,0.128715685053824,0.128715685053824,0.146476938308834,0.159203815233684,0.115390226562701,0.115390226562701,0.115757199047087,0.117226887208748,0.12017493178573,0.127969137773072,0.123134610062407,0.122764010919598,0.134714967135873,0 [...]
+GraySeal,0.225019465845213,0.196277923101098,0.194237383140154,0.195869370728201,0.208223802448709,0.153006233162976,0.178109897064382,0.136599627004349,0.176118128532199,0.165060932076743,0.156873716272093,0.118699461003701,0.118331046407075,0.120544253472376,0.114290385231543,0.12017493178573,0.143043128418947,0.148008137003248,0.106273790020137,0.108815242288635,0.105911427408909,0.10917901093891,0.11282643454104,0.120544253472376,0.119068056661691,0.117962812694019,0.12983690115899,0 [...]
diff --git a/dendropy/test/data/other/pythonidae.mle.node-to-node-dists.csv b/dendropy/test/data/other/pythonidae.mle.node-to-node-dists.csv
new file mode 100644
index 0000000..20db026
--- /dev/null
+++ b/dendropy/test/data/other/pythonidae.mle.node-to-node-dists.csv
@@ -0,0 +1,65 @@
+"","1","2","3","4","5","6","7","8","9","10","11","12","13","14","15","16","17","18","19","20","21","22","23","24","25","26","27","28","29","30","31","32","33","34","35","36","37","38","39","40","41","42","43","44","45","46","47","48","49","50","51","52","53","54","55","56","57","58","59","60","61","62","63","64"
+"1",0,0.206680834,0.1772956722,0.2287647687,0.2888683792,0.2855426181,0.3018928857,0.2944219408,0.3016418479,0.3026748597,0.29404438,0.2972777898,0.2982954816,0.3193034914,0.290858292,0.2987610245,0.2982749473,0.2973182023,0.306927251,0.3006605074,0.2766623783,0.2914095963,0.2861109173,0.2916878309,0.2861657022,0.2949165253,0.3045617969,0.2839327069,0.3041070425,0.285888581,0.4463000552,0.657224606,0.462213152,0.1994242755,0.1386352755,0.1058922755,0.1220552755,0.1437052755,0.1695872755, [...]
+"2",0.206680834,0,0.0965659552,0.1913350517,0.2837646622,0.2804389011,0.2967891687,0.2893182238,0.2965381309,0.2975711427,0.288940663,0.2921740728,0.2931917646,0.3141997744,0.285754575,0.2936573075,0.2931712303,0.2922144853,0.301823534,0.2955567904,0.2715586613,0.2863058793,0.2810072003,0.2865841139,0.2810619852,0.2898128083,0.2994580799,0.2788289899,0.2990033255,0.280784864,0.4411963382,0.652120889,0.457109435,0.1943205585,0.1335315585,0.1007885585,0.0846255585,0.0629755585,0.1644835585 [...]
+"3",0.1772956722,0.0965659552,0,0.1619498899,0.2543795004,0.2510537393,0.2674040069,0.259933062,0.2671529691,0.2681859809,0.2595555012,0.262788911,0.2638066028,0.2848146126,0.2563694132,0.2642721457,0.2637860685,0.2628293235,0.2724383722,0.2661716286,0.2421734995,0.2569207175,0.2516220385,0.2571989521,0.2516768234,0.2604276465,0.2700729181,0.2494438281,0.2696181637,0.2513997022,0.4118111764,0.6227357272,0.4277242732,0.1649353967,0.1041463967,0.0714033967,0.0552403967,0.0335903967,0.13509 [...]
+"4",0.2287647687,0.1913350517,0.1619498899,0,0.3058485969,0.3025228358,0.3188731034,0.3114021585,0.3186220656,0.3196550774,0.3110245977,0.3142580075,0.3152756993,0.3362837091,0.3078385097,0.3157412422,0.315255165,0.31429842,0.3239074687,0.3176407251,0.293642596,0.308389814,0.303091135,0.3086680486,0.3031459199,0.311896743,0.3215420146,0.3009129246,0.3210872602,0.3028687987,0.4632802729,0.6742048237,0.4791933697,0.2164044932,0.1556154932,0.1228724932,0.1067094932,0.1283594932,0.1865674932 [...]
+"5",0.2888683792,0.2837646622,0.2543795004,0.3058485969,0,0.0516584463,0.1207207139,0.113249769,0.1204696761,0.1215026879,0.1128722082,0.116105618,0.1805873098,0.2015953196,0.1731501202,0.1810528527,0.1805667755,0.1796100305,0.1892190792,0.1961563356,0.1721582065,0.1869054245,0.1816067455,0.1871836591,0.1816615304,0.1904123535,0.2000576251,0.1794285351,0.2538008707,0.2355824092,0.4578978834,0.6688224342,0.4738109802,0.2110221037,0.1502331037,0.1829761037,0.1991391037,0.2207891037,0.11928 [...]
+"6",0.2855426181,0.2804389011,0.2510537393,0.3025228358,0.0516584463,0,0.1173949528,0.1099240079,0.117143915,0.1181769268,0.1095464471,0.1127798569,0.1772615487,0.1982695585,0.1698243591,0.1777270916,0.1772410144,0.1762842694,0.1858933181,0.1928305745,0.1688324454,0.1835796634,0.1782809844,0.183857898,0.1783357693,0.1870865924,0.196731864,0.176102774,0.2504751096,0.2322566481,0.4545721223,0.6654966731,0.4704852191,0.2076963426,0.1469073426,0.1796503426,0.1958133426,0.2174633426,0.1159553 [...]
+"7",0.3018928857,0.2967891687,0.2674040069,0.3188731034,0.1207207139,0.1173949528,0,0.0681162755,0.0753361826,0.0763691944,0.0677387147,0.1205641245,0.1936118163,0.2146198261,0.1861746267,0.1940773592,0.193591282,0.192634537,0.2022435857,0.2091808421,0.185182713,0.199929931,0.194631252,0.2002081656,0.1946860369,0.20343686,0.2130821316,0.1924530416,0.2668253772,0.2486069157,0.4709223899,0.6818469407,0.4868354867,0.2240466102,0.1632576102,0.1960006102,0.2121636102,0.2338136102,0.1323056102 [...]
+"8",0.2944219408,0.2893182238,0.259933062,0.3114021585,0.113249769,0.1099240079,0.0681162755,0,0.0163092377,0.0173422495,0.0459057698,0.1130931796,0.1861408714,0.2071488812,0.1787036818,0.1866064143,0.1861203371,0.1851635921,0.1947726408,0.2017098972,0.1777117681,0.1924589861,0.1871603071,0.1927372207,0.187215092,0.1959659151,0.2056111867,0.1849820967,0.2593544323,0.2411359708,0.463451445,0.6743759958,0.4793645418,0.2165756653,0.1557866653,0.1885296653,0.2046926653,0.2263426653,0.1248346 [...]
+"9",0.3016418479,0.2965381309,0.2671529691,0.3186220656,0.1204696761,0.117143915,0.0753361826,0.0163092377,0,0.0161981566,0.0531256769,0.1203130867,0.1933607785,0.2143687883,0.1859235889,0.1938263214,0.1933402442,0.1923834992,0.2019925479,0.2089298043,0.1849316752,0.1996788932,0.1943802142,0.1999571278,0.1944349991,0.2031858222,0.2128310938,0.1922020038,0.2665743394,0.2483558779,0.4706713521,0.6815959029,0.4865844489,0.2237955724,0.1630065724,0.1957495724,0.2119125724,0.2335625724,0.1320 [...]
+"10",0.3026748597,0.2975711427,0.2681859809,0.3196550774,0.1215026879,0.1181769268,0.0763691944,0.0173422495,0.0161981566,0,0.0541586887,0.1213460985,0.1943937903,0.2154018001,0.1869566007,0.1948593332,0.194373256,0.193416511,0.2030255597,0.2099628161,0.185964687,0.200711905,0.195413226,0.2009901396,0.1954680109,0.204218834,0.2138641056,0.1932350156,0.2676073512,0.2493888897,0.4717043639,0.6826289147,0.4876174607,0.2248285842,0.1640395842,0.1967825842,0.2129455842,0.2345955842,0.13308758 [...]
+"11",0.29404438,0.288940663,0.2595555012,0.3110245977,0.1128722082,0.1095464471,0.0677387147,0.0459057698,0.0531256769,0.0541586887,0,0.1127156188,0.1857633106,0.2067713204,0.178326121,0.1862288535,0.1857427763,0.1847860313,0.19439508,0.2013323364,0.1773342073,0.1920814253,0.1867827463,0.1923596599,0.1868375312,0.1955883543,0.2052336259,0.1846045359,0.2589768715,0.24075841,0.4630738842,0.673998435,0.478986981,0.2161981045,0.1554091045,0.1881521045,0.2043151045,0.2259651045,0.1244571045,0 [...]
+"12",0.2972777898,0.2921740728,0.262788911,0.3142580075,0.116105618,0.1127798569,0.1205641245,0.1130931796,0.1203130867,0.1213460985,0.1127156188,0,0.1889967204,0.2100047302,0.1815595308,0.1894622633,0.1889761861,0.1880194411,0.1976284898,0.2045657462,0.1805676171,0.1953148351,0.1900161561,0.1955930697,0.190070941,0.1988217641,0.2084670357,0.1878379457,0.2622102813,0.2439918198,0.466307294,0.6772318448,0.4822203908,0.2194315143,0.1586425143,0.1913855143,0.2075485143,0.2291985143,0.127690 [...]
+"13",0.2982954816,0.2931917646,0.2638066028,0.3152756993,0.1805873098,0.1772615487,0.1936118163,0.1861408714,0.1933607785,0.1943937903,0.1857633106,0.1889967204,0,0.156850422,0.1284052226,0.1363079551,0.1590558779,0.1580991329,0.1677081816,0.205583438,0.1815853089,0.1963325269,0.1910338479,0.1966107615,0.1910886328,0.1998394559,0.2094847275,0.1888556375,0.2632279731,0.2450095116,0.4673249858,0.6782495366,0.4832380826,0.2204492061,0.1596602061,0.1924032061,0.2085662061,0.2302162061,0.1287 [...]
+"14",0.3193034914,0.3141997744,0.2848146126,0.3362837091,0.2015953196,0.1982695585,0.2146198261,0.2071488812,0.2143687883,0.2154018001,0.2067713204,0.2100047302,0.156850422,0,0.1237172324,0.1316199649,0.1800638877,0.1791071427,0.1887161914,0.2265914478,0.2025933187,0.2173405367,0.2120418577,0.2176187713,0.2120966426,0.2208474657,0.2304927373,0.2098636473,0.2842359829,0.2660175214,0.4883329956,0.6992575464,0.5042460924,0.2414572159,0.1806682159,0.2134112159,0.2295742159,0.2512242159,0.149 [...]
+"15",0.290858292,0.285754575,0.2563694132,0.3078385097,0.1731501202,0.1698243591,0.1861746267,0.1787036818,0.1859235889,0.1869566007,0.178326121,0.1815595308,0.1284052226,0.1237172324,0,0.0383807655,0.1516186883,0.1506619433,0.160270992,0.1981462484,0.1741481193,0.1888953373,0.1835966583,0.1891735719,0.1836514432,0.1924022663,0.2020475379,0.1814184479,0.2557907835,0.237572322,0.4598877962,0.670812347,0.475800893,0.2130120165,0.1522230165,0.1849660165,0.2011290165,0.2227790165,0.121271016 [...]
+"16",0.2987610245,0.2936573075,0.2642721457,0.3157412422,0.1810528527,0.1777270916,0.1940773592,0.1866064143,0.1938263214,0.1948593332,0.1862288535,0.1894622633,0.1363079551,0.1316199649,0.0383807655,0,0.1595214208,0.1585646758,0.1681737245,0.2060489809,0.1820508518,0.1967980698,0.1914993908,0.1970763044,0.1915541757,0.2003049988,0.2099502704,0.1893211804,0.263693516,0.2454750545,0.4677905287,0.6787150795,0.4837036255,0.220914749,0.160125749,0.192868749,0.209031749,0.230681749,0.12917374 [...]
+"17",0.2982749473,0.2931712303,0.2637860685,0.315255165,0.1805667755,0.1772410144,0.193591282,0.1861203371,0.1933402442,0.194373256,0.1857427763,0.1889761861,0.1590558779,0.1800638877,0.1516186883,0.1595214208,0,0.1311145986,0.1407236473,0.2055629037,0.1815647746,0.1963119926,0.1910133136,0.1965902272,0.1910680985,0.1998189216,0.2094641932,0.1888351032,0.2632074388,0.2449889773,0.4673044515,0.6782290023,0.4832175483,0.2204286718,0.1596396718,0.1923826718,0.2085456718,0.2301956718,0.12868 [...]
+"18",0.2973182023,0.2922144853,0.2628293235,0.31429842,0.1796100305,0.1762842694,0.192634537,0.1851635921,0.1923834992,0.193416511,0.1847860313,0.1880194411,0.1580991329,0.1791071427,0.1506619433,0.1585646758,0.1311145986,0,0.0851089023,0.2046061587,0.1806080296,0.1953552476,0.1900565686,0.1956334822,0.1901113535,0.1988621766,0.2085074482,0.1878783582,0.2622506938,0.2440322323,0.4663477065,0.6772722573,0.4822608033,0.2194719268,0.1586829268,0.1914259268,0.2075889268,0.2292389268,0.127730 [...]
+"19",0.306927251,0.301823534,0.2724383722,0.3239074687,0.1892190792,0.1858933181,0.2022435857,0.1947726408,0.2019925479,0.2030255597,0.19439508,0.1976284898,0.1677081816,0.1887161914,0.160270992,0.1681737245,0.1407236473,0.0851089023,0,0.2142152074,0.1902170783,0.2049642963,0.1996656173,0.2052425309,0.1997204022,0.2084712253,0.2181164969,0.1974874069,0.2718597425,0.253641281,0.4759567552,0.686881306,0.491869852,0.2290809755,0.1682919755,0.2010349755,0.2171979755,0.2388479755,0.1373399755 [...]
+"20",0.3006605074,0.2955567904,0.2661716286,0.3176407251,0.1961563356,0.1928305745,0.2091808421,0.2017098972,0.2089298043,0.2099628161,0.2013323364,0.2045657462,0.205583438,0.2265914478,0.1981462484,0.2060489809,0.2055629037,0.2046061587,0.2142152074,0,0.1101583347,0.1452415527,0.1399428737,0.1723637873,0.1668416586,0.1910604817,0.2007057533,0.1855026633,0.2655929989,0.2473745374,0.4696900116,0.6806145624,0.4856031084,0.2228142319,0.1620252319,0.1947682319,0.2109312319,0.2325812319,0.131 [...]
+"21",0.2766623783,0.2715586613,0.2421734995,0.293642596,0.1721582065,0.1688324454,0.185182713,0.1777117681,0.1849316752,0.185964687,0.1773342073,0.1805676171,0.1815853089,0.2025933187,0.1741481193,0.1820508518,0.1815647746,0.1806080296,0.1902170783,0.1101583347,0,0.1212434236,0.1159447446,0.1483656582,0.1428435295,0.1670623526,0.1767076242,0.1615045342,0.2415948698,0.2233764083,0.4456918825,0.6566164333,0.4616049793,0.1988161028,0.1380271028,0.1707701028,0.1869331028,0.2085831028,0.10707 [...]
+"22",0.2914095963,0.2863058793,0.2569207175,0.308389814,0.1869054245,0.1835796634,0.199929931,0.1924589861,0.1996788932,0.200711905,0.1920814253,0.1953148351,0.1963325269,0.2173405367,0.1888953373,0.1967980698,0.1963119926,0.1953552476,0.2049642963,0.1452415527,0.1212434236,0,0.0336819626,0.1631128762,0.1575907475,0.1818095706,0.1914548422,0.1762517522,0.2563420878,0.2381236263,0.4604391005,0.6713636513,0.4763521973,0.2135633208,0.1527743208,0.1855173208,0.2016803208,0.2233303208,0.12182 [...]
+"23",0.2861109173,0.2810072003,0.2516220385,0.303091135,0.1816067455,0.1782809844,0.194631252,0.1871603071,0.1943802142,0.195413226,0.1867827463,0.1900161561,0.1910338479,0.2120418577,0.1835966583,0.1914993908,0.1910133136,0.1900565686,0.1996656173,0.1399428737,0.1159447446,0.0336819626,0,0.1578141972,0.1522920685,0.1765108916,0.1861561632,0.1709530732,0.2510434088,0.2328249473,0.4551404215,0.6660649723,0.4710535183,0.2082646418,0.1474756418,0.1802186418,0.1963816418,0.2180316418,0.11652 [...]
+"24",0.2916878309,0.2865841139,0.2571989521,0.3086680486,0.1871836591,0.183857898,0.2002081656,0.1927372207,0.1999571278,0.2009901396,0.1923596599,0.1955930697,0.1966107615,0.2176187713,0.1891735719,0.1970763044,0.1965902272,0.1956334822,0.2052425309,0.1723637873,0.1483656582,0.1631128762,0.1578141972,0,0.0706169821,0.1820878052,0.1917330768,0.1765299868,0.2566203224,0.2384018609,0.4607173351,0.6716418859,0.4766304319,0.2138415554,0.1530525554,0.1857955554,0.2019585554,0.2236085554,0.122 [...]
+"25",0.2861657022,0.2810619852,0.2516768234,0.3031459199,0.1816615304,0.1783357693,0.1946860369,0.187215092,0.1944349991,0.1954680109,0.1868375312,0.190070941,0.1910886328,0.2120966426,0.1836514432,0.1915541757,0.1910680985,0.1901113535,0.1997204022,0.1668416586,0.1428435295,0.1575907475,0.1522920685,0.0706169821,0,0.1765656765,0.1862109481,0.1710078581,0.2510981937,0.2328797322,0.4551952064,0.6661197572,0.4711083032,0.2083194267,0.1475304267,0.1802734267,0.1964364267,0.2180864267,0.1165 [...]
+"26",0.2949165253,0.2898128083,0.2604276465,0.311896743,0.1904123535,0.1870865924,0.20343686,0.1959659151,0.2031858222,0.204218834,0.1955883543,0.1988217641,0.1998394559,0.2208474657,0.1924022663,0.2003049988,0.1998189216,0.1988621766,0.2084712253,0.1910604817,0.1670623526,0.1818095706,0.1765108916,0.1820878052,0.1765656765,0,0.1180737712,0.1797586812,0.2598490168,0.2416305553,0.4639460295,0.6748705803,0.4798591263,0.2170702498,0.1562812498,0.1890242498,0.2051872498,0.2268372498,0.125329 [...]
+"27",0.3045617969,0.2994580799,0.2700729181,0.3215420146,0.2000576251,0.196731864,0.2130821316,0.2056111867,0.2128310938,0.2138641056,0.2052336259,0.2084670357,0.2094847275,0.2304927373,0.2020475379,0.2099502704,0.2094641932,0.2085074482,0.2181164969,0.2007057533,0.1767076242,0.1914548422,0.1861561632,0.1917330768,0.1862109481,0.1180737712,0,0.1894039528,0.2694942884,0.2512758269,0.4735913011,0.6845158519,0.4895043979,0.2267155214,0.1659265214,0.1986695214,0.2148325214,0.2364825214,0.134 [...]
+"28",0.2839327069,0.2788289899,0.2494438281,0.3009129246,0.1794285351,0.176102774,0.1924530416,0.1849820967,0.1922020038,0.1932350156,0.1846045359,0.1878379457,0.1888556375,0.2098636473,0.1814184479,0.1893211804,0.1888351032,0.1878783582,0.1974874069,0.1855026633,0.1615045342,0.1762517522,0.1709530732,0.1765299868,0.1710078581,0.1797586812,0.1894039528,0,0.2488651984,0.2306467369,0.4529622111,0.6638867619,0.4688753079,0.2060864314,0.1452974314,0.1780404314,0.1942034314,0.2158534314,0.114 [...]
+"29",0.3041070425,0.2990033255,0.2696181637,0.3210872602,0.2538008707,0.2504751096,0.2668253772,0.2593544323,0.2665743394,0.2676073512,0.2589768715,0.2622102813,0.2632279731,0.2842359829,0.2557907835,0.263693516,0.2632074388,0.2622506938,0.2718597425,0.2655929989,0.2415948698,0.2563420878,0.2510434088,0.2566203224,0.2510981937,0.2598490168,0.2694942884,0.2488651984,0,0.1307410725,0.4731365467,0.6840610975,0.4890496435,0.226260767,0.165471767,0.198214767,0.214377767,0.236027767,0.13451976 [...]
+"30",0.285888581,0.280784864,0.2513997022,0.3028687987,0.2355824092,0.2322566481,0.2486069157,0.2411359708,0.2483558779,0.2493888897,0.24075841,0.2439918198,0.2450095116,0.2660175214,0.237572322,0.2454750545,0.2449889773,0.2440322323,0.253641281,0.2473745374,0.2233764083,0.2381236263,0.2328249473,0.2384018609,0.2328797322,0.2416305553,0.2512758269,0.2306467369,0.1307410725,0,0.4549180852,0.665842636,0.470831182,0.2080423055,0.1472533055,0.1799963055,0.1961593055,0.2178093055,0.1163013055 [...]
+"31",0.4463000552,0.4411963382,0.4118111764,0.4632802729,0.4578978834,0.4545721223,0.4709223899,0.463451445,0.4706713521,0.4717043639,0.4630738842,0.466307294,0.4673249858,0.4883329956,0.4598877962,0.4677905287,0.4673044515,0.4663477065,0.4759567552,0.4696900116,0.4456918825,0.4604391005,0.4551404215,0.4607173351,0.4551952064,0.4639460295,0.4735913011,0.4529622111,0.4731365467,0.4549180852,0,0.6076601102,0.5096646562,0.2468757797,0.3076647797,0.3404077797,0.3565707797,0.3782207797,0.3386 [...]
+"32",0.657224606,0.652120889,0.6227357272,0.6742048237,0.6688224342,0.6654966731,0.6818469407,0.6743759958,0.6815959029,0.6826289147,0.673998435,0.6772318448,0.6782495366,0.6992575464,0.670812347,0.6787150795,0.6782290023,0.6772722573,0.686881306,0.6806145624,0.6566164333,0.6713636513,0.6660649723,0.6716418859,0.6661197572,0.6748705803,0.6845158519,0.6638867619,0.6840610975,0.665842636,0.6076601102,0,0.720589207,0.4578003305,0.5185893305,0.5513323305,0.5674953305,0.5891453305,0.549541330 [...]
+"33",0.462213152,0.457109435,0.4277242732,0.4791933697,0.4738109802,0.4704852191,0.4868354867,0.4793645418,0.4865844489,0.4876174607,0.478986981,0.4822203908,0.4832380826,0.5042460924,0.475800893,0.4837036255,0.4832175483,0.4822608033,0.491869852,0.4856031084,0.4616049793,0.4763521973,0.4710535183,0.4766304319,0.4711083032,0.4798591263,0.4895043979,0.4688753079,0.4890496435,0.470831182,0.5096646562,0.720589207,0,0.2627888765,0.3235778765,0.3563208765,0.3724838765,0.3941338765,0.354529876 [...]
+"34",0.1994242755,0.1943205585,0.1649353967,0.2164044932,0.2110221037,0.2076963426,0.2240466102,0.2165756653,0.2237955724,0.2248285842,0.2161981045,0.2194315143,0.2204492061,0.2414572159,0.2130120165,0.220914749,0.2204286718,0.2194719268,0.2290809755,0.2228142319,0.1988161028,0.2135633208,0.2082646418,0.2138415554,0.2083194267,0.2170702498,0.2267155214,0.2060864314,0.226260767,0.2080423055,0.2468757797,0.4578003305,0.2627888765,0,0.060789,0.093532,0.109695,0.131345,0.091741,0.11884,0.125 [...]
+"35",0.1386352755,0.1335315585,0.1041463967,0.1556154932,0.1502331037,0.1469073426,0.1632576102,0.1557866653,0.1630065724,0.1640395842,0.1554091045,0.1586425143,0.1596602061,0.1806682159,0.1522230165,0.160125749,0.1596396718,0.1586829268,0.1682919755,0.1620252319,0.1380271028,0.1527743208,0.1474756418,0.1530525554,0.1475304267,0.1562812498,0.1659265214,0.1452974314,0.165471767,0.1472533055,0.3076647797,0.5185893305,0.3235778765,0.060789,0,0.032743,0.048906,0.070556,0.030952,0.058051,0.06 [...]
+"36",0.1058922755,0.1007885585,0.0714033967,0.1228724932,0.1829761037,0.1796503426,0.1960006102,0.1885296653,0.1957495724,0.1967825842,0.1881521045,0.1913855143,0.1924032061,0.2134112159,0.1849660165,0.192868749,0.1923826718,0.1914259268,0.2010349755,0.1947682319,0.1707701028,0.1855173208,0.1802186418,0.1857955554,0.1802734267,0.1890242498,0.1986695214,0.1780404314,0.198214767,0.1799963055,0.3404077797,0.5513323305,0.3563208765,0.093532,0.032743,0,0.016163,0.037813,0.063695,0.090794,0.09 [...]
+"37",0.1220552755,0.0846255585,0.0552403967,0.1067094932,0.1991391037,0.1958133426,0.2121636102,0.2046926653,0.2119125724,0.2129455842,0.2043151045,0.2075485143,0.2085662061,0.2295742159,0.2011290165,0.209031749,0.2085456718,0.2075889268,0.2171979755,0.2109312319,0.1869331028,0.2016803208,0.1963816418,0.2019585554,0.1964364267,0.2051872498,0.2148325214,0.1942034314,0.214377767,0.1961593055,0.3565707797,0.5674953305,0.3724838765,0.109695,0.048906,0.016163,0,0.02165,0.079858,0.106957,0.113 [...]
+"38",0.1437052755,0.0629755585,0.0335903967,0.1283594932,0.2207891037,0.2174633426,0.2338136102,0.2263426653,0.2335625724,0.2345955842,0.2259651045,0.2291985143,0.2302162061,0.2512242159,0.2227790165,0.230681749,0.2301956718,0.2292389268,0.2388479755,0.2325812319,0.2085831028,0.2233303208,0.2180316418,0.2236085554,0.2180864267,0.2268372498,0.2364825214,0.2158534314,0.236027767,0.2178093055,0.3782207797,0.5891453305,0.3941338765,0.131345,0.070556,0.037813,0.02165,0,0.101508,0.128607,0.135 [...]
+"39",0.1695872755,0.1644835585,0.1350983967,0.1865674932,0.1192811037,0.1159553426,0.1323056102,0.1248346653,0.1320545724,0.1330875842,0.1244571045,0.1276905143,0.1287082061,0.1497162159,0.1212710165,0.129173749,0.1286876718,0.1277309268,0.1373399755,0.1310732319,0.1070751028,0.1218223208,0.1165236418,0.1221005554,0.1165784267,0.1253292498,0.1349745214,0.1143454314,0.134519767,0.1163013055,0.3386167797,0.5495413305,0.3545298765,0.091741,0.030952,0.063695,0.079858,0.101508,0,0.027099,0.03 [...]
+"40",0.1966862755,0.1915825585,0.1621973967,0.2136664932,0.0921821037,0.0888563426,0.1052066102,0.0977356653,0.1049555724,0.1059885842,0.0973581045,0.1005915143,0.1016092061,0.1226172159,0.0941720165,0.102074749,0.1015886718,0.1006319268,0.1102409755,0.1039742319,0.0799761028,0.0947233208,0.0894246418,0.0950015554,0.0894794267,0.0982302498,0.1078755214,0.0872464314,0.161618767,0.1434003055,0.3657157797,0.5766403305,0.3816288765,0.11884,0.058051,0.090794,0.106957,0.128607,0.027099,0,0.006 [...]
+"41",0.2032882755,0.1981845585,0.1687993967,0.2202684932,0.0855801037,0.0822543426,0.0986046102,0.0911336653,0.0983535724,0.0993865842,0.0907561045,0.0939895143,0.0950072061,0.1160152159,0.0875700165,0.095472749,0.0949866718,0.0940299268,0.1036389755,0.1105762319,0.0865781028,0.1013253208,0.0960266418,0.1016035554,0.0960814267,0.1048322498,0.1144775214,0.0938484314,0.168220767,0.1500023055,0.3723177797,0.5832423305,0.3882308765,0.125442,0.064653,0.097396,0.113559,0.135209,0.033701,0.0066 [...]
+"42",0.2350202755,0.2299165585,0.2005313967,0.2520004932,0.0538481037,0.0505223426,0.0668726102,0.0594016653,0.0666215724,0.0676545842,0.0590241045,0.0622575143,0.1267392061,0.1477472159,0.1193020165,0.127204749,0.1267186718,0.1257619268,0.1353709755,0.1423082319,0.1183101028,0.1330573208,0.1277586418,0.1333355554,0.1278134267,0.1365642498,0.1462095214,0.1255804314,0.199952767,0.1817343055,0.4040497797,0.6149743305,0.4199628765,0.157174,0.096385,0.129128,0.145291,0.166941,0.065433,0.0383 [...]
+"43",0.2613762755,0.2562725585,0.2268873967,0.2783564932,0.0274921037,0.0241663426,0.0932286102,0.0857576653,0.0929775724,0.0940105842,0.0853801045,0.0886135143,0.1530952061,0.1741032159,0.1456580165,0.153560749,0.1530746718,0.1521179268,0.1617269755,0.1686642319,0.1446661028,0.1594133208,0.1541146418,0.1596915554,0.1541694267,0.1629202498,0.1725655214,0.1519364314,0.226308767,0.2080903055,0.4304057797,0.6413303305,0.4463188765,0.18353,0.122741,0.155484,0.171647,0.193297,0.091789,0.06469 [...]
+"44",0.2393032755,0.2341995585,0.2048143967,0.2562834932,0.0581311037,0.0548053426,0.0625896102,0.0551186653,0.0623385724,0.0633715842,0.0547411045,0.0579745143,0.1310222061,0.1520302159,0.1235850165,0.131487749,0.1310016718,0.1300449268,0.1396539755,0.1465912319,0.1225931028,0.1373403208,0.1320416418,0.1376185554,0.1320964267,0.1408472498,0.1504925214,0.1298634314,0.204235767,0.1860173055,0.4083327797,0.6192573305,0.4242458765,0.161457,0.100668,0.133411,0.149574,0.171224,0.069716,0.0426 [...]
+"45",0.2640992755,0.2589955585,0.2296103967,0.2810794932,0.0829271037,0.0796013426,0.0377936102,0.0303226653,0.0375425724,0.0385755842,0.0299451045,0.0827705143,0.1558182061,0.1768262159,0.1483810165,0.156283749,0.1557976718,0.1548409268,0.1644499755,0.1713872319,0.1473891028,0.1621363208,0.1568376418,0.1624145554,0.1568924267,0.1656432498,0.1752885214,0.1546594314,0.229031767,0.2108133055,0.4331287797,0.6440533305,0.4490418765,0.186253,0.125464,0.158207,0.17437,0.19602,0.094512,0.067413 [...]
+"46",0.2712802755,0.2661765585,0.2367913967,0.2882604932,0.0901081037,0.0867823426,0.0449746102,0.0231416653,0.0303615724,0.0313945842,0.0227641045,0.0899515143,0.1629992061,0.1840072159,0.1555620165,0.163464749,0.1629786718,0.1620219268,0.1716309755,0.1785682319,0.1545701028,0.1693173208,0.1640186418,0.1695955554,0.1640734267,0.1728242498,0.1824695214,0.1618404314,0.236212767,0.2179943055,0.4403097797,0.6512343305,0.4562228765,0.193434,0.132645,0.165388,0.181551,0.203201,0.101693,0.0745 [...]
+"47",0.2898772755,0.2847735585,0.2553883967,0.3068574932,0.1087051037,0.1053793426,0.0635716102,0.0045446653,0.0117645724,0.0127975842,0.0413611045,0.1085485143,0.1815962061,0.2026042159,0.1741590165,0.182061749,0.1815756718,0.1806189268,0.1902279755,0.1971652319,0.1731671028,0.1879143208,0.1826156418,0.1881925554,0.1826704267,0.1914212498,0.2010665214,0.1804374314,0.254809767,0.2365913055,0.4589067797,0.6698313305,0.4748198765,0.212031,0.151242,0.183985,0.200148,0.221798,0.12029,0.09319 [...]
+"48",0.2940592755,0.2889555585,0.2595703967,0.3110394932,0.1128871037,0.1095613426,0.0677536102,0.0087266653,0.0075825724,0.0086155842,0.0455431045,0.1127305143,0.1857782061,0.2067862159,0.1783410165,0.186243749,0.1857576718,0.1848009268,0.1944099755,0.2013472319,0.1773491028,0.1920963208,0.1867976418,0.1923745554,0.1868524267,0.1956032498,0.2052485214,0.1846194314,0.258991767,0.2407733055,0.4630887797,0.6740133305,0.4790018765,0.216213,0.155424,0.188167,0.20433,0.22598,0.124472,0.097373 [...]
+"49",0.2187572755,0.2136535585,0.1842683967,0.2357374932,0.1010491037,0.0977233426,0.1140736102,0.1066026653,0.1138225724,0.1148555842,0.1062251045,0.1094585143,0.0795382061,0.1005462159,0.0721010165,0.080003749,0.0795176718,0.0785609268,0.0881699755,0.1260452319,0.1020471028,0.1167943208,0.1114956418,0.1170725554,0.1115504267,0.1203012498,0.1299465214,0.1093174314,0.183689767,0.1654713055,0.3877867797,0.5987113305,0.4036998765,0.140911,0.080122,0.112865,0.129028,0.150678,0.04917,0.02207 [...]
+"50",0.2303742755,0.2252705585,0.1958853967,0.2473544932,0.1126661037,0.1093403426,0.1256906102,0.1182196653,0.1254395724,0.1264725842,0.1178421045,0.1210755143,0.0679212061,0.0889292159,0.0604840165,0.068386749,0.0911346718,0.0901779268,0.0997869755,0.1376622319,0.1136641028,0.1284113208,0.1231126418,0.1286895554,0.1231674267,0.1319182498,0.1415635214,0.1209344314,0.195306767,0.1770883055,0.3994037797,0.6103283305,0.4153168765,0.152528,0.091739,0.124482,0.140645,0.162295,0.060787,0.0336 [...]
+"51",0.2432222755,0.2381185585,0.2087333967,0.2602024932,0.1255141037,0.1221883426,0.1385386102,0.1310676653,0.1382875724,0.1393205842,0.1306901045,0.1339235143,0.0807692061,0.0760812159,0.0476360165,0.055538749,0.1039826718,0.1030259268,0.1126349755,0.1505102319,0.1265121028,0.1412593208,0.1359606418,0.1415375554,0.1360154267,0.1447662498,0.1544115214,0.1337824314,0.208154767,0.1899363055,0.4122517797,0.6231763305,0.4281648765,0.165376,0.104587,0.13733,0.153493,0.175143,0.073635,0.04653 [...]
+"52",0.2756192755,0.2705155585,0.2411303967,0.2925994932,0.1579111037,0.1545853426,0.1709356102,0.1634646653,0.1706845724,0.1717175842,0.1630871045,0.1663205143,0.1131662061,0.1084782159,0.0152390165,0.023141749,0.1363796718,0.1354229268,0.1450319755,0.1829072319,0.1589091028,0.1736563208,0.1683576418,0.1739345554,0.1684124267,0.1771632498,0.1868085214,0.1661794314,0.240551767,0.2223333055,0.4446487797,0.6555733305,0.4605618765,0.197773,0.136984,0.169727,0.18589,0.20754,0.106032,0.078933 [...]
+"53",0.2322392755,0.2271355585,0.1977503967,0.2492194932,0.1145311037,0.1112053426,0.1275556102,0.1200846653,0.1273045724,0.1283375842,0.1197071045,0.1229405143,0.0930202061,0.1140282159,0.0855830165,0.093485749,0.0660356718,0.0650789268,0.0746879755,0.1395272319,0.1155291028,0.1302763208,0.1249776418,0.1305545554,0.1250324267,0.1337832498,0.1434285214,0.1227994314,0.197171767,0.1789533055,0.4012687797,0.6121933305,0.4171818765,0.154393,0.093604,0.126347,0.14251,0.16416,0.062652,0.035553 [...]
+"54",0.2595682755,0.2544645585,0.2250793967,0.2765484932,0.1418601037,0.1385343426,0.1548846102,0.1474136653,0.1546335724,0.1556665842,0.1470361045,0.1502695143,0.1203492061,0.1413572159,0.1129120165,0.120814749,0.0933646718,0.0377499268,0.0473589755,0.1668562319,0.1428581028,0.1576053208,0.1523066418,0.1578835554,0.1523614267,0.1611122498,0.1707575214,0.1501284314,0.224500767,0.2062823055,0.4285977797,0.6395223305,0.4445108765,0.181722,0.120933,0.153676,0.169839,0.191489,0.089981,0.0628 [...]
+"55",0.1995452755,0.1944415585,0.1650563967,0.2165254932,0.0950411037,0.0917153426,0.1080656102,0.1005946653,0.1078145724,0.1088475842,0.1002171045,0.1034505143,0.1044682061,0.1254762159,0.0970310165,0.104933749,0.1044476718,0.1034909268,0.1130999755,0.1011152319,0.0771171028,0.0918643208,0.0865656418,0.0921425554,0.0866204267,0.0953712498,0.1050165214,0.0843874314,0.164477767,0.1462593055,0.3685747797,0.5794993305,0.3844878765,0.121699,0.06091,0.093653,0.109816,0.131466,0.029958,0.00285 [...]
+"56",0.2022582755,0.1971545585,0.1677693967,0.2192384932,0.0977541037,0.0944283426,0.1107786102,0.1033076653,0.1105275724,0.1115605842,0.1029301045,0.1061635143,0.1071812061,0.1281892159,0.0997440165,0.107646749,0.1071606718,0.1062039268,0.1158129755,0.0984022319,0.0744041028,0.0891513208,0.0838526418,0.0894295554,0.0839074267,0.0926582498,0.1023035214,0.0871004314,0.167190767,0.1489723055,0.3712877797,0.5822123305,0.3872008765,0.124412,0.063623,0.096366,0.112529,0.134179,0.032671,0.0055 [...]
+"57",0.2099922755,0.2048885585,0.1755033967,0.2269724932,0.1054881037,0.1021623426,0.1185126102,0.1110416653,0.1182615724,0.1192945842,0.1106641045,0.1138975143,0.1149152061,0.1359232159,0.1074780165,0.115380749,0.1148946718,0.1139379268,0.1235469755,0.0906682319,0.0666701028,0.0814173208,0.0761186418,0.0816955554,0.0761734267,0.1003922498,0.1100375214,0.0948344314,0.174924767,0.1567063055,0.3790217797,0.5899463305,0.3949348765,0.132146,0.071357,0.1041,0.120263,0.141913,0.040405,0.013306 [...]
+"58",0.2234142755,0.2183105585,0.1889253967,0.2403944932,0.1189101037,0.1155843426,0.1319346102,0.1244636653,0.1316835724,0.1327165842,0.1240861045,0.1273195143,0.1283372061,0.1493452159,0.1209000165,0.128802749,0.1283166718,0.1273599268,0.1369689755,0.0772462319,0.0532481028,0.0679953208,0.0626966418,0.0951175554,0.0895954267,0.1138142498,0.1234595214,0.1082564314,0.188346767,0.1701283055,0.3924437797,0.6033683305,0.4083568765,0.145568,0.084779,0.117522,0.133685,0.155335,0.053827,0.0267 [...]
+"59",0.2335822755,0.2284785585,0.1990933967,0.2505624932,0.1290781037,0.1257523426,0.1421026102,0.1346316653,0.1418515724,0.1428845842,0.1342541045,0.1374875143,0.1385052061,0.1595132159,0.1310680165,0.138970749,0.1384846718,0.1375279268,0.1471369755,0.0670782319,0.0430801028,0.0781633208,0.0728646418,0.1052855554,0.0997634267,0.1239822498,0.1336275214,0.1184244314,0.198514767,0.1802963055,0.4026117797,0.6135363305,0.4185248765,0.155736,0.094947,0.12769,0.143853,0.165503,0.063995,0.03689 [...]
+"60",0.2719192755,0.2668155585,0.2374303967,0.2888994932,0.1674151037,0.1640893426,0.1804396102,0.1729686653,0.1801885724,0.1812215842,0.1725911045,0.1758245143,0.1768422061,0.1978502159,0.1694050165,0.177307749,0.1768216718,0.1758649268,0.1854739755,0.1257512319,0.1017531028,0.0194903208,0.0141916418,0.1436225554,0.1381004267,0.1623192498,0.1719645214,0.1567614314,0.236851767,0.2186333055,0.4409487797,0.6518733305,0.4568618765,0.194073,0.133284,0.166027,0.18219,0.20384,0.102332,0.075233 [...]
+"61",0.2536182755,0.2485145585,0.2191293967,0.2705984932,0.1491141037,0.1457883426,0.1621386102,0.1546676653,0.1618875724,0.1629205842,0.1542901045,0.1575235143,0.1585412061,0.1795492159,0.1511040165,0.159006749,0.1585206718,0.1575639268,0.1671729755,0.1342942319,0.1102961028,0.1250433208,0.1197446418,0.0380695554,0.0325474267,0.1440182498,0.1536635214,0.1384604314,0.218550767,0.2003323055,0.4226477797,0.6335723305,0.4385608765,0.175772,0.114983,0.147726,0.163889,0.185539,0.084031,0.0569 [...]
+"62",0.2407022755,0.2355985585,0.2062133967,0.2576824932,0.1361981037,0.1328723426,0.1492226102,0.1417516653,0.1489715724,0.1500045842,0.1413741045,0.1446075143,0.1456252061,0.1666332159,0.1381880165,0.146090749,0.1456046718,0.1446479268,0.1542569755,0.1368462319,0.1128481028,0.1275953208,0.1222966418,0.1278735554,0.1223514267,0.0542142498,0.0638595214,0.1255444314,0.205634767,0.1874163055,0.4097317797,0.6206563305,0.4256448765,0.162856,0.102067,0.13481,0.150973,0.172623,0.071115,0.04401 [...]
+"63",0.2296272755,0.2245235585,0.1951383967,0.2466074932,0.1793211037,0.1759953426,0.1923456102,0.1848746653,0.1920945724,0.1931275842,0.1844971045,0.1877305143,0.1887482061,0.2097562159,0.1813110165,0.189213749,0.1887276718,0.1877709268,0.1973799755,0.1911132319,0.1671151028,0.1818623208,0.1765636418,0.1821405554,0.1766184267,0.1853692498,0.1950145214,0.1743854314,0.074479767,0.0562613055,0.3986567797,0.6095813305,0.4145698765,0.151781,0.090992,0.123735,0.139898,0.161548,0.06004,0.08713 [...]
+"64",0.2479322755,0.2428285585,0.2134433967,0.2649124932,0.2595301037,0.2562043426,0.2725546102,0.2650836653,0.2723035724,0.2733365842,0.2647061045,0.2679395143,0.2689572061,0.2899652159,0.2615200165,0.269422749,0.2689366718,0.2679799268,0.2775889755,0.2713222319,0.2473241028,0.2620713208,0.2567726418,0.2623495554,0.2568274267,0.2655782498,0.2752235214,0.2545944314,0.274768767,0.2565503055,0.1983677797,0.4092923305,0.3112968765,0.048508,0.109297,0.14204,0.158203,0.179853,0.140249,0.16734 [...]
diff --git a/dendropy/test/data/other/pythonidae.mle.unweighted.node-to-node-dists.csv b/dendropy/test/data/other/pythonidae.mle.unweighted.node-to-node-dists.csv
new file mode 100644
index 0000000..74fad4d
--- /dev/null
+++ b/dendropy/test/data/other/pythonidae.mle.unweighted.node-to-node-dists.csv
@@ -0,0 +1,65 @@
+"","1","2","3","4","5","6","7","8","9","10","11","12","13","14","15","16","17","18","19","20","21","22","23","24","25","26","27","28","29","30","31","32","33","34","35","36","37","38","39","40","41","42","43","44","45","46","47","48","49","50","51","52","53","54","55","56","57","58","59","60","61","62","63","64"
+"1",0,4,4,3,8,8,9,11,12,12,10,8,8,9,10,10,8,9,9,10,10,10,10,9,9,8,8,6,5,5,5,5,4,3,2,1,2,3,3,4,5,6,7,7,8,9,10,11,6,7,8,9,7,8,5,6,7,8,9,9,8,7,4,4
+"2",4,0,2,3,10,10,11,13,14,14,12,10,10,11,12,12,10,11,11,12,12,12,12,11,11,10,10,8,7,7,7,7,6,5,4,3,2,1,5,6,7,8,9,9,10,11,12,13,8,9,10,11,9,10,7,8,9,10,11,11,10,9,6,6
+"3",4,2,0,3,10,10,11,13,14,14,12,10,10,11,12,12,10,11,11,12,12,12,12,11,11,10,10,8,7,7,7,7,6,5,4,3,2,1,5,6,7,8,9,9,10,11,12,13,8,9,10,11,9,10,7,8,9,10,11,11,10,9,6,6
+"4",3,3,3,0,9,9,10,12,13,13,11,9,9,10,11,11,9,10,10,11,11,11,11,10,10,9,9,7,6,6,6,6,5,4,3,2,1,2,4,5,6,7,8,8,9,10,11,12,7,8,9,10,8,9,6,7,8,9,10,10,9,8,5,5
+"5",8,10,10,9,0,2,5,7,8,8,6,4,6,7,8,8,6,7,7,10,10,10,10,9,9,8,8,6,7,7,9,9,8,7,6,7,8,9,5,4,3,2,1,3,4,5,6,7,4,5,6,7,5,6,5,6,7,8,9,9,8,7,6,8
+"6",8,10,10,9,2,0,5,7,8,8,6,4,6,7,8,8,6,7,7,10,10,10,10,9,9,8,8,6,7,7,9,9,8,7,6,7,8,9,5,4,3,2,1,3,4,5,6,7,4,5,6,7,5,6,5,6,7,8,9,9,8,7,6,8
+"7",9,11,11,10,5,5,0,4,5,5,3,3,7,8,9,9,7,8,8,11,11,11,11,10,10,9,9,7,8,8,10,10,9,8,7,8,9,10,6,5,4,3,4,2,1,2,3,4,5,6,7,8,6,7,6,7,8,9,10,10,9,8,7,9
+"8",11,13,13,12,7,7,4,0,3,3,3,5,9,10,11,11,9,10,10,13,13,13,13,12,12,11,11,9,10,10,12,12,11,10,9,10,11,12,8,7,6,5,6,4,3,2,1,2,7,8,9,10,8,9,8,9,10,11,12,12,11,10,9,11
+"9",12,14,14,13,8,8,5,3,0,2,4,6,10,11,12,12,10,11,11,14,14,14,14,13,13,12,12,10,11,11,13,13,12,11,10,11,12,13,9,8,7,6,7,5,4,3,2,1,8,9,10,11,9,10,9,10,11,12,13,13,12,11,10,12
+"10",12,14,14,13,8,8,5,3,2,0,4,6,10,11,12,12,10,11,11,14,14,14,14,13,13,12,12,10,11,11,13,13,12,11,10,11,12,13,9,8,7,6,7,5,4,3,2,1,8,9,10,11,9,10,9,10,11,12,13,13,12,11,10,12
+"11",10,12,12,11,6,6,3,3,4,4,0,4,8,9,10,10,8,9,9,12,12,12,12,11,11,10,10,8,9,9,11,11,10,9,8,9,10,11,7,6,5,4,5,3,2,1,2,3,6,7,8,9,7,8,7,8,9,10,11,11,10,9,8,10
+"12",8,10,10,9,4,4,3,5,6,6,4,0,6,7,8,8,6,7,7,10,10,10,10,9,9,8,8,6,7,7,9,9,8,7,6,7,8,9,5,4,3,2,3,1,2,3,4,5,4,5,6,7,5,6,5,6,7,8,9,9,8,7,6,8
+"13",8,10,10,9,6,6,7,9,10,10,8,6,0,3,4,4,4,5,5,10,10,10,10,9,9,8,8,6,7,7,9,9,8,7,6,7,8,9,5,4,3,4,5,5,6,7,8,9,2,1,2,3,3,4,5,6,7,8,9,9,8,7,6,8
+"14",9,11,11,10,7,7,8,10,11,11,9,7,3,0,3,3,5,6,6,11,11,11,11,10,10,9,9,7,8,8,10,10,9,8,7,8,9,10,6,5,4,5,6,6,7,8,9,10,3,2,1,2,4,5,6,7,8,9,10,10,9,8,7,9
+"15",10,12,12,11,8,8,9,11,12,12,10,8,4,3,0,2,6,7,7,12,12,12,12,11,11,10,10,8,9,9,11,11,10,9,8,9,10,11,7,6,5,6,7,7,8,9,10,11,4,3,2,1,5,6,7,8,9,10,11,11,10,9,8,10
+"16",10,12,12,11,8,8,9,11,12,12,10,8,4,3,2,0,6,7,7,12,12,12,12,11,11,10,10,8,9,9,11,11,10,9,8,9,10,11,7,6,5,6,7,7,8,9,10,11,4,3,2,1,5,6,7,8,9,10,11,11,10,9,8,10
+"17",8,10,10,9,6,6,7,9,10,10,8,6,4,5,6,6,0,3,3,10,10,10,10,9,9,8,8,6,7,7,9,9,8,7,6,7,8,9,5,4,3,4,5,5,6,7,8,9,2,3,4,5,1,2,5,6,7,8,9,9,8,7,6,8
+"18",9,11,11,10,7,7,8,10,11,11,9,7,5,6,7,7,3,0,2,11,11,11,11,10,10,9,9,7,8,8,10,10,9,8,7,8,9,10,6,5,4,5,6,6,7,8,9,10,3,4,5,6,2,1,6,7,8,9,10,10,9,8,7,9
+"19",9,11,11,10,7,7,8,10,11,11,9,7,5,6,7,7,3,2,0,11,11,11,11,10,10,9,9,7,8,8,10,10,9,8,7,8,9,10,6,5,4,5,6,6,7,8,9,10,3,4,5,6,2,1,6,7,8,9,10,10,9,8,7,9
+"20",10,12,12,11,10,10,11,13,14,14,12,10,10,11,12,12,10,11,11,0,2,4,4,5,5,6,6,6,9,9,11,11,10,9,8,9,10,11,7,6,7,8,9,9,10,11,12,13,8,9,10,11,9,10,5,4,3,2,1,3,4,5,8,10
+"21",10,12,12,11,10,10,11,13,14,14,12,10,10,11,12,12,10,11,11,2,0,4,4,5,5,6,6,6,9,9,11,11,10,9,8,9,10,11,7,6,7,8,9,9,10,11,12,13,8,9,10,11,9,10,5,4,3,2,1,3,4,5,8,10
+"22",10,12,12,11,10,10,11,13,14,14,12,10,10,11,12,12,10,11,11,4,4,0,2,5,5,6,6,6,9,9,11,11,10,9,8,9,10,11,7,6,7,8,9,9,10,11,12,13,8,9,10,11,9,10,5,4,3,2,3,1,4,5,8,10
+"23",10,12,12,11,10,10,11,13,14,14,12,10,10,11,12,12,10,11,11,4,4,2,0,5,5,6,6,6,9,9,11,11,10,9,8,9,10,11,7,6,7,8,9,9,10,11,12,13,8,9,10,11,9,10,5,4,3,2,3,1,4,5,8,10
+"24",9,11,11,10,9,9,10,12,13,13,11,9,9,10,11,11,9,10,10,5,5,5,5,0,2,5,5,5,8,8,10,10,9,8,7,8,9,10,6,5,6,7,8,8,9,10,11,12,7,8,9,10,8,9,4,3,2,3,4,4,1,4,7,9
+"25",9,11,11,10,9,9,10,12,13,13,11,9,9,10,11,11,9,10,10,5,5,5,5,2,0,5,5,5,8,8,10,10,9,8,7,8,9,10,6,5,6,7,8,8,9,10,11,12,7,8,9,10,8,9,4,3,2,3,4,4,1,4,7,9
+"26",8,10,10,9,8,8,9,11,12,12,10,8,8,9,10,10,8,9,9,6,6,6,6,5,5,0,2,4,7,7,9,9,8,7,6,7,8,9,5,4,5,6,7,7,8,9,10,11,6,7,8,9,7,8,3,2,3,4,5,5,4,1,6,8
+"27",8,10,10,9,8,8,9,11,12,12,10,8,8,9,10,10,8,9,9,6,6,6,6,5,5,2,0,4,7,7,9,9,8,7,6,7,8,9,5,4,5,6,7,7,8,9,10,11,6,7,8,9,7,8,3,2,3,4,5,5,4,1,6,8
+"28",6,8,8,7,6,6,7,9,10,10,8,6,6,7,8,8,6,7,7,6,6,6,6,5,5,4,4,0,5,5,7,7,6,5,4,5,6,7,3,2,3,4,5,5,6,7,8,9,4,5,6,7,5,6,1,2,3,4,5,5,4,3,4,6
+"29",5,7,7,6,7,7,8,10,11,11,9,7,7,8,9,9,7,8,8,9,9,9,9,8,8,7,7,5,0,2,6,6,5,4,3,4,5,6,2,3,4,5,6,6,7,8,9,10,5,6,7,8,6,7,4,5,6,7,8,8,7,6,1,5
+"30",5,7,7,6,7,7,8,10,11,11,9,7,7,8,9,9,7,8,8,9,9,9,9,8,8,7,7,5,2,0,6,6,5,4,3,4,5,6,2,3,4,5,6,6,7,8,9,10,5,6,7,8,6,7,4,5,6,7,8,8,7,6,1,5
+"31",5,7,7,6,9,9,10,12,13,13,11,9,9,10,11,11,9,10,10,11,11,11,11,10,10,9,9,7,6,6,0,2,3,2,3,4,5,6,4,5,6,7,8,8,9,10,11,12,7,8,9,10,8,9,6,7,8,9,10,10,9,8,5,1
+"32",5,7,7,6,9,9,10,12,13,13,11,9,9,10,11,11,9,10,10,11,11,11,11,10,10,9,9,7,6,6,2,0,3,2,3,4,5,6,4,5,6,7,8,8,9,10,11,12,7,8,9,10,8,9,6,7,8,9,10,10,9,8,5,1
+"33",4,6,6,5,8,8,9,11,12,12,10,8,8,9,10,10,8,9,9,10,10,10,10,9,9,8,8,6,5,5,3,3,0,1,2,3,4,5,3,4,5,6,7,7,8,9,10,11,6,7,8,9,7,8,5,6,7,8,9,9,8,7,4,2
+"34",3,5,5,4,7,7,8,10,11,11,9,7,7,8,9,9,7,8,8,9,9,9,9,8,8,7,7,5,4,4,2,2,1,0,1,2,3,4,2,3,4,5,6,6,7,8,9,10,5,6,7,8,6,7,4,5,6,7,8,8,7,6,3,1
+"35",2,4,4,3,6,6,7,9,10,10,8,6,6,7,8,8,6,7,7,8,8,8,8,7,7,6,6,4,3,3,3,3,2,1,0,1,2,3,1,2,3,4,5,5,6,7,8,9,4,5,6,7,5,6,3,4,5,6,7,7,6,5,2,2
+"36",1,3,3,2,7,7,8,10,11,11,9,7,7,8,9,9,7,8,8,9,9,9,9,8,8,7,7,5,4,4,4,4,3,2,1,0,1,2,2,3,4,5,6,6,7,8,9,10,5,6,7,8,6,7,4,5,6,7,8,8,7,6,3,3
+"37",2,2,2,1,8,8,9,11,12,12,10,8,8,9,10,10,8,9,9,10,10,10,10,9,9,8,8,6,5,5,5,5,4,3,2,1,0,1,3,4,5,6,7,7,8,9,10,11,6,7,8,9,7,8,5,6,7,8,9,9,8,7,4,4
+"38",3,1,1,2,9,9,10,12,13,13,11,9,9,10,11,11,9,10,10,11,11,11,11,10,10,9,9,7,6,6,6,6,5,4,3,2,1,0,4,5,6,7,8,8,9,10,11,12,7,8,9,10,8,9,6,7,8,9,10,10,9,8,5,5
+"39",3,5,5,4,5,5,6,8,9,9,7,5,5,6,7,7,5,6,6,7,7,7,7,6,6,5,5,3,2,2,4,4,3,2,1,2,3,4,0,1,2,3,4,4,5,6,7,8,3,4,5,6,4,5,2,3,4,5,6,6,5,4,1,3
+"40",4,6,6,5,4,4,5,7,8,8,6,4,4,5,6,6,4,5,5,6,6,6,6,5,5,4,4,2,3,3,5,5,4,3,2,3,4,5,1,0,1,2,3,3,4,5,6,7,2,3,4,5,3,4,1,2,3,4,5,5,4,3,2,4
+"41",5,7,7,6,3,3,4,6,7,7,5,3,3,4,5,5,3,4,4,7,7,7,7,6,6,5,5,3,4,4,6,6,5,4,3,4,5,6,2,1,0,1,2,2,3,4,5,6,1,2,3,4,2,3,2,3,4,5,6,6,5,4,3,5
+"42",6,8,8,7,2,2,3,5,6,6,4,2,4,5,6,6,4,5,5,8,8,8,8,7,7,6,6,4,5,5,7,7,6,5,4,5,6,7,3,2,1,0,1,1,2,3,4,5,2,3,4,5,3,4,3,4,5,6,7,7,6,5,4,6
+"43",7,9,9,8,1,1,4,6,7,7,5,3,5,6,7,7,5,6,6,9,9,9,9,8,8,7,7,5,6,6,8,8,7,6,5,6,7,8,4,3,2,1,0,2,3,4,5,6,3,4,5,6,4,5,4,5,6,7,8,8,7,6,5,7
+"44",7,9,9,8,3,3,2,4,5,5,3,1,5,6,7,7,5,6,6,9,9,9,9,8,8,7,7,5,6,6,8,8,7,6,5,6,7,8,4,3,2,1,2,0,1,2,3,4,3,4,5,6,4,5,4,5,6,7,8,8,7,6,5,7
+"45",8,10,10,9,4,4,1,3,4,4,2,2,6,7,8,8,6,7,7,10,10,10,10,9,9,8,8,6,7,7,9,9,8,7,6,7,8,9,5,4,3,2,3,1,0,1,2,3,4,5,6,7,5,6,5,6,7,8,9,9,8,7,6,8
+"46",9,11,11,10,5,5,2,2,3,3,1,3,7,8,9,9,7,8,8,11,11,11,11,10,10,9,9,7,8,8,10,10,9,8,7,8,9,10,6,5,4,3,4,2,1,0,1,2,5,6,7,8,6,7,6,7,8,9,10,10,9,8,7,9
+"47",10,12,12,11,6,6,3,1,2,2,2,4,8,9,10,10,8,9,9,12,12,12,12,11,11,10,10,8,9,9,11,11,10,9,8,9,10,11,7,6,5,4,5,3,2,1,0,1,6,7,8,9,7,8,7,8,9,10,11,11,10,9,8,10
+"48",11,13,13,12,7,7,4,2,1,1,3,5,9,10,11,11,9,10,10,13,13,13,13,12,12,11,11,9,10,10,12,12,11,10,9,10,11,12,8,7,6,5,6,4,3,2,1,0,7,8,9,10,8,9,8,9,10,11,12,12,11,10,9,11
+"49",6,8,8,7,4,4,5,7,8,8,6,4,2,3,4,4,2,3,3,8,8,8,8,7,7,6,6,4,5,5,7,7,6,5,4,5,6,7,3,2,1,2,3,3,4,5,6,7,0,1,2,3,1,2,3,4,5,6,7,7,6,5,4,6
+"50",7,9,9,8,5,5,6,8,9,9,7,5,1,2,3,3,3,4,4,9,9,9,9,8,8,7,7,5,6,6,8,8,7,6,5,6,7,8,4,3,2,3,4,4,5,6,7,8,1,0,1,2,2,3,4,5,6,7,8,8,7,6,5,7
+"51",8,10,10,9,6,6,7,9,10,10,8,6,2,1,2,2,4,5,5,10,10,10,10,9,9,8,8,6,7,7,9,9,8,7,6,7,8,9,5,4,3,4,5,5,6,7,8,9,2,1,0,1,3,4,5,6,7,8,9,9,8,7,6,8
+"52",9,11,11,10,7,7,8,10,11,11,9,7,3,2,1,1,5,6,6,11,11,11,11,10,10,9,9,7,8,8,10,10,9,8,7,8,9,10,6,5,4,5,6,6,7,8,9,10,3,2,1,0,4,5,6,7,8,9,10,10,9,8,7,9
+"53",7,9,9,8,5,5,6,8,9,9,7,5,3,4,5,5,1,2,2,9,9,9,9,8,8,7,7,5,6,6,8,8,7,6,5,6,7,8,4,3,2,3,4,4,5,6,7,8,1,2,3,4,0,1,4,5,6,7,8,8,7,6,5,7
+"54",8,10,10,9,6,6,7,9,10,10,8,6,4,5,6,6,2,1,1,10,10,10,10,9,9,8,8,6,7,7,9,9,8,7,6,7,8,9,5,4,3,4,5,5,6,7,8,9,2,3,4,5,1,0,5,6,7,8,9,9,8,7,6,8
+"55",5,7,7,6,5,5,6,8,9,9,7,5,5,6,7,7,5,6,6,5,5,5,5,4,4,3,3,1,4,4,6,6,5,4,3,4,5,6,2,1,2,3,4,4,5,6,7,8,3,4,5,6,4,5,0,1,2,3,4,4,3,2,3,5
+"56",6,8,8,7,6,6,7,9,10,10,8,6,6,7,8,8,6,7,7,4,4,4,4,3,3,2,2,2,5,5,7,7,6,5,4,5,6,7,3,2,3,4,5,5,6,7,8,9,4,5,6,7,5,6,1,0,1,2,3,3,2,1,4,6
+"57",7,9,9,8,7,7,8,10,11,11,9,7,7,8,9,9,7,8,8,3,3,3,3,2,2,3,3,3,6,6,8,8,7,6,5,6,7,8,4,3,4,5,6,6,7,8,9,10,5,6,7,8,6,7,2,1,0,1,2,2,1,2,5,7
+"58",8,10,10,9,8,8,9,11,12,12,10,8,8,9,10,10,8,9,9,2,2,2,2,3,3,4,4,4,7,7,9,9,8,7,6,7,8,9,5,4,5,6,7,7,8,9,10,11,6,7,8,9,7,8,3,2,1,0,1,1,2,3,6,8
+"59",9,11,11,10,9,9,10,12,13,13,11,9,9,10,11,11,9,10,10,1,1,3,3,4,4,5,5,5,8,8,10,10,9,8,7,8,9,10,6,5,6,7,8,8,9,10,11,12,7,8,9,10,8,9,4,3,2,1,0,2,3,4,7,9
+"60",9,11,11,10,9,9,10,12,13,13,11,9,9,10,11,11,9,10,10,3,3,1,1,4,4,5,5,5,8,8,10,10,9,8,7,8,9,10,6,5,6,7,8,8,9,10,11,12,7,8,9,10,8,9,4,3,2,1,2,0,3,4,7,9
+"61",8,10,10,9,8,8,9,11,12,12,10,8,8,9,10,10,8,9,9,4,4,4,4,1,1,4,4,4,7,7,9,9,8,7,6,7,8,9,5,4,5,6,7,7,8,9,10,11,6,7,8,9,7,8,3,2,1,2,3,3,0,3,6,8
+"62",7,9,9,8,7,7,8,10,11,11,9,7,7,8,9,9,7,8,8,5,5,5,5,4,4,1,1,3,6,6,8,8,7,6,5,6,7,8,4,3,4,5,6,6,7,8,9,10,5,6,7,8,6,7,2,1,2,3,4,4,3,0,5,7
+"63",4,6,6,5,6,6,7,9,10,10,8,6,6,7,8,8,6,7,7,8,8,8,8,7,7,6,6,4,1,1,5,5,4,3,2,3,4,5,1,2,3,4,5,5,6,7,8,9,4,5,6,7,5,6,3,4,5,6,7,7,6,5,0,4
+"64",4,6,6,5,8,8,9,11,12,12,10,8,8,9,10,10,8,9,9,10,10,10,10,9,9,8,8,6,5,5,1,1,2,1,2,3,4,5,3,4,5,6,7,7,8,9,10,11,6,7,8,9,7,8,5,6,7,8,9,9,8,7,4,0
diff --git a/dendropy/test/data/other/pythonidae.mle.unweighted.pdm.csv b/dendropy/test/data/other/pythonidae.mle.unweighted.pdm.csv
new file mode 100644
index 0000000..bba12b7
--- /dev/null
+++ b/dendropy/test/data/other/pythonidae.mle.unweighted.pdm.csv
@@ -0,0 +1,34 @@
+"","Python_regius","Python_sebae","Python_molurus","Python_curtus","Morelia_bredli","Morelia_spilota","Morelia_tracyae","Morelia_clastolepis","Morelia_kinghorni","Morelia_nauta","Morelia_amethistina","Morelia_oenpelliensis","Antaresia_maculosa","Antaresia_perthensis","Antaresia_stimsoni","Antaresia_childreni","Morelia_carinata","Morelia_viridisN","Morelia_viridisS","Apodora_papuana","Liasis_olivaceus","Liasis_fuscus","Liasis_mackloti","Antaresia_melanocephalus","Antaresia_ramsayi","Liasi [...]
+"Python_regius",0,4,4,3,8,8,9,11,12,12,10,8,8,9,10,10,8,9,9,10,10,10,10,9,9,8,8,6,5,5,5,5,4
+"Python_sebae",4,0,2,3,10,10,11,13,14,14,12,10,10,11,12,12,10,11,11,12,12,12,12,11,11,10,10,8,7,7,7,7,6
+"Python_molurus",4,2,0,3,10,10,11,13,14,14,12,10,10,11,12,12,10,11,11,12,12,12,12,11,11,10,10,8,7,7,7,7,6
+"Python_curtus",3,3,3,0,9,9,10,12,13,13,11,9,9,10,11,11,9,10,10,11,11,11,11,10,10,9,9,7,6,6,6,6,5
+"Morelia_bredli",8,10,10,9,0,2,5,7,8,8,6,4,6,7,8,8,6,7,7,10,10,10,10,9,9,8,8,6,7,7,9,9,8
+"Morelia_spilota",8,10,10,9,2,0,5,7,8,8,6,4,6,7,8,8,6,7,7,10,10,10,10,9,9,8,8,6,7,7,9,9,8
+"Morelia_tracyae",9,11,11,10,5,5,0,4,5,5,3,3,7,8,9,9,7,8,8,11,11,11,11,10,10,9,9,7,8,8,10,10,9
+"Morelia_clastolepis",11,13,13,12,7,7,4,0,3,3,3,5,9,10,11,11,9,10,10,13,13,13,13,12,12,11,11,9,10,10,12,12,11
+"Morelia_kinghorni",12,14,14,13,8,8,5,3,0,2,4,6,10,11,12,12,10,11,11,14,14,14,14,13,13,12,12,10,11,11,13,13,12
+"Morelia_nauta",12,14,14,13,8,8,5,3,2,0,4,6,10,11,12,12,10,11,11,14,14,14,14,13,13,12,12,10,11,11,13,13,12
+"Morelia_amethistina",10,12,12,11,6,6,3,3,4,4,0,4,8,9,10,10,8,9,9,12,12,12,12,11,11,10,10,8,9,9,11,11,10
+"Morelia_oenpelliensis",8,10,10,9,4,4,3,5,6,6,4,0,6,7,8,8,6,7,7,10,10,10,10,9,9,8,8,6,7,7,9,9,8
+"Antaresia_maculosa",8,10,10,9,6,6,7,9,10,10,8,6,0,3,4,4,4,5,5,10,10,10,10,9,9,8,8,6,7,7,9,9,8
+"Antaresia_perthensis",9,11,11,10,7,7,8,10,11,11,9,7,3,0,3,3,5,6,6,11,11,11,11,10,10,9,9,7,8,8,10,10,9
+"Antaresia_stimsoni",10,12,12,11,8,8,9,11,12,12,10,8,4,3,0,2,6,7,7,12,12,12,12,11,11,10,10,8,9,9,11,11,10
+"Antaresia_childreni",10,12,12,11,8,8,9,11,12,12,10,8,4,3,2,0,6,7,7,12,12,12,12,11,11,10,10,8,9,9,11,11,10
+"Morelia_carinata",8,10,10,9,6,6,7,9,10,10,8,6,4,5,6,6,0,3,3,10,10,10,10,9,9,8,8,6,7,7,9,9,8
+"Morelia_viridisN",9,11,11,10,7,7,8,10,11,11,9,7,5,6,7,7,3,0,2,11,11,11,11,10,10,9,9,7,8,8,10,10,9
+"Morelia_viridisS",9,11,11,10,7,7,8,10,11,11,9,7,5,6,7,7,3,2,0,11,11,11,11,10,10,9,9,7,8,8,10,10,9
+"Apodora_papuana",10,12,12,11,10,10,11,13,14,14,12,10,10,11,12,12,10,11,11,0,2,4,4,5,5,6,6,6,9,9,11,11,10
+"Liasis_olivaceus",10,12,12,11,10,10,11,13,14,14,12,10,10,11,12,12,10,11,11,2,0,4,4,5,5,6,6,6,9,9,11,11,10
+"Liasis_fuscus",10,12,12,11,10,10,11,13,14,14,12,10,10,11,12,12,10,11,11,4,4,0,2,5,5,6,6,6,9,9,11,11,10
+"Liasis_mackloti",10,12,12,11,10,10,11,13,14,14,12,10,10,11,12,12,10,11,11,4,4,2,0,5,5,6,6,6,9,9,11,11,10
+"Antaresia_melanocephalus",9,11,11,10,9,9,10,12,13,13,11,9,9,10,11,11,9,10,10,5,5,5,5,0,2,5,5,5,8,8,10,10,9
+"Antaresia_ramsayi",9,11,11,10,9,9,10,12,13,13,11,9,9,10,11,11,9,10,10,5,5,5,5,2,0,5,5,5,8,8,10,10,9
+"Liasis_albertisii",8,10,10,9,8,8,9,11,12,12,10,8,8,9,10,10,8,9,9,6,6,6,6,5,5,0,2,4,7,7,9,9,8
+"Bothrochilus_boa",8,10,10,9,8,8,9,11,12,12,10,8,8,9,10,10,8,9,9,6,6,6,6,5,5,2,0,4,7,7,9,9,8
+"Morelia_boeleni",6,8,8,7,6,6,7,9,10,10,8,6,6,7,8,8,6,7,7,6,6,6,6,5,5,4,4,0,5,5,7,7,6
+"Python_timoriensis",5,7,7,6,7,7,8,10,11,11,9,7,7,8,9,9,7,8,8,9,9,9,9,8,8,7,7,5,0,2,6,6,5
+"Python_reticulatus",5,7,7,6,7,7,8,10,11,11,9,7,7,8,9,9,7,8,8,9,9,9,9,8,8,7,7,5,2,0,6,6,5
+"Xenopeltis_unicolor",5,7,7,6,9,9,10,12,13,13,11,9,9,10,11,11,9,10,10,11,11,11,11,10,10,9,9,7,6,6,0,2,3
+"Candoia_aspera",5,7,7,6,9,9,10,12,13,13,11,9,9,10,11,11,9,10,10,11,11,11,11,10,10,9,9,7,6,6,2,0,3
+"Loxocemus_bicolor",4,6,6,5,8,8,9,11,12,12,10,8,8,9,10,10,8,9,9,10,10,10,10,9,9,8,8,6,5,5,3,3,0
diff --git a/dendropy/test/data/other/pythonidae.mle.weighted.pdm.csv b/dendropy/test/data/other/pythonidae.mle.weighted.pdm.csv
new file mode 100644
index 0000000..2563e67
--- /dev/null
+++ b/dendropy/test/data/other/pythonidae.mle.weighted.pdm.csv
@@ -0,0 +1,34 @@
+,Python_regius,Python_sebae,Python_molurus,Python_curtus,Morelia_bredli,Morelia_spilota,Morelia_tracyae,Morelia_clastolepis,Morelia_kinghorni,Morelia_nauta,Morelia_amethistina,Morelia_oenpelliensis,Antaresia_maculosa,Antaresia_perthensis,Antaresia_stimsoni,Antaresia_childreni,Morelia_carinata,Morelia_viridisN,Morelia_viridisS,Apodora_papuana,Liasis_olivaceus,Liasis_fuscus,Liasis_mackloti,Antaresia_melanocephalus,Antaresia_ramsayi,Liasis_albertisii,Bothrochilus_boa,Morelia_boeleni,Python_ [...]
+Python_regius,0.00000000000000000000000,0.20668083399999997995522,0.17729567219999997629287,0.22876476870000000962690,0.28886837920000002499776,0.28554261810000003407595,0.30189288570000000211380,0.29442194079999994826835,0.30164184789999998193011,0.30267485970000002071245,0.29404437999999999409084,0.29727778980000002517770,0.29829548160000002310355,0.31930349140000002794437,0.29085829199999996275139,0.29876102449999997201502,0.29827494730000003730908,0.29731820230000000071513,0.30692725 [...]
+Python_sebae,0.20668083399999997995522,0.00000000000000000000000,0.09656595519999999766014,0.19133505170000000839003,0.28376466220000001738910,0.28043890110000002646728,0.29678916870000005001629,0.28931822380000005168199,0.29653813090000002983260,0.29757114270000006861494,0.28894066300000004199333,0.29217407280000007308018,0.29319176460000001549489,0.31419977440000002033571,0.28575457500000001065388,0.29365730750000001991751,0.29317123030000002970041,0.29221448530000004861762,0.301823534 [...]
+Python_molurus,0.17729567219999997629287,0.09656595519999999766014,0.00000000000000000000000,0.16194988990000000472769,0.25437950040000001372675,0.25105373930000002280494,0.26740400690000004635394,0.25993306199999999250849,0.26715296910000002617025,0.26818598090000006495259,0.25955550120000003833098,0.26278891100000001390669,0.26380660280000001183254,0.28481461260000001667336,0.25636941320000000699153,0.26427214570000001625516,0.26378606850000002603807,0.26282932349999998944412,0.2724383 [...]
+Python_curtus,0.22876476870000000962690,0.19133505170000000839003,0.16194988990000000472769,0.00000000000000000000000,0.30584859689999999154963,0.30252283580000000062782,0.31887310339999996866567,0.31140215849999997033137,0.31862206559999994848198,0.31965507739999998726432,0.31102459769999996064271,0.31425800749999999172957,0.31527569930000004516657,0.33628370910000005000740,0.30783850970000004032556,0.31574124220000004958919,0.31525516500000005937210,0.31429842000000002277815,0.32390746 [...]
+Morelia_bredli,0.28886837920000002499776,0.28376466220000001738910,0.25437950040000001372675,0.30584859689999999154963,0.00000000000000000000000,0.05165844630000000076153,0.12072071389999999846410,0.11324976900000000012980,0.12046967610000000603598,0.12150268790000000318496,0.11287220819999999044114,0.11610561799999999377242,0.18058730979999998433883,0.20159531959999998917965,0.17315012020000000725339,0.18105285269999998876145,0.18056677549999999854435,0.17961003049999998970598,0.1892190 [...]
+Morelia_spilota,0.28554261810000003407595,0.28043890110000002646728,0.25105373930000002280494,0.30252283580000000062782,0.05165844630000000076153,0.00000000000000000000000,0.11739495280000000754228,0.10992400790000000920799,0.11714391500000001511417,0.11817692680000001226315,0.10954644709999999951933,0.11277985690000000285060,0.17726154869999999341701,0.19826955849999999825783,0.16982435910000001633158,0.17772709159999999783963,0.17724101440000000762254,0.17628426939999999878417,0.185893 [...]
+Morelia_tracyae,0.30189288570000000211380,0.29678916870000005001629,0.26740400690000004635394,0.31887310339999996866567,0.12072071389999999846410,0.11739495280000000754228,0.00000000000000000000000,0.06811627550000000363983,0.07533618260000000954602,0.07636919440000000669500,0.06773871470000000782896,0.12056412450000000835537,0.19361181630000001696601,0.21461982609999999405126,0.18617462670000001212500,0.19407735919999999363306,0.19359128200000000341596,0.19263453699999999457759,0.202243 [...]
+Morelia_clastolepis,0.29442194079999994826835,0.28931822380000005168199,0.25993306199999999250849,0.31140215849999997033137,0.11324976900000000012980,0.10992400790000000920799,0.06811627550000000363983,0.00000000000000000000000,0.01630923769999999967117,0.01734224950000000028960,0.04590576979999999585047,0.11309317959999999614329,0.18614087140000001863172,0.20714888119999999571696,0.17870368180000001379071,0.18660641429999999529876,0.18612033709999997732609,0.18516359209999999624330,0.19 [...]
+Morelia_kinghorni,0.30164184789999998193011,0.29653813090000002983260,0.26715296910000002617025,0.31862206559999994848198,0.12046967610000000603598,0.11714391500000001511417,0.07533618260000000954602,0.01630923769999999967117,0.00000000000000000000000,0.01619815659999999934993,0.05312567690000000175665,0.12031308669999998817168,0.19336077849999999678232,0.21436878830000000162315,0.18592358890000001969689,0.19382632140000000120494,0.19334024420000001098785,0.19238349920000000214948,0.2019 [...]
+Morelia_nauta,0.30267485970000002071245,0.29757114270000006861494,0.26818598090000006495259,0.31965507739999998726432,0.12150268790000000318496,0.11817692680000001226315,0.07636919440000000669500,0.01734224950000000028960,0.01619815659999999934993,0.00000000000000000000000,0.05415868869999999890563,0.12134609849999999919845,0.19439379029999998005351,0.21540180009999998489434,0.18695660070000000296808,0.19485933319999998447614,0.19437325599999999425904,0.19341651099999998542067,0.20302555 [...]
+Morelia_amethistina,0.29404437999999999409084,0.28894066300000004199333,0.25955550120000003833098,0.31102459769999996064271,0.11287220819999999044114,0.10954644709999999951933,0.06773871470000000782896,0.04590576979999999585047,0.05312567690000000175665,0.05415868869999999890563,0.00000000000000000000000,0.11271561880000000033242,0.18576331060000000894306,0.20677132039999998602831,0.17832612100000000410205,0.18622885349999998561010,0.18574277629999996763743,0.18478603129999998655464,0.19 [...]
+Morelia_oenpelliensis,0.29727778980000002517770,0.29217407280000007308018,0.26278891100000001390669,0.31425800749999999172957,0.11610561799999999377242,0.11277985690000000285060,0.12056412450000000835537,0.11309317959999999614329,0.12031308669999998817168,0.12134609849999999919845,0.11271561880000000033242,0.00000000000000000000000,0.18899672040000001227433,0.21000473020000001711516,0.18155953080000003518890,0.18946226330000001669696,0.18897618609999999872429,0.18801944109999998988592,0. [...]
+Antaresia_maculosa,0.29829548160000002310355,0.29319176460000001549489,0.26380660280000001183254,0.31527569930000004516657,0.18058730979999998433883,0.17726154869999999341701,0.19361181630000001696601,0.18614087140000001863172,0.19336077849999999678232,0.19439379029999998005351,0.18576331060000000894306,0.18899672040000001227433,0.00000000000000000000000,0.15685042199999998935311,0.12840522260000000742686,0.13630795509999998893491,0.15905587790000000336654,0.15809913289999999452817,0.167 [...]
+Antaresia_perthensis,0.31930349140000002794437,0.31419977440000002033571,0.28481461260000001667336,0.33628370910000005000740,0.20159531959999998917965,0.19826955849999999825783,0.21461982609999999405126,0.20714888119999999571696,0.21436878830000000162315,0.21540180009999998489434,0.20677132039999998602831,0.21000473020000001711516,0.15685042199999998935311,0.00000000000000000000000,0.12371723240000001564631,0.13161996489999999715437,0.18006388769999998045179,0.17910714269999999936900,0.1 [...]
+Antaresia_stimsoni,0.29085829199999996275139,0.28575457500000001065388,0.25636941320000000699153,0.30783850970000004032556,0.17315012020000000725339,0.16982435910000001633158,0.18617462670000001212500,0.17870368180000001379071,0.18592358890000001969689,0.18695660070000000296808,0.17832612100000000410205,0.18155953080000003518890,0.12840522260000000742686,0.12371723240000001564631,0.00000000000000000000000,0.03838076549999999698137,0.15161868829999999852554,0.15066194329999998968717,0.160 [...]
+Antaresia_childreni,0.29876102449999997201502,0.29365730750000001991751,0.26427214570000001625516,0.31574124220000004958919,0.18105285269999998876145,0.17772709159999999783963,0.19407735919999999363306,0.18660641429999999529876,0.19382632140000000120494,0.19485933319999998447614,0.18622885349999998561010,0.18946226330000001669696,0.13630795509999998893491,0.13161996489999999715437,0.03838076549999999698137,0.00000000000000000000000,0.15952142079999998003359,0.15856467579999999895080,0.16 [...]
+Morelia_carinata,0.29827494730000003730908,0.29317123030000002970041,0.26378606850000002603807,0.31525516500000005937210,0.18056677549999999854435,0.17724101440000000762254,0.19359128200000000341596,0.18612033709999997732609,0.19334024420000001098785,0.19437325599999999425904,0.18574277629999996763743,0.18897618609999999872429,0.15905587790000000336654,0.18006388769999998045179,0.15161868829999999852554,0.15952142079999998003359,0.00000000000000000000000,0.13111459859999999300051,0.14072 [...]
+Morelia_viridisN,0.29731820230000000071513,0.29221448530000004861762,0.26282932349999998944412,0.31429842000000002277815,0.17961003049999998970598,0.17628426939999999878417,0.19263453699999999457759,0.18516359209999999624330,0.19238349920000000214948,0.19341651099999998542067,0.18478603129999998655464,0.18801944109999998988592,0.15809913289999999452817,0.17910714269999999936900,0.15066194329999998968717,0.15856467579999999895080,0.13111459859999999300051,0.00000000000000000000000,0.08510 [...]
+Morelia_viridisS,0.30692725100000001203782,0.30182353400000005994031,0.27243837220000000076681,0.32390746870000003410084,0.18921907919999997327309,0.18589331809999998235128,0.20224358570000000590028,0.19477264080000000756598,0.20199254789999998571659,0.20302555969999996898778,0.19439507999999999787732,0.19762848979999997345303,0.16770818160000000585086,0.18871619140000001069168,0.16027099200000000100985,0.16817372450000001027348,0.14072364729999997656762,0.08510890229999999723187,0.00000 [...]
+Apodora_papuana,0.30066050739999999885654,0.29555679039999999124788,0.26617162859999998758553,0.31764072510000002091957,0.19615633560000000912282,0.19283057450000001820101,0.20918084209999998623886,0.20170989719999998790456,0.20892980430000002156632,0.20996281610000000483751,0.20133233639999997821590,0.20456574620000000930276,0.20558343800000000722861,0.22659144779999995655828,0.19814624840000000238760,0.20604898090000001165123,0.20556290370000002143414,0.20460615869999998484019,0.214215 [...]
+Liasis_olivaceus,0.27666237830000001141073,0.27155866130000000380207,0.24217349950000000013972,0.29364259600000003347375,0.17215820650000002167701,0.16883244540000003075519,0.18518271299999999879304,0.17771176810000000045875,0.18493167520000000636493,0.18596468700000001739170,0.17733420729999999077009,0.18056761710000002185694,0.18158530890000001978279,0.20259331869999996911247,0.17414811930000001494179,0.18205085180000002420542,0.18156477460000000623275,0.18060802959999999739438,0.19021 [...]
+Liasis_fuscus,0.29140959630000001778782,0.28630587930000001017916,0.25692071750000000651681,0.30838981400000003985085,0.18690542450000000029853,0.18357966340000000937671,0.19992993099999997741456,0.19245898609999997908027,0.19967889319999998498645,0.20071190499999999601322,0.19208142529999996939161,0.19531483510000000047846,0.19633252689999999840431,0.21734053669999994773399,0.18889533729999999356330,0.19679806980000000282693,0.19631199259999998485426,0.19535524759999997601589,0.20496429 [...]
+Liasis_mackloti,0.28611091729999998944933,0.28100720029999998184067,0.25162203849999997817832,0.30309113500000001151236,0.18160674549999999971561,0.17828098440000000879380,0.19463125199999997683165,0.18716030709999997849735,0.19438021419999998440353,0.19541322599999999543030,0.18678274629999996880869,0.19001615609999999989554,0.19103384789999999782140,0.21204185769999994715107,0.18359665829999999298039,0.19149939080000000224402,0.19101331359999998427135,0.19005656859999997543298,0.199665 [...]
+Antaresia_melanocephalus,0.29168783090000000024489,0.28658411389999999263622,0.25719895209999998897388,0.30866804860000002230791,0.18718365910000001051117,0.18385789800000001958935,0.20020816559999998762720,0.19273722069999998929291,0.19995712780000002295466,0.20099013960000000622586,0.19235965989999997960425,0.19559306970000001069110,0.19661076150000000861695,0.21761877129999998570220,0.18917357190000000377594,0.19707630440000001303957,0.19659022720000002282248,0.19563348219999998622853 [...]
+Antaresia_ramsayi,0.28616570219999998281324,0.28106198520000003071573,0.25167682340000002705338,0.30314591990000000487626,0.18166153039999999307952,0.17833576930000000215770,0.19468603689999997019555,0.18721509199999997186126,0.19443499910000000552301,0.19546801089999998879421,0.18683753119999996217260,0.19007094099999999325945,0.19108863279999999118530,0.21209664259999996827055,0.18365144319999998634430,0.19155417569999999560793,0.19106809850000000539083,0.19011135349999996879689,0.1997 [...]
+Liasis_albertisii,0.29491652530000000975718,0.28981280830000000214852,0.26042764650000005399733,0.31189674300000003182021,0.19041235350000002002346,0.18708659240000002910165,0.20343685999999999713950,0.19596591509999999880520,0.20318582220000000471138,0.20421883400000001573815,0.19558835429999998911654,0.19882176410000002020340,0.19983945590000001812925,0.22084746569999999521450,0.19240226630000001328824,0.20030499880000002255187,0.19981892160000000457920,0.19886217659999999574083,0.2084 [...]
+Bothrochilus_boa,0.30456179690000001469841,0.29945807990000000708974,0.27007291810000000342740,0.32154201460000003676143,0.20005762510000002496469,0.19673186400000003404287,0.21308213160000000208072,0.20561118670000000374642,0.21283109379999998189703,0.21386410560000002067937,0.20523362589999999405777,0.20846703570000002514462,0.20948472750000002307047,0.23049273729999997240014,0.20204753790000001822946,0.20995027040000002749309,0.20946419319999998176485,0.20850744820000000068205,0.21811 [...]
+Morelia_boeleni,0.28393270689999999811803,0.27882898990000004602052,0.24944382810000004235818,0.30091292460000002018106,0.17942853510000000838431,0.17610277400000001746250,0.19245304159999998550035,0.18498209669999998716605,0.19220200380000002082781,0.19323501560000000409900,0.18460453589999997747739,0.18783794570000000856425,0.18885563750000000649010,0.20986364730000001133092,0.18141844790000000164909,0.18932118040000001091272,0.18883510320000002069563,0.18787835819999998410168,0.197487 [...]
+Python_timoriensis,0.30410704249999997994536,0.29900332550000002784785,0.26961816370000002418550,0.32108726020000000200838,0.25380087070000001414627,0.25047510960000002322445,0.26682537719999999126230,0.25935443229999999292801,0.26657433940000002658977,0.26760735120000000986096,0.25897687150000003875050,0.26221028130000001432620,0.26322797310000001225205,0.28423598290000001709288,0.25579078350000006292220,0.26369351600000001667468,0.26320743880000002645758,0.26225069379999998986364,0.271 [...]
+Python_reticulatus,0.28588858100000003048535,0.28078486400000002287669,0.25139970220000001921434,0.30286879870000005254838,0.23558240920000000917511,0.23225664810000001825330,0.24860691570000001404672,0.24113597080000001571243,0.24835587790000002161861,0.24938888970000003264538,0.24075841000000000602377,0.24399181980000000935505,0.24500951160000000728090,0.26601752140000001212172,0.23757232200000003019547,0.24547505450000001170352,0.24498897730000002148643,0.24403223230000001264806,0.253 [...]
+Xenopeltis_unicolor,0.44630005519999998986336,0.44119633819999998225470,0.41181117639999997859235,0.46328027289999995641523,0.45789788340000003863395,0.45457212229999999220098,0.47092238990000001574998,0.46345144500000001741569,0.47067135209999999556629,0.47170436390000003434864,0.46307388419999995221588,0.46630729400000003881388,0.46732498580000003673973,0.48833299559999998606941,0.45988779619999997638757,0.46779052870000004116235,0.46730445149999999543411,0.46634770650000001435131,0.47 [...]
+Candoia_aspera,0.65722460599999998898113,0.65212088899999998137247,0.62273572720000003322127,0.67420482370000001104415,0.66882243419999998224057,0.66549667310000004682990,0.68184694070000007037891,0.67437599579999996102231,0.68159590290000005019522,0.68262891469999997795526,0.67399843500000000684480,0.67723184480000009344280,0.67824953660000009136866,0.69925754640000004069833,0.67081234700000003101650,0.67871507950000009579128,0.67822900230000005006303,0.67727225730000006898024,0.6868813 [...]
+Loxocemus_bicolor,0.46221315200000001599534,0.45710943500000000838668,0.42772427319999994921318,0.47919336969999998254721,0.47381098020000000925478,0.47048521909999996282181,0.48683548669999998637081,0.47936454179999998803652,0.48658444889999996618712,0.48761746070000000496947,0.47898698099999997834786,0.48222039080000000943471,0.48323808260000000736056,0.50424609239999995669024,0.47580089300000000251956,0.48370362550000001178319,0.48321754829999996605494,0.48226080329999998497215,0.4918 [...]
diff --git a/dendropy/test/data/other/saitou_and_nei_1987_table1.csv b/dendropy/test/data/other/saitou_and_nei_1987_table1.csv
new file mode 100644
index 0000000..c997964
--- /dev/null
+++ b/dendropy/test/data/other/saitou_and_nei_1987_table1.csv
@@ -0,0 +1,9 @@
+,a  ,b  ,c  ,d  ,e  ,f  ,g  ,h
+a ,0  ,7  ,8  ,11 ,13 ,16 ,13 ,17
+b ,7  ,0  ,5  ,8  ,10 ,13 ,10 ,14
+c ,8  ,5  ,0  ,5  ,7  ,10 ,7  ,11
+d ,11 ,8  ,5  ,0  ,8  ,11 ,8  ,12
+e ,13 ,10 ,7  ,8  ,0  ,5  ,6  ,10
+f ,16 ,13 ,10 ,11 ,5  ,0  ,9  ,13
+g ,13 ,10 ,7  ,8  ,6  ,9  ,0  ,8
+h ,17 ,14 ,11 ,12 ,10 ,13 ,8  ,0
diff --git a/dendropy/test/data/other/wpnjex.csv b/dendropy/test/data/other/wpnjex.csv
new file mode 100644
index 0000000..0d4a45e
--- /dev/null
+++ b/dendropy/test/data/other/wpnjex.csv
@@ -0,0 +1,6 @@
+,a ,b  ,c  ,d  ,e
+a ,0 ,5  ,9  ,9  ,8
+b ,5 ,0  ,10 ,10 ,9
+c ,9 ,10 ,0  ,8  ,7
+d ,9 ,10 ,8  ,0  ,3
+e ,8 ,9  ,7  ,3  ,0
diff --git a/dendropy/test/data/other/wpupgmaex.csv b/dendropy/test/data/other/wpupgmaex.csv
new file mode 100644
index 0000000..19fd21f
--- /dev/null
+++ b/dendropy/test/data/other/wpupgmaex.csv
@@ -0,0 +1,6 @@
+,a,b,c,d,e
+a,0,17,21,31,23
+b,17,0,30,34,21
+c,21,30,0,28,39
+d,31,34,28,0,43
+e,23,21,39,43,0
diff --git a/dendropy/test/data/trees/community.tree.newick b/dendropy/test/data/trees/community.tree.newick
new file mode 100644
index 0000000..a5dc026
--- /dev/null
+++ b/dendropy/test/data/trees/community.tree.newick
@@ -0,0 +1 @@
+((((spA:0.1069227899,spB:0.1069227899):0.6790659992,(((spC:0.08759679337,spD:0.08759679337):0.2425718267,(spE:0.1304344941,spF:0.1304344941):0.1997341259):0.4031376156,(spG:0.1272250006,((spH:0.0459695118,spI:0.0459695118):0.07610566242,spJ:0.1220751742):0.005149826433):0.606081235):0.05268255344):0.7805873584,((spK:0.05840645685,(spL:0.04082421791,spM:0.04082421791):0.01758223893):0.3144974758,spN:0.3729039327):1.193672215):1.229545656,spO:2.796121803);
diff --git a/dendropy/test/data/trees/hiv1.newick b/dendropy/test/data/trees/hiv1.newick
index 7cda28d..266c731 100644
--- a/dendropy/test/data/trees/hiv1.newick
+++ b/dendropy/test/data/trees/hiv1.newick
@@ -1 +1 @@
-(((((((((((A97DCA1EQTB52:182,A97DCA1MBFE185:182):1,(A97DCA1MBS12:181,A97DCA1MBS30:181):2):1,A97DCA1SJDS17:184):1,(A97DCA1KCD9:180,A97DCA1KTB185:180):5):1,A97DCA1KFE58:186):1,(A97DCA1KP18:179,(A97DCA1KP28:178,(A97DCA1KP78:177,A97DCA1MBS63:177):1):1):8):1,(((A97DCA2KP82:174,A97DCA2KP86:174):1,A97DCA2MBCD5:175):1,((((A97DCEQS1:170,A97DCKFE326:170):1,A97DCMBS32:171):1,(A97DCEQS18:169,A97DCKP72:169):3):1,((((((A97DCEQS25:163,A97DCKS34:163):1,A97DCKS47:164):1,(A97DCKMST147:162,(A97DCKMST89:161 [...]
+(((((((((((1:182,2:182)204:1,(3:181,4:181)205:2)203:1,5:184)202:1,(6:180,7:180)206:5)201:1,8:186)200:1,(9:179,(10:178,(11:177,12:177)209:1)208:1)207:8)199:1,(((13:174,14:174)212:1,15:175)211:1,((((16:170,17:170)216:1,18:171)215:1,(19:169,20:169)217:3)214:1,((((((21:163,22:163)223:1,23:164)222:1,(24:162,(25:161,26:161)225:1)224:3)221:1,((((27:157,((28:155,29:155)231:1,30:156)230:1)229:1,(31:154,32:154)232:4)228:1,(33:153,(((34:150,35:150)236:1,36:151)235:1,(37:149,38:149)237:3)234:1)233:6 [...]
diff --git a/dendropy/test/data/trees/hiv1.nexus b/dendropy/test/data/trees/hiv1.nexus
index ff4a6c3..63dee8e 100644
--- a/dendropy/test/data/trees/hiv1.nexus
+++ b/dendropy/test/data/trees/hiv1.nexus
@@ -200,200 +200,5 @@ BEGIN TAXA;
 	;
 END;
 BEGIN TREES;
-	TRANSLATE
-		1	A97DCA1EQTB52,
-		2	A97DCA1MBFE185,
-		3	A97DCA1MBS12,
-		4	A97DCA1MBS30,
-		5	A97DCA1SJDS17,
-		6	A97DCA1KCD9,
-		7	A97DCA1KTB185,
-		8	A97DCA1KFE58,
-		9	A97DCA1KP18,
-		10	A97DCA1KP28,
-		11	A97DCA1KP78,
-		12	A97DCA1MBS63,
-		13	A97DCA2KP82,
-		14	A97DCA2KP86,
-		15	A97DCA2MBCD5,
-		16	A97DCEQS1,
-		17	A97DCKFE326,
-		18	A97DCMBS32,
-		19	A97DCEQS18,
-		20	A97DCKP72,
-		21	A97DCEQS25,
-		22	A97DCKS34,
-		23	A97DCKS47,
-		24	A97DCKMST147,
-		25	A97DCKMST89,
-		26	A97DCKTB6,
-		27	A97DCEQTB44,
-		28	A97DCKDS85,
-		29	A97DCMBS26,
-		30	A97DCKTB79,
-		31	A97DCKTB118,
-		32	A97DCKTB132,
-		33	A97DCKCC4,
-		34	A97DCKP25,
-		35	A97DCKTB7,
-		36	A97DCMBS9,
-		37	A97DCKS36,
-		38	A97DCKTB37,
-		39	A97DCKCD6,
-		40	A97DCMBFE149,
-		41	A97DCMBFE247,
-		42	A97DCKFE198,
-		43	A97DCKP77,
-		44	A97DCKMST52,
-		45	A97DCKS7,
-		46	A97DCKTB36,
-		47	A97DCKP36,
-		48	A97DCKTB16,
-		49	A97DCMBS28,
-		50	A97DCMBTB54,
-		51	A97DCKP5,
-		52	A97DCMBFE155,
-		53	A97DCMBFE244,
-		54	A97DCMBFE78,
-		55	A97DCMBS7,
-		56	A97DCMBS341,
-		57	A97DCKTB157,
-		58	A97DCMBP2,
-		59	A97DCMBS4,
-		60	A97DCMBTB29,
-		61	A97DCMBDS17,
-		62	A97DCEQS45,
-		63	A97DCEQS49,
-		64	A97DCKS56,
-		65	A97DCEQTB14,
-		66	A97DCKTB20,
-		67	A97DCKTB44,
-		68	A97DCKCC2,
-		69	A97DCKCC3,
-		70	A97DCKTB13,
-		71	A97DCKMST140,
-		72	A97DCKMST121,
-		73	A97DCKP43,
-		74	A97DCKP79,
-		75	A97DCKS55,
-		76	A97DCKTB124,
-		77	A97DCKFE4,
-		78	A97DCKS10,
-		79	A97DCKTB48,
-		80	A97DCKFE288,
-		81	A97DCMBFE5,
-		82	A97DCSJFE26,
-		83	A97DCKMST50,
-		84	A97DCKS14,
-		85	U97DCKFE267,
-		86	U97DCKTB119,
-		87	U97DCMBFE250,
-		88	U97DCKMST91,
-		89	E97DCEQS21,
-		90	E97DCEQS5,
-		91	E97DCKP14,
-		92	E97DCEQTB60,
-		93	U97DCKFE45,
-		94	U97DCKTB49,
-		95	D97DCD1KCD4,
-		96	D97DCD1KMST126,
-		97	D97DCD1KS2,
-		98	D97DCKP54,
-		99	D97DCKP44,
-		100	D97DCKTB181,
-		101	D97DCMBS55,
-		102	D97DCMBS56,
-		103	D97DCD2KTB23,
-		104	D97DCKMST66,
-		105	D97DCKMST30,
-		106	D97DCKP1,
-		107	D97DCKS11,
-		108	D97DCKTB27,
-		109	D97DCKTB4,
-		110	D97DCMBS35,
-		111	D97DCD2KS26,
-		112	D97DCKS15,
-		113	D97DCKS39,
-		114	D97DCMBS342,
-		115	D97DCKMST144,
-		116	D97DCKS29,
-		117	D97DCKFE53,
-		118	C97DCKCD11,
-		119	C97DCKFE372,
-		120	C97DCMBFE92,
-		121	C97DCKTB110,
-		122	C97DCMBFE14,
-		123	C97DCMBFE300,
-		124	C97DCMBFE34,
-		125	C97DCMBS37,
-		126	C97DCMBFE61,
-		127	C97DCMBTB58,
-		128	C97DCMBTB11,
-		129	C97DCMBTB10,
-		130	C97DCSJFE59,
-		131	C97DCMBS20,
-		132	C97DCMBTB3,
-		133	C97DCMBS33,
-		134	C97DCMBS80,
-		135	C97DCMBTB13,
-		136	F97DCF1EQS16,
-		137	F97DCF1KP35,
-		138	F97DCF1KP40,
-		139	F97DCF1KTB136,
-		140	F97DCF1KTB50,
-		141	F97DCF1KS50,
-		142	F97DCF1KTB165,
-		143	F97DCF1MBFE183,
-		144	K97DCEQTB43,
-		145	K97DCKTB160,
-		146	K97DCKP13,
-		147	K97DCKTB111,
-		148	K97DCMBFE71,
-		149	K97DCKTB1,
-		150	U97DCKTB17,
-		151	U97DCEQS8,
-		152	G97DCKCC1,
-		153	G97DCKFE181,
-		154	G97DCKTB56,
-		155	G97DCKFE77,
-		156	G97DCKP74,
-		157	G97DCKMST100,
-		158	G97DCKMST85,
-		159	G97DCMBTB7,
-		160	G97DCKS4,
-		161	G97DCKTB142,
-		162	G97DCKTB18,
-		163	G97DCKMST10,
-		164	G97DCKS30,
-		165	G97DCMBFE91,
-		166	G97DCKS27,
-		167	U97DCKTB22,
-		168	U97DCKMST135,
-		169	U97DCEQS29,
-		170	J97DCKFE339,
-		171	J97DCMBTB4,
-		172	J97DCKS22,
-		173	J97DCMBS41,
-		174	J97DCKTB147,
-		175	J97DCKTB14,
-		176	J97DCKS16,
-		177	U97DCKMST120,
-		178	H97DCEQTB1,
-		179	H97DCEQTB80,
-		180	H97DCKP63,
-		181	H97DCKTB158,
-		182	H97DCKS18,
-		183	H97DCKS42,
-		184	H97DCKTB176,
-		185	H97DCKTB62,
-		186	H97DCKCD2,
-		187	H97DCKMST43,
-		188	H97DCKTB140,
-		189	H97DCKTB188,
-		190	H97DCKS38,
-		191	H97DCKS43,
-		192	H97DCKTB32,
-		193	H97DCKTB52
-	;
-	TREE * UNTITLED = [&R] (((((((((((1:182,2:182):1,(3:181,4:181):2):1,5:184):1,(6:180,7:180):5):1,8:186):1,(9:179,(10:178,(11:177,12:177):1):1):8):1,(((13:174,14:174):1,15:175):1,((((16:170,17:170):1,18:171):1,(19:169,20:169):3):1,((((((21:163,22:163):1,23:164):1,(24:162,(25:161,26:161):1):3):1,((((27:157,((28:155,29:155):1,30:156):1):1,(31:154,32:154):4):1,(33:153,(((34:150,35:150):1,36:151):1,(37:149,38:149):3):1):6):1,(((39:146,(40:145,41:145):1):1,((42:143,43:143):1,(44:142,45:142):2) [...]
+	TREE * UNTITLED = [&R] (((((((((((A97DCA1EQTB52:182,A97DCA1MBFE185:182)204:1,(A97DCA1MBS12:181,A97DCA1MBS30:181)205:2)203:1,A97DCA1SJDS17:184)202:1,(A97DCA1KCD9:180,A97DCA1KTB185:180)206:5)201:1,A97DCA1KFE58:186)200:1,(A97DCA1KP18:179,(A97DCA1KP28:178,(A97DCA1KP78:177,A97DCA1MBS63:177)209:1)208:1)207:8)199:1,(((A97DCA2KP82:174,A97DCA2KP86:174)212:1,A97DCA2MBCD5:175)211:1,((((A97DCEQS1:170,A97DCKFE326:170)216:1,A97DCMBS32:171)215:1,(A97DCEQS18:169,A97DCKP72:169)217:3)214:1,((((((A97DCEQS [...]
 END;
diff --git a/dendropy/test/data/trees/pythonidae.mle.numbered-nodes.newick b/dendropy/test/data/trees/pythonidae.mle.numbered-nodes.newick
new file mode 100644
index 0000000..5261c21
--- /dev/null
+++ b/dendropy/test/data/trees/pythonidae.mle.numbered-nodes.newick
@@ -0,0 +1,2 @@
+(((1:0.1058922755,((2:0.0629755585,3:0.0335903967)38:0.02165,4:0.1067094932)37:0.016163)36:0.032743,(((((5:0.0274921037,6:0.0241663426)43:0.026356,((7:0.0377936102,((8:0.0045446653,(9:0.0075825724,10:0.0086155842)48:0.004182)47:0.018597,11:0.0227641045)46:0.007181)45:0.024796,12:0.0579745143)44:0.004283)42:0.031732,((13:0.0679212061,(14:0.0760812159,(15:0.0152390165,16:0.023141749)52:0.032397)51:0.012848)50:0.011617,(17:0.0660356718,(18:0.0377499268,19:0.0473589755)54:0.027329)53:0.01348 [...]
+
diff --git a/dendropy/test/support/compare_and_validate.py b/dendropy/test/support/compare_and_validate.py
index 8b621ae..350554d 100644
--- a/dendropy/test/support/compare_and_validate.py
+++ b/dendropy/test/support/compare_and_validate.py
@@ -16,13 +16,10 @@
 ##
 ##############################################################################
 
-try:
-    from StringIO import StringIO # Python 2 legacy support: StringIO in this module is the one needed (not io)
-except ImportError:
-    from io import StringIO # Python 3
 from . import pathmap
 from dendropy.datamodel import basemodel
 from dendropy.datamodel import charmatrixmodel
+from dendropy.utility.textprocessing import StringIO
 
 class ValidateWriteable(object):
 
diff --git a/dendropy/test/support/dendropytest.py b/dendropy/test/support/dendropytest.py
index e6dc013..43a210f 100644
--- a/dendropy/test/support/dendropytest.py
+++ b/dendropy/test/support/dendropytest.py
@@ -38,9 +38,9 @@ __unittest = True
 
 def discover_test_module_paths(filter_patterns=None):
     """
-    Discovers test modules. If ``filter_patterns`` is `None`, then
+    Discovers test modules. If ``filter_patterns`` is |None|, then
     all files in *immediate* directory that begin with 'test' will
-    be added to the set returned. If ``filter_patterns`` is not `None`, then it
+    be added to the set returned. If ``filter_patterns`` is not |None|, then it
     should be a list of regular expression patterns, and only files that match
     at least one of the patterns will be returned.
     """
@@ -61,7 +61,7 @@ def discover_test_module_paths(filter_patterns=None):
 
 def get_test_suite(test_names=None):
     """
-    If ``test_names`` is not `None`, creates a test suite out of those
+    If ``test_names`` is not |None|, creates a test suite out of those
     modules. Otherwise, creates a test suite from all of the modules in
     ``dendropy.test`` using the discovery.
     """
diff --git a/dendropy/test/support/pathmap.py b/dendropy/test/support/pathmap.py
index e36e2a0..f0a6644 100644
--- a/dendropy/test/support/pathmap.py
+++ b/dendropy/test/support/pathmap.py
@@ -83,6 +83,17 @@ def splits_source_path(filename=None):
         filename = ""
     return os.path.join(TESTS_DATA_DIR, "splits", filename)
 
+def other_source_stream(filename):
+    if not (sys.version_info.major >= 3 and sys.version_info.minor >= 4):
+        return open(other_source_path(filename), "rU")
+    else:
+        return open(other_source_path(filename), "r")
+
+def other_source_path(filename=None):
+    if filename is None:
+        filename = ""
+    return os.path.join(TESTS_DATA_DIR, "other", filename)
+
 def data_source_stream(filename):
     return open(data_source_path(filename), "rU")
 
diff --git a/dendropy/test/test_dataio_tokenizer.py b/dendropy/test/test_dataio_tokenizer.py
index a6969a4..0c6c49a 100644
--- a/dendropy/test/test_dataio_tokenizer.py
+++ b/dendropy/test/test_dataio_tokenizer.py
@@ -20,12 +20,9 @@
 Tests for tokenizers classes.
 """
 
-try:
-    from StringIO import StringIO # Python 2 legacy support: StringIO in this module is the one needed (not io)
-except ImportError:
-    from io import StringIO # Python 3
 import unittest
 from dendropy.dataio import nexusprocessing
+from dendropy.utility.textprocessing import StringIO
 
 class NexusTokenizerTestCase(unittest.TestCase):
     """
diff --git a/dendropy/test/test_datamodel_bipartitions.py b/dendropy/test/test_datamodel_bipartitions.py
index 581aebb..1c757c2 100644
--- a/dendropy/test/test_datamodel_bipartitions.py
+++ b/dendropy/test/test_datamodel_bipartitions.py
@@ -25,10 +25,6 @@ import unittest
 import re
 import sys
 import json
-try:
-    from StringIO import StringIO # Python 2 legacy support: StringIO in this module is the one needed (not io)
-except ImportError:
-    from io import StringIO # Python 3
 from dendropy.test.support import pathmap
 from dendropy.test.support import paupsplitsreference
 from dendropy.test.support.dendropytest import ExtendedTestCase
diff --git a/dendropy/test/test_datamodel_charmatrix.py b/dendropy/test/test_datamodel_charmatrix.py
index a490209..e1b7bdb 100644
--- a/dendropy/test/test_datamodel_charmatrix.py
+++ b/dendropy/test/test_datamodel_charmatrix.py
@@ -929,7 +929,11 @@ class MatrixCreatingAndCloningTester(
             self.assertIs(tcopy, toriginal)
             seq_copy = char_matrix2[tcopy]
             seq_original = char_matrix1[toriginal]
-            self.assertIs(seq_copy, seq_original)
+            ### changed, 2016-01-09: lists not longer the same object
+            # self.assertIs(seq_copy, seq_original)
+            self.assertEqual(len(seq_copy), len(seq_original))
+            for c1, c2 in zip(seq_copy, seq_original):
+                self.assertIs(c1, c2)
 
     def test_clone0(self):
         char_matrix1 = self.get_char_matrix()
@@ -997,7 +1001,7 @@ class ContinuousCharacterMatrixCreatingAndCloningTestCase(
     @classmethod
     def setUpClass(cls):
         cls.matrix_type = dendropy.ContinuousCharacterMatrix
-        cls.sequence_type = dendropy.ContinuousCharacterMatrix.ContinuousCharacterDataSequence
+        cls.sequence_type = dendropy.ContinuousCharacterDataSequence
         cls.sequence_source = [-1.0e-1, 42, 2.5e-6, 3.14e5, -1]
         cls.nseqs = 1000
         cls.build()
@@ -1009,7 +1013,7 @@ class DnaCharacterMatrixCreatingAndCloningTestCase(
     @classmethod
     def setUpClass(cls):
         cls.matrix_type = dendropy.DnaCharacterMatrix
-        cls.sequence_type = dendropy.DnaCharacterMatrix.DnaCharacterDataSequence
+        cls.sequence_type = dendropy.DnaCharacterDataSequence
         cls.sequence_source = list(cls.matrix_type.datatype_alphabet)
         cls.nseqs = 100
         cls.build()
@@ -1021,7 +1025,7 @@ class RnaCharacterMatrixCreatingAndCloningTestCase(
     @classmethod
     def setUpClass(cls):
         cls.matrix_type = dendropy.RnaCharacterMatrix
-        cls.sequence_type = dendropy.RnaCharacterMatrix.RnaCharacterDataSequence
+        cls.sequence_type = dendropy.RnaCharacterDataSequence
         cls.sequence_source = list(cls.matrix_type.datatype_alphabet)
         cls.nseqs = 100
         cls.build()
@@ -1033,7 +1037,7 @@ class NucleotideCharacterMatrixCreatingAndCloningTestCase(
     @classmethod
     def setUpClass(cls):
         cls.matrix_type = dendropy.NucleotideCharacterMatrix
-        cls.sequence_type = dendropy.NucleotideCharacterMatrix.NucleotideCharacterDataSequence
+        cls.sequence_type = dendropy.NucleotideCharacterDataSequence
         cls.sequence_source = list(cls.matrix_type.datatype_alphabet)
         cls.nseqs = 100
         cls.build()
@@ -1045,7 +1049,7 @@ class ProteinCharacterMatrixCreatingAndCloningTestCase(
     @classmethod
     def setUpClass(cls):
         cls.matrix_type = dendropy.ProteinCharacterMatrix
-        cls.sequence_type = dendropy.ProteinCharacterMatrix.ProteinCharacterDataSequence
+        cls.sequence_type = dendropy.ProteinCharacterDataSequence
         cls.sequence_source = list(cls.matrix_type.datatype_alphabet)
         cls.nseqs = 100
         cls.build()
@@ -1057,7 +1061,7 @@ class RestrictionSitesCharacterMatrixCreatingAndCloningTestCase(
     @classmethod
     def setUpClass(cls):
         cls.matrix_type = dendropy.RestrictionSitesCharacterMatrix
-        cls.sequence_type = dendropy.RestrictionSitesCharacterMatrix.RestrictionSitesCharacterDataSequence
+        cls.sequence_type = dendropy.RestrictionSitesCharacterDataSequence
         cls.sequence_source = list(cls.matrix_type.datatype_alphabet)
         cls.nseqs = 100
         cls.build()
@@ -1069,7 +1073,7 @@ class InfiniteSitesCharacterMatrixCreatingAndCloningTestCase(
     @classmethod
     def setUpClass(cls):
         cls.matrix_type = dendropy.InfiniteSitesCharacterMatrix
-        cls.sequence_type = dendropy.InfiniteSitesCharacterMatrix.InfiniteSitesCharacterDataSequence
+        cls.sequence_type = dendropy.InfiniteSitesCharacterDataSequence
         cls.sequence_source = list(cls.matrix_type.datatype_alphabet)
         cls.nseqs = 100
         cls.build()
diff --git a/dendropy/test/test_datamodel_split_bitmasks.py b/dendropy/test/test_datamodel_split_bitmasks.py
index 845a03a..5f2c994 100644
--- a/dendropy/test/test_datamodel_split_bitmasks.py
+++ b/dendropy/test/test_datamodel_split_bitmasks.py
@@ -24,17 +24,13 @@ import warnings
 import unittest
 import re
 import sys
-try:
-    from StringIO import StringIO # Python 2 legacy support: StringIO in this module is the one needed (not io)
-except ImportError:
-    from io import StringIO # Python 3
-
 from dendropy.test.support import pathmap
 from dendropy.test.support import paupsplitsreference
 from dendropy.test.support.dendropytest import ExtendedTestCase
 from dendropy.utility import messaging
 from dendropy.utility import bitprocessing
 from dendropy.interop import paup
+from dendropy.utility.textprocessing import StringIO
 from dendropy.calculate import treecompare
 import dendropy
 
diff --git a/dendropy/test/test_fitch.py b/dendropy/test/test_fitch.py
index 713104a..df5717b 100644
--- a/dendropy/test/test_fitch.py
+++ b/dendropy/test/test_fitch.py
@@ -23,10 +23,6 @@ Tests of Fitch algorithm calculations.
 import random
 import unittest
 import math
-try:
-    from StringIO import StringIO # Python 2 legacy support: StringIO in this module is the one needed (not io)
-except ImportError:
-    from io import StringIO # Python 3
 import sys
 if not (sys.version_info.major >= 3 and sys.version_info.minor >= 4):
     from dendropy.utility.filesys import pre_py34_open as open
diff --git a/dendropy/test/test_phylogenetic_distance_matrix.py b/dendropy/test/test_phylogenetic_distance_matrix.py
new file mode 100644
index 0000000..10c05f5
--- /dev/null
+++ b/dendropy/test/test_phylogenetic_distance_matrix.py
@@ -0,0 +1,854 @@
+#! /usr/bin/env python
+
+##############################################################################
+##  DendroPy Phylogenetic Computing Library.
+##
+##  Copyright 2010-2015 Jeet Sukumaran and Mark T. Holder.
+##  All rights reserved.
+##
+##  See "LICENSE.rst" for terms and conditions of usage.
+##
+##  If you use this work or any portion thereof in published work,
+##  please cite it as:
+##
+##     Sukumaran, J. and M. T. Holder. 2010. DendroPy: a Python library
+##     for phylogenetic computing. Bioinformatics 26: 1569-1571.
+##
+##############################################################################
+
+import unittest
+import dendropy
+import csv
+from dendropy.utility import container
+from dendropy.utility.textprocessing import StringIO
+from dendropy.test.support import pathmap
+from dendropy.calculate import treemeasure
+from dendropy.calculate import probability
+from dendropy.calculate import combinatorics
+
+class PhylogeneticDistanceMatrixCloneTest(unittest.TestCase):
+
+    def setUp(self):
+        self.tree = dendropy.Tree.get_from_string("(((a:1, b:1):1, c:2):1, (d:2, (e:1,f:1):1):1):0;", schema="newick")
+
+    def test_clone(self):
+        pdm0 = self.tree.phylogenetic_distance_matrix()
+        pdm1 = pdm0.clone()
+        self.assertIsNot(pdm0, pdm1)
+        self.assertIs(pdm0.taxon_namespace, pdm1.taxon_namespace)
+        self.assertEqual(len(pdm0.taxon_namespace), len(pdm0._mapped_taxa))
+        self.assertEqual(len(pdm1.taxon_namespace), len(pdm1._mapped_taxa))
+        for src, dest in (
+                    (pdm0._taxon_phylogenetic_distances, pdm1._taxon_phylogenetic_distances,),
+                    (pdm0._taxon_phylogenetic_path_steps, pdm1._taxon_phylogenetic_path_steps,),
+                    (pdm0._mrca, pdm1._mrca,),
+                ):
+            self.assertIsNot(src, dest)
+            for t1 in src:
+                self.assertIn(t1, dest)
+                self.assertIsNot(src[t1], dest[t1])
+        for t1 in self.tree.taxon_namespace:
+            for t2 in self.tree.taxon_namespace:
+                self.assertEqual(pdm0.patristic_distance(t1, t2), pdm1.patristic_distance(t1, t2))
+                self.assertEqual(pdm0.mrca(t1, t2), pdm1.mrca(t1, t2))
+                self.assertEqual(pdm0.path_edge_count(t1, t2), pdm1.path_edge_count(t1, t2))
+        self.assertEqual(set(pdm0.distances()), set(pdm1.distances()))
+        self.assertEqual(pdm0.sum_of_distances(), pdm1.sum_of_distances())
+        self.assertEqual(pdm0, pdm1)
+
+class PhylogeneticDistanceMatrixCompileTest(unittest.TestCase):
+
+        def setUp(self):
+            # library(ape)
+            # tree = read.nexus("data/pythonidae.mle.nex")
+            # pdm = cophenetic.phylo(tree)
+            # write.csv(format(pdm,digits=22), "pythonidae.mle.weighted.pdm.csv")
+            with open(pathmap.other_source_path("pythonidae.mle.weighted.pdm.csv")) as src:
+                self.reference_pdm_weighted_table = container.DataTable.from_csv(src, default_data_type=float, delimiter=",")
+            with open(pathmap.other_source_path("pythonidae.mle.unweighted.pdm.csv")) as src:
+                self.reference_pdm_unweighted_table = container.DataTable.from_csv(src, default_data_type=float, delimiter=",")
+            self.tree = dendropy.Tree.get(path=pathmap.tree_source_path(
+                "pythonidae.mle.nex"),
+                schema="nexus",
+                preserve_underscores=True)
+            self.pdm = self.tree.phylogenetic_distance_matrix()
+
+        def test_mapped_taxa(self):
+            n1 = len(self.tree.taxon_namespace)
+            self.assertEqual(self.pdm.taxon_namespace, self.tree.taxon_namespace)
+            self.assertEqual(n1, len(self.tree.taxon_namespace))
+            for taxon1 in self.tree.taxon_namespace:
+                self.assertIn(taxon1, self.pdm._mapped_taxa)
+            for taxon in self.pdm.taxon_iter():
+                self.assertIn(taxon1, self.pdm._mapped_taxa)
+                self.assertIn(taxon1, self.tree.taxon_namespace)
+
+        def test_all_distinct_mapped_taxa_pairs(self):
+            n1 = len(self.tree.taxon_namespace)
+            taxon_pair_iter1 = iter(self.pdm._all_distinct_mapped_taxa_pairs)
+            taxon_pair_iter2 = self.pdm.distinct_taxon_pair_iter()
+            for tpi in (taxon_pair_iter1, taxon_pair_iter2):
+                seen_pairs = set()
+                visited_taxa = set()
+                for taxon1, taxon2 in tpi:
+                    s = frozenset([taxon1, taxon2])
+                    self.assertIn(taxon1, self.pdm._mapped_taxa)
+                    self.assertIn(taxon1, self.tree.taxon_namespace)
+                    self.assertIn(taxon2, self.pdm._mapped_taxa)
+                    self.assertIn(taxon2, self.tree.taxon_namespace)
+                    self.assertNotIn(s, seen_pairs)
+                    seen_pairs.add(s)
+                    visited_taxa.add(taxon1)
+                    visited_taxa.add(taxon2)
+                self.assertEqual(len(visited_taxa), n1)
+                self.assertEqual(len(seen_pairs), combinatorics.choose(n1, 2))
+
+        def test_tree_length(self):
+            self.assertEqual(self.pdm._tree_length, self.tree.length())
+
+        def test_tree_num_edges(self):
+            self.assertEqual(self.pdm._num_edges, combinatorics.num_edges_on_tree(
+                num_leaves=len(self.tree.taxon_namespace), is_rooted=True))
+
+        def test_tree_weighted_unnormalized_pairwise_distance_query(self):
+            for taxon1 in self.tree.taxon_namespace:
+                for taxon2 in self.tree.taxon_namespace:
+                    exp = self.reference_pdm_weighted_table[taxon1.label, taxon2.label]
+                    obs1 = self.pdm._taxon_phylogenetic_distances[taxon1][taxon2]
+                    self.assertAlmostEqual(obs1, exp, 6)
+                    obs2 = self.pdm.patristic_distance(taxon1, taxon2)
+                    self.assertAlmostEqual(obs2, exp, 6)
+                    obs3 = self.pdm.distance(
+                            taxon1,
+                            taxon2,
+                            is_weighted_edge_distances=True,
+                            is_normalize_by_tree_size=False)
+                    self.assertAlmostEqual(obs3, exp, 6)
+
+        def test_tree_weighted_normalized_pairwise_distance_query(self):
+            tree_length = self.tree.length()
+            for taxon1 in self.tree.taxon_namespace:
+                for taxon2 in self.tree.taxon_namespace:
+                    exp = self.reference_pdm_weighted_table[taxon1.label, taxon2.label] / tree_length
+                    obs2 = self.pdm.patristic_distance(taxon1, taxon2, is_normalize_by_tree_size=True)
+                    self.assertAlmostEqual(obs2, exp, 6)
+                    obs3 = self.pdm.distance(
+                            taxon1,
+                            taxon2,
+                            is_weighted_edge_distances=True,
+                            is_normalize_by_tree_size=True)
+                    self.assertAlmostEqual(obs3, exp, 6)
+
+        def test_tree_unweighted_unnormalized_pairwise_distance_query(self):
+            for taxon1 in self.tree.taxon_namespace:
+                for taxon2 in self.tree.taxon_namespace:
+                    exp = self.reference_pdm_unweighted_table[taxon1.label, taxon2.label]
+                    obs1 = self.pdm._taxon_phylogenetic_path_steps[taxon1][taxon2]
+                    self.assertAlmostEqual(obs1, exp, 6)
+                    obs2 = self.pdm.path_edge_count(taxon1, taxon2)
+                    self.assertAlmostEqual(obs2, exp, 6)
+                    obs3 = self.pdm.distance(
+                            taxon1,
+                            taxon2,
+                            is_weighted_edge_distances=False,
+                            is_normalize_by_tree_size=False)
+                    self.assertAlmostEqual(obs3, exp, 6)
+
+        def test_tree_unweighted_normalized_pairwise_distance_query(self):
+            num_edges_on_tree = combinatorics.num_edges_on_tree(
+                    num_leaves=len(self.tree.taxon_namespace), is_rooted=True)
+            for taxon1 in self.tree.taxon_namespace:
+                for taxon2 in self.tree.taxon_namespace:
+                    exp = self.reference_pdm_unweighted_table[taxon1.label, taxon2.label] / num_edges_on_tree
+                    obs2 = self.pdm.path_edge_count(taxon1, taxon2, is_normalize_by_tree_size=True)
+                    self.assertAlmostEqual(obs2, exp, 6)
+                    obs3 = self.pdm.distance(
+                            taxon1,
+                            taxon2,
+                            is_weighted_edge_distances=False,
+                            is_normalize_by_tree_size=True)
+                    self.assertAlmostEqual(obs3, exp, 6)
+
+        def test_tree_weighted_unnormalized_pairwise_distance_collection(self):
+            # this test relies on populating the expected result list
+            # in the *same order* as the function it is testing
+            exp_list = []
+            for taxon1, taxon2 in self.pdm.distinct_taxon_pair_iter():
+                exp = self.reference_pdm_weighted_table[taxon1.label, taxon2.label]
+                exp_list.append(exp)
+            obs = self.pdm.distances(
+                    is_weighted_edge_distances=True,
+                    is_normalize_by_tree_size=False,
+                    )
+            self.assertEqual(len(obs), len(exp_list))
+            for obs, exp in zip(obs, exp_list):
+                self.assertAlmostEqual(obs, exp, 6)
+            self.assertAlmostEqual(self.pdm.sum_of_distances(
+                    is_weighted_edge_distances=True,
+                    is_normalize_by_tree_size=False,
+                    ), sum(exp_list), 6)
+
+        def test_tree_weighted_normalized_pairwise_distance_collection(self):
+            # this test relies on populating the expected result list
+            # in the *same order* as the function it is testing
+            tree_length = self.tree.length()
+            exp_list = []
+            for taxon1, taxon2 in self.pdm.distinct_taxon_pair_iter():
+                exp = self.reference_pdm_weighted_table[taxon1.label, taxon2.label] / tree_length
+                exp_list.append(exp)
+            obs = self.pdm.distances(
+                    is_weighted_edge_distances=True,
+                    is_normalize_by_tree_size=True,
+                    )
+            self.assertEqual(len(obs), len(exp_list))
+            for obs, exp in zip(obs, exp_list):
+                self.assertAlmostEqual(obs, exp, 6)
+            self.assertAlmostEqual(self.pdm.sum_of_distances(
+                    is_weighted_edge_distances=True,
+                    is_normalize_by_tree_size=True,
+                    ), sum(exp_list), 6)
+
+        def test_tree_unweighted_unnormalized_pairwise_distance_collection(self):
+            # this test relies on populating the expected result list
+            # in the *same order* as the function it is testing
+            exp_list = []
+            for taxon1, taxon2 in self.pdm.distinct_taxon_pair_iter():
+                exp = self.reference_pdm_unweighted_table[taxon1.label, taxon2.label]
+                exp_list.append(exp)
+            obs = self.pdm.distances(
+                    is_weighted_edge_distances=False,
+                    is_normalize_by_tree_size=False,
+                    )
+            self.assertEqual(len(obs), len(exp_list))
+            for obs, exp in zip(obs, exp_list):
+                self.assertAlmostEqual(obs, exp, 6)
+            self.assertAlmostEqual(self.pdm.sum_of_distances(
+                    is_weighted_edge_distances=False,
+                    is_normalize_by_tree_size=False,
+                    ), sum(exp_list), 6)
+
+        def test_tree_unweighted_normalized_pairwise_distance_collection(self):
+            # this test relies on populating the expected result list
+            # in the *same order* as the function it is testing
+            num_edges_on_tree = combinatorics.num_edges_on_tree(
+                    num_leaves=len(self.tree.taxon_namespace), is_rooted=True)
+            exp_list = []
+            for taxon1, taxon2 in self.pdm.distinct_taxon_pair_iter():
+                exp = self.reference_pdm_unweighted_table[taxon1.label, taxon2.label] / num_edges_on_tree
+                exp_list.append(exp)
+            obs = self.pdm.distances(
+                    is_weighted_edge_distances=False,
+                    is_normalize_by_tree_size=True,
+                    )
+            self.assertEqual(len(obs), len(exp_list))
+            for obs, exp in zip(obs, exp_list):
+                self.assertAlmostEqual(obs, exp, 6)
+            self.assertAlmostEqual(self.pdm.sum_of_distances(
+                    is_weighted_edge_distances=False,
+                    is_normalize_by_tree_size=True,
+                    ), sum(exp_list), 6)
+
+        def test_max_pairwise_weighted_distance_taxa(self):
+            maxd = None
+            maxt = None
+            for taxon1 in self.tree.taxon_namespace:
+                for taxon2 in self.tree.taxon_namespace:
+                    d = self.reference_pdm_weighted_table[taxon1.label, taxon2.label]
+                    if maxd is None or d > maxd:
+                        maxd = d
+                        maxt = set([taxon1, taxon2])
+            obs_maxt = self.pdm.max_pairwise_distance_taxa(is_weighted_edge_distances=True)
+            self.assertEqual(set(obs_maxt), maxt)
+
+        def test_max_pairwise_weighted_distance_taxa(self):
+            maxd = None
+            maxt = None
+            for taxon1 in self.tree.taxon_namespace:
+                for taxon2 in self.tree.taxon_namespace:
+                    d = self.reference_pdm_weighted_table[taxon1.label, taxon2.label]
+                    if maxd is None or d > maxd:
+                        maxd = d
+                        maxt = set([taxon1, taxon2])
+            obs_maxt = self.pdm.max_pairwise_distance_taxa(is_weighted_edge_distances=True)
+            self.assertEqual(set(obs_maxt), maxt)
+
+        def test_max_pairwise_unweighted_distance_taxa(self):
+            maxd = None
+            maxts = []
+            for taxon1 in self.tree.taxon_namespace:
+                for taxon2 in self.tree.taxon_namespace:
+                    d = self.reference_pdm_unweighted_table[taxon1.label, taxon2.label]
+                    if maxd is None or d > maxd:
+                        maxd = d
+                        maxts.append(set([taxon1, taxon2]))
+                    elif d == maxd:
+                        maxts.append(set([taxon1, taxon2]))
+            obs_maxt = self.pdm.max_pairwise_distance_taxa(is_weighted_edge_distances=False)
+            found_match = False
+            for maxt in maxts:
+                if set(obs_maxt) == maxt:
+                    found_match = True
+                    break
+            else:
+                self.fail()
+
+class PhylogeneticDistanceMatrixShuffleTest(unittest.TestCase):
+
+    def test_shuffle(self):
+        tree = dendropy.Tree.get_from_path(
+                    src=pathmap.tree_source_path("community.tree.newick"),
+                    schema="newick",
+                    rooting="force-rooted")
+        pdc0 = tree.phylogenetic_distance_matrix()
+        pdc1 = tree.phylogenetic_distance_matrix()
+        current_to_shuffled_taxon_map = pdc1.shuffle_taxa()
+        keys = set(current_to_shuffled_taxon_map.keys())
+        values = set(current_to_shuffled_taxon_map.values())
+        self.assertEqual(len(keys), len(values), "\n\n({}): {}\n\n({}): {}".format(len(keys), keys, len(values), values))
+        self.assertEqual(keys, values)
+        for taxon in tree.taxon_namespace:
+            self.assertIn(taxon, current_to_shuffled_taxon_map)
+        for nd in tree.leaf_node_iter():
+            self.assertIn(current_to_shuffled_taxon_map[nd.taxon], tree.taxon_namespace)
+            nd.taxon = current_to_shuffled_taxon_map[nd.taxon]
+        pdc2 = tree.phylogenetic_distance_matrix()
+        same_as_before = []
+        different = []
+        for t1 in tree.taxon_namespace:
+            for t2 in tree.taxon_namespace:
+                d2 = pdc2.patristic_distance(t1, t2)
+                d1 = pdc1.patristic_distance(t1, t2)
+                self.assertEqual(d1, d2)
+                if t1 is not t2:
+                    d0 = pdc0.patristic_distance(t1, t2)
+                    if d0 == d1:
+                        same_as_before.append( (t1, t2) )
+                    else:
+                        different.append( (t1, t2) )
+                else:
+                    self.assertEqual(d1, 0)
+        self.assertTrue(len(different) > 0)
+        self.assertEqual(pdc1, pdc2)
+        self.assertNotEqual(pdc0, pdc1)
+
+class TreePatristicDistTest(unittest.TestCase):
+
+    def setUp(self):
+        self.tree = dendropy.Tree.get_from_string("(((a:1, b:1):1, c:2):1, (d:2, (e:1,f:1):1):1):0;", schema="newick")
+
+    def testPatDistMatrix(self):
+        pdm = dendropy.PhylogeneticDistanceMatrix.from_tree(self.tree)
+        def _chk_distance(pdm, t1, t2, exp_distance):
+            tax1 = self.tree.taxon_namespace.require_taxon(label=t1)
+            tax2 = self.tree.taxon_namespace.require_taxon(label=t2)
+            pd = pdm(tax1, tax2)
+            self.assertEqual(pd, exp_distance, "{}: {} <-> {}: {} instead of {}".format(self.tree, t1, t2, pd, exp_distance))
+        _chk_distance(pdm, "a", "b", 2)
+        _chk_distance(pdm, "a", "c", 4)
+        _chk_distance(pdm, "b", "c", 4)
+        _chk_distance(pdm, "a", "d", 6)
+        _chk_distance(pdm, "f", "d", 4)
+        _chk_distance(pdm, "c", "d", 6)
+
+    def testPatDistFunc(self):
+        self.tree.encode_bipartitions()
+        def _chk_distance(t1, t2, exp_distance):
+            tax1 = self.tree.taxon_namespace.get_taxon(label=t1)
+            tax2 = self.tree.taxon_namespace.get_taxon(label=t2)
+            pd = treemeasure.patristic_distance(self.tree, tax1, tax2)
+            self.assertEqual(pd, exp_distance)
+        _chk_distance("a", "b", 2)
+        _chk_distance("a", "c", 4)
+        _chk_distance("b", "c", 4)
+        _chk_distance("a", "d", 6)
+        _chk_distance("f", "d", 4)
+        _chk_distance("c", "d", 6)
+
+class PhylogeneticEcologyStatsTests(unittest.TestCase):
+
+    def setUp(self):
+        self.tree = dendropy.Tree.get_from_path(
+                src=pathmap.tree_source_path("community.tree.newick"),
+                schema="newick",
+                rooting="force-rooted")
+        self.pdm = dendropy.PhylogeneticDistanceMatrix.from_tree(self.tree)
+        assemblage_data_filepath = pathmap.other_source_path("community.data.tsv")
+        with open(assemblage_data_filepath) as src:
+            self.data_table = container.DataTable.from_csv(src, default_data_type=int, delimiter="\t")
+        self.assemblage_membership_definitions = self.pdm.assemblage_membership_definitions_from_csv(
+                assemblage_data_filepath,
+                delimiter="\t")
+        self.assemblage_memberships = self.assemblage_membership_definitions.values()
+
+    def _low_precision_equality(self, v1, v2, error=1.0):
+        return abs(v1-v2) <= error
+
+    def test_nonabundance_edgeweighted_unnormalized_mpd(self):
+        # my.sample = read.table("data/PD.example.sample.txt", sep = "\t", row.names = 1, header = T)
+        # my.phylo = read.tree("data/PD.example.phylo.txt")
+        # pd.matrix = cophenetic(my.phylo)
+        # mpd(my.sample, cophenetic(my.phylo), abundance.weighted=F)
+        #    [1] 3.2225706087019050372078 1.9156605943056665974922 1.9156605943290001548007
+        #    [4] 1.9395923093204667786438 0.1934132401466666650869
+        expected_results = {
+                "C1": 3.222570608701905037208,
+                "C2": 1.915660594305666597492,
+                "C3": 1.915660594329000154801,
+                "C4": 1.939592309320466778644,
+                "C5": 0.1934132401466666650869,
+        }
+        for row_name in self.data_table.row_name_iter():
+            filter_fn = lambda taxon: self.data_table[row_name, taxon.label] > 0
+            d = self.pdm.mean_pairwise_distance(filter_fn=filter_fn)
+            self.assertAlmostEqual(d, expected_results[row_name])
+
+    def test_nonabundance_edgeweighted_unnormalized_mntd(self):
+        # my.sample = read.table("data/PD.example.sample.txt", sep = "\t", row.names = 1, header = T)
+        # my.phylo = read.tree("data/PD.example.phylo.txt")
+        # pd.matrix = cophenetic(my.phylo)
+        # mntd(my.sample, cophenetic(my.phylo), abundance.weighted=F)
+        #   [1] 1.6347319809428570991372 1.0891173926393333815099 1.0891173926543333827510
+        #   [4] 0.1180230301583333335502 0.1426761318733333339104
+        expected_results = {
+                "C1": 1.6347319809428570991372,
+                "C2": 1.0891173926393333815099,
+                "C3": 1.0891173926543333827510,
+                "C4": 0.1180230301583333335502,
+                "C5": 0.1426761318733333339104,
+        }
+        for row_name in self.data_table.row_name_iter():
+            filter_fn = lambda taxon: self.data_table[row_name, taxon.label] > 0
+            d = self.pdm.mean_nearest_taxon_distance(filter_fn=filter_fn)
+            self.assertAlmostEqual(d, expected_results[row_name])
+
+    def test_nonabundance_edgeweighted_unnormalized_ses_mpd(self):
+        # suppressMessages(library(picante))
+        # dists = as.matrix(read.csv("data/dist.csv",header=T,row.names=1))
+        # comm = as.matrix(read.csv("data/community.data.tsv",sep="\t",header=T,row.names=1))
+        # results.mpd = ses.mpd(comm, dists, null.model="taxa.labels",abundance.weighted=F,runs=100000)
+        # write.csv(format(results.mpd, digits=22), quote=F, "community.data.weighted.unnormalized.ses.mpd.csv")
+        # results.mntd = ses.mntd(comm, dists, null.model="taxa.labels",abundance.weighted=F,runs=100000)
+        # write.csv(format(results.mntd,digits=22), quote=F, "community.data.weighted.unnormalized.ses.mntd.csv")
+        with open(pathmap.other_source_path("community.data.weighted.unnormalized.ses.mpd.csv")) as src:
+            expected_results_data_table = container.DataTable.from_csv(src, default_data_type=float)
+        # for row_name in expected_results_data_table.row_name_iter():
+        #     for column_name in expected_results_data_table.column_name_iter():
+        #         v = expected_results_data_table[row_name, column_name]
+        #         print("{}, {}: {} ({})".format(row_name, column_name, v, type(v)))
+        obs_results = self.pdm.standardized_effect_size_mean_pairwise_distance(
+                assemblage_memberships=self.assemblage_memberships,
+                num_randomization_replicates=100,
+                is_weighted_edge_distances=True,
+                is_normalize_by_tree_size=False,
+                )
+        self.assertEqual(len(obs_results), expected_results_data_table.num_rows())
+        for obs_result, expected_result_row_name in zip(obs_results, expected_results_data_table.row_name_iter()):
+            self.assertTrue(self._low_precision_equality(
+                    obs_result.obs,
+                    expected_results_data_table[expected_result_row_name, "mpd.obs"],
+                    ))
+            self.assertTrue(self._low_precision_equality(
+                    obs_result.null_model_mean,
+                    expected_results_data_table[expected_result_row_name, "mpd.rand.mean"],
+                    ))
+            self.assertTrue(self._low_precision_equality(
+                    obs_result.null_model_sd,
+                    expected_results_data_table[expected_result_row_name, "mpd.rand.sd"],
+                    ))
+            self.assertTrue(self._low_precision_equality(
+                    obs_result.z,
+                    expected_results_data_table[expected_result_row_name, "mpd.obs.z"],
+                    ))
+            self.assertTrue(self._low_precision_equality(
+                    obs_result.p,
+                    expected_results_data_table[expected_result_row_name, "mpd.obs.p"],
+                    ))
+
+    def test_nonabundance_edgeweighted_unnormalized_ses_mntd(self):
+        # suppressMessages(library(picante))
+        # dists = as.matrix(read.csv("data/dist.csv",header=T,row.names=1))
+        # comm = as.matrix(read.csv("data/community.data.tsv",sep="\t",header=T,row.names=1))
+        # results.mntd = ses.mntd(comm, dists, null.model="taxa.labels",abundance.weighted=F,runs=100000)
+        # write.csv(format(results.mntd, digits=22), quote=F, "community.data.weighted.unnormalized.ses.mntd.csv")
+        # results.mntd = ses.mntd(comm, dists, null.model="taxa.labels",abundance.weighted=F,runs=100000)
+        # write.csv(format(results.mntd,digits=22), quote=F, "community.data.weighted.unnormalized.ses.mntd.csv")
+        with open(pathmap.other_source_path("community.data.weighted.unnormalized.ses.mntd.csv")) as src:
+            expected_results_data_table = container.DataTable.from_csv(src, default_data_type=float, delimiter=",")
+        # for row_name in expected_results_data_table.row_name_iter():
+        #     for column_name in expected_results_data_table.column_name_iter():
+        #         v = expected_results_data_table[row_name, column_name]
+        #         print("{}, {}: {} ({})".format(row_name, column_name, v, type(v)))
+        obs_results = self.pdm.standardized_effect_size_mean_nearest_taxon_distance(
+                assemblage_memberships=self.assemblage_memberships,
+                num_randomization_replicates=100,
+                is_weighted_edge_distances=True,
+                is_normalize_by_tree_size=False,
+                )
+        self.assertEqual(len(obs_results), expected_results_data_table.num_rows())
+        for obs_result, expected_result_row_name in zip(obs_results, expected_results_data_table.row_name_iter()):
+            self.assertTrue(self._low_precision_equality(
+                    obs_result.obs,
+                    expected_results_data_table[expected_result_row_name, "mntd.obs"],
+                    ))
+            self.assertTrue(self._low_precision_equality(
+                    obs_result.null_model_mean,
+                    expected_results_data_table[expected_result_row_name, "mntd.rand.mean"],
+                    ))
+            self.assertTrue(self._low_precision_equality(
+                    obs_result.null_model_sd,
+                    expected_results_data_table[expected_result_row_name, "mntd.rand.sd"],
+                    ))
+            self.assertTrue(self._low_precision_equality(
+                    obs_result.z,
+                    expected_results_data_table[expected_result_row_name, "mntd.obs.z"],
+                    ))
+            self.assertTrue(self._low_precision_equality(
+                    obs_result.p,
+                    expected_results_data_table[expected_result_row_name, "mntd.obs.p"],
+                    ))
+
+class PhylogeneticDistanceMatrixReader(unittest.TestCase):
+
+    def setUp(self):
+        self.s00 = """\
+         0  , 1  , 2  , 3  , 4  , 5
+         6  , 0  , 7  , 8  , 9  , 10
+         11 , 12 , 0  , 13 , 14 , 15
+         16 , 17 , 18 ,  0 , 19 , 20
+         21 , 22 , 23 , 24 , 0  , 25
+         26 , 27 , 28 , 29 , 30 , 0
+        """
+        self.s11 = """\
+        .  , a  , b  , c  , d  , e  , f
+        a  , 0  , 1  , 2  , 3  , 4  , 5
+        b  , 6  , 0  , 7  , 8  , 9  , 10
+        c  , 11 , 12 , 0  , 13 , 14 , 15
+        d  , 16 , 17 , 18 ,  0 , 19 , 20
+        e  , 21 , 22 , 23 , 24 , 0  , 25
+        f  , 26 , 27 , 28 , 29 , 30 , 0
+        """
+        self.s10 = """\
+        a  , 0  , 1  , 2  , 3  , 4  , 5
+        b  , 6  , 0  , 7  , 8  , 9  , 10
+        c  , 11 , 12 , 0  , 13 , 14 , 15
+        d  , 16 , 17 , 18 ,  0 , 19 , 20
+        e  , 21 , 22 , 23 , 24 , 0  , 25
+        f  , 26 , 27 , 28 , 29 , 30 , 0
+        """
+        self.s01 = """\
+        a  , b  , c  , d  , e  , f
+        0  , 1  , 2  , 3  , 4  , 5
+        6  , 0  , 7  , 8  , 9  , 10
+        11 , 12 , 0  , 13 , 14 , 15
+        16 , 17 , 18 ,  0 , 19 , 20
+        21 , 22 , 23 , 24 , 0  , 25
+        26 , 27 , 28 , 29 , 30 , 0
+        """
+        self.expected_labels = {
+            0 : "a",
+            1 : "b",
+            2 : "c",
+            3 : "d",
+            4 : "e",
+            5 : "f",
+        }
+        self.expected_distances = {
+            frozenset([0,1]): 1,
+            frozenset([0,2]): 2,
+            frozenset([0,3]): 3,
+            frozenset([0,4]): 4,
+            frozenset([0,5]): 5,
+            frozenset([1,2]): 7,
+            frozenset([1,3]): 8,
+            frozenset([1,4]): 9,
+            frozenset([1,5]): 10,
+            frozenset([2,2]): 0,
+            frozenset([2,3]): 13,
+            frozenset([2,4]): 14,
+            frozenset([2,5]): 15,
+            frozenset([3,4]): 19,
+            frozenset([3,5]): 20,
+            frozenset([4,5]): 25,
+        }
+
+    def check_pdm(self, pdm, is_check_labels=True):
+        self.assertEqual(len(pdm.taxon_namespace), 6)
+        for i1 in range(6):
+            t1 = pdm.taxon_namespace[i1]
+            if is_check_labels:
+                self.assertEqual(t1.label, self.expected_labels[i1])
+            for i2 in range(6):
+                t2 = pdm.taxon_namespace[i2]
+                if is_check_labels:
+                    self.assertEqual(t2.label, self.expected_labels[i2])
+                if i1 == i2:
+                    self.assertIs(t1, t2)
+                    self.assertEqual(pdm.patristic_distance(t1, t2), 0)
+                else:
+                    self.assertEqual(pdm.patristic_distance(t1, t2), self.expected_distances[frozenset([i1, i2])])
+
+    def test_read_new_taxon_namespace_with_no_row_and_no_column_names(self):
+        pdm = dendropy.PhylogeneticDistanceMatrix.from_csv(
+                StringIO(self.s00),
+                is_first_row_column_names=False,
+                is_first_column_row_names=False,
+                is_allow_new_taxa=True)
+        self.check_pdm(pdm, is_check_labels=False)
+
+    def test_read_new_taxon_namespace_with_row_and_no_column_names(self):
+        pdm = dendropy.PhylogeneticDistanceMatrix.from_csv(
+                StringIO(self.s10),
+                is_first_row_column_names=False,
+                is_first_column_row_names=True,
+                is_allow_new_taxa=True)
+        self.check_pdm(pdm, is_check_labels=True)
+
+    def test_read_new_taxon_namespace_with_no_row_and_column_names(self):
+        pdm = dendropy.PhylogeneticDistanceMatrix.from_csv(
+                StringIO(self.s01),
+                is_first_row_column_names=True,
+                is_first_column_row_names=False,
+                is_allow_new_taxa=True)
+        self.check_pdm(pdm, is_check_labels=True)
+
+    def test_read_new_taxon_namespace_with_row_and_column_names(self):
+        pdm = dendropy.PhylogeneticDistanceMatrix.from_csv(
+                StringIO(self.s11),
+                is_first_row_column_names=True,
+                is_first_column_row_names=True,
+                is_allow_new_taxa=True)
+        self.check_pdm(pdm, is_check_labels=False)
+
+    def test_read_existing_taxon_namespace_with_no_row_and_no_column_names(self):
+        taxon_namespace = dendropy.TaxonNamespace()
+        for label in self.expected_labels.values():
+            t1 = taxon_namespace.require_taxon(label=label)
+        pdm = dendropy.PhylogeneticDistanceMatrix.from_csv(
+                StringIO(self.s00),
+                taxon_namespace=taxon_namespace,
+                is_first_row_column_names=False,
+                is_first_column_row_names=False,
+                is_allow_new_taxa=True)
+        self.assertIs(taxon_namespace, pdm.taxon_namespace)
+        self.check_pdm(pdm, is_check_labels=False)
+
+    def test_read_existing_taxon_namespace_with_no_row_and_column_names(self):
+        taxon_namespace = dendropy.TaxonNamespace()
+        for label in self.expected_labels.values():
+            t1 = taxon_namespace.require_taxon(label=label)
+        pdm = dendropy.PhylogeneticDistanceMatrix.from_csv(
+                StringIO(self.s01),
+                taxon_namespace=taxon_namespace,
+                is_first_row_column_names=True,
+                is_first_column_row_names=False,
+                is_allow_new_taxa=True)
+        self.assertIs(taxon_namespace, pdm.taxon_namespace)
+        self.check_pdm(pdm, is_check_labels=True)
+
+    def test_read_existing_taxon_namespace_with_row_and_no_column_names(self):
+        taxon_namespace = dendropy.TaxonNamespace()
+        for label in self.expected_labels.values():
+            t1 = taxon_namespace.require_taxon(label=label)
+        pdm = dendropy.PhylogeneticDistanceMatrix.from_csv(
+                StringIO(self.s10),
+                taxon_namespace=taxon_namespace,
+                is_first_row_column_names=False,
+                is_first_column_row_names=True,
+                is_allow_new_taxa=True)
+        self.assertIs(taxon_namespace, pdm.taxon_namespace)
+        self.check_pdm(pdm, is_check_labels=True)
+
+    def test_read_existing_taxon_namespace_with_row_and_column_names(self):
+        taxon_namespace = dendropy.TaxonNamespace()
+        for label in self.expected_labels.values():
+            t1 = taxon_namespace.require_taxon(label=label)
+        pdm = dendropy.PhylogeneticDistanceMatrix.from_csv(
+                StringIO(self.s11),
+                taxon_namespace=taxon_namespace,
+                is_first_row_column_names=True,
+                is_first_column_row_names=True,
+                is_allow_new_taxa=True)
+        self.assertIs(taxon_namespace, pdm.taxon_namespace)
+        self.check_pdm(pdm, is_check_labels=True)
+
+class PdmTreeChecker(object):
+
+    def check_tree(self, obs_tree, expected_tree):
+        bipartitions1 = obs_tree.encode_bipartitions()
+        bipartitions2 = expected_tree.encode_bipartitions()
+        self.assertEqual(len(bipartitions1), len(bipartitions2))
+        b1 = [b.split_as_bitstring() for b in bipartitions1]
+        b2 = [b.split_as_bitstring() for b in bipartitions2]
+        self.assertEqual(set(b1), set(b2))
+        self.assertEqual(set(bipartitions1), set(bipartitions2))
+        # try:
+        #     self.assertEqual(set(bipartitions1), set(bipartitions2))
+        # except AssertionError as e:
+        #     print(e)
+        #     print(e.__dict__)
+        #     raise
+        for b1 in expected_tree.bipartition_edge_map:
+            self.assertIn(b1, obs_tree.bipartition_edge_map)
+            self.assertAlmostEqual(
+                    expected_tree.bipartition_edge_map[b1].length,
+                    obs_tree.bipartition_edge_map[b1].length,
+                    7,
+                    "{}: {} != {}".format(b1.leafset_as_newick_string(obs_tree.taxon_namespace), expected_tree.bipartition_edge_map[b1].length, obs_tree.bipartition_edge_map[b1].length,)
+                    )
+
+class PdmNeighborJoiningTree(PdmTreeChecker, unittest.TestCase):
+
+    def test_njtree_from_distance_matrices(self):
+
+        # library(ape)
+        # ---
+        # z = matrix( c(0,5,9,9,8, 5,0,10,10,9, 9,10,0,8,7, 9,10,8,0,3, 8,9,7,3,0), byrow=T, nrow=5)
+        # rownames(z)  <- c("a", "b", "c", "d", "e")
+        # colnames(z)  <- c("a", "b", "c", "d", "e")
+        # t = nj(z)
+        # write.tree(t)
+        # ---
+        # p1 = read.csv("pythonidae.mle.unweighted.pdm.csv", header=T, row.names=1)
+        # m1 = as.matrix(p1)
+        # nj(m1)
+        # t = nj(m1)
+        # write.tree(t)
+        test_runs = [
+                ("wpnjex.csv", "(e:1,d:2,((a:2,b:3):3,c:4):2);"),
+                ("saitou_and_nei_1987_table1.csv", "(h:6,g:2,((((a:5,b:2):2,c:1):1,d:3):2,(e:1,f:4):2):1);"),
+                ("pythonidae.mle.unweighted.pdm.csv", "(Morelia_spilota:1,Morelia_bredli:1,((((((Morelia_kinghorni:1,Morelia_nauta:1):1,Morelia_clastolepis:1):1,Morelia_amethistina:1):1,Morelia_tracyae:1):1,Morelia_oenpelliensis:1):1,(((((Liasis_albertisii:1,Bothrochilus_boa:1):1,((Antaresia_melanocephalus:1,Antaresia_ramsayi:1):1,((Liasis_fuscus:1,Liasis_mackloti:1):1,(Apodora_papuana:1,Liasis_olivaceus:1):1):1):1):1,Morelia_boeleni:1):1,((Python_timoriensis:1,Python_reticulatus:1):1,(( [...]
+                ("pythonidae.mle.weighted.pdm.csv", "((Liasis_albertisii:0.0542142498,Bothrochilus_boa:0.0638595214):0.038444,(((Apodora_papuana:0.0670782319,Liasis_olivaceus:0.0430801028):0.010168,(Liasis_fuscus:0.0194903208,Liasis_mackloti:0.0141916418):0.048505):0.013422,(Antaresia_melanocephalus:0.0380695554,Antaresia_ramsayi:0.0325474267):0.043626):0.007734,(((((((Antaresia_stimsoni:0.0152390165,Antaresia_childreni:0.023141749):0.032397,Antaresia_perthensis:0.0760812159):0.012848,An [...]
+                ]
+        for data_filename, expected_tree_str in test_runs:
+            with open(pathmap.other_source_path(data_filename)) as src:
+                pdm = dendropy.PhylogeneticDistanceMatrix.from_csv(
+                        src,
+                        is_first_row_column_names=True,
+                        is_first_column_row_names=True,
+                        is_allow_new_taxa=True,
+                        delimiter=",")
+            obs_tree = pdm.nj_tree()
+            # print(obs_tree.as_string("newick"))
+            # print(obs_tree.as_ascii_plot(plot_metric="length"))
+            expected_tree = dendropy.Tree.get(
+                    data=expected_tree_str,
+                    schema="newick",
+                    rooting="force-unrooted",
+                    taxon_namespace=pdm.taxon_namespace,
+                    preserve_underscores=True)
+            self.check_tree(obs_tree=obs_tree,
+                    expected_tree=expected_tree)
+
+    def test_njtree_from_weighted_and_unweighted_distances(self):
+
+        tree = dendropy.Tree.get(path=pathmap.tree_source_path(
+            "pythonidae.mle.nex"),
+            schema="nexus",
+            preserve_underscores=True)
+        pdm = tree.phylogenetic_distance_matrix()
+        test_runs = [
+                (False,  "(Morelia_spilota:1,Morelia_bredli:1,((((((Morelia_kinghorni:1,Morelia_nauta:1):1,Morelia_clastolepis:1):1,Morelia_amethistina:1):1,Morelia_tracyae:1):1,Morelia_oenpelliensis:1):1,(((((Liasis_albertisii:1,Bothrochilus_boa:1):1,((Antaresia_melanocephalus:1,Antaresia_ramsayi:1):1,((Liasis_fuscus:1,Liasis_mackloti:1):1,(Apodora_papuana:1,Liasis_olivaceus:1):1):1):1):1,Morelia_boeleni:1):1,((Python_timoriensis:1,Python_reticulatus:1):1,((((Python_sebae:1,Python_molur [...]
+                (True,   "((Liasis_albertisii:0.0542142498,Bothrochilus_boa:0.0638595214):0.038444,(((Apodora_papuana:0.0670782319,Liasis_olivaceus:0.0430801028):0.010168,(Liasis_fuscus:0.0194903208,Liasis_mackloti:0.0141916418):0.048505):0.013422,(Antaresia_melanocephalus:0.0380695554,Antaresia_ramsayi:0.0325474267):0.043626):0.007734,(((((((Antaresia_stimsoni:0.0152390165,Antaresia_childreni:0.023141749):0.032397,Antaresia_perthensis:0.0760812159):0.012848,Antaresia_maculosa:0.06792120 [...]
+                ]
+        for is_weighted_edge_distances, expected_tree_str in test_runs:
+            obs_tree = pdm.nj_tree(is_weighted_edge_distances=is_weighted_edge_distances)
+            expected_tree = dendropy.Tree.get(
+                    data=expected_tree_str,
+                    schema="newick",
+                    rooting="force-unrooted",
+                    taxon_namespace=pdm.taxon_namespace,
+                    preserve_underscores=True)
+            self.check_tree(obs_tree=obs_tree,
+                    expected_tree=expected_tree)
+
+class PdmUpgmaTree(PdmTreeChecker, unittest.TestCase):
+
+    def test_upgma_average_from_distance_matrices(self):
+        # library(phangorn)
+        # d = read.csv("wpupgmaex.csv", header=T, row.names=1)
+        # upgma(d)
+        test_runs = [
+                ("wpupgmaex.csv", "((e:11,(a:8.5,b:8.5):2.5):5.5,(c:14,d:14):2.5);"),
+                ("pythonidae.mle.weighted.pdm.csv", "(Candoia_aspera:0.3358679339,(Loxocemus_bicolor:0.239139024,(Xenopeltis_unicolor:0.2306593655,((Python_regius:0.1021235458,(Python_curtus:0.0883212354,(Python_sebae:0.0482829776,Python_molurus:0.0482829776):0.0400382578):0.01380231042):0.04278465647,((Python_timoriensis:0.06537053625,Python_reticulatus:0.06537053625):0.06029549731,(((Liasis_albertisii:0.0590368856,Bothrochilus_boa:0.0590368856):0.03300696511,(Morelia_boeleni:0.08681248 [...]
+                ("laurasiatherian.distances.ml.csv", "(Platypus:0.115554082,((Opposum:0.04554785647,(Bandicoot:0.03760589713,(Wallaroo:0.02994721074,Possum:0.02994721074):0.00765868639):0.007941959338):0.05561264108,(Elephant:0.09767314505,(Tenrec:0.09197201988,(Hedghog:0.08893681608,((Cebus:0.07429923126,(Baboon:0.06398456889,Human:0.06398456889):0.01031466238):0.01347573751,((Mouse:0.04952979734,Vole:0.04952979734):0.03752885067,(Gymnure:0.08423117145,((GuineaPig:0.0740040685,CaneRat:0 [...]
+                ## note:following fails, probably due to different arbitrary resolutions of equal distances
+                # ("pythonidae.mle.unweighted.pdm.csv", "((((Morelia_carinata:1.5,(Morelia_viridisN:1,Morelia_viridisS:1):0.5):1.458333333,((Antaresia_stimsoni:1,Antaresia_childreni:1):0.75,(Antaresia_maculosa:1.5,Antaresia_perthensis:1.5):0.25):1.208333333):1.416666667,((Morelia_bredli:1,Morelia_spilota:1):2.166666667,((Morelia_clastolepis:1.5,(Morelia_kinghorni:1,Morelia_nauta:1):0.5):0.8333333333,(Morelia_oenpelliensis:1.75,(Morelia_tracyae:1.5,Morelia_amethistina:1.5):0.25):0.5833333 [...]
+                ]
+        for data_filename, expected_tree_str in test_runs:
+            with open(pathmap.other_source_path(data_filename)) as src:
+                pdm = dendropy.PhylogeneticDistanceMatrix.from_csv(
+                        src,
+                        is_first_row_column_names=True,
+                        is_first_column_row_names=True,
+                        is_allow_new_taxa=True,
+                        delimiter=",")
+            obs_tree = pdm.upgma_tree()
+            expected_tree = dendropy.Tree.get(
+                    data=expected_tree_str,
+                    schema="newick",
+                    # rooting="force-unrooted",
+                    taxon_namespace=pdm.taxon_namespace,
+                    preserve_underscores=True)
+            self.check_tree(obs_tree=obs_tree,
+                    expected_tree=expected_tree)
+
+class NodeToNodeDistancesTest(unittest.TestCase):
+
+    def test_distances(self):
+        ## get distances from ape
+        # library(ape)
+        # tr = read.nexus("pythonidae.mle.nex")
+        # tr$node.label <- (Ntip(tr)+1):(nrow(tr$edge)+1)
+        # tr$tip.label <- (1:Ntip(tr))
+        # write.tree(tr)
+        # d = dist.nodes(tr)
+        # write.csv(d, "file.csv")
+        test_runs = [
+                ("hiv1.newick", True, "hiv1.node-to-node-dists.csv"),
+                ("pythonidae.mle.numbered-nodes.newick", True, "pythonidae.mle.node-to-node-dists.csv"),
+                ("hiv1.newick", False, "hiv1.unweighted.node-to-node-dists.csv"),
+                ("pythonidae.mle.numbered-nodes.newick", False, "pythonidae.mle.unweighted.node-to-node-dists.csv"),
+                ]
+        for tree_filename, is_weighted, distances_filename in test_runs:
+            tree = dendropy.Tree.get_from_path(
+                    src=pathmap.tree_source_path(tree_filename),
+                    schema='newick',
+                    suppress_leaf_node_taxa=True)
+            ndm = tree.node_distance_matrix()
+            reference_table = container.DataTable.from_csv(
+                    src=open(pathmap.other_source_path(distances_filename)),
+                    default_data_type=float,
+                    delimiter=",")
+            for nd1 in tree.postorder_node_iter():
+                for nd2 in tree.postorder_node_iter():
+                    d = ndm.distance(nd1, nd2, is_weighted_edge_distances=is_weighted)
+                    e = reference_table[nd1.label, nd2.label]
+                    self.assertAlmostEqual(d, e)
+
+    def test_mrca(self):
+        test_runs = [
+                "hiv1.newick",
+                "pythonidae.mle.numbered-nodes.newick",
+                ]
+        for tree_filename in test_runs:
+            tree = dendropy.Tree.get_from_path(
+                    src=pathmap.tree_source_path(tree_filename),
+                    schema='newick',
+                    rooting="force-rooted")
+            tree.encode_bipartitions()
+            ndm = tree.node_distance_matrix()
+            for nd1 in tree.postorder_node_iter():
+                for nd2 in tree.postorder_node_iter():
+                    leafset_bitmask = nd1.leafset_bitmask | nd2.leafset_bitmask
+                    exp_mrca = tree.mrca(leafset_bitmask=leafset_bitmask)
+                    obs_mrca = ndm.mrca(nd1, nd2)
+                    # print("{} | {} = {} ({})".format(
+                    #     nd1.leafset_bitmask,
+                    #     nd2.leafset_bitmask,
+                    #     leafset_bitmask,
+                    #     obs_mrca.edge.bipartition.leafset_bitmask))
+                    self.assertIs(exp_mrca, obs_mrca)
+
+if __name__ == "__main__":
+    unittest.main()
+
diff --git a/dendropy/test/test_protractedspeciation.py b/dendropy/test/test_protractedspeciation.py
new file mode 100644
index 0000000..54326f8
--- /dev/null
+++ b/dendropy/test/test_protractedspeciation.py
@@ -0,0 +1,317 @@
+#! /usr/bin/env python
+
+##############################################################################
+##  DendroPy Phylogenetic Computing Library.
+##
+##  Copyright 2010-2015 Jeet Sukumaran and Mark T. Holder.
+##  All rights reserved.
+##
+##  See "LICENSE.rst" for terms and conditions of usage.
+##
+##  If you use this work or any portion thereof in published work,
+##  please cite it as:
+##
+##     Sukumaran, J. and M. T. Holder. 2010. DendroPy: a Python library
+##     for phylogenetic computing. Bioinformatics 26: 1569-1571.
+##
+##############################################################################
+
+"""
+Tests of protracted speciation model/process.
+"""
+
+import math
+import unittest
+import dendropy
+from dendropy.model import protractedspeciation
+
+class ProtractedSpeciationCalcs(unittest.TestCase):
+
+    def test_expected_duration_of_speciation(self):
+        refs = [
+            ((0.01, 0.01, 0.0), 69.31471805599453),
+            ((0.01, 0.01, 0.005), 60.96406423356387),
+            ((0.01, 0.01, 0.01), 52.344553381571906),
+            ((0.01, 0.05, 0.0), 18.232155679395458),
+            ((0.01, 0.05, 0.005), 17.03243269197848),
+            ((0.01, 0.05, 0.01), 15.945243534199998),
+            ((0.01, 0.1, 0.0), 9.531017980432493),
+            ((0.01, 0.1, 0.005), 9.151173562881866),
+            ((0.01, 0.1, 0.01), 8.796646443907925),
+            ((0.01, 0.5, 0.0), 1.980262729617973),
+            ((0.01, 0.5, 0.005), 1.9614061471032902),
+            ((0.01, 0.5, 0.01), 1.9428949825831419),
+            ((0.01, 1.0, 0.0), 0.9950330853168092),
+            ((0.01, 1.0, 0.005), 0.9901794650170307),
+            ((0.01, 1.0, 0.01), 0.9853722709707085),
+            ((0.05, 0.01, 0.0), 35.8351893845611),
+            ((0.05, 0.01, 0.025), 34.610696533124994),
+            ((0.05, 0.01, 0.05), 27.67607317551539),
+            ((0.05, 0.05, 0.0), 13.862943611198906),
+            ((0.05, 0.05, 0.025), 12.192812846712773),
+            ((0.05, 0.05, 0.05), 10.46891067631438),
+            ((0.05, 0.1, 0.0), 8.109302162163289),
+            ((0.05, 0.1, 0.025), 7.261356156801292),
+            ((0.05, 0.1, 0.05), 6.4859100952301745),
+            ((0.05, 0.5, 0.0), 1.9062035960864987),
+            ((0.05, 0.5, 0.025), 1.830234712576371),
+            ((0.05, 0.5, 0.05), 1.7593292887815883),
+            ((0.05, 1.0, 0.0), 0.9758032833886409),
+            ((0.05, 1.0, 0.025), 0.9541399331844385),
+            ((0.05, 1.0, 0.05), 0.9333523826096167),
+            ((0.1, 0.01, 0.0), 23.978952727983707),
+            ((0.1, 0.01, 0.05), 25.39055478519575),
+            ((0.1, 0.01, 0.1), 20.28571191298721),
+            ((0.1, 0.05, 0.0), 10.986122886681098),
+            ((0.1, 0.05, 0.05), 9.802581434685468),
+            ((0.1, 0.05, 0.1), 8.109302162163289),
+            ((0.1, 0.1, 0.0), 6.931471805599453),
+            ((0.1, 0.1, 0.05), 6.096406423356386),
+            ((0.1, 0.1, 0.1), 5.23445533815719),
+            ((0.1, 0.5, 0.0), 1.8232155679395459),
+            ((0.1, 0.5, 0.05), 1.7032432691978485),
+            ((0.1, 0.5, 0.1), 1.5945243534199998),
+            ((0.1, 1.0, 0.0), 0.9531017980432493),
+            ((0.1, 1.0, 0.05), 0.9151173562881855),
+            ((0.1, 1.0, 0.1), 0.8796646443907942),
+            ((0.5, 0.01, 0.0), 7.8636512654486515),
+            ((0.5, 0.01, 0.25), 10.29910408256293),
+            ((0.5, 0.01, 0.5), 9.485738357710689),
+            ((0.5, 0.05, 0.0), 4.795790545596741),
+            ((0.5, 0.05, 0.25), 5.07811095703915),
+            ((0.5, 0.05, 0.5), 4.057142382597441),
+            ((0.5, 0.1, 0.0), 3.58351893845611),
+            ((0.5, 0.1, 0.25), 3.4610696533125007),
+            ((0.5, 0.1, 0.5), 2.7676073175515397),
+            ((0.5, 0.5, 0.0), 1.3862943611198906),
+            ((0.5, 0.5, 0.25), 1.219281284671277),
+            ((0.5, 0.5, 0.5), 1.046891067631438),
+            ((0.5, 1.0, 0.0), 0.8109302162163288),
+            ((0.5, 1.0, 0.25), 0.7261356156801294),
+            ((0.5, 1.0, 0.5), 0.6485910095230177),
+            ((1.0, 0.01, 0.0), 4.61512051684126),
+            ((1.0, 0.01, 0.5), 6.465141234074228),
+            ((1.0, 0.01, 1.0), 6.774422698356164),
+            ((1.0, 0.05, 0.0), 3.044522437723423),
+            ((1.0, 0.05, 0.5), 3.556910942852685),
+            ((1.0, 0.05, 1.0), 2.9389333245105935),
+            ((1.0, 0.1, 0.0), 2.3978952727983707),
+            ((1.0, 0.1, 0.5), 2.539055478519575),
+            ((1.0, 0.1, 1.0), 2.0285711912987203),
+            ((1.0, 0.5, 0.0), 1.0986122886681098),
+            ((1.0, 0.5, 0.5), 0.9802581434685471),
+            ((1.0, 0.5, 1.0), 0.8109302162163288),
+            ((1.0, 1.0, 0.0), 0.6931471805599453),
+            ((1.0, 1.0, 0.5), 0.6096406423356385),
+            ((1.0, 1.0, 1.0), 0.523445533815719),
+        ]
+        for params, exp_result in refs:
+            obs_result = protractedspeciation.expected_duration_of_speciation(
+                    speciation_initiation_rate=params[0],
+                    speciation_completion_rate=params[1],
+                    incipient_species_extinction_rate=params[2],
+                    )
+            self.assertAlmostEqual(obs_result, exp_result)
+
+    def test_probability_of_duration_of_speciation(self):
+        refs = [
+            ((0.01, 0.01, 0.0, 0.8795348619957456), 0.009999226458320016),
+            ((0.01, 0.01, 0.0, 0.14519027181737457), 0.009999978919814594),
+            ((0.01, 0.01, 0.0, 34.684466460885076), 0.008887282087181123),
+            ((0.01, 0.01, 0.0, 63.20061216231189), 0.0068703579303570775),
+            ((0.01, 0.01, 0.005, 0.08536631008065432), 0.012802289144553825),
+            ((0.01, 0.01, 0.005, 0.011137362557058923), 0.01280705070148593),
+            ((0.01, 0.01, 0.005, 76.52294782192368), 0.005405202225298228),
+            ((0.01, 0.01, 0.005, 72.84339288579332), 0.0057297611990511305),
+            ((0.01, 0.01, 0.01, 0.33558726166937963), 0.016125950330407143),
+            ((0.01, 0.01, 0.01, 0.20457203115105108), 0.016147205741964963),
+            ((0.01, 0.01, 0.01, 19.079554492974783), 0.012922829672422163),
+            ((0.01, 0.01, 0.01, 24.68247362845256), 0.011956431293373187),
+            ((0.01, 0.1, 0.0, 0.5935352032024056), 0.09476554969639099),
+            ((0.01, 0.1, 0.0, 0.7003470486083184), 0.09384632919173516),
+            ((0.01, 0.1, 0.0, 81.78775148685204), 1.498228340113515e-05),
+            ((0.01, 0.1, 0.0, 23.412278765465388), 0.009072720079842342),
+            ((0.01, 0.1, 0.005, 0.7792322482865833), 0.09704508143428221),
+            ((0.01, 0.1, 0.005, 0.963289936603788), 0.09533361321027416),
+            ((0.01, 0.1, 0.005, 22.853616783069036), 0.00905378799214888),
+            ((0.01, 0.1, 0.005, 65.4548715141025), 7.09734365226258e-05),
+            ((0.01, 0.1, 0.01, 0.7004511480083776), 0.10172748819395837),
+            ((0.01, 0.1, 0.01, 0.3859718489988695), 0.10501232743022515),
+            ((0.01, 0.1, 0.01, 18.979988804020195), 0.013337248459689992),
+            ((0.01, 0.1, 0.01, 22.757722164422592), 0.0085842630673195),
+            ((0.01, 1.0, 0.0, 0.3130295270193749), 0.7328713233872153),
+            ((0.01, 1.0, 0.0, 0.31154063743324156), 0.7339582420670433),
+            ((0.01, 1.0, 0.0, 88.07424235690094), 2.3767511877766183e-39),
+            ((0.01, 1.0, 0.0, 50.37034301380811), 8.209658743393956e-23),
+            ((0.01, 1.0, 0.005, 0.9003232000282951), 0.4077827698121026),
+            ((0.01, 1.0, 0.005, 0.12159170357864164), 0.8903084715946127),
+            ((0.01, 1.0, 0.005, 81.55525905558959), 1.1585339262652681e-36),
+            ((0.01, 1.0, 0.005, 72.67637856869439), 9.493325334690782e-33),
+            ((0.01, 1.0, 0.01, 0.6890551804405882), 0.5050883931592011),
+            ((0.01, 1.0, 0.01, 0.9501351410838736), 0.3878984254146435),
+            ((0.01, 1.0, 0.01, 20.649073041437447), 7.368492351424008e-10),
+            ((0.01, 1.0, 0.01, 40.24647761617133), 1.540927018047582e-18),
+            ((0.1, 0.01, 0.0, 0.8113389029985384), 0.01075027226017838),
+            ((0.1, 0.01, 0.0, 0.846887182506354), 0.010784061294478495),
+            ((0.1, 0.01, 0.0, 59.62256474016563), 0.0016681779606101286),
+            ((0.1, 0.01, 0.0, 91.65272435084043), 5.057688899425374e-05),
+            ((0.1, 0.01, 0.05, 0.8760733456577112), 0.018023721654607777),
+            ((0.1, 0.01, 0.05, 0.8409206587355896), 0.01799950113041887),
+            ((0.1, 0.01, 0.05, 51.06343770607376), 0.006125364048638298),
+            ((0.1, 0.01, 0.05, 21.687465805666022), 0.023289784397034694),
+            ((0.1, 0.01, 0.1, 0.4792155173312089), 0.03683021581716226),
+            ((0.1, 0.01, 0.1, 0.7263126839962858), 0.036728414105188914),
+            ((0.1, 0.01, 0.1, 55.892356838488816), 0.002968979103551312),
+            ((0.1, 0.01, 0.1, 81.82838924315757), 0.0005828087031488993),
+            ((0.1, 0.1, 0.0, 0.8258322196685367), 0.09932109002004828),
+            ((0.1, 0.1, 0.0, 0.2824909284607273), 0.09992024131094354),
+            ((0.1, 0.1, 0.0, 53.32752907252014), 9.334034463585915e-06),
+            ((0.1, 0.1, 0.0, 67.44160225894768), 5.548245175549618e-07),
+            ((0.1, 0.1, 0.05, 0.5636100846520368), 0.12412769734346397),
+            ((0.1, 0.1, 0.05, 0.9787149640606224), 0.12081870252730309),
+            ((0.1, 0.1, 0.05, 55.67386202995424), 3.438050746152094e-06),
+            ((0.1, 0.1, 0.05, 43.70942242490415), 4.049995603202447e-05),
+            ((0.1, 0.1, 0.1, 0.3999889157738908), 0.1552139893311176),
+            ((0.1, 0.1, 0.1, 0.6345726544794333), 0.15125759800964952),
+            ((0.1, 0.1, 0.1, 97.62739362247933), 1.0215724557144834e-10),
+            ((0.1, 0.1, 0.1, 24.52730240810091), 0.0012785880221897646),
+            ((0.1, 1.0, 0.0, 0.8115065427563289), 0.4573450980393226),
+            ((0.1, 1.0, 0.0, 0.4516132153221019), 0.6542319875705164),
+            ((0.1, 1.0, 0.0, 40.872089582281994), 3.6075312673974335e-20),
+            ((0.1, 1.0, 0.0, 24.255563803233162), 3.1283987494891642e-12),
+            ((0.1, 1.0, 0.05, 0.3457237938404357), 0.7448748845936354),
+            ((0.1, 1.0, 0.05, 0.576803770523732), 0.5879219371779756),
+            ((0.1, 1.0, 0.05, 83.20031921894818), 7.200169398604266e-42),
+            ((0.1, 1.0, 0.05, 91.43820228760569), 5.9464003697653356e-46),
+            ((0.1, 1.0, 0.1, 0.031986829095719926), 1.057136415593703),
+            ((0.1, 1.0, 0.1, 0.5519036055923441), 0.6128084744263474),
+            ((0.1, 1.0, 0.1, 77.67899885507961), 1.554561011597814e-40),
+            ((0.1, 1.0, 0.1, 20.09264881920249), 6.069727719207903e-11),
+            ((1.0, 0.01, 0.0, 0.4446353921382625), 0.015494312486713001),
+            ((1.0, 0.01, 0.0, 0.06884594296267747), 0.01070481974865263),
+            ((1.0, 0.01, 0.0, 45.0622683427891), 1.7484182033029857e-18),
+            ((1.0, 0.01, 0.0, 23.93500942694461), 3.2348325257220874e-09),
+            ((1.0, 0.01, 0.5, 0.07678647673830719), 0.020373520291909725),
+            ((1.0, 0.01, 0.5, 0.3885919433134037), 0.02369988607726227),
+            ((1.0, 0.01, 0.5, 45.11804274928912), 6.08508209809671e-10),
+            ((1.0, 0.01, 0.5, 20.568063200782436), 0.0002670604419545594),
+            ((1.0, 0.01, 1.0, 0.224072444141194), 0.10483702314125201),
+            ((1.0, 0.01, 1.0, 0.5226436349919803), 0.1042922825095739),
+            ((1.0, 0.01, 1.0, 33.02193432605858), 0.0005111539346059228),
+            ((1.0, 0.01, 1.0, 40.74024255784781), 0.00010917936840225393),
+            ((1.0, 0.1, 0.0, 0.8362413301387851), 0.194015289449898),
+            ((1.0, 0.1, 0.0, 0.6926320472771594), 0.17581989725130096),
+            ((1.0, 0.1, 0.0, 92.62429483753988), 6.822494879649729e-44),
+            ((1.0, 0.1, 0.0, 19.625562941290408), 5.095470692858589e-09),
+            ((1.0, 0.1, 0.5, 0.5302925473060789), 0.20894273300712232),
+            ((1.0, 0.1, 0.5, 0.041980900523581485), 0.17708370000687484),
+            ((1.0, 0.1, 0.5, 52.81106500217504), 2.2071314894480564e-17),
+            ((1.0, 0.1, 0.5, 25.460992608253292), 1.7080423876427843e-08),
+            ((1.0, 0.1, 1.0, 0.9296668365468552), 0.31052945846276236),
+            ((1.0, 0.1, 1.0, 0.12145631266764487), 0.36515087675508107),
+            ((1.0, 0.1, 1.0, 50.374060615431524), 1.0868531521448435e-14),
+            ((1.0, 0.1, 1.0, 11.579762731930778), 0.0006666049628160538),
+            ((1.0, 1.0, 0.0, 0.09683251662922314), 0.9906817667603305),
+            ((1.0, 1.0, 0.0, 0.10193348600169332), 0.989681117037441),
+            ((1.0, 1.0, 0.0, 39.66911063337399), 1.3992918064758832e-34),
+            ((1.0, 1.0, 0.0, 13.915328179066181), 3.2761177836735036e-12),
+            ((1.0, 1.0, 0.5, 0.8635504500484475), 0.46002864196564114),
+            ((1.0, 1.0, 0.5, 0.7909190840591199), 0.518603031188729),
+            ((1.0, 1.0, 0.5, 86.89921906556235), 5.226596384633828e-78),
+            ((1.0, 1.0, 0.5, 21.085927006318414), 4.3877525911023785e-19),
+            ((1.0, 1.0, 1.0, 0.6306393480885447), 0.6311458539888442),
+            ((1.0, 1.0, 1.0, 0.041694658805305165), 1.5492998515367982),
+            ((1.0, 1.0, 1.0, 54.275592049617586), 6.057654470628204e-53),
+            ((1.0, 1.0, 1.0, 79.41886144450676), 2.3193926494535927e-77),
+        ]
+        for params, exp_result in refs:
+            obs_result = protractedspeciation.probability_of_duration_of_speciation(
+                    tau=params[3],
+                    speciation_initiation_rate=params[0],
+                    speciation_completion_rate=params[1],
+                    incipient_species_extinction_rate=params[2],
+                    )
+            self.assertAlmostEqual(obs_result, exp_result)
+            obs_result = protractedspeciation.log_probability_of_duration_of_speciation(
+                    tau=params[3],
+                    speciation_initiation_rate=params[0],
+                    speciation_completion_rate=params[1],
+                    incipient_species_extinction_rate=params[2],
+                    )
+            self.assertAlmostEqual(obs_result, math.log(exp_result))
+
+    def test_maximum_probability_duration_of_speciation(self):
+        refs = [
+            ((0.01, 0.0001, 0.0), 455.9574441572374),
+            ((0.01, 0.0001, 0.005), 615.4051920172764),
+            ((0.01, 0.0001, 0.01), 0.0),
+            ((0.01, 0.001, 0.0), 209.32591754491338),
+            ((0.01, 0.001, 0.005), 159.4094017279303),
+            ((0.01, 0.001, 0.01), 0.0),
+            ((0.01, 0.01, 0.0), 0.0),
+            ((0.01, 0.01, 0.005), 0.0),
+            ((0.01, 0.01, 0.01), 0.0),
+            ((0.01, 100.0, 0.0), 0.0),
+            ((0.01, 100.0, 0.005), 0.0),
+            ((0.01, 100.0, 0.01), 0.0),
+            ((0.5, 0.005, 0.0), 9.119148883144735),
+            ((0.5, 0.005, 0.25), 12.308103840345511),
+            ((0.5, 0.005, 0.5), 0.0),
+            ((0.5, 0.05, 0.0), 4.186518350898265),
+            ((0.5, 0.05, 0.25), 3.1881880345586024),
+            ((0.5, 0.05, 0.5), 0.0),
+            ((0.5, 0.5, 0.0), 0.0),
+            ((0.5, 0.5, 0.25), 0.0),
+            ((0.5, 0.5, 0.5), 0.0),
+            ((0.5, 5000.0, 0.0), 0.0),
+            ((0.5, 5000.0, 0.25), 0.0),
+            ((0.5, 5000.0, 0.5), 0.0),
+            ((1.0, 0.01, 0.0), 4.559574441572368),
+            ((1.0, 0.01, 0.5), 6.154051920172756),
+            ((1.0, 0.01, 1.0), 0.0),
+            ((1.0, 0.1, 0.0), 2.0932591754491323),
+            ((1.0, 0.1, 0.5), 1.5940940172793012),
+            ((1.0, 0.1, 1.0), 0.0),
+            ((1.0, 1.0, 0.0), 0.0),
+            ((1.0, 1.0, 0.5), 0.0),
+            ((1.0, 1.0, 1.0), 0.0),
+            ((1.0, 10000.0, 0.0), 0.0),
+            ((1.0, 10000.0, 0.5), 0.0),
+            ((1.0, 10000.0, 1.0), 0.0),
+            ((100, 1.0, 0.0), 0.045595744415723685),
+            ((100, 1.0, 50.0), 0.06154051920172753),
+            ((100, 1.0, 100), 0.0),
+            ((100, 10.0, 0.0), 0.020932591754491324),
+            ((100, 10.0, 50.0), 0.01594094017279301),
+            ((100, 10.0, 100), 0.0),
+            ((100, 100.0, 0.0), 0.0),
+            ((100, 100.0, 50.0), 0.0),
+            ((100, 100.0, 100), 0.0),
+            ((100, 1000000, 0.0), 0.0),
+            ((100, 1000000, 50.0), 0.0),
+            ((100, 1000000, 100), 0.0),
+            ((1000, 10.0, 0.0), 0.004559574441572368),
+            ((1000, 10.0, 500.0), 0.006154051920172753),
+            ((1000, 10.0, 1000), 0.0),
+            ((1000, 100.0, 0.0), 0.0020932591754491327),
+            ((1000, 100.0, 500.0), 0.0015940940172793014),
+            ((1000, 100.0, 1000), 0.0),
+            ((1000, 1000.0, 0.0), 0.0),
+            ((1000, 1000.0, 500.0), 0.0),
+            ((1000, 1000.0, 1000), 0.0),
+            ((1000, 10000000, 0.0), 0.0),
+            ((1000, 10000000, 500.0), 0.0),
+            ((1000, 10000000, 1000), 0.0),
+        ]
+        for params, exp_result in refs:
+            obs_result = protractedspeciation.maximum_probability_duration_of_speciation(
+                    speciation_initiation_rate=params[0],
+                    speciation_completion_rate=params[1],
+                    incipient_species_extinction_rate=params[2],
+                    )
+            self.assertAlmostEqual(obs_result, exp_result)
+
+if __name__ == "__main__":
+    unittest.main()
+
+
diff --git a/dendropy/test/test_tree_calculations_and_metrics.py b/dendropy/test/test_tree_calculations_and_metrics.py
index 826319a..bbcc9e8 100644
--- a/dendropy/test/test_tree_calculations_and_metrics.py
+++ b/dendropy/test/test_tree_calculations_and_metrics.py
@@ -21,18 +21,15 @@ Tests of tree metrics.
 """
 
 import random
-import unittest
 import math
-try:
-    from StringIO import StringIO # Python 2 legacy support: StringIO in this module is the one needed (not io)
-except ImportError:
-    from io import StringIO # Python 3
+import unittest
 from dendropy.test.support import dendropytest
 from dendropy.test.support import pathmap
 
 import dendropy
 from dendropy.calculate import treemeasure
 from dendropy.calculate import treecompare
+from dendropy.utility.textprocessing import StringIO
 
 def _get_reference_tree_list(taxon_namespace=None):
     tree_list = dendropy.TreeList(label=None, taxon_namespace=taxon_namespace)
@@ -803,69 +800,6 @@ def _get_reference_tree_list(taxon_namespace=None):
 
     return tree_list
 
-
-class TreeEuclideanDistTest(unittest.TestCase):
-
-    def runTest(self):
-         tree_list = dendropy.TreeList.get_from_stream(
-            StringIO("""((t5:0.161175,t6:0.161175):0.392293,((t4:0.104381,(t2:0.075411,t1:0.075411):1):0.065840,t3:0.170221):0.383247);
-                        ((t5:2.161175,t6:0.161175):0.392293,((t4:0.104381,(t2:0.075411,t1:0.075411):1):0.065840,t3:0.170221):0.383247);
-                        ((t5:0.161175,t6:0.161175):0.392293,((t2:0.075411,(t4:0.104381,t1:0.075411):1):0.065840,t3:0.170221):0.383247);
-                        ((t5:0.161175,t6:0.161175):0.392293,((t4:0.104381,(t2:0.075411,t1:0.075411):0.028969):0.065840,t3:0.170221):0.383247);
-                        """),
-            schema="newick")
-         for t in tree_list:
-             t.encode_bipartitions()
-         self.assertAlmostEqual(treecompare.euclidean_distance(tree_list[0], tree_list[1]), 2.0)
-         self.assertAlmostEqual(treecompare.euclidean_distance(tree_list[0], tree_list[2]), math.sqrt(2.0))
-         self.assertAlmostEqual(treecompare.euclidean_distance(tree_list[0], tree_list[3]), 0.97103099999999998)
-         self.assertAlmostEqual(treecompare.euclidean_distance(tree_list[1], tree_list[2]), math.sqrt(6.0))
-         self.assertAlmostEqual(treecompare.euclidean_distance(tree_list[1], tree_list[3]), 2.2232636377544162)
-         self.assertAlmostEqual(treecompare.euclidean_distance(tree_list[2], tree_list[3]), 1.000419513484718)
-
-class TreeSymmetricDistTest(unittest.TestCase):
-
-    def runTest(self):
-         ref = dendropy.Tree.get_from_stream(StringIO("((t5,t6),((t4,(t2,t1)),t3));"), schema="newick")
-         taxon_namespace = ref.taxon_namespace
-         ref.encode_bipartitions()
-         o_tree = dendropy.Tree.get_from_stream(StringIO("((t1,t2),((t4,(t5,t6)),t3));"), schema="newick", taxon_namespace=taxon_namespace)
-         o_tree.encode_bipartitions()
-         self.assertEqual(treecompare.symmetric_difference(o_tree, ref), 2)
-
-class TreePatristicDistTest(unittest.TestCase):
-
-    def setUp(self):
-        self.tree = dendropy.Tree.get_from_string("(((a:1, b:1):1, c:2):1, (d:2, (e:1,f:1):1):1):0;", schema="newick")
-
-    def testPatDistMatrix(self):
-        pdm = treemeasure.PatristicDistanceMatrix(self.tree)
-        def _chk_distance(pdm, t1, t2, exp_distance):
-            tax1 = self.tree.taxon_namespace.require_taxon(label=t1)
-            tax2 = self.tree.taxon_namespace.require_taxon(label=t2)
-            pd = pdm(tax1, tax2)
-            self.assertEqual(pd, exp_distance, "{}: {} <-> {}: {} instead of {}".format(self.tree, t1, t2, pd, exp_distance))
-        _chk_distance(pdm, "a", "b", 2)
-        _chk_distance(pdm, "a", "c", 4)
-        _chk_distance(pdm, "b", "c", 4)
-        _chk_distance(pdm, "a", "d", 6)
-        _chk_distance(pdm, "f", "d", 4)
-        _chk_distance(pdm, "c", "d", 6)
-
-    def testPatDistFunc(self):
-        self.tree.encode_bipartitions()
-        def _chk_distance(t1, t2, exp_distance):
-            tax1 = self.tree.taxon_namespace.get_taxon(label=t1)
-            tax2 = self.tree.taxon_namespace.get_taxon(label=t2)
-            pd = treemeasure.patristic_distance(self.tree, tax1, tax2)
-            self.assertEqual(pd, exp_distance)
-        _chk_distance("a", "b", 2)
-        _chk_distance("a", "c", 4)
-        _chk_distance("b", "c", 4)
-        _chk_distance("a", "d", 6)
-        _chk_distance("f", "d", 4)
-        _chk_distance("c", "d", 6)
-
 class TreeUnaryMetricsTest(unittest.TestCase):
 
     def testNBar(self):
@@ -1017,6 +951,35 @@ class TreeUnaryMetricsTest(unittest.TestCase):
         g = treemeasure.pybus_harvey_gamma(tree)
         self.assertAlmostEqual(g, 0.546276, 4)
 
+class TreeEuclideanDistTest(unittest.TestCase):
+
+    def runTest(self):
+         tree_list = dendropy.TreeList.get_from_stream(
+            StringIO("""((t5:0.161175,t6:0.161175):0.392293,((t4:0.104381,(t2:0.075411,t1:0.075411):1):0.065840,t3:0.170221):0.383247);
+                        ((t5:2.161175,t6:0.161175):0.392293,((t4:0.104381,(t2:0.075411,t1:0.075411):1):0.065840,t3:0.170221):0.383247);
+                        ((t5:0.161175,t6:0.161175):0.392293,((t2:0.075411,(t4:0.104381,t1:0.075411):1):0.065840,t3:0.170221):0.383247);
+                        ((t5:0.161175,t6:0.161175):0.392293,((t4:0.104381,(t2:0.075411,t1:0.075411):0.028969):0.065840,t3:0.170221):0.383247);
+                        """),
+            schema="newick")
+         for t in tree_list:
+             t.encode_bipartitions()
+         self.assertAlmostEqual(treecompare.euclidean_distance(tree_list[0], tree_list[1]), 2.0)
+         self.assertAlmostEqual(treecompare.euclidean_distance(tree_list[0], tree_list[2]), math.sqrt(2.0))
+         self.assertAlmostEqual(treecompare.euclidean_distance(tree_list[0], tree_list[3]), 0.97103099999999998)
+         self.assertAlmostEqual(treecompare.euclidean_distance(tree_list[1], tree_list[2]), math.sqrt(6.0))
+         self.assertAlmostEqual(treecompare.euclidean_distance(tree_list[1], tree_list[3]), 2.2232636377544162)
+         self.assertAlmostEqual(treecompare.euclidean_distance(tree_list[2], tree_list[3]), 1.000419513484718)
+
+class TreeSymmetricDistTest(unittest.TestCase):
+
+    def runTest(self):
+         ref = dendropy.Tree.get_from_stream(StringIO("((t5,t6),((t4,(t2,t1)),t3));"), schema="newick")
+         taxon_namespace = ref.taxon_namespace
+         ref.encode_bipartitions()
+         o_tree = dendropy.Tree.get_from_stream(StringIO("((t1,t2),((t4,(t5,t6)),t3));"), schema="newick", taxon_namespace=taxon_namespace)
+         o_tree.encode_bipartitions()
+         self.assertEqual(treecompare.symmetric_difference(o_tree, ref), 2)
+
 class TreeCompareTests(dendropytest.ExtendedTestCase):
 
     def setUp(self):
@@ -1098,22 +1061,52 @@ class TreeCompareTests(dendropytest.ExtendedTestCase):
 #                if (i * i+j+1) % 6 == 0:
 #                    print
 
-class FrequencyOfSplitsTest(unittest.TestCase):
+class FrequencyOfBipartitionsTests(unittest.TestCase):
 
-    def setUp(self):
-        self.trees = dendropy.TreeList.get_from_path(
+    def testCount1(self):
+        trees = dendropy.TreeList.get_from_path(
                 src=pathmap.tree_source_path('pythonidae.random.bd0301.tre'),
                 schema='nexus')
-
-    def testCount1(self):
         bipartition_leaves = ['Python regius', 'Apodora papuana']
-        f = self.trees.frequency_of_bipartition(labels=bipartition_leaves)
+        f = trees.frequency_of_bipartition(labels=bipartition_leaves)
         self.assertAlmostEqual(f, 0.04)
 
     def testRaisesIndexError(self):
+        trees = dendropy.TreeList.get_from_path(
+                src=pathmap.tree_source_path('pythonidae.random.bd0301.tre'),
+                schema='nexus')
         bipartition_leaves = ['Bad Taxon', 'Apodora papuana']
-        self.assertRaises(IndexError, self.trees.frequency_of_bipartition, labels=bipartition_leaves)
+        self.assertRaises(IndexError, trees.frequency_of_bipartition, labels=bipartition_leaves)
+
+    def test_freqs2(self):
+        trees = dendropy.TreeList.get(
+                path=pathmap.tree_source_path("pythonidae.mb.run1.t"),
+                schema='nexus')
+        test_sets = [
+                # labels, split bitmask, frequency
+                ( ["Python molurus", "Python regius"],                                24576, 0.00990099009901 ),
+                ( ["Morelia clastolepis", "Morelia nauta", "Morelia kinghorni"],  536877056,   0.990099009901 ),
+                ( ["Liasis olivaceus", "Apodora papuana"],                          4194432,   0.346534653465 ),
+                ]
+        for labels, split_bitmask, exp_freq in test_sets:
+            self.assertAlmostEqual(trees.frequency_of_bipartition(labels=labels), exp_freq)
+            taxa = trees.taxon_namespace.get_taxa(labels=labels)
+            self.assertAlmostEqual(trees.frequency_of_bipartition(taxa=taxa), exp_freq)
+            split_bitmask = trees.taxon_namespace.taxa_bitmask(labels=labels)
+            self.assertEqual(split_bitmask, split_bitmask)
+            self.assertAlmostEqual(trees.frequency_of_bipartition(split_bitmask=split_bitmask), exp_freq)
+            bipartition = dendropy.Bipartition(bitmask=split_bitmask)
+            self.assertAlmostEqual(trees.frequency_of_bipartition(bipartition=bipartition), exp_freq)
 
+    def test_tree_bipartitions_encoding(self):
+        trees = dendropy.TreeList.get(
+                path=pathmap.tree_source_path("pythonidae.mb.run1.t"),
+                schema='nexus')
+        labels = ["Liasis olivaceus", "Apodora papuana"]
+        freq = trees.frequency_of_bipartition(
+                labels=labels,
+                is_bipartitions_updated=True) # this will be ignore as the member `Tree.bipartition_encoding` are not populated
+        self.assertAlmostEqual(freq, 0.346534653465)
 
 if __name__ == "__main__":
     unittest.main()
diff --git a/dendropy/test/test_tree_operations_and_manipulations.py b/dendropy/test/test_tree_operations_and_manipulations.py
index 661070b..cf7944f 100644
--- a/dendropy/test/test_tree_operations_and_manipulations.py
+++ b/dendropy/test/test_tree_operations_and_manipulations.py
@@ -20,15 +20,12 @@
 Tests native tree structuring routines.
 """
 
-try:
-    from StringIO import StringIO # Python 2 legacy support: StringIO in this module is the one needed (not io)
-except ImportError:
-    from io import StringIO # Python 3
 import sys
 if not (sys.version_info.major >= 3 and sys.version_info.minor >= 4):
     from dendropy.utility.filesys import pre_py34_open as open
 import unittest
 from dendropy.test.support import curated_test_tree
+from dendropy.test.support import compare_and_validate
 from dendropy.test.support import pathmap
 from dendropy.test.support import dendropytest
 from dendropy.utility import messaging
@@ -36,6 +33,7 @@ from dendropy.test.support.dendropytest import ExtendedTestCase
 from dendropy.test.support.mockrandom import MockRandom
 import dendropy
 from dendropy.calculate import treecompare
+from dendropy.utility.textprocessing import StringIO
 import re
 
 _LOG = messaging.get_logger(__name__)
@@ -768,6 +766,151 @@ class ResolvePolytomiesTestCase(dendropytest.ExtendedTestCase):
                 for rng in (MockRandom(), None):
                     self.verify_resolve_polytomies(tree_string2, rng)
 
+class TestStructureExtraction(
+        curated_test_tree.CuratedTestTree,
+        compare_and_validate.Comparator,
+        unittest.TestCase):
+
+    def setUp(self):
+        self.taxon_label_inclusion_sets = (
+            ("i", "k", "l", "n", "p"),
+            ("i", "j", "k", "l", "m", "n", "p"),
+            ("j", "k"),
+            ("i", "k"),
+            ("i", "p"),
+            ("i", "j", "n"),
+        )
+
+    def test_full_extract(self):
+        tree1, anodes1, lnodes1, inodes1 = self.get_tree(
+                suppress_internal_node_taxa=True,
+                suppress_leaf_node_taxa=False)
+        tree2 = tree1.extract_tree()
+        self.compare_distinct_trees(tree1, tree2,
+                taxon_namespace_scoped=True,
+                compare_tree_annotations=False,
+                compare_taxon_annotations=False)
+
+    def test_filtered_leaf_extract(self):
+        for suppress_internal_node_taxa in (True, ):#False):
+            for inclusion_set in self.taxon_label_inclusion_sets:
+                tree1, anodes1, lnodes1, inodes1 = self.get_tree(
+                        suppress_internal_node_taxa=suppress_internal_node_taxa,
+                        suppress_leaf_node_taxa=False)
+                to_include = set([tree1.taxon_namespace.get_taxon(label) for label in inclusion_set])
+                assert None not in to_include
+                node_filter_fn = lambda nd: nd.is_internal() or nd.taxon in to_include
+                tree2 = tree1.extract_tree(node_filter_fn=node_filter_fn)
+                tree1.retain_taxa(to_include)
+                self.compare_distinct_trees(tree1, tree2,
+                        taxon_namespace_scoped=True,
+                        compare_tree_annotations=False,
+                        compare_taxon_annotations=False)
+
+    def test_extract_with_taxa(self):
+        for taxon_label_inclusion_set in self.taxon_label_inclusion_sets:
+            tree1, anodes1, lnodes1, inodes1 = self.get_tree(
+                    suppress_internal_node_taxa=False,
+                    suppress_leaf_node_taxa=False)
+            to_include_taxa = set([tree1.taxon_namespace.get_taxon(label) for label in taxon_label_inclusion_set])
+            assert None not in to_include_taxa
+            tree1.retain_taxa(to_include_taxa)
+            tree2 = tree1.extract_tree_with_taxa_labels(taxon_label_inclusion_set)
+            self.compare_distinct_trees(tree1, tree2,
+                    taxon_namespace_scoped=True,
+                    compare_tree_annotations=False,
+                    compare_taxon_annotations=False)
+            tree3 = tree1.extract_tree_with_taxa(to_include_taxa)
+            self.compare_distinct_trees(tree1, tree3,
+                    taxon_namespace_scoped=True,
+                    compare_tree_annotations=False,
+                    compare_taxon_annotations=False)
+
+    def test_extract_without_taxa(self):
+        for taxon_label_inclusion_set in self.taxon_label_inclusion_sets:
+            tree1, anodes1, lnodes1, inodes1 = self.get_tree(
+                    suppress_internal_node_taxa=False,
+                    suppress_leaf_node_taxa=False)
+            to_exclude_taxa = set([t for t in tree1.taxon_namespace if t.label not in taxon_label_inclusion_set])
+            assert None not in to_exclude_taxa
+            tree1.prune_taxa(to_exclude_taxa)
+            to_exclude_taxa_labels = set([t.label for t in to_exclude_taxa])
+            tree2 = tree1.extract_tree_without_taxa(to_exclude_taxa)
+            self.compare_distinct_trees(tree1, tree2,
+                    taxon_namespace_scoped=True,
+                    compare_tree_annotations=False,
+                    compare_taxon_annotations=False)
+            tree3 = tree1.extract_tree_without_taxa_labels(to_exclude_taxa_labels)
+            self.compare_distinct_trees(tree1, tree3,
+                    taxon_namespace_scoped=True,
+                    compare_tree_annotations=False,
+                    compare_taxon_annotations=False)
+
+    def test_special_case1(self):
+        original_tree_str = """\
+        [&R] ((((e1:4.25978504749,a0:4.25978504749):9.75100657322,(e5:11.2557415909,c9:11.2557415909):2.75505002977):5.25672273638,(c5:17.0225375511,e6:17.0225375511):2.24497680601):20.9755404109,(((c7:0.0433876754663,e4:0.0433876754663):16.2031718648,(b1:14.1628944123,d7:14.1628944123):2.08366512802):14.3825543479,((((d1:13.4235384066,(d4:7.64533761739,c3:7.64533761739):5.77820078917):2.00948796838,((d8:3.10025757397,b5:3.10025757397):5.07496414931,a4:8.17522172328):7.25780465166):4.528 [...]
+        """
+        expected_tree_strs = """\
+        [&R] (a0:40.243054768,((a4:19.9612599287,((a7:8.94718577977,(a1:7.27393108685,(a5:6.96381328023,(a2:3.43218264885,a9:3.43218264885):3.53163063138):0.310117806629):1.67325469292):10.4373218626,a3:19.3845076424):0.576752286338):1.05878660087,(a8:7.31781944487,a6:7.31781944487):13.7022270847):19.2230082384):6.65318140005;
+        [&R] (b1:30.6291138882,((b5:19.9612599287,(((b6:7.27393108685,(b8:5.11546115425,b4:5.11546115425):2.15846993261):5.94434017116,b9:13.218271258):6.16623638436,b2:19.3845076424):0.576752286338):1.05878660087,((b0:1.6464852541,b7:1.6464852541):10.0630186678,b3:11.7095039219):9.31054260769):9.60906735859):16.2671222799;
+        [&R] ((c9:19.2675143571,c5:19.2675143571):20.9755404109,(c7:30.6291138882,(c3:19.9612599287,((((c2:7.27393108685,c6:7.27393108685):2.2871299598,(c1:5.91732320427,c8:5.91732320427):3.64373784238):3.65721021136,c0:13.218271258):6.16623638436,c4:19.3845076424):0.576752286338):10.6678539595):9.61394087983):6.65318140005;
+        [&R] (d7:30.6291138882,(((d1:13.4235384066,d4:13.4235384066):2.00948796838,d8:15.4330263749):4.52823355379,(((((d6:9.56106104665,d9:9.56106104665):3.65721021136,d2:13.218271258):1.63573163655,d5:14.8540028946):2.25255068893,d3:17.1065535835):2.27795405888,d0:19.3845076424):0.576752286338):10.6678539595):16.2671222799;
+        [&R] (((e1:14.0107916207,e5:14.0107916207):5.25672273638,e6:19.2675143571):20.9755404109,(e4:30.6291138882,(((e0:7.27393108685,e8:7.27393108685):5.94434017116,(e9:1.84550535315,e3:1.84550535315):11.3727659049):6.16623638436,(e7:11.8237814661,e2:11.8237814661):7.56072617631):11.2446062458):9.61394087983):6.65318140005;
+        """
+
+        tns = dendropy.TaxonNamespace()
+        source_tree1 = dendropy.Tree.get(
+                data=original_tree_str,
+                schema="newick",
+                taxon_namespace=tns)
+        source_tree2 = dendropy.Tree.get(
+                data=original_tree_str,
+                schema="newick",
+                taxon_namespace=tns)
+        self.assertEqual(treecompare.weighted_robinson_foulds_distance(source_tree1, source_tree2), 0.0)
+        group_ids = ("a", "b", "c", "d", "e")
+        expected_induced_trees = dendropy.TreeList.get(
+                data=expected_tree_strs,
+                schema="newick",
+                taxon_namespace=tns)
+        assert len(expected_induced_trees) == len(group_ids)
+        for group_id, expected_induced_tree in zip(group_ids, expected_induced_trees):
+            extracted_tree = source_tree1.extract_tree(
+                    node_filter_fn=lambda node: node.taxon.label.startswith(group_id),
+                    is_apply_filter_to_leaf_nodes=True,
+                    is_apply_filter_to_internal_nodes=False)
+            for leaf_nd in extracted_tree.leaf_node_iter():
+                self.assertTrue(leaf_nd.taxon.label.startswith(group_id))
+            for leaf_nd in expected_induced_tree.leaf_node_iter():
+                assert leaf_nd.taxon.label.startswith(group_id)
+
+            # self.assertEqual(treecompare.weighted_robinson_foulds_distance(source_tree1, source_tree2), 0.0)
+            self.assertEqual(treecompare.unweighted_robinson_foulds_distance(extracted_tree, expected_induced_tree), 0)
+            self.assertAlmostEqual(treecompare.weighted_robinson_foulds_distance(extracted_tree, expected_induced_tree), 0.0)
+
+    def test_special_case2(self):
+        original_tree_str = """\
+        [&R] ((a1,(a2,(a3,a4)a0)),(b1,(b2,(b3,b4))));
+        """
+        source_tree1 = dendropy.Tree.get(
+                data=original_tree_str,
+                schema="newick",
+                )
+        expected_tree_str = """\
+        [&R] ((a3,a4)a0);
+        """
+        extracted_tree = source_tree1.extract_tree(
+                # node_filter_fn=lambda node: node.taxon is not None and node.taxon.label.startswith("a"),
+                node_filter_fn=lambda node: node.taxon.label in set(["a3", "a4"]),
+                is_apply_filter_to_leaf_nodes=True,
+                is_apply_filter_to_internal_nodes=False,
+                )
+        expected_tree = dendropy.Tree.get(
+                data=expected_tree_str,
+                schema="newick",
+                taxon_namespace=source_tree1.taxon_namespace)
+        self.assertEqual(treecompare.unweighted_robinson_foulds_distance(extracted_tree, expected_tree), 0.0)
+
 class TreeRestructuring(dendropytest.ExtendedTestCase):
 
     def test_collapse_basal_bifurcation(self):
@@ -785,9 +928,6 @@ class TreeRestructuring(dendropytest.ExtendedTestCase):
     def test_reroot_at_edge(self):
         self.assertFalse(self.fail_incomplete_tests())
 
-    def test_reroot_at_midpoint(self):
-        self.assertFalse(self.fail_incomplete_tests())
-
     def test_suppress_unifurcations(self):
         self.assertFalse(self.fail_incomplete_tests())
 
diff --git a/dendropy/test/test_tree_shape_kernel.py b/dendropy/test/test_tree_shape_kernel.py
new file mode 100644
index 0000000..503c4b0
--- /dev/null
+++ b/dendropy/test/test_tree_shape_kernel.py
@@ -0,0 +1,291 @@
+#! /usr/bin/env python
+
+##############################################################################
+##  DendroPy Phylogenetic Computing Library.
+##
+##  Copyright 2010-2015 Jeet Sukumaran and Mark T. Holder.
+##  All rights reserved.
+##
+##  See "LICENSE.rst" for terms and conditions of usage.
+##
+##  If you use this work or any portion thereof in published work,
+##  please cite it as:
+##
+##     Sukumaran, J. and M. T. Holder. 2010. DendroPy: a Python library
+##     for phylogenetic computing. Bioinformatics 26: 1569-1571.
+##
+##############################################################################
+
+import math
+import unittest
+import collections
+import dendropy
+from dendropy.calculate import treecompare
+from dendropy.calculate.treecompare import TreeShapeKernel
+from dendropy.calculate.treecompare import AssemblageInducedTreeManager
+from dendropy.calculate.treecompare import AssemblageInducedTreeShapeKernel
+
+class TreeShapeKernelBasicCalculationTest(unittest.TestCase):
+
+    def test_small_single(self):
+        ## Test based on:
+        ##      KAMPHIR
+        ##      By Art F.Y. Poon and Rosemary McCloskey
+        ##      https://github.com/ArtPoon/kamphir.git
+        T1_str = "[&R] ( ( A:0.5, B:0.25 )E:0.5, ( C:0.25, D:0.25 )F:0.5 )G;"
+        T2_str = "[&R] ( ( ( A:0.25, B:0.25 )E:0.5, C:0.25 )F:0.5, D:0.25 )G;"
+        taxon_namespace = dendropy.TaxonNamespace()
+        T1 = dendropy.Tree.get_from_string(T1_str, "newick", taxon_namespace=taxon_namespace)
+        T2 = dendropy.Tree.get_from_string(T2_str, "newick", taxon_namespace=taxon_namespace)
+        tree_shape_kernel = TreeShapeKernel(decay_factor=0.5, gauss_factor=1)
+        assert tree_shape_kernel(T1, T2) == 1.125 * (1+math.exp(-0.0625))
+
+    def test_different_size_trees(self):
+        # sigma = 1
+        # gaussFactor = 1
+        # decayFactor = 0.1
+        trees_str = """\
+        [&R] (T1:12.5150033896,((T2:9.56663932282,(((T3:1.07963880769,T4:1.07963880769):4.33934073323,(T5:0.649236454849,T6:0.649236454849):4.76974308607):1.9951772698,T7:7.41415681072):2.1524825121):0.294448382741,T8:9.86108770556):2.65391568409):1.88016636219;
+        [&R] ((((T1:2.63300806671,(T2:1.36260395686,T3:1.36260395686):1.27040410984):13.0805656885,(((T4:6.49642565476,(T5:4.76391492099,(T6:2.31456992456,(T7:1.43347670305,(T8:0.845099591454,(T9:0.749944158281,T10:0.749944158281):0.0951554331727):0.588377111599):0.881093221511):2.44934499642):1.73251073377):1.78625805849,(T11:1.99279678602,T12:1.99279678602):6.28988692723):5.93122188014,T13:14.2139055934):1.49966816178):9.5804936484,(((((((T14:0.205658120519,T15:0.205658120519):7.754821 [...]
+        [&R] ((T1:18.4726052336,(T2:16.7820588123,T3:16.7820588123):1.69054642133):21.0361145203,(((T4:22.1454645535,T5:22.1454645535):1.47756990124,((((((T6:3.72910479068,T7:3.72910479068):0.635795000427,(T8:3.12137642206,T9:3.12137642206):1.24352336905):4.02980332076,T10:8.39470311187):0.544576038938,T11:8.93927915081):4.15398513837,((T12:1.29491896299,T13:1.29491896299):3.95016532419,(T14:3.55950898913,T15:3.55950898913):1.68557529805):7.848180002):6.79081967153,(T16:13.3961088469,((T [...]
+        [&R] ((((T1:12.2171017101,(T2:5.80709236615,T3:5.80709236615):6.4100093439):0.163771078375,(T4:1.48920874144,T5:1.48920874144):10.891664047):6.14111109308,((T6:18.0816707702,T7:18.0816707702):0.315080693117,(T8:9.85665216391,((T9:3.58056555459,T10:3.58056555459):0.704080460611,T11:4.2846460152):5.57200614872):8.54009929938):0.125232418213):0.445776242893,(((T12:10.3677145836,(T13:1.58010326492,T14:1.58010326492):8.78761131866):2.28511142688,T15:12.6528260105):1.47666702282,(T16:1 [...]
+        [&R] (((T1:10.2887625813,((T2:3.40673675066,T3:3.40673675066):4.35878457692,T4:7.76552132758):2.52324125374):8.94208354363,((((((T5:1.25729509129,T6:1.25729509129):1.98815007493,T7:3.24544516622):9.92816453819,T8:13.1736097044):0.131783344535,((T9:5.12529436775,T10:5.12529436775):2.8254015761,T11:7.95069594385):5.3546971051):0.31354548999,((T12:6.23707496437,T13:6.23707496437):1.40621592147,T14:7.64329088584):5.97564765309):2.09487953589,(((T15:4.48342349888,T16:4.48342349888):1. [...]
+        [&R] (((T1:21.6283980853,(T2:10.2523638386,T3:10.2523638386):11.3760342467):5.43593515808,(((T4:14.5815467291,((T5:10.2802760256,(T6:2.13975995776,T7:2.13975995776):8.14051606783):1.62385561861,T8:11.9041316442):2.67741508492):5.60705586175,(T9:5.28631833362,(T10:5.19018203656,((T11:0.654535739431,(T12:0.451288383503,T13:0.451288383503):0.203247355928):0.3240577623,T14:0.978593501732):4.21158853482):0.0961362970605):14.9022842572):6.30642464811,(T15:6.96742024513,T16:6.9674202451 [...]
+        [&R] (((((T1:2.69139513211,T2:2.69139513211):8.551485817,T3:11.2428809491):6.39974203014,((T4:17.0587824705,(((((T5:1.0038538602,(T6:0.65693286312,(T7:0.372810170449,T8:0.372810170449):0.284122692671):0.346920997081):0.992649847145,T9:1.99650370735):8.59545004131,T10:10.5919537487):3.93618536755,(T11:11.4771452793,(T12:11.3117342188,(((T13:1.44496178243,T14:1.44496178243):1.39593941106,T15:2.84090119349):7.36176225558,T16:10.2026634491):1.10907076976):0.16541106051):3.05099383686 [...]
+        [&R] ((((T1:7.07157972517,(T2:0.0218808463127,T3:0.0218808463127):7.04969887886):0.8655582016,(T4:3.02712438178,T5:3.02712438178):4.91001354499):1.21415733877,(((T6:0.0583489618229,T7:0.0583489618229):1.01650984984,T8:1.07485881166):4.07712736061,T9:5.15198617228):3.99930909326):7.26950003749,(((T10:0.424456263841,T11:0.424456263841):8.04936250082,T12:8.47381876466):3.5117568466,((T13:6.98368939693,(T14:0.777662333494,T15:0.777662333494):6.20602706344):2.06669325023,T16:9.0503826 [...]
+        [&R] (((T1:14.4454814308,((T2:3.56688601323,T3:3.56688601323):5.84751651584,T4:9.41440252907):5.03107890172):20.1795615891,(((((T5:4.15054680055,T6:4.15054680055):11.295603376,(T7:6.43442739414,T8:6.43442739414):9.01172278238):0.10084264253,(T9:8.4004080966,T10:8.4004080966):7.14658472244):2.73330732663,(((T11:6.10577944378,(T12:4.04456805007,(T13:2.80049127557,T14:2.80049127557):1.2440767745):2.06121139371):1.90192017764,(T15:7.79084487337,T16:7.79084487337):0.216854748047):7.40 [...]
+        """
+        expected = [[ [] for i in range(10) ] for i in range(10)]
+        expected[0][0] = 1.02943649816
+        expected[0][1] = 0.629696880372
+        expected[0][2] = 0.226436166785
+        expected[0][3] = 0.504437998991
+        expected[0][4] = 0.532944026681
+        expected[0][5] = 1.06675009986
+        expected[0][6] = 0.63997331036
+        expected[0][7] = 0.533570048403
+        expected[0][8] = 0.316006296153
+        expected[0][9] = 0.763121914566
+        expected[1][0] = 0.629696880372
+        expected[1][1] = 5.73381840453
+        expected[1][2] = 0.609230566852
+        expected[1][3] = 1.36716715734
+        expected[1][4] = 1.66142414246
+        expected[1][5] = 3.3424585382
+        expected[1][6] = 2.81647328252
+        expected[1][7] = 1.6426813156
+        expected[1][8] = 1.71534697686
+        expected[1][9] = 2.11186097095
+        expected[2][0] = 0.226436166785
+        expected[2][1] = 0.609230566852
+        expected[2][2] = 3.41707388515
+        expected[2][3] = 0.965818487686
+        expected[2][4] = 1.8148659483
+        expected[2][5] = 1.09814847947
+        expected[2][6] = 1.70646748651
+        expected[2][7] = 0.543992787817
+        expected[2][8] = 1.89068146553
+        expected[2][9] = 1.2301930343
+        expected[3][0] = 0.504437998991
+        expected[3][1] = 1.36716715734
+        expected[3][2] = 0.965818487686
+        expected[3][3] = 3.52734267013
+        expected[3][4] = 1.6121784729
+        expected[3][5] = 1.9713400052
+        expected[3][6] = 1.968844455
+        expected[3][7] = 0.727319654436
+        expected[3][8] = 1.07080235987
+        expected[3][9] = 2.06317190944
+        expected[4][0] = 0.532944026681
+        expected[4][1] = 1.66142414246
+        expected[4][2] = 1.8148659483
+        expected[4][3] = 1.6121784729
+        expected[4][4] = 7.13717804604
+        expected[4][5] = 2.47204082769
+        expected[4][6] = 2.17747252512
+        expected[4][7] = 1.58536532878
+        expected[4][8] = 2.31434377631
+        expected[4][9] = 2.23786059877
+        expected[5][0] = 1.06675009986
+        expected[5][1] = 3.3424585382
+        expected[5][2] = 1.09814847947
+        expected[5][3] = 1.9713400052
+        expected[5][4] = 2.47204082769
+        expected[5][5] = 7.77913926686
+        expected[5][6] = 2.87296840413
+        expected[5][7] = 2.30072202059
+        expected[5][8] = 2.12831286543
+        expected[5][9] = 3.00420928696
+        expected[6][0] = 0.63997331036
+        expected[6][1] = 2.81647328252
+        expected[6][2] = 1.70646748651
+        expected[6][3] = 1.968844455
+        expected[6][4] = 2.17747252512
+        expected[6][5] = 2.87296840413
+        expected[6][6] = 7.32395549398
+        expected[6][7] = 1.3099686298
+        expected[6][8] = 2.72462663407
+        expected[6][9] = 2.60804726918
+        expected[7][0] = 0.533570048403
+        expected[7][1] = 1.6426813156
+        expected[7][2] = 0.543992787817
+        expected[7][3] = 0.727319654436
+        expected[7][4] = 1.58536532878
+        expected[7][5] = 2.30072202059
+        expected[7][6] = 1.3099686298
+        expected[7][7] = 3.00348381586
+        expected[7][8] = 1.05294859724
+        expected[7][9] = 1.30614199254
+        expected[8][0] = 0.316006296153
+        expected[8][1] = 1.71534697686
+        expected[8][2] = 1.89068146553
+        expected[8][3] = 1.07080235987
+        expected[8][4] = 2.31434377631
+        expected[8][5] = 2.12831286543
+        expected[8][6] = 2.72462663407
+        expected[8][7] = 1.05294859724
+        expected[8][8] = 6.04463164133
+        expected[8][9] = 2.07119628549
+        expected[9][0] = 0.763121914566
+        expected[9][1] = 2.11186097095
+        expected[9][2] = 1.2301930343
+        expected[9][3] = 2.06317190944
+        expected[9][4] = 2.23786059877
+        expected[9][5] = 3.00420928696
+        expected[9][6] = 2.60804726918
+        expected[9][7] = 1.30614199254
+        expected[9][8] = 2.07119628549
+        expected[9][9] = 4.7667655343
+        trees = dendropy.TreeList.get(data=trees_str, schema="newick")
+        tree_shape_kernel = TreeShapeKernel(
+                sigma=1,
+                gauss_factor=1,
+                decay_factor=0.1,
+                )
+        for idx1, t1 in enumerate(trees):
+            for idx2, t2 in enumerate(trees):
+                self.assertAlmostEqual(tree_shape_kernel(t1, t2), expected[idx1][idx2])
+                # print("{}, {} = {}".format(idx1+1, idx2+1, tree_shape_kernel(t1, t2)))
+
+class AssemblageInducedTreeManagerTestBase(unittest.TestCase):
+
+    GROUP_IDS = ("a", "b", "c", "d", "e")
+
+    @staticmethod
+    def get_random_tree():
+        from dendropy.model import birthdeath
+        tns = dendropy.TaxonNamespace()
+        for group_id in AssemblageInducedTreeManagerTests.GROUP_IDS:
+            for group_member in range(10):
+                t = tns.require_taxon(label="{}{}".format(
+                    group_id,
+                    group_member))
+        tree = dendropy.simulate.birth_death_tree(
+                birth_rate=0.1,
+                death_rate=0.0,
+                taxon_namespace=tns)
+        tree.assemblage_leaf_sets = []
+        tree.assemblage_classification_regime_subtrees = []
+        for group_id in AssemblageInducedTreeManagerTests.GROUP_IDS:
+            node_filter_fn=lambda nd: nd.taxon is None or nd.taxon.label.startswith(group_id)
+            subtree1 = tree.extract_tree(
+                    node_filter_fn=node_filter_fn)
+            assemblage_leaf_set = set()
+            for leaf_nd in tree.leaf_node_iter():
+                if node_filter_fn(leaf_nd):
+                    assert leaf_nd.taxon.label.startswith(group_id)
+                    assemblage_leaf_set.add(leaf_nd)
+            tree.assemblage_leaf_sets.append(assemblage_leaf_set)
+            tree.assemblage_classification_regime_subtrees.append(subtree1)
+        assert len(tree.assemblage_classification_regime_subtrees) == len(AssemblageInducedTreeManagerTests.GROUP_IDS)
+        return tree
+
+    def validate_managed_trees(self, test_target, trees):
+        self.assertEqual(test_target._num_assemblage_classifications, len(AssemblageInducedTreeManagerTests.GROUP_IDS))
+        self.assertEqual(len(test_target._tree_assemblage_induced_trees_map), len(trees))
+        for tree in trees:
+            self.assertIn(tree, test_target._tree_assemblage_induced_trees_map)
+            self.assertEqual(len(test_target._tree_assemblage_induced_trees_map[tree]), len(AssemblageInducedTreeManagerTests.GROUP_IDS))
+            self.assertEqual(len(test_target._tree_assemblage_induced_trees_map[tree]), len(tree.assemblage_leaf_sets))
+            induced_trees = test_target._tree_assemblage_induced_trees_map[tree]
+            for ( induced_tree, group_id, original_leafset_nodes) in zip( induced_trees, AssemblageInducedTreeManagerTests.GROUP_IDS, tree.assemblage_leaf_sets):
+                original_leafset = set(original_leafset_nodes)
+                for leaf_nd in induced_tree.leaf_node_iter():
+                    self.assertTrue(leaf_nd.taxon.label.startswith(group_id), leaf_nd.taxon.label)
+                    original_node = leaf_nd.extraction_source
+                    self.assertIn(original_node, original_leafset)
+                    original_leafset.remove(original_node)
+                self.assertEqual(len(original_leafset), 0)
+                labels=[x.taxon.label for x in original_leafset_nodes]
+                t2 = tree.extract_tree_with_taxa_labels(labels=labels)
+                self.assertEqual(treecompare.weighted_robinson_foulds_distance(t2, induced_tree), 0.0)
+                t3 = dendropy.Tree(tree)
+                t3.retain_taxa_with_labels(labels=labels)
+                # print(t3.as_string("newick"))
+                # print(induced_tree.as_string("newick"))
+                self.assertAlmostEqual(treecompare.weighted_robinson_foulds_distance(t3, induced_tree), 0.0)
+
+class AssemblageInducedTreeManagerTests(AssemblageInducedTreeManagerTestBase):
+
+    def test_basic_subtree_generation_and_caching(self):
+        test_target = AssemblageInducedTreeManager()
+        trees = []
+        for idx in range(10):
+            tree = self.get_random_tree()
+            tree.induced_trees = test_target.generate_induced_trees(
+                tree=tree,
+                assemblage_leaf_sets=tree.assemblage_leaf_sets)
+            self.assertEqual(len(tree.induced_trees), len(AssemblageInducedTreeManagerTests.GROUP_IDS))
+            self.assertEqual(len(tree.induced_trees), len(tree.assemblage_leaf_sets))
+            for induced_tree in tree.induced_trees:
+                self.assertIn(induced_tree, test_target._tree_assemblage_induced_trees_map[tree])
+            trees.append(tree)
+        self.validate_managed_trees(
+                test_target=test_target,
+                trees=trees)
+
+class AssemblageInducedTreeShapeKernelTests(AssemblageInducedTreeManagerTestBase):
+
+    def validate_managed_and_cached_trees(self, test_target, trees):
+        self.validate_managed_trees(
+                test_target=test_target,
+                trees=trees)
+        for tree in trees:
+            self.assertIn(tree, test_target._tree_cache)
+            self.assertEqual(len(test_target._tree_assemblage_induced_trees_map[tree]), len(AssemblageInducedTreeManagerTests.GROUP_IDS))
+            # for induced_tree in test_target._tree_assemblage_induced_trees_map[tree]:
+            #     self.assertIn(induced_tree, test_target._tree_cache)
+
+    def test_comparison_add_trees_directly(self):
+        test_target = AssemblageInducedTreeShapeKernel()
+        trees = [self.get_random_tree() for idx in range(10)]
+        for tree in trees:
+            test_target.update_assemblage_induced_tree_cache(
+                    tree=tree,
+                    assemblage_leaf_sets=tree.assemblage_leaf_sets)
+            ## to check for inadvertent double adding
+            test_target.update_assemblage_induced_tree_cache(
+                    tree=tree,
+                    assemblage_leaf_sets=tree.assemblage_leaf_sets)
+        self.validate_managed_and_cached_trees(
+                test_target=test_target,
+                trees=trees)
+
+    def test_comparison_add_trees_by_comparison(self):
+        test_target = AssemblageInducedTreeShapeKernel()
+        trees = [self.get_random_tree() for idx in range(10)]
+        tree1 = trees[0]
+        for tree2 in trees[1:]:
+            x = test_target(
+                    tree1=tree1,
+                    tree2=tree2,
+                    tree1_assemblage_leaf_sets=tree1.assemblage_leaf_sets,
+                    tree2_assemblage_leaf_sets=tree2.assemblage_leaf_sets,
+                    )
+        self.validate_managed_and_cached_trees(
+                test_target=test_target,
+                trees=trees)
+
+if __name__ == "__main__":
+    unittest.main()
+
diff --git a/dendropy/utility/bitprocessing.py b/dendropy/utility/bitprocessing.py
index 2561d74..6c5bd78 100644
--- a/dendropy/utility/bitprocessing.py
+++ b/dendropy/utility/bitprocessing.py
@@ -70,9 +70,9 @@ def least_significant_set_bit(n):
     return m ^ n
 
 def indexes_of_set_bits(s, fill_bitmask=-1, one_based=False, ordination_in_mask=False):
-    return [i for i in iter_set_bit_indexes(s, fill_bitmask, one_based, ordination_in_mask)]
+    return [i for i in set_bit_index_iter(s, fill_bitmask, one_based, ordination_in_mask)]
 
-def iter_set_bit_indexes(s, fill_bitmask=-1, one_based=False, ordination_in_mask=False):
+def set_bit_index_iter(s, fill_bitmask=-1, one_based=False, ordination_in_mask=False):
     """
     Returns the index of each bit that is on in ``s`` and the ``fill_bitmask``
 
diff --git a/dendropy/utility/cli.py b/dendropy/utility/cli.py
index c38ca7a..8f72175 100644
--- a/dendropy/utility/cli.py
+++ b/dendropy/utility/cli.py
@@ -117,7 +117,7 @@ def compose_citation_for_program(
         include_preamble=True,
         include_epilog=True):
     if dendropy_description is None:
-        dendropy_description = dendropy.description()
+        dendropy_description = dendropy.description_text()
     citation_lines = []
     citation_lines.extend(dendropy.citation_info(include_preamble=include_preamble, width=width))
     if additional_citations:
diff --git a/dendropy/utility/container.py b/dendropy/utility/container.py
index 3f4a5c0..a6d65e0 100644
--- a/dendropy/utility/container.py
+++ b/dendropy/utility/container.py
@@ -23,6 +23,7 @@ Various data structures.
 import collections
 import copy
 import sys
+import csv
 
 ###############################################################################
 ## OrderedSet
@@ -145,7 +146,7 @@ class OrderedSet(object):
 
     def __contains__(self, value):
         """
-        Returns `True` if ``value`` is in ``self`` or `False` otherwise.
+        Returns |True| if ``value`` is in ``self`` or |False| otherwise.
         """
         return value in self._item_set
 
@@ -676,6 +677,272 @@ class FrozenOrderedDict(collections.OrderedDict):
         temp._is_frozen = True
         return temp
 
+##############################################################################
+## DataTable
+
+class DataTable(object):
+
+    @classmethod
+    def from_csv(cls,
+            src,
+            is_first_row_column_names=True,
+            is_first_column_row_names=True,
+            is_trim_space=True,
+            default_data_type=None,
+            column_data_types=None,
+            label_transform_fn=None,
+            **csv_reader_kwargs
+            ):
+        """
+        Returns table from a full-configured csv.Reader instance.
+
+        Parameters
+        -----------
+        csv_reader : a csv.Reader instance
+            The source of the data.
+        is_first_row_column_names : bool
+            If True, then the first row is interpreted as column names;
+            otherwise, treated as data row.
+        is_first_column_row_names : bool
+            If True, then the first column is interpreted as row names;
+            otherwise, treated as data column.
+        is_trim_space : bool
+            If True, then will strip space from both sides of all tokens before
+            processing. Note that only spaces will be trimmed, not tabs.
+        default_data_type : type or function object
+            Any callable that, when passed a value, returns the coerced-to-type
+            equivalent for the data.
+        column_data_types : dict
+            A dictionary where the key are the column names and the
+            corresponding value the type (see ``default_data_type`` for
+            description).
+
+        Returns
+        -------
+        t: a DataTable instance
+            Returns table from a full-configured csv.Reader instance.
+
+        """
+        if isinstance(src, str):
+            with open(src, "r") as fsrc:
+                return cls._from_csv_file(
+                    src=fsrc,
+                    is_first_row_column_names=is_first_row_column_names,
+                    is_first_column_row_names=is_first_column_row_names,
+                    is_trim_space=is_trim_space,
+                    default_data_type=default_data_type,
+                    column_data_types=column_data_types,
+                    label_transform_fn=label_transform_fn,
+                    **csv_reader_kwargs)
+        else:
+            return cls._from_csv_file(
+                src=src,
+                is_first_row_column_names=is_first_row_column_names,
+                is_first_column_row_names=is_first_column_row_names,
+                is_trim_space=is_trim_space,
+                default_data_type=default_data_type,
+                column_data_types=column_data_types,
+                label_transform_fn=label_transform_fn,
+                **csv_reader_kwargs)
+
+    @classmethod
+    def _from_csv_file(cls,
+            src,
+            is_first_row_column_names=True,
+            is_first_column_row_names=True,
+            is_trim_space=True,
+            default_data_type=None,
+            column_data_types=None,
+            label_transform_fn=None,
+            **csv_reader_kwargs
+            ):
+        ncols = None
+        data_table = cls()
+        if is_first_row_column_names:
+            first_data_row_offset = 1
+        else:
+            first_data_row_offset = 0
+        if is_first_column_row_names:
+            first_data_column_offset = 1
+        else:
+            first_data_column_offset = 0
+        if column_data_types is None:
+            column_data_types = {}
+        if label_transform_fn is None:
+            label_transform_fn = lambda x: x
+        csv_reader = csv.reader(src, **csv_reader_kwargs)
+        for row_idx, row in enumerate(csv_reader):
+            if ncols is None:
+                ncols = len(row)
+            else:
+                if len(row) == 1 and row[0].strip() == "" and is_trim_space: # blank row
+                    continue
+                assert ncols == len(row), "{} != {}".format(ncols, len(row))
+            for cell_idx, cell in enumerate(row):
+                if is_trim_space:
+                    cell = cell.strip(" ")
+                if row_idx == 0 and is_first_row_column_names:
+                    if cell_idx == 0 and is_first_column_row_names:
+                        continue
+                    data_table.add_column(
+                            column_name=label_transform_fn(cell),
+                            data_type=column_data_types.get(cell, default_data_type))
+                elif cell_idx == 0 and is_first_column_row_names:
+                    data_table.add_row(label_transform_fn(cell))
+                else:
+                    if row_idx == 0 and not is_first_row_column_names:
+                        data_table.add_column(data_type=column_data_types.get(cell, default_data_type))
+                    if cell_idx == 0 and not is_first_column_row_names:
+                        data_table.add_row()
+                    effective_row_idx = row_idx - first_data_row_offset
+                    assert effective_row_idx < len(data_table._row_names), "{}: {}".format(effective_row_idx, data_table._row_names)
+                    effective_column_idx = cell_idx - first_data_column_offset
+                    assert effective_column_idx < len(data_table._column_names), "{}: {}".format(effective_column_idx, data_table._column_names)
+                    data_table[effective_row_idx, effective_column_idx] = cell
+        return data_table
+
+    def __init__(self):
+        self._row_names = []
+        self._row_name_set = set()
+        self._column_names = []
+        self._column_data_types = {}
+        self._column_name_set = set()
+        self._data = {}
+
+    def add_column(self, column_name=None, pos=None, data_type=None):
+        column_name = self._validate_new_column_name(column_name)
+        assert column_name not in self._column_name_set
+        if pos is None:
+            pos = len(self._column_names)
+        self._column_names.insert(pos, column_name)
+        self._column_name_set.add(column_name)
+        self._column_data_types[column_name] = data_type
+
+    def add_row(self, row_name=None, pos=None):
+        row_name = self._validate_new_row_name(row_name)
+        assert row_name not in self._row_name_set
+        if pos is None:
+            pos = len(self._row_names)
+        self._row_names.insert(pos, row_name)
+        self._row_name_set.add(row_name)
+
+    def __getitem__(self, key):
+        row_name = self._dereference_key(
+                key=key[0],
+                name_list=self._row_names,
+                name_set=self._row_name_set)
+        column_name = self._dereference_key(
+                key=key[1],
+                name_list=self._column_names,
+                name_set=self._column_name_set)
+        if row_name not in self._data:
+            return None
+        if column_name not in self._data[row_name]:
+            return None
+        return self._data[row_name][column_name]
+
+    def __setitem__(self, key, value):
+        row_name = self._dereference_key(
+                key=key[0],
+                name_list=self._row_names,
+                name_set=self._row_name_set)
+        column_name = self._dereference_key(
+                key=key[1],
+                name_list=self._column_names,
+                name_set=self._column_name_set)
+        if row_name not in self._data:
+            self._data[row_name] = {}
+        if self._column_data_types[column_name] is not None:
+            value = self._column_data_types[column_name](value)
+        self._data[row_name][column_name] = value
+
+    def row_name_iter(self):
+        for row_name in self._row_names:
+            yield row_name
+
+    def column_name_iter(self):
+        for column_name in self._column_names:
+            yield column_name
+
+    def row_value_iter(self, column_name):
+        column_name = self._dereference_key(
+                key=column_name,
+                name_list=self._column_names,
+                name_set=self._column_name_set)
+        for row_name in self._row_names:
+            yield self[row_name, column_name]
+
+    def column_value_iter(self, row_name):
+        row_name = self._dereference_key(
+                key=row_name,
+                name_list=self._row_names,
+                name_set=self._row_name_set)
+        for column_name in self._column_names:
+            yield self[row_name, column_name]
+
+    def write_csv(self,
+            out,
+            is_first_row_column_names=True,
+            is_first_column_row_names=True,
+            missing_data_value="NA",
+            **csv_writer_kwargs
+            ):
+        if isinstance(out, str):
+            dest = open(out, "w")
+        else:
+            dest = out
+        if "delimiter" not in csv_writer_kwargs:
+            csv_writer_kwargs["delimiter"] = ","
+        csv_writer = csv.writer(dest, csv_writer_kwargs)
+        if is_first_row_column_names:
+            header = []
+            if is_first_column_row_names:
+                header.append("")
+            header.extend(self._column_names)
+            csv_writer.writerow(header)
+        for row_name in self._row_names:
+            row = []
+            if is_first_column_row_names:
+                row.append(row_name)
+            for column_name in self._column_names:
+                v = self[row_name, column_name]
+                if v is None:
+                    v = missing_data_value
+                row.append(v)
+            csv_writer.writerow(row)
+
+    def _validate_new_column_name(self, column_name=None):
+        if column_name is None:
+            column_name = "V{}".format(len(self._column_names))
+        else:
+            column_name = str(column_name)
+        return column_name
+
+    def _validate_new_row_name(self, row_name=None):
+        if row_name is None:
+            row_name = "V{}".format(len(self._row_names))
+        else:
+            row_name = str(row_name)
+        return row_name
+
+    def _dereference_key(self, key, name_list, name_set):
+        if isinstance(key, int):
+            return name_list[key]
+        else:
+            if key not in name_set:
+                raise KeyError(key)
+            else:
+                return key
+
+    def num_rows(self):
+        return len(self._row_names)
+
+    def num_columns(self):
+        return len(self._column_names)
+
+    def __len__(self):
+        return self.num_rows()
+
 ###############################################################################
 ## Generic Container Interace (for reference)
 
diff --git a/dendropy/utility/error.py b/dendropy/utility/error.py
index af52db4..96d80ba 100644
--- a/dendropy/utility/error.py
+++ b/dendropy/utility/error.py
@@ -20,10 +20,6 @@
 Errors, exceptions, warnings, etc.
 """
 
-try:
-    from StringIO import StringIO # Python 2 legacy support: StringIO in this module is the one needed (not io)
-except ImportError:
-    from io import StringIO # Python 3
 import sys
 import re
 import warnings
@@ -34,7 +30,7 @@ class ImmutableTaxonNamespaceError(TypeError):
     def __init__(self, message):
         TypeError.__init__(self, message)
 
-class DataError(Exception):
+class DataParseError(Exception):
 
     def __init__(self,
             message=None,
@@ -71,21 +67,6 @@ class DataError(Exception):
             c =  " at column {}".format(self.col_num)
         return "Error parsing data source{}{}{}: {}".format(f, l, c, self.message)
 
-class DataParseError(DataError):
-
-    def __init__(self,
-            message=None,
-            line_num=None,
-            col_num=None,
-            filename=None,
-            stream=None):
-        DataError.__init__(self,
-                message=message,
-                line_num=line_num,
-                col_num=col_num,
-                filename=filename,
-                stream=stream)
-
 class UnsupportedSchemaError(NotImplementedError):
 
     def __init__(self, *args, **kwargs):
@@ -133,6 +114,14 @@ class TaxonNamespaceIdentityError(ValueError):
                 )
         ValueError.__init__(self, message)
 
+class SingleTaxonAssemblageException(ValueError):
+    def __init__(self, message=None):
+        ValueError.__init__(self, message)
+
+class NullAssemblageException(ValueError):
+    def __init__(self, message=None):
+        ValueError.__init__(self, message)
+
 class MixedRootingError(ValueError):
     def __init__(self, message=None):
         ValueError.__init__(self, message)
@@ -145,11 +134,16 @@ class UltrametricityError(ValueError):
     def __init__(self, message=None):
         ValueError.__init__(self, message)
 
-class TreeSimTotalExtinctionException(Exception):
+class ProcessFailedException(Exception):
     """Exception to be raised when branching process results in all lineages going extinct."""
     def __init__(self, *args, **kwargs):
         Exception.__init__(self, *args, **kwargs)
 
+class TreeSimTotalExtinctionException(ProcessFailedException):
+    """Exception to be raised when branching process results in all lineages going extinct."""
+    def __init__(self, *args, **kwargs):
+        ProcessFailedException.__init__(self, *args, **kwargs)
+
 class SeedNodeDeletionException(Exception):
 
     def __init__(self, *args, **kwargs):
diff --git a/dendropy/utility/textprocessing.py b/dendropy/utility/textprocessing.py
index 40c854c..9bb8d50 100644
--- a/dendropy/utility/textprocessing.py
+++ b/dendropy/utility/textprocessing.py
@@ -28,6 +28,13 @@ import locale
 import codecs
 
 ###############################################################################
+## Cross-version compatibility
+try:
+    from StringIO import StringIO # Python 2 legacy support: StringIO in this module is the one needed (not io)
+except ImportError:
+    from io import StringIO # Python 3
+
+###############################################################################
 ## Unicode/String Conversions
 
 ENCODING = locale.getdefaultlocale()[1]
@@ -54,6 +61,18 @@ def parse_curie_standard_qualified_name(prefixed_name, sep=":"):
         raise ValueError("'{}' is not a valid CURIE-standard qualified name".format(prefixed_name))
     return prefixed_name.split(":", 1)
 
+## From:
+    # The Peyotl module of the Open Tree of Life Project
+    # Mark T. Holder
+    # https://github.com/mtholder/peyotl
+    # https://github.com/mtholder/peyotl/blob/c3a544211edc669e664bae28095d52cecfa004f3/peyotl/utility/str_util.py#L5-L25
+if sys.version_info.major == 2:
+    def is_str_type(x):
+        return isinstance(x, basestring)
+else:
+    def is_str_type(x):
+        return isinstance(x, str)
+
 ###############################################################################
 ##
 
diff --git a/dendropy/utility/vcsinfo.py b/dendropy/utility/vcsinfo.py
index d3259f4..4aef2ed 100644
--- a/dendropy/utility/vcsinfo.py
+++ b/dendropy/utility/vcsinfo.py
@@ -22,12 +22,9 @@ Wraps up source version control system system information.
 
 import os
 import sys
-try:
-    from StringIO import StringIO # Python 2 legacy support: StringIO in this module is the one needed (not io)
-except ImportError:
-    from io import StringIO # Python 3
 import subprocess
 import datetime
+from dendropy.utility import textprocessing
 from dendropy.utility import processio
 
 class Revision(object):
@@ -143,7 +140,7 @@ class Revision(object):
         self._is_available = True
 
     def _run_vcs(self, cmd):
-        if isinstance(cmd, str):
+        if textprocessing.is_str_type(cmd):
             cmd = self.vcs_app_path + " " + cmd
         else:
             cmd.insert(0, self.vcs_app_path)

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-med/python-dendropy.git



More information about the debian-med-commit mailing list